[racket] Lunch choosing program ported from Haskell to Racket

From: Brian Adkins (racketusers at lojic.com)
Date: Sat Jul 5 12:10:47 EDT 2014

I've modified the code with Matthias' feedback and a brief reading of the style guide. I must have been confused on the use of "local". I got the impression that it was required if you wanted to (define (foo arg ...)) within another function, but I took it out, and everything works fine. Maybe local is only required for circumstances that I haven't hit yet. The rank-restaurants functions is nicer looking w/o the local.

There's a lunch-v2.rkt at the top of the gist now. Still needs improvement, but it's significantly better now stylistically.

https://gist.github.com/lojic/d45437453ccc8bcba196

I read in the style guide about preferring define over let due to indentation level. I think I like that for one or two bindings, but if you have a longer list of bindings, the verbosity of repeated define's is harder to handle. For small functions of a few lines, I don't think using let is that bad, for example:

(define (my-function arg)
  (define var-1 (foo1 arg))
  (define var-2 (foo2 arg))
  (define var-3 (foo3 arg))
  (define var-4 (foo4 arg))
  (define var-5 (foo5 arg))
  (foo-n var-1 var-2 var-3 var-4 var-5))

vs.

(define (my-function arg)
  (let ([var-1 (foo1 arg)]
        [var-2 (foo2 arg)]
        [var-3 (foo3 arg)]
        [var-4 (foo4 arg)]
        [var-5 (foo5 arg)])
    (foo-n var-1 var-2 var-3 var-4 var-5))

I'm fine with following the style guide when contributing later - consistency is a big win over subtle, subjective pros/cons. But, out of curiosity, would the multiple-defines example above be absolutely preferred over the let example for Racket code?

Is match typically used to destructure lists? I used it a few times in the program, but in the following example, a couple defines w/ second & third seemed better given the complexity of the nested folds.

(define (summed-history history)
  (foldl (λ (3tuple hsh)
           (define rest (second 3tuple))
           (define users (third 3tuple))
           (foldl (λ (user hsh) 
                    (hash-set hsh (list user rest) (+ 1 (hash-ref hsh (list user rest) 0))))
                  hsh 
                  users))
         (hash) 
         history))

vs.

(define (summed-history history)
  (foldl (λ (3tuple hsh)
           (match 3tuple 
             [(list _ rest users)
              (foldl (λ (user hsh) 
                       (hash-set hsh 
                                 (list user rest) 
                                 (+ 1 (hash-ref hsh (list user rest) 0))))
                     hsh 
                     users)]))
         (hash) 
         history))

What I'd really like is to replace the 3tuple arg with a pattern:

(define (summed-history history)
  (foldl (λ ((_ rest users) hsh)
           (foldl (λ (user hsh) 
                    (hash-set hsh (list user rest) (+ 1 (hash-ref hsh (list user rest) 0))))
                  hsh 
                  users))
         (hash) 
         history))


Thanks,
Brian



Posted on the users mailing list.