On 9/18/12 4:08 PM, thorso...@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

____________________
 Racket Users list:
 http://lists.racket-lang.org/users

Reply via email to