Jan 17, 2014

There are a number of errors made in putative Monad tutorials in languages other than Haskell. Any implementation of monadic computations should be able to implement the equivalent of the following in Haskell:

```minimal :: Bool -> [(Int, String)]
minimal b = do
x <- if b then [1, 2] else [3, 4]
if x `mod` 2 == 0
then do
y <- ["a", "b"]
return (x, y)
else do
y <- ["y", "z"]
return (x, y)```

This should yield the local equivalent of:

```Prelude> minimal True
[(1,"y"),(1,"z"),(2,"a"),(2,"b")]
Prelude> minimal False
[(3,"y"),(3,"z"),(4,"a"),(4,"b")]```

At the risk of being offensive, you, ahhh... really ought to understand why that's the result too, without too much effort... or you really shouldn't be writing a Monad tutorial. Ahem.

In particular:

• Many putative monadic computation solutions only work with a "container" that contains zero or one elements, and therefore do not work on lists. >>= is allowed to call its second argument (a -> m b) an arbitrary number of times. It may be once, it may be dozens, it may be none. If you can't do that, you don't have a monadic computation.
• A monadic computation has the ability to examine the intermediate results of the computation, and make decisions, as shown by the if statement. If you can't do that, you don't have a monadic computation.
• In statically-typed languages, the type of the inner value is not determined by the incoming argument. It's a -> m b, not a -> m a, which is quite different. Note how x and y are of different types.
• The monadic computation builds up a namespace as it goes along; note we determine x, then somewhat later use it in the return, regardless of which branch we go down, and in both cases, we do not use it right away. Many putative implementations end up with a pipeline, where each stage can use the previous stage's values, but can not refer back to values before that.
• Monads are not "about effects". The monadic computation I show above is in fact perfectly pure, in every sense of the term. And yes, in practice monad notation is used this way in real Haskell all the time, it isn't just an incidental side-effect.

A common misconception is that you can implement this in Javascript or similar languages using "method chaining". I do not believe this is possible; for monadic computations to work in Javascript at all, you must be nesting functions within calls to bind within functions within calls to bind... basically, it's impossibly inconvenient to use monadic computations in Javascript, and a number of other languages. A mere implementation of method chaining is not "monadic", and libraries that use method chaining are not "monadic" (unless they really do implement the rest of what it takes to be a monad, but I've so far never seen one).

If you can translate the above code correctly, and obtain the correct result, I don't guarantee that you have a proper monadic computation, but if you've got a bind or a join function with the right type signatures, and you can do the above, you're probably at least on the right track. This is the approximately minimal example that a putative implementation of a monadic computation ought to be able to do.

Jan 15, 2014
Programming
Scientists (and, in my experience, especially bioinformaticians) tend to make horrible, awful messes no matter how maintainable you think a language is. (You can hand them Inform 7 and it'll still end up looking like Fortran ate the csh manual and vomited all over an APL keyboard.)

Dec 19, 2013
Programming, Golang

I've pushed two repos to GitHub with Go code:

• gomempool (godoc): A []byte pool manager for Go. It's less generic than the Pool implementation that is working its way into Go tip, but also therefore understands more about []bytes, and is much simpler than the I-don't-even-know-what magic is in that implementation. It also tracks stats, which I've hooked up to my monitoring so I can see the usefulness of the pool in my real running code.
• abtime (godoc): An abstract time library that removes your dependency on the OS time from the time module. I've now run into this problem at work in three forms; unfortunately one of them is in a module I plan on releasing someday and don't want a dependency on this module, but the other two can benefit from a standardized way of dealing with this. I had a semi-complete version of this in my local code base already, but I was inspired to bring it up to public spec by Moonpig.

Both libraries have 100% test coverage, and are golint and go vet clean.

There's more coming, but they're bigger than these. My supervisor tree library is nearly ready to go, but the requisite blog post explaining the design is still in progress. (It's big.) The library that implements Erlang-style mailboxes, including the ability to cluster together machines and send messages across the cluster the way Erlang does, is still in progress. (I have just barely started the clustering.) My current plan is to lock down and stabilize the system this is being written for in the single-server case, then implement this clustering.

I wouldn't mention it, except that Google does not seem inclined to index these without some form of external link. GitHub permits external indexing of the master branch of projects but I think perhaps their robots.txt forbids the scraping necessary to find unlinked projects. Hopefully this fixes that.

Computer Security Haiku

Gold in vault, target
Steel door closed, locked, key thrown away;
Thief laughs "There's no wall!"

Data stream flows, filling
Lake overflows; disaster!
Arbitrary code

Man trusts fellow Man,
fellow Man undeserving.
Script code injected.

Novice celebrates,
Output easy, just append strings!
Master needs new novice.

Tells foe the password is lost...
Rubber hose finds it.

"Love", Alice tells Bob
In anger, Eve flips one bit
Now love's checksum fails

Small time differences,
timing attacks still work.

Chick digs my profile,
sends regards in attachment.
Virus, still no love.

Easy, but when the press hears...
thought too hard to bear.

Security mindset sees
a way to spam foes.

I'm aware of the rule that haiku are supposed to have "season words", but I just couldn't jam them in there. "Arbitrary Javascript injection" is ten syllables already, for instance. It seemed better to not jam them in.

Parametricity in Go
Oct 17, 2013
Programming, Golang

One of my objections to Erlang is that despite paying the price of being a functional language, it often fails to reap the advantages. An example of this is in testability; nominally, a purely functional bit of code ought to be easier to test than the imperative equivalent, because it is just a matter of setting up your parameters and checking the results, with no IO or state in between.

Erlang doesn't make this impossible, but it's less convenient than the brochure promises. The core of your application is generally locked up in the various gen_* handlers. These handlers have very stereotyped ways of being called, which include the full state of the thing being tested. I find this very tedious to test, for two reasons: 1. Every test assertion must define some sort of "complete state" for the handler, which is probably full of real-world concerns in it. In particular if it has further messages it is going to send, those are often relatively hard-coded somehow... an inconvenient-to-mock Mnesia entry, an atom-registered process name, etc. (Erlang programs end up having a surprising amount of global state like that.) 2. If you want to test some sort of sequence of events, you are responsible for threading through the code, or manually invoking the proper gen_* start up functions, or something. It's possible to refactor your way out of this mess, but in practice it's a lot of work for the reward. So many of the tools you could use in other languages aren't available.

Go, in theory, ought to be harder to test than Erlang, being an imperative programming language. In practice, I'm finding it much easier, and I'm doing a lot more testing in it.

 <- Future Posts Past Posts ->