Study Topic: Language: Racket

From Matt Morris Wiki
Jump to navigation Jump to search

This is a Study Leave topic.

What Is It?

Racket is a relatively new, teaching-oriented variant of Scheme: adds structures, a class system, exceptions, loop constructs, modules, custodians, eventspaces, GUI libraries, and more.

Why Study It?

Best way to explore multiple Scheme variants in a single environment

Toggl code

Toggl code is LANG-RACKET

Deliverables

  • First 7 hours of time. Work through "Realm of Racket" and write up first impressions.
  • [DONE] Next 7 hours of time. Finish "Realm of Racket" and identify (a) next learning text (b) project to work on (c) if I should perhaps be looking at Clojure or some other Lisp instead?

First Impressions

After close onto 7 hours I've still got about 30% of the "Realm of Racket" book to go. The scary bit of Lisp is the homoiconicity: the way code and data use the same representation, giving rise to an amazing variety of basic constructs.

It's worth getting through to the end of the "Realm of Racket" book, which will take a few more hours, but it's looking likely that I should then switch to a different implementation of Lisp: Clojure.

For instance Clojure has a number of AMQP libraries for RabbitMQ, while Racket only has a single STOMP plugin, which may or may not work.

So I'll finish the book and then have a think about that.

Cheat Sheet

Common Stuff:

  • lists
    • empty, '(), (list): empty list
    • cons cell is car + cdr: a list has values in car & cdr pointing to next cons cell (with final cdr empty)
    • so (cons 'a (cons 'b (cons 'c '()))) = '(a b c)
    • make a list by '(a b c)
    • first for front element, rest for rest of list
  • equality testing; equal? for field-by-field testing (where struct is transparent), eq? for actual object identity
  • define var value
  • set! var new value

Structs:

  • struct stname (f1 f2 f3)) as basic form
    • stname-f1, stname-f2 etc to access
    • (define varname (stname v1 v2 v3)) to instantiate
  • struct stname (f1 f2 f3) #:transparent) to allow equal? to work & general access to internals
  • struct stname (f1 f2 f3) #:prefab) to allow serialisation
  • You can nest structs
    • (struct s1 (f1)) then (struct s2 s1 (f2))
    • s2 instance will have selectors s1-f1 and s2-f2
  • You can have mutable members
    • (struct s1 (f1 #:mutable)) for member
    • (struct s1 (f1) #:mutable) for whole struct
    • then can use set-s1-f1! to modify in place
    • returns nothing: (void)
  • (values v1 v2 ...) for an anonymous tuplet
    • can do (define-values (one two three) (values 'one 'two 'three))

Conditions:

  • type predicates: number?, string?, boolean?, stance?, ..
  • if predicate true-expr false-expr
  • cond [cond1 expr1] [cond2 expr2] ... [else expr-else]

Loops:

  • (for/list (for-clause...) body) - assemble values in list
  • for/vector: assemble values in vector
  • for/fold ([accum-id init-expr] ...) (for-clause...) body) - assemble values in list
  • for/or, for/and
  • for/first, for/last when adding #:when, e.g.
    • (for/first ([i '(1 2 3 4)] #:when (even? i)) i) -> 2
  • for*/version for multiple nested clauses

Higher-Order Functions:

  • apply op lst: apply to each member
  • build-list n f: build list of f(i) for i in [0,n)
  • foldl op lst: left-fold: foldl cons empty '(a b c) -> '(c b a)
  • foldr op list: right-fold: foldr cons empty '(a b c) -> '(c b a)
  • lambda params body: anonymous function
  • map func lst: return new list with each member replaced by func(member)
    • andmap pred lst: get "and: of prod(member)
    • ormap pred lst: get "or" of prod(member)

Lazy Evaluation:

  • delay: (define lazy+ (delay (apply + (build-list 5000000 values))))
  • force: (force lazy+)