The philosophy of these changes is here. Summary of changes is:
- Application must be explicitly shown with a dot (Dijkstra philosophy)
- This applies to other non first class applications as well
viz. type constructors (Tree.a) and class constructors (Eq.a)
- 
bindis reversed and called with a double dot..(so that the generalization of simple application to monadic bind is apparent)
- syntax of data is changed to ctype− concrete type − so that the syntax es (is it syntices?) ofclass,instanceandctypeare uniform[1].
- : and :: are flipped
 To allow for the above changes the following changes are also there
- enumFrometc use triple dot instead of double dot
- composition is named ';' and is in left-to right order
 And to make allowances for the above
- layout is the only way to denote nesting. Use of {} gives the error
 Layout imperative in functional programming.
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]
- Gofer
- ? 1 ++ [2,3,4] ERROR: Type error in application *** expression : 1 ++ [2,3,4] *** term : 1 *** type : Int *** does not match : [Int] 
- Ghc
- Prelude> 1 ++ [2,3,4] - :2:1: 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] - :2:7: 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' ...plus three others In the expression: 2 In the second argument of `(++)', namely `[2, 3, 4]' In the expression: 1 ++ [2, 3, 4] 
- Standard Prelude
- ? :t (==) (==) : Eq.a => a -> a -> Bool ? :t (+) (+) : Num.a => a -> a -> a 
- Simple Prelude
- ? :t (==) (==) : a -> a -> Bool ? :t (+) (+) : Int -> Int -> Int ? 
   Eq.a => a -> a -> Boolto
   a -> a -> Boolwould 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.
 
Having suffered cabal hell with my students during the Autumn term last year, I feel very drawn to this idea...
ReplyDeletePS - the links above to standard and simple prelude have gone stale - I get github's 404 webpage for them.
Links corrected -- please check.
DeleteAnd 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