On 9/18/12 4:08 PM, thorsopia at lavabit.com wrote:
>> It's also possible to write Typed Racket programs "types first", like
>> one would in Haskell, and I sometimes do. The "sums-of-products"
>> programming style of Haskell and ML can be expressed easily with Typed
>> Racket's structs and union types. You can also mix and match between
>> "Haskell" and "Racket" styles of programming, and it will all work.
>> Are you talking about this?
>> We have already seen the : type annotation form. This is useful for
> definitions, at both the top level of a module
>> (: x Number)
> (define x 7)
>> and in an internal definition
>> (let ()
> (: x Number)
> (define x 7)
> (add1 x))
>>http://docs.racket-lang.org/ts-guide/more.html#(part._.Annotating_.Definitions)
No, by "types first" I think John and Vincent are talking about a
conceptual order. I would phrase it a little more subtly: an ML (or
Haskell) programmer writes their types, then their programs (as you
must); a TR programmer thinks about their data, writes down a program,
then writes down the types (describing the data) they had in mind in the
first place (and often were written down as comments). Vincent is
pointing out that writing TR programs in the other order works just
fine, too. The flexibility is one of the best things about TR: you get
to choose how much of your program is typed and this can evolve over time.
There's also a style to types that's different. Since Racket
programmers often think in terms of union types, it was really important
TR supported union types. It was also important to support the kind of
control flow based on predicates that discriminate between members of a
union, hence the occurrence typing features. In ML or Haskell, you
would instead use _disjoint_ unions and pattern matching against
constructors. As Vincent said, you can program in that style in TR,
too, but that style is often not what you would have written in Racket
in the first place.
A good exercise to get the feel of both styles is to develop a data
definition for XML expressions or something similar. Try it out first
in Racket, then TR. Then re-develop the program in Haskell. You'll
notice that in one, you probably have something like
;; A XExpr is one of
;; - String
;; - Number
;; - ...
and programs look like:
(define (xexpr-function x)
(cond [(string? x) ... x is a string]
[(number? x) ... x is a number]
...))
And in the other you'll have (OK, ML since I know it better):
datatype XExpr = Str of string | Num of real | ...
and programs:
fun xexprfunction Str(s) = ... s is a string
| xexprfunction Num(n) = ... n is a real
| ...
The latter style you can always recreate in TR using structs and match,
but the other direction won't work.
David