< Main

Disciple vs Haskell

These are some syntactic differences that tend to trip up Haskell programmers when they first start with Disciple.

Evaluation Order

Disciple uses strict / call-by-value as the default evaluation order. This implies that bindings in let and where expressions must be written in dependency order. For example, you can write:

fun :: Int -> Int
fun x = x + z
 where  y = g x
        z = 3 + y

but not:

fun :: Int -> Int
fun x = x + z
 where  z = 3 + y
        y = g x

This doesn't work because the bindings for y and z are in the "wrong" order.

For let and where expressions, all the bindings are evaluated in-order, before moving to the body.

The (.) operator

We use (.) for projection instead of function composition. If you want to compose two functions then use ($), or suggest a good replacement for (.) on the mailing lists.

Death to [Char]

In the Disciple prelude, strings are defined as append-lists of arrays of characters. This provides sane complexities to the common operations of constructing and printing strings, with respect to the regular Haskell ones. For this reason you need to use the string append operator (%) to append lists, instead of the list append operator (++). If you really want a list of characters then use charListOfString :: String -> [Char] defined in Data.List.

No Dictionary Passing

Dictionary passing for type classes isn't implemented yet, but we plan to do this in the medium term (within 12 months). You can still define new classes and instances, but each method call must be resolved to its instance at the point of use. In practice this means that you can't write functions who's types have class contexts. For example, this is ok:

showTwoInts :: (Int, Int)  -> String
showTwoInts (x, y) = "you've got a " % show x % " and a " % show y

but this doesn't work:

showTwoThings :: Show a => (a, a) -> String
showTwoThings (x, y) = "you've got a " % show x % " and a " % show y