Search This Blog

Friday, September 26, 2014


In the early 90s  I used gofer to teach FP in the introductory programming class at the university of Pune.  At first I used Miranda/Scheme, then gofer. I was also impressed with Dijkstra's philosophy of making function application explicit with a dot ('.') and decided to incorporate this into gofer.  This changed gofer was called pugofer.

The philosophy of these changes is here. Summary of changes is:
  1. Application must be explicitly shown with a dot (Dijkstra philosophy)
  2. This applies to other non first class applications as well viz. type constructors (Tree.a) and class constructors (Eq.a)
  3. bind is reversed and called with a double dot ..(so that the generalization of simple application to monadic bind is apparent)
  4. syntax of data is changed to ctype − concrete type − so that the syntax es (is it syntices?) of class, instance and ctype are uniform[1].
  5. : and :: are flipped
    To allow for the above changes the following changes are also there
  6. enumFrom etc use triple dot instead of double dot
  7. composition is named ';' and is in left-to right order
    And to make allowances for the above
  8. layout is the only way to denote nesting. Use of {} gives the error
    Layout imperative in functional programming.
For those who are inclined the sources for this are at github.
The modified prelude should give an idea of how it looks.
The original gofer – a wonderful work of art by Mark Jones – is Mark Jones archive.

There is still some interest and use in pugofer (after 22 years!) and it compiles on modern systems.  I can provide more tips to anyone who is interested.  Some people find a pedagogical advantage to using a system that is a hundredfold smaller than ghc. As long as you are not looking for 'realistic' and/or 'modern' :-)

Specifically it can be useful if the agenda is – Think in haskell; code in Java/C++.
[A recent training request was from a team using javascript]

A big plus is that if one uses the simple prelude there are no type-classes/overloaded values, thus making the essence of Hindley-Milner much more easy to grasp.

For those wanting to write (real) code in haskell please use ghc!! For those wanting a 'why' as to pedagogic superiority of gofer over ghc, here's the error they give for 1 ++ [2,3,4]
? 1 ++ [2,3,4]
ERROR: Type error in application
*** expression     : 1 ++ [2,3,4]
*** term           : 1
*** type           : Int
*** does not match : [Int]
Prelude> 1 ++ [2,3,4]

    No instance for (Num [a0]) arising from the literal `1'
    Possible fix: add an instance declaration for (Num [a0])
    In the first argument of `(++)', namely `1'
    In the expression: 1 ++ [2, 3, 4]
    In an equation for `it': it = 1 ++ [2, 3, 4]

    No instance for (Num a0) arising from the literal `2'
    The type variable `a0' is ambiguous
    Possible fix: add a type signature that fixes these type variable(s)
    Note: there are several potential instances:
      instance Num Double -- Defined in `GHC.Float'
      instance Num Float -- Defined in `GHC.Float'
      instance Integral a => Num (GHC.Real.Ratio a)
        -- Defined in `GHC.Real' three others
    In the expression: 2
    In the second argument of `(++)', namely `[2, 3, 4]'
    In the expression: 1 ++ [2, 3, 4] 
Things get even simpler when we change from the standard to the simple (no typeclasses) prelude.
Standard Prelude
? :t (==)
(==) : Eq.a => a -> a -> Bool
? :t (+)
(+) : Num.a => a -> a -> a

Simple Prelude
? :t (==)
(==) : a -> a -> Bool
? :t (+)
(+) : Int -> Int -> Int
The theoretical minded will be appalled: Reducing
   Eq.a => a -> a -> Bool
   a -> a -> Bool
would solve the halting-problem! Right... I am not talking theory; just teaching kids

[1] Nowadays called GADTs. This was 10+ years before. Same syntax different intention.


  1. Having suffered cabal hell with my students during the Autumn term last year, I feel very drawn to this idea...

    PS - the links above to standard and simple prelude have gone stale - I get github's 404 webpage for them.

    1. Links corrected -- please check.
      And if you do try do keep me posted!
      [When you build ie make there are some compile errors...
      its only for gofc -- the compiler -- the interpreter gofer should be ok