However as a result of that fiasco a number of articles were posted about the removal of DRM from e-books using Calibre, which is an open-source program for managing your electronic library on your computer and converting between formats. You have to download and manually install some plugins in addition to the standard distribution, but once they are installed you just add a DRMed book to your Calibre library, and it automatically gets the DRM stripped out.
In parallel with this, a long-running legal case between the US Department of Justice and a number of e-book publishers resulted in a settlement under which prices have dropped considerably, and are now significantly cheaper than the paperback price.
So that was my two main objections to an ebook reader dealt with: I could now share books with family in a similar way to a paper copy, and I wasn't paying the publisher to leave out the paper. So I asked for a Kindle for my birthday last year.
I'm very happy with it. I've downloaded some classics from the Gutenberg project, and also picked up some more obscure books like the updated edition of "Code and Other Laws of Cyberspace" that I have been wanting to read for a long time. Specialist books like this seem to be a lot cheaper in ebook format, presumably because so much of the cost in the dead-tree version is taken up in the overheads of short-run printing and storage. But even Anathem was only £2.99 (although it seems to be rather more when I look at it now).
My wife tried out my Kindle as well, and asked for one for Christmas. When Amazon proved unable to deliver in time I bought one from the local branch of Waterstones bookshop. This turned out to be a mistake: the Kindles bought from Waterstones have the nice varied "screensaver" pictures replaced with a fixed bit of Waterstones branding that can't be replaced (I've come across some instructions for replacing that image by logging into the Kindle using TCP over USB, but that particular back door seems to have been closed now).
On Monday, 13 August 2012, while passing a bus on Princes Street my bike got caught in the tram line and I was thrown to the ground. A second bus was behind me, and stopped in time. Perhaps I am fortunate that the trams have been so delayed, for if it had been a tram behind me I doubt it could have come to a halt quickly enough to avoid running me over. In my case, I merely had to wait in ER four hours to have my little finger x-rayed and stitched, plus further hospital visits later to check that the fracture healed correctly. The current street signage suggests bicyclists should ride down the middle of the tram tracks, which seems a recipe for disaster. I've met with others who have had bicycle accidents on Princes Street, and we are convinced that if nothing is done it is only a matter of time until there is a fatality. To save lives, and to improve the quality of life in Edinburgh, I've joined with others to petition that Princes Street be made car-free, with separate zones for pedestrians, bicycles, and trams. This will provide a much needed bicycle route west-to-east across the city centre, connecting existing routes. You can sign the petition here.
Which Comonad typeclass from Hackage should I be using? Ed Kmett's comonad package? Or is there a better option?
To build up my intuition about comonads, I would like to immerse myself in as many comonadic instances as possible. What are the important comonadic types?
And to reduce the pain of using them in my code, where are their canonical implementations on Hackage?
I am aware of:
Ed Kmett's comonad-transformers package, containing
- Store/Costate --- e.g. data Store b a = Store b (b -> a)
- Environment/Coreader --- e.g. data Env b a = Env b a
- Traced/Cowriter --- e.g. data Traced m a = Monoid m => Traced (m -> a)
Stream --- e.g. data Stream a = Stream a (Stream a)
I can only find this in obselete versions of comonad-transformers.
Non-empty lists --- e.g. data NonEmptyList a = NonEmptyList a [a]
Available with a Comonad instance from the appropriately-named NonEmptyList package.
Identity --- e.g. newtype Identity a = Identity a
As far as I know, this is the only trivial comonad. (e.g. you cannot write an extract for newtype Const b a = Const b.) Am I wrong?
Cofree --- from Ed Kmett's free package --- thanks Tekmo
Density --- from Ed Kmett's kan-extensions package --- thanks Tekmo
[link] [11 comments]
The end of last month saw the 0.11 release of the heist and snap packages. It was not accompanied by our traditional announcement and release notes blog post, and some people have been asking about it. Here is a brief description of what is going on and how the 0.11 release affects you.
tl;dr The core functionality of compiled heist is stable, but the API is still maturing. 0.11 is a significant step in the right direction, but it didn’t get a release announcement because we’re making rapid progress and might make more major releases in the near future. If you want to start using compiled heist today in production applications, then you should talk to us directly on IRC so we can collaborate.0.10
The 0.10 release completely redesigned heist, but those changes did not affect snap-core and snap-server at all. Prior to this, we had made a pattern of making major releases of all our packages in lock step. But since 0.10 made no breaking changes to snap-core and snap-server, we decided after much debate to not introduce a major version bump to -core and -server that did not actually have any breaking changes.
The main motivator here was that we wanted to get the new Heist code out the door so we could get more feedback. We are working up to a 1.0 release and wanted to have more experience working with the new compiled heist paradigm before giving it 1.0 status.Maturing an API
When 0.10 was released we had been working on it for eight months. The core idea of compiled splices was fairly mature and well thought out, but since it still had not been used in large-scale production applications the API was immature. This pattern is not unfamiliar. The basic concept for interpreted Heist was there in 0.1, but we didn’t discover the incredibly useful runChildrenWith pattern until 0.6. It takes time to tease apart the higher level patterns that make a more friendly API.
The compiled Heist paradigm is no different. I recently started doing a lot of work with compiled splices in a real world app. That is giving me a lot of feedback that I am using to improve the API. I released 0.11 early so that people could become aware of these patterns now, rather than getting used to the less friendly 0.10 API. However, the new API is still a work in progress. I don’t know what tomorrow will bring, so I can’t predict how it will evolve. But once I feel the API is more stable we will make full release notes for everything that happened after 0.10.
Time for another upgrade of my GHC installation. OK, I know I already posted about this twice but yet again the process was different from the previous ones.
My first attempts of installing GHC and the Haskell Platform a year ago relied on using packages from my distribution’s repository. This quickly turned out to be problematic so I decided for a direct installation of the Haskell Platform. This worked perfectly fine except for the fact that Haskell packages were installed in different subdirectories of /usr/local, which lead to a bit of a mess and problems with controlling what is installed where (this is useful if you want to remove a package). So the second time I was installing Haskell Platform I was smarter and refined the whole process. This time I confined the installation to a single directory so that both GHC and all the packages are located in a single, easy to find place.
Yesterday I figured out it would be great to get a new version of GHC. GHC 7.6.1 was released on 6th September 2012 and the updated 7.6.2 version is only two weeks old. While GHC 7.6.1 has been out for over 5 months it is still not part of the Haskell Platform and it won’t be for the next three months. That’s too long a wait for me so I decided to send the Platform to /dev/null and just install GHC and its environment from scratch.
My plan to install GHC from precompiled binaries went up the spout:
This build requires libgmp.so.3.
Watwatwat? Now what is that supposed to mean? Previously released binaries didn’t depend on one particular version of libgmp library. Of course my system has libgmp.so.10 and any attempt to install an older version results in breaking package dependencies. I downloaded binaries anyway and tried to run them:[killy@xerxes : ~/ghc-7.6.2/ghc/stage2/build/tmp] ./ghc-stage2 --interactive ./ghc-stage2: error while loading shared libraries: libgmp.so.3: cannot open shared object file: No such file or directory
OK, so that requirement is true – you need the exact version of libgmp. So what now? I know! Compilation from sources! I’ve been hacking on GHC recently so I already have sources on my drive. Unfortunately it turned out that after switching GHC repo and all its subrepos to ghc-7.6 branch I get some compilation errors. I wasn’t in the mood for debugging this so I switched everything back to master and downloaded the source snapshot. From now on things are easy, assuming that you already have an older version of GHC on your system. After extracting the sources I copied $(TOP)/mk/build.mk.sample to $(TOP)/mk/build.mk ($(TOP) refers to directory containing GHC sources) and uncommented the line BuildFlavour = perf-llvm. This gives me fully optimized build using LLVM. Now the compilation:perl boot ./configure --prefix=/usr/local/ghc-7.6.2 make
This will build GHC and prepare it for installation in /usr/local/ghc-7.6.2. Fully optimized build takes much over an hour on all 4 cores. After the build is done all one needs to do is run make install as root. At this stage old GHC can be removed. You of course need to add /usr/local/ghc-7.6.2/bin to PATH environmental variable. As I already have mentioned I have the habit of installing all the packages system-wide in a single directory. For that I need to edit /root/.cabal/config file by adding the following entry:install-dirs global prefix:/usr/local/ghc-7.6.2
All that is left now is installing cabal-install. Grab the sources from hackage, extract them and run (as root) sh bootstrap.sh --global in the source directory. This installs cabal-install with its dependencies. Now you can start installing other packages that you need (a.k.a. compile the World).
This completes Yet Another Installation of GHC.