[racket] Lunch choosing program ported from Haskell to Racket

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Fri Jul 4 02:42:09 EDT 2014

On Jul 3, 2014, at 8:01 PM, John Clements wrote:

> 
> On Jul 3, 2014, at 8:52 AM, Brian Adkins <racketusers at lojic.com> wrote:
> 
>> Hi all:
>> 
>> I've recently begun learning Racket. After making some progress through various books & tutorials, I took a shot at porting a non-trivial program I had written in Haskell to help choose a lunch place for a group of colleagues based on personal rankings of restaurants and individual history of visiting restaurants.
>> 
>> The Haskell code was quite unpolished to begin with, so when you combine that with my very limited Racket knowledge, the ported code has much potential for improvement :) Both versions are in this gist:
>> 
>> https://gist.github.com/lojic/d45437453ccc8bcba196
> 
> Hmm, looks pretty good to me… except for the missing purpose statements on `rankrestaurants`, `rankUser`, and `rank`…

I would work hard to squeeze the program into 102 columns, and I might eliminate local and let in favor of defined variables, thusly: 

(define rawRatings
  '((chik     ((brian .0) (duff 11.0) (fred .5) (jimmy  5.0) (matthew .5) (nathaniel 1.0) (tom .0)))
    (chipotle ((brian .3) (duff  8.0) (fred .7) (jimmy  7.0) (matthew 1.0) (nathaniel 2.0) (tom .8)))
    (dickeys  ((brian .3) (duff  5.0) (fred .7) (jimmy  1.0) (matthew .0) (nathaniel 1.0) (tom .4)))
    (mexican  ((brian 1.5) (duff 1.0) (fred 1.0) (jimmy 1.0) (matthew .5) (nathaniel 2.0) (tom .6)))
    (nwc      ((brian .4) (duff  5.0) (fred .7) (jimmy  7.0) (matthew .0) (nathaniel 1.0) (tom .5)))
    (pizza    ((brian .9) (duff 12.0) (fred .7) (jimmy 1.0) (matthew .0) (nathaniel 2.0) (tom .7)))
    (thai     ((brian .9) (duff 11.0) (fred .8) (jimmy  5.0) (matthew 2.0) (nathaniel 2.0) (tom .8)))
    ))

;; completeRatings adds a default (User, 1.0) rating to
;; restaurants so each restaurant has a rating from every user
(define (filledOut ratings) 
  (for/list ([user users]) (or (assoc user ratings) (list user 1.0))))
(define completeRatings
  (for/list ([entry rawRatings])
    (match entry [(list restaurant ratings) (list restaurant (filledOut ratings))])))

I might also embed such things in a 'main' function. 

If there were a remote chance that the program would have to be used again, I would probably add (module+ test (require rackunit)) and I'd add tests for functions. 




Posted on the users mailing list.