News aggregator

ICFP 2016 Second Call for Papers

haskell-cafe - Tue, 02/09/2016 - 8:09am
ICFP 2016 The 21st ACM SIGPLAN International Conference on Functional Programming Second Call for Papers Important dates --------------- Submissions due: Wednesday, March 16 2016, 15:00 (UTC) (now open) Author response: Monday, 2 May, 2016, 15:00 (UTC) - Thursday, 5 May, 2016, 15:00 (UTC) Notification: Friday, 20 May, 2016 Final copy due: TBA Early registration: TBA Conference: Monday, 19 September - Wednesday, 21 September, 2016 (note updated conference dates) Scope ----- ICFP 2016 seeks original papers on the art and science of functional programming. Submissions are invited on all topics from principles to practice, from foundations to features, and from abstraction to application. The scope includes all languages that encourage functional prog
Categories: Offsite Discussion

Combining ST with STM

haskell-cafe - Tue, 02/09/2016 - 5:43am
Hi friends, I have an STM transaction that needs some private, temporary state. The most obvious way is to simply pass pure state as arguments, but for efficiency, I would like this state to be some kind of mutable array, like STArray. I know, STM has TVars and TArray, but since this state is private to the transaction, I am wondering if using TVars/TArrays for private state might be overkill that will unnecessarily slow down the STM commit process. The private state is, by definition, not shared, so including it in the STM log and commit process is, as far as I can tell, pointless. ST and STArray still appear to be the most appropriate tools for the private state, because STRefs and STArrays really, really are private. So this basically means I want to interleave ST and STM in a "safe" way. That is, if the STM transaction retries, I want the ST state to be vaporised as well. Ideally, I would love to be able to say something like this:
Categories: Offsite Discussion

Matrices as Applicatives and Monads

haskell-cafe - Tue, 02/09/2016 - 4:02am
I have been writing code encoding matrices here <> as a learning experience. However, I cannot figure out a method to make Matrix an instance of Applicative and Monad. I believe it is possible, but I cannot find an implementation. For context my form of Matrix does not have a requirement to be of integers, it is just a 2-Dimensional array in essence. Thank you in advance for any help you may provide :) _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >
Categories: Offsite Discussion

[ANN] aeson

haskell-cafe - Mon, 02/08/2016 - 11:22pm
Hi haskellers, As a new co-maintainer of aeson I'm happy to announce aeson[1]. v0.10 had a number of issues and v0.11 aims to fix all of these. I'm happy to see that all known regressions have been fixed, and I didn't have to write any code myself! ;) Going 0.9 to 0.11 should be no work for most users. I've built all packages in stackage nightly[2] and out of 222 only one needs a non-trivial change (sorry pagerduty maintainers!) Please help out by letting us know if we missed something, including if something should be added to the CHANGELOG[3]. A big thanks to everyone who contributed code to this release: Bryan O'Sullivan Bas van Dijk Oleg Grenrus Herbert Valerio Riedel Ben Weitzman Daniel Díaz RyanGlScott David Johnson Artyom Cale Gibbard Mikhail Glushenkov Ondrej Palkovsky Tim Bodeit mrkkrp And a thank you to everyone else who helped in other ways! All the best, Adam [1] [2] [3]
Categories: Offsite Discussion

Call for PhD students: Logical Methods in Computer Science (Vienna, Austria)

General haskell list - Mon, 02/08/2016 - 9:44pm
(* Apologies if you got multiple copies of this email *) Funded Doctoral Positions in Computer Science [] TU Wien, TU Graz, and JKU Linz are seeking exceptionally talented and motivated students for their joint doctoral program LogiCS. The LogiCS doctoral college focuses on interdisciplinary research topics covering (i) computational logic, and applications of logic to (ii) databases and artificial intelligence as well as to (iii) computer-aided verification. THE PROGRAM LogiCS is a doctoral college focusing on logic and its applications in computer science. Successful applicants will work with and be supervised by leading researchers in the fields of computational logic, databases and knowledge representation, and computer-aided verification. FACULTY MEMBERS M. Baaz A. Biere R. Bloem A. Ciabattoni U. Egly T. Eiter C. Fermueller R. Grosu A. Leitsch M. Ortiz R. Pichler S. Szeider H. Tompits H. Veith G. Weissenbacher The LogiCS faculty comprises 15
Categories: Incoming News

ANNOUNCE: hoppy, qtah

haskell-cafe - Mon, 02/08/2016 - 8:11pm
Are you sick and tired of the ease with which Haskell code flows onto the page? Even the thrill of binding to a C library losing its lustre? Look no further! I present to you a tool restoring the good old days of pointer arithmetic, manual memory management, and hours lost to the debugger: Hoppy is a new C++ FFI generator for Haskell. It takes Haskell code that describes a C++ API, and generates C++ and Haskell code to allow the two languages to interact. It supports a good subset of C++, including functions, classes, variables, enums and bitflags, operator overloading, constness, and simple templates. Adding a function takes only a few lines of code, and you normally don't need to write C++ yourself. For example, a definition for std::string is: c_string :: Class c_string = addReqIncludes [includeStd "string"] $ classAddFeatures [Assignable, Comparable, Copyable, Equatable] $ makeClass (ident1 "std" "string") (Just $ toExtName "StdString") [] [ mkCtor "new" []
Categories: Offsite Discussion

Functional Programming Group at the University of Kansas: The Remote JSON library

Planet Haskell - Mon, 02/08/2016 - 6:00pm

JSON-RPC is a simple and well supported protocol for remote procedure calls over HTTP, supporting both synchronous remote methods calls and asynchronous notifications. We want to access JSON-RPC from Haskell, but in a principled way. This blog post discusses the design and user-facing interface of remote-json, a new library for JSON-RPC that makes use of the remote monad design pattern

To give an example from the specification, consider calling a method subtract, with the arguments 42 and 23.

<figure class="highlight">--> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1} <-- {"jsonrpc": "2.0", "result": 19, "id": 1}</figure>

Here, --> is the data sent from client to server, and <-- is what the server responds. The packet being sent is a simple JSON object, as is the reply from the server.

The JSON-RPC protocol supports batching (sending several method calls and notifications at the same time) and is easy to debug, because it is straightforward to read JSON structures. Furthermore, by using JSON-RPC we can implement our clients in Haskell, and be agnostic about what language or framework the server is written in.

There are at least five existing Haskell libraries that support JSON-RPC. So why a new library? We wanted to build our own because we saw a way of simplifying the API considerably, while still allowing access to all the capabilities of JSON-RPC. Specifically, by using the remote monad design pattern we can automate taking advantage of the batch capability, amortizing the cost of the remote call. Rather than have separate entry points for batched and singleton calls, a single entry point can provide both batched and singleton calls. The library also acts as a case study of using the remote monad.

Basic Design of the JSON-RPC API

We center our design around the RPC monad.

<figure class="highlight">-- The monad data RPC :: * -> * deriving (Monad, Applicative, Functor) -- The primitives method :: FromJSON a => Text -> Args -> RPC a notification :: Text -> Args -> RPC () -- the remote send send :: Session -> RPC a -> IO a</figure>

This is a classical remote monad design - a restricted monad, a small number of primitives for this monad, and a send function. Session is an abstract handle to the web server we want to talk to; we’ll come back to how to generate a Session shortly.

This API gives an (aeson) Value-based access to JSON-RPC. Adding specific primitives gives stronger typing. As an example, consider providing say notifications, that make the remote server say things, a temperature method that returns the remote server’s temperature, and an uptime method that returns the uptime of a specific service.

<figure class="highlight">say :: Text -> RPC () say msg = notification "say" $ List [String msg] temperature :: RPC Int temperature = method "temperature" None uptime :: Text -> RPC Double uptime nm = method "uptime" $ List [String nm] -- provided utilities for generating Args, and parsing the Value result of a method. List :: [Value] -> Args None :: Args</figure>

As an example we have our typed API for temperature, uptime and say, saying “Hello, World!”, getting the temperature, and the uptime of “orange”.

<figure class="highlight">example :: Session -> IO () example s = do (t,u) <- send s $ do say "Hello, " t <- temperature say "World!" u <- uptime "orange" return (t,u) print t print u </figure>

send can be used multiple times if needed, acting as translation between our IO monad, and the remote RPC monad. Furthermore, the following JSON-RPC interaction with the server would be a valid trace of interactions for the above example.

<figure class="highlight">--> {"jsonrpc": "2.0", "method": "say", "params": ["Hello, "]} // No reply --> {"jsonrpc": "2.0", "method": "temperature", id: 1 } <-- {"jsonrpc": "2.0", "result": 99, "id": 1} --> {"jsonrpc": "2.0", "method": "say", "params": ["World "]} // No reply --> {"jsonrpc": "2.0", "method": "uptime", "params": ["orange"], id: 1 } <-- {"jsonrpc": "2.0", "result": 3.14, "id": 1}</figure>

In this interaction:

  • notifications are methods without id’s, and do not have replies, and
  • methods use an id to tag a result.

This usage is reasonable, but we can do better. We want to bundle together notifications and methods, to amortize the cost of network traffic, but without comprising the API. Specifically, we want users to just write code using send, and the RPC library to figure out the best bundling possible.

The Remote Monad

In the remote monad theory, there are two key concepts:

  • Splitting the monadic primitives into commands and procedures.
    • Commands do not have a result value (typically () in Haskell), and
    • Procedures have a result.

    There are restrictions on commands and procedures, specifically that they must be serializable.

  • Choosing a bundling strategy. There are two strategies that were documented in the original paper and one new bundling strategy that we are investigating.
    • Weak - a bundle of a single command or a single procedure, or
    • Strong - a bundle of a sequence of commands, optionally terminated by a procedure, or
    • Applicative - a bundle of a sequence of commands and procedures, held together using an applicative functor.

By factoring our primitives into commands and procedures, we can automatically split up a monadic computation into maximal bundles, and then use a transport layer to send, execute and get the result from each bundle. The good news is there is a library, called the remote-monad, that has a plug-and-play API. If we provide the best bundling transport we can, then the library can pick the best way of splitting up the monadic computation into our bundles.

Considering JSON-RPC, the concept of notification and method map straight onto the remote monad concepts of commands and procedures. This makes things straightforward.

Weak Bundles

You can create a JSON-RPC instance using weakSession, which takes an encoding of how to send values to a remote server, and returns a Session.

<figure class="highlight">weakSession :: (SendAPI :~> IO) -> Session</figure>

SendAPI :~> IO is a natural transformation.

<figure class="highlight">newtype f :~> g = Nat (∀ a. f a -> g a)</figure>

Specifically, SendAPI :~> IO is a functor morphism between SendAPI and IO, and isomorphic to ∀ a. SendAPI a -> IO a. Operationally, this transformation is how you run SendAPI, using IO. SendAPI is a deep embedding of both synchronous and asynchronous communications of JSON Value.

<figure class="highlight">data SendAPI :: * -> * where Sync :: Value -> SendAPI Value Async :: Value -> SendAPI () </figure>

So, calling send with the RPC monadic remote commands factors up the specifics commands, and calls the natural transformation argument with either Sync or ASync. With the weakSession, every primitive causes its own Sync or ASync; there is no complex bundling.

You can write your own matcher for SendAPI, or use remote-json-client, which provides a function that, when given a URL, returns the SendAPI to IO natural transformation using the wreq library.

<figure class="highlight">clientSendAPI :: String -> (SendAPI :~> IO)</figure>

Putting this together, we get

<figure class="highlight">main :: IO () main = do let s = weakSession (clientSendAPI "") (t,u) <- send s $ do say "Hello, " t <- temperature say "World!" u <- uptime "orange" return (t,u) print t print u </figure>

Having selected the weak remote monad, we have the weakest JSON-RPC interaction - four transactions.

<figure class="highlight">// (1) --> {"jsonrpc": "2.0", "method": "say", "params": ["Hello, "]} // No reply // (2) --> {"jsonrpc": "2.0", "method": "temperature", id: 1 } <-- {"jsonrpc": "2.0", "result": 99, "id": 1} // (3) --> {"jsonrpc": "2.0", "method": "say", "params": ["World "]} // No reply // (4) --> {"jsonrpc": "2.0", "method": "uptime", "params": ["orange"], id: 1 } <-- {"jsonrpc": "2.0", "result": 3.14, "id": 1}</figure> Strong Bundles

The strong remote monad bundles together commands, where possible, to amortize the cost of the remote call. In our example above, we have two notifications, and a method call. We want to combine them together. We do so by using the strongSession combinator.

<figure class="highlight">main :: IO () main = do let s = strongSession (clientSendAPI "") (t,u) <- send s $ do say "Hello, " t <- temperature say "World!" u <- uptime "orange" return (t,u) print t print u </figure>

Now, we get a two transactions, which conforms to the JSON-RPC specification.

<figure class="highlight">--> [ {"jsonrpc": "2.0", "method": "say", "params": ["Hello. "]} , {"jsonrpc": "2.0", "method": "temperature", id: 1 } ] <-- [ {"jsonrpc": "2.0", "result": 99, "id": 1} ] --> [ {"jsonrpc": "2.0", "method": "say", "params": ["World "]} , {"jsonrpc": "2.0", "method": "uptime", "params": ["orange"], id: 1 } ] <-- [ {"jsonrpc": "2.0", "result": 3.14, "id": 1} ]</figure>

The same RPC send command gives better bundling, solely from changing the strategy from a weakSession to a strongSession. Now, the JSON-RPC specification says

  • “The Server MAY process a batch rpc call as a set of concurrent tasks, processing them in any order and with any width of parallelism.”

This is where it gets interesting. The RPC monad reflects the concurrency policy of the the server, up to method calls. If you wish to insist on sequentiality, then use the weakSession.

Applicative Bundles

One obvious question is “can we improve this reflection of concurrency, and bundle method calls as well as notification?” Yes! For example, Haxl, a Haskell DSL for database access, uses an even stronger bundling strategy, which we call the applicative bundling strategy. In this strategy, methods that are expressed using applicative functors can be bundled together, as well as commands that can already be bundled.

The remote-json library supports applicative bundling. Again, the details are abstracted by the library, and again the monad and applicative functor reflect the concurrency semantics of the server. We’ve added a new remote command uptime that returns the uptime of a specific machine, to aid the demonstration of batching, and reworked the computation to use applicative.

<figure class="highlight">main :: IO () main = do let s = applicativeSession (clientSendAPI "") (t,u) <- send s $ say "Hello, " *> (pure (,) <*> temperature <* say "World!" <*> uptime "orange") print (t,u)</figure>

The packet now includes two notifications and two methods. (Remember, a notification is a JSON-RPC method that has no id tag.)

<figure class="highlight">--> [ {"jsonrpc":"2.0","params":["Hello,"],"method":"say"} , {"jsonrpc":"2.0","method":"temperature","id":2}, , {"jsonrpc":"2.0","params":["World!"],"method":"say"} , {"jsonrpc":"2.0","params":["orange"],"method":"uptime","id":1} ] <-- [ {"result":65,"jsonrpc":"2.0","id":2} , {"result":68.28,"jsonrpc":"2.0","id":1} ]</figure>

When Applicative do arrives with GHC 8, we can take immediate advantage of this, and start using do-notation to write out remote applicative functors. In fact, we can interperse our usage of monads and applicative RPC, and the package will choose the best bundling it can for the specific strategy.


We have written a remote monad for JSON-RPC. The library automatically bundles inside send to attempt to amortize the cost of the remote procedure call. It simplifies making multiple requests, without resorting to specialized variants of send. These idea has been used before. For example, Haxl lead the charge of using the applicative bundling strategy, and Oleg implemented a remote monad in OCaml several years ago. And we’ve been using predecessors to remote-json for several years now. Feel free to try remote-json, and if you are adventurous, remote-monad. Or roll your own remote monad. Once you know the pattern, it’s quite straightforward!

In a future blog post, we will look at our JSON-RPC server.


Justin Dawson and Andy Gill

Resources and Related Work Existing JSON-RPC packages Our Publications about the Remote Monad
  • A. Gill, N. Sculthorpe, J. Dawson, A. Eskilson, A. Farmer, M. Grebe, J. Rosenbluth, R. Scott, and J. Stanton, “The remote monad design pattern,” in Proceedings of the 8th ACM SIGPLAN Symposium on Haskell. New York, NY, USA: ACM, 2015, pp. 59–70.

Categories: Offsite Blogs

Including a "XXX_stub.h" file from another Haskelllibrary?

haskell-cafe - Mon, 02/08/2016 - 3:34pm
Hello -cafe! Let's say I have two Haskell libraries, `A` and `B`. `A` uses the FFI, `foreign export` to be precise, to make a Haskell function available to C land. This generates a "stub" C header file with a corresponding C function declaration. `B` has some C code in it and needs to include the stub header that was generated when compiling `A`, in order to call the function that I 'foreign export'ed in A. When I "naively" include the stub header file for the module in A that contains the 'foreign export' statement, inside one of the C files of the `B` library, the said header can't be found. Is what I want to do at all possible? If yes, how could I make this work? Thanks!
Categories: Offsite Discussion

Joachim Breitner: Protecting static content with mod_rewrite

Planet Haskell - Mon, 02/08/2016 - 10:39am

Since fourteen years, I have been photographing digitally and putting the pictures on my webpage. Back then, online privacy was not a big deal, but things have changed, and I had to at least mildly protect the innocent. In particular, I wanted to prevent search engines from accessing some of my pictures.

As I did not want my friends and family having to create an account and remember a password, I set up an OpenID based scheme five years ago. This way, they could use any of their OpenID enabled account, e.g. their Google Mail account, to log in, without disclosing any data to me. As my photo album consists of just static files, I created two copies on the server: the real one with everything, and a bunch of symbolic links representing the publicly visible parts. I then used mod_auth_openid to prevent access to the protected files, unless the users logged in. I never got around of actually limiting who could log in, so strangers were still able to see all photos, but at least search engine spiders were locked out.

But, very unfortunately, OpenID did never really catch on, Google even stopped being a provider, and other promising decentralized authentication schemes like Mozilla Persona are also phased out. So I needed an alternative.

A very simply scheme would be a single password that my friends and family can get from me and that unlocks the pictures. I could have done that using HTTP Auth, but that is not very user-friendly, and the login does not persist (at least not without the help of the browser). Instead, I wanted something that involves a simple HTTP form. But I also wanted to avoid server-side programming, for performance and security reasons. I love serving static files whenever it is feasible.

Then I found that mod_rewrite, Apache’s all-around-tool for URL rewriting and request mangling, supports reading and writing cookies! So I came up with a scheme that implements the whole login logic in the Apache server configuration. I’d like to describe this setup here, in case someone finds it inspiring.

I created a login.html with a simple HTML form:

<form method="GET" action="/bilder/login.html"> <div style="text-align:center"> <input name="password" placeholder="Password" /> <button type="submit">Sign-In</button> </div> </form>

It sends the user to the same page again, putting the password into the query string, hence the method="GET" – mod_rewrite unfortunately cannot read the parameters of a POST request.

The Apache configuration is as follows:

RewriteMap public "dbm:/var/www/" <Directory /var/www/> RewriteEngine On # This is a GET request, trying to set a password. RewriteCond %{QUERY_STRING} password=correcthorsebatterystaple RewriteRule ^login.html /bilder/loggedin.html [L,R,QSD,] # This is a GET request, trying to set a wrong password. RewriteCond %{QUERY_STRING} password= RewriteRule ^login.html /bilder/notloggedin.html [L,R,QSD] # No point in loggin in if there is already the right password RewriteCond %{HTTP:Cookie} bilderhp=correcthorsebatterystaple RewriteRule ^login.html /bilder/loggedin.html [L,R] # If protected file is requested, check for cookie. # If no cookie present, redirect pictures to replacement picture RewriteCond %{HTTP:Cookie} !bilderhp=correcthorsebatterystaple RewriteCond ${public:$0|private} private RewriteRule ^.*\.(png|jpg)$ /bilder/pleaselogin.png [L] RewriteCond %{HTTP:Cookie} !bilderhp=correcthorsebatterystaple RewriteCond ${public:$0|private} private RewriteRule ^.+$ /bilder/login.html [L,R] </Directory>

The publicfiles.dbm file is generated from a text file with lines like

login.html.en 1 1 pleaselogin.png 1 thumbs/20030920165701_thumb.jpg 1 thumbs/20080813225123_thumb.jpg 1 ...


/usr/sbin/httxt2dbm -i publicfiles.txt -o publicfiles.dbm

and whitelists all files that are visible without login. Make sure it contains the login page, otherwise you’ll get a redirect circle.

The other directives in the above configure fulfill these tasks:

  • If the password (correcthorsebatterystaple) is in the query string, the server redirects the user to a logged-in-page that tells him that the login was successful and instructs him to reload the photo album. It also sets a cookie that will last very long -- after all, I want this to be convenient for my visitors. The query string parsing is not very strict (e.g. a password of correcthorsebatterystaplexkcdrules would also work), but that’s ok.
  • The next request detects an attempt to set a password. It must be wrong (otherwise the first rule would have matched), so we redirect the user to a variant of the login page that tells him so.
  • If the user tries to access the login page with a valid cookie, just log him in.
  • The next two rules implement the actual protection. If there no valid cookie and the accessed file is not whitelisted, then access is forbidden. For requests to images, we do an internal redirect to a placeholder image, while for everything else we redirect the user to the login page.

And that’s it! No resource-hogging web frameworks, not security-dubious scripting languages, and a dead-simple way to authenticate.

Oh, and if you believe you know me well enough to be allowed to see all photos: The real password is not correcthorsebatterystaple; just ask me what it is.

Categories: Offsite Blogs

RebindableSyntax, ifThenElse, and pattern matching

haskell-cafe - Sun, 02/07/2016 - 9:08pm
In a custom prelude, I have written the following definitions: data Truth = True | False ifThenElse :: Truth -> a -> a -> a ifThenElse True x _ = x ifThenElse False _ x = x (==) :: a -> a -> Truth (==) = ... I'm replacing Bool with my own Truth type. Clients will be built with RebindableSyntax, so that they will use these definitions for desugaring. However, if I write this: f :: Text -> Text f "r" = "rrr" f other = other I get a build error indicating that GHC expected the (==) operator to return a value of type Bool, rather than Truth. Shouldn't pattern matching desugar to use overloaded ifThenElse in these situations? Or is it expected that use of GHC.Types.Bool is hard-coded even with RebindableSyntax enabled? Thanks, Chris _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >
Categories: Offsite Discussion

[ANNOUNCE] GHC 8.0.1 release candidate 2

glasgow-user - Sun, 02/07/2016 - 8:13pm
Hello everyone, The GHC Team is very pleased to announce the second release candidate of the Glasgow Haskell Compiler 8.0.1 release. Source and binary distributions as well as the newly revised users guide and Haddock documentation can be found at This is the second in a series of release candidates leading up to the 8.0.1 release and fixes many of the issues reported in -rc1. These fixes include, * A re-rewrite of the pattern checker by George Karachalias. The new checker should have far more predictable performance characteristics while sacrificing minimal reasoning power. This should resolve a large number of the issues felt in -rc1. * Richard Eisenberg has been hammering out all manner of type-application- and TypeInType-related issues (#11335, #11416, #11405). There is still more work to do here, however (e.g. #11471). * Matthew Pickering has restored support for multi-clause pattern synonyms (#11367) * A latent bug
Categories: Offsite Discussion

Incredibly slow type-level Nub

haskell-cafe - Sun, 02/07/2016 - 3:37pm
Dear Cafe, I have faced a type-level performance problem (with GHC 7.10.3). I am trying to implement type-level Nub which removes duplicates from a type-level list. My implementation [1] with an example of a list of length 20 takes forever to compile. If you reduce the size of the example list (e.g. to 15 items), it will compile faster. Also, if you remove the Nub application from exampleVals, it compiles instantly (this is how I know the problem is in Nub). My question is how can I speed up type-level Nub? And less importantly why exactly is it this slow? The practical application for this is building automatic tests [2] for servant-swagger. There I am interested in generating exactly one test for each distinct type. Kind regards, Nick [1] [2] _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >
Categories: Offsite Discussion

Mark Jason Dominus: Four Victorian novels

Planet Haskell - Sun, 02/07/2016 - 1:37pm

I've read a bunch of 19-century English novels lately. I'm not exactly sure why; it just sort of happened. But it's been a lot of fun. When I was small, my mother told me more than once that people often dislike these books because they are made to read them too young; the books were written for adult readers and don't make sense to children. I deliberately waited to read most of these, and I am very pleased now to find that now that I am approaching middle age I enjoy books that were written for people approaching middle age.

Spoilers abound.

Jane Eyre

This is one of my wife's favorite books, or perhaps her very favorite, but I had not read it before. Wow, it's great! Jane is as fully three-dimensional as anyone in fiction.

I had read The Eyre Affair, which unfortunately spoiled a lot of the plot for me, including the Big Shocker; I kept wondering how I would feel if I didn't know what was coming next. Fortunately I didn't remember all the details.

  • From her name, I had expected Blanche Ingram to be pale and limp; I was not expecting a dark, disdainful beauty.

  • When Jane tells Rochester she must leave, he promises to find her another position, and the one he claims to have found is hilariously unattractive: she will be the governess to the five daughters of Mrs. Dionysus O'Gall of Bitternutt Lodge, somewhere in the ass-end of Ireland.

  • What a thrill when Jane proclaims “I am an independent woman now”! But she has achieved this by luck; she inherited a fortune from her long-lost uncle. That was pretty much the only possible path, and it makes an interesting counterpoint to Vanity Fair, which treats some of the same concerns.

  • The thought of dutifully fulfilling the duty of a dutiful married person by having dutiful sex with the dutiful Mr. Rivers makes my skin crawl. I imagine that Jane felt the same way.

  • Mr. Brocklehurst does not get one-tenth of what he deserves.

Jane Eyre set me off on a Victorian novel kick. The preface of Jane Eyre praises William Thackeray and Vanity Fair in particular. So I thought I'd read some Thackeray and see how I liked that. Then for some reason I read Silas Marner instead of Vanity Fair. I'm not sure how that happened.

Silas Marner

Silas Marner was the big surprise of this batch of books. I don't know why I had always imagined Silas Marner would be the very dreariest and most tedious of all Victorian novels. But Silas Marner is quite short, and I found it very sweet and charming.

I do not suppose my Gentle Readers are as likely to be familiar with Silas Marner as with Jane Eyre. As a young man, Silas is a member of a rigid, inward-looking religious sect. His best friend frames him for a crime, and he is cast out. Feeling abandoned by society and by God, he settles in Raveloe and becomes a miser, almost a hermit. Many years pass, and his hoarded gold is stolen, leaving him bereft. But one snowy evening a two-year-old girl stumbles into his house and brings new purpose to his life. I have omitted the subplot here, but it's a good subplot.

One of the scenes I particularly enjoyed concerns Silas’ first (and apparently only) attempt to discipline his adopted two-year-old daughter Eppie, with whom he is utterly besotted. Silas knows that sooner or later he will have to, but he doesn't know how—striking her seems unthinkable—and consults his neighbors. One suggests that he shut her in the dark, dirty coal-hole by the fireplace. When Eppie wanders away one day, Silas tries to be stern.

“Eppie must go into the coal hole for being naughty. Daddy must put her in the coal hole.”

He half expected that this would be shock enough and that Eppie would begin to cry. But instead of that she began to shake herself on his knee as if the proposition opened a pleasing novelty.

As they say, no plan survives contact with the enemy.

Seeing that he must proceed to extremities, he put her into the coal hole, and held the door closed, with a trembling sense that he was using a strong measure. For a moment there was silence but then came a little cry “Opy, opy!” and Silas let her out again…

Silas gets her cleaned up and changes her clothes, and is about to settle back to his work

when she peeped out at him with black face and hands again and said “Eppie in de toal hole!”

Two-year-olds are like that: you would probably strangle them, if they weren't so hilariously cute.

Everyone in this book gets what they deserve, except the hapless Nancy Lammeter, who gets a raw deal. But it's a deal partly of her own making. As Thackeray says of Lady Crawley, in a somewhat similar circumstance, “a title and a coach and four are toys more precious than happiness in Vanity Fair”.

There is a chapter about a local rustics at the pub which may remind you that human intercourse could be plenty tiresome even before the invention of social media. The one guy who makes everything into an argument will be quite familiar to my Gentle Readers.

I have added Silas Marner to the long list of books that I am glad I was not forced to read when I was younger.

The Old Curiosity Shop

Unlike Silas Marner, I know why I read this one. In the park near my house is a statue of Charles Dickens and Little Nell, on which my daughter Toph is accustomed to climb. As she inevitably asked me who it was a statue of, I explained that Dickens was a famous writer, and Nell is a character in a book by Dickens. She then asked me what the book was about, and who Nell was, and I did not know. I said I would read the book and find out, so here we are.

My experience with Dickens is very mixed. Dickens was always my mother's number one example of a writer that people were forced to read when too young. My grandfather had read me A Christmas Carol when I was young, and I think I liked it, but probably a lot of it went over my head. When I was about twenty-two I decided to write a parody of it, which meant I had to read it first, but I found it much better than I expected, and too good to be worth parodying. I have reread it a couple of times since. it is very much worth going back to, and is much better than its many imitators.

I had been required to read Great Expectations in high school, had not cared for it, and had stopped after four or five chapters. But as an adult I kept a copy in my house for many years, waiting for the day when I might try again, and when I was thirty-five I did try again, and I loved it.

Everyone agrees that Great Expectations is one of Dickens’ best, and so it is not too surprising that I was much less impressed with Martin Chuzzlewit when I tried that a couple of years later. I remember liking Mark Tapley, but I fell off the bus shortly after Martin came to America, and I did not get back on.

A few years ago I tried reading The Pickwick Papers, which my mother said should only be read by middle-aged people, and I have not yet finished it. It is supposed to be funny, and I almost never find funny books funny, except when they are read aloud. (When I tell people this, they inevitably name their favorite funny books: “Oh, but you thought The Hitchhiker’s Guide to the Galaxy was funny, didn't you?” or whatever. Sorry, I did not. There are a few exceptions; the only one that comes to mind is Stanisław Lem's The Cyberiad, which splits my sides every time. SEVEN!

Anyway, I digress. The Old Curiosity Shop was extremely popular when it was new. You always hear the same two stories about it: that crowds assembled at the wharves in New York to get spoilers from the seamen who might have read the new installments already, and that Oscar Wilde once said “one must have a heart of stone to read the death of Little Nell without laughing.” So I was not expecting too much, and indeed The Old Curiosity Shop is a book with serious problems.

Chief among them: it was published in installments, and about a third of the way through writing it Dickens seems to have changed his mind about how he wanted it to go, but by then it was too late to go back and change it. There is Nell and her grandfather on the one hand, the protagonists, and the villain is the terrifying Daniel Quilp. It seems at first that Nell's brother Fred is going to be important, but he disappears and does not come back until the last page when we find out he has been dead for some time. It seems that Quilp's relations with his tyrannized wife are going to be important, but Quilp soon moves out of his house and leaves Mrs. Quilp more or less alone. It seems that Quilp is going to pursue the thirteen-year-old Nell sexually, but Nell and Grandpa flee in the night and Quilp never meets them again. They spend the rest of the book traveling from place to place not doing much, while Quilp plots against Nell's friend Kit Nubbles.

Dickens doesn't even bother to invent names for many of the characters. There is Nell’s unnamed grandfather; the old bachelor; the kind schoolmaster; the young student; the guy who talks to the fire in the factory in Birmingham; and the old single gentleman.

The high point of the book for me was the development of Dick Swiveller. When I first met Dick I judged him to be completely worthless; we later learn that Dick keeps a memorandum book with a list of streets he must not go into, lest he bump into one of his legion of creditors. But Dick turns out to have some surprises in him. Quilp's lawyer Sampson Brass is forced to take on Swiveller as a clerk, in furtherment of Quilp's scheme to get Swiveller married to Nell, another subplot that comes to nothing. While there, Swiveller, with nothing to amuse himself, teaches the Brasses’ tiny servant, a slave so starved and downtrodden that she has never been given a name, to play cribbage. She later runs away from the Brasses, and Dick names her Sophronia Sphynx, which he feels is “euphonious and genteel, and furthermore indicative of mystery.” He eventually marries her, “and they played many hundred thousand games of cribbage together.”

I'm not alone in finding Dick and Sophronia to be the most interesting part of The Old Curiosity Shop. The anonymous author of the excellent blog A Reasonable Quantity of Butter agrees with me, and so does G.K. Chesterton:

The real hero and heroine of The Old Curiosity Shop are of course Dick Swiveller and [Sophronia]. It is significant in a sense that these two sane, strong, living, and lovable human beings are the only two, or almost the only two, people in the story who do not run after Little Nell. They have something better to do than to go on that shadowy chase after that cheerless phantom.

Today is Dickens’ 204th birthday. Happy birthday, Charles!

Vanity Fair

I finally did get to Vanity Fair, which I am only a quarter of the way through. It seems that Vanity Fair is going to live or die on the strength of its protagonist Becky Sharp.

When I first met Ms. Sharp, I thought I would love her. She is independent, clever, and sharp-tongued. But she quickly turned out to be scheming, manipulative, and mercenary. She might be hateful if the people she was manipulating were not quite such a flock of nincompoops and poltroons. I do not love her, but I love watching her, and I partly hope that her schemes succeed, although I rather suspect that she will sabotage herself and undo all her own best plans.

Becky, like Jane Eyre, is a penniless orphan. She wants money, and in Victorian England there are only two ways for her to get it: She can marry it or inherit it. Unlike Jane, she does not have a long-lost wealthy uncle (at least, not so far) so she schemes to get it by marriage. It's not very creditable, but one can't feel too righteous about it; she is in the crappy situation of being a woman in Victorian England, and she is working hard to make the best of it. She is extremely cynical, but the disagreeable thing about a cynic is that they refuse to pretend that things are better than they are. I don't think she has done anything actually wrong, and so far her main path to success has been to act so helpful and agreeable that everyone loves her, so I worry that I may come out of this feeling that Thackeray does not give her a fair shake.

In the part of the book I am reading, she has just married the exceptionally stupid Rawdon Crawley. I chuckle to I think of the flattering lies she must tell him when they are in the sack. She has married him because he is the favorite relative of his rich but infirm aunt. I wonder at this, because the plan does not seem up to Becky’s standards: what if the old lady hangs on for another ten years? But perhaps she has a plan B that hasn't yet been explained.

Thackeray says that Becky is very good-looking, but in his illustrations she has a beaky nose and an unpleasant, predatory grin. In a recent film version she was played by Reese Witherspoon, which does not seem to me like a good fit. Although Becky is blonde, I keep picturing Aubrey Plaza, who always seems to me to be saying something intended to distract you from what she is really thinking.

I don't know yet if I will finish Vanity Fair—I never know if I will finish a book until I finish it, and I have at times said “fuck this” and put down a book that I was ninety-five percent of the way through—but right now I am eager to find out what happens next.

Blah blah blah

This post observes the tenth anniversary of this blog, which I started in January 2006, directly inspired by Steve Yegge’s rant on why You Should Write Blogs, which I found extremely persuasive. (Articles that appear to have been posted before that were backdated, for some reason that I no longer remember but would probably find embarrassing.) I hope my Gentle Readers will excuse a bit of navel-gazing and self-congratulation.

When I started the blog I never imagined that I would continue as long as I have. I tend to get tired of projects after about four years and I was not at all sure the blog would last even that long. But to my great surprise it is one of the biggest projects I have ever done. I count 484 published articles totalling about 450,000 words. (Also 203 unpublished articles in every possible state of incompletion.) I drew, found, stole, or otherwise obtained something like 1,045 diagrams and illustrations. There were some long stoppages between articles, but I always came back to it. And I never wrote out of obligation or to meet a deadline, but always because the spirit moved me to write.

Looking back on the old articles, I am quite pleased with the blog and with myself. I find it entertaining and instructive. I like the person who wrote it. When I'm reading articles written by other people it sometimes happens that I smile ruefully and wish that I had been clever enough to write that myself; sometimes that happens to me when I reread my own old blog articles, and then my smile isn't rueful.

The blog paints a good picture, I think, of my personality, and of the kinds of things that make me unusual. I realized long long ago that I was a lot less smart than many people. But the way in which I was smart was very different from the way most smart people are smart. Most of the smart people I meet are specialists, even ultra-specialists. I am someone who is interested in a great many things and who strives for breadth of knowledge rather than depth. I want to be the person who makes connections that the specialists are too nearsighted to see. That is the thing I like most about myself, and that comes through clearly in the blog. I know that if my twenty-five-year-old self were to read it, he would be delighted to discover that he would grow up to be the kind of person that he wanted to be, that he did not let the world squash his individual spark. I have changed, but mostly for the better. I am a much less horrible person than I was then: the good parts of the twenty-five-year-old’s personality have developed, and the bad ones have shrunk a bit. I let my innate sense of fairness and justice overcome my innate indifference to other people’s feelings, and I now treat people less callously than before. I am still very self-absorbed and self-satisfied, still delighted above all by my own mind, but I think I do a better job now of sharing my delight with other people without making them feel less.

My grandparents had Eliot and Thackeray on the shelf, and I was always intrigued by them. I was just a little thing when I learned that George Eliot was a woman. When I asked about these books, my grandparents told me that they were grown-up books and I wouldn't like them until I was older—the implication being that I would like them when I was older. I was never sure that I would actually read them when I was older. Well, now I'm older and hey, look at that: I grew up to be someone who reads Eliot and Thackeray, not out of obligation or to meet a deadline, but because the spirit moves me to read.

Thank you Grandma Libby and Grandpa Dick, for everything. Thank you, Gentle Readers, for your kind attention and your many letters through the years.

Categories: Offsite Blogs

Pulling an applicative/apply out of a record

haskell-cafe - Sun, 02/07/2016 - 9:25am
Quick question for the experts out there. I need to process some records. The records come in in an unordered stream of record fields. From each stream of fields I want to produce a Record entry containing the fields I need to do my calculation. I was thinking this setup might work nice with something like as I could then have (1) a monoid version I could accumulate use as an accumulator over the stream and (2) a final version. This final version seems like it should easily come from the later by pulling the [] (or anything else that has the Apply/Applicative structure) to the outside and then taking the head of the resulting list. While I could write the boilerplate to do this, it seems like something I should be able to do more elegantly. The best I have come up with so far is to use the lens package to give me an isomorphism to a tuple. Then I need a uncurried zip for arbitrarily large tuples. Follow this by an isomorphism back. RecordF (f Type1) (f Type2) ... -> (f Type1, f Type2, ....) -
Categories: Offsite Discussion

New gtk2hs 0.12.4 release

gtk2hs - Wed, 11/21/2012 - 12:56pm

Thanks to John Lato and Duncan Coutts for the latest bugfix release! The latest packages should be buildable on GHC 7.6, and the cairo package should behave a bit nicer in ghci on Windows. Thanks to all!


Categories: Incoming News