[plt-scheme] Mini code review request
On Thu, Apr 8, 2010 at 3:24 PM, Greg Hendershott
<greghendershott at gmail.com> wrote:
> If anyone has time to do a mini code review, I'd appreciate the feedback.
I think it's helpful to start by thinking about per-element
operations, then figure out a specialized fold you want to perform on
the resultant data structure. For instance, I think I prefer this for
the function body:
(string-join (map (λ(p) (let ((k (form-urlencoded-encode (car p)))
(v (form-urlencoded-encode (cadr p))))
(string-append k "=" v)))
lst)
"&"))
It involves a function that maps an input element to the corresponding
component of the output, then a fold over the result of that
transformation to produce the output.
The map function lets us operate within the structure of the input,
then we use a specialized fold (string-join) to change the structure
itself.
Anthony
>
> Welcome any comments, but mainly I'm curious about my experiment to
> stop being Mr. Imperative. Avoid iterating and mutating. Instead
> embrace map and fold. Don't just sip the kool aid, actually swallow
> it.
>
> I ended up with a (rest (reverse (flatten ...))) sequence which seems
> a bit of a pretzel.
>
> I'm looking at this code with the following questions:
> 1. Is this clean and simple ... or too "clever"?
> b. Is this reasonably idiomatic ... or am I still speaking Scheme as a
> second language?
> iii. How would you native speakers write it?
> 100. Should I spit up the kool aid and revert to my old iterative ways? :)
>
> Thanks in advance.
>
> Code:
>
> ---------
>
> #lang scheme
>
> (require net/uri-codec)
> (require test-engine/scheme-tests)
>
> (define/contract (pairs->params-string lst) ((listof (list/c string?
> string?)) . -> . string?)
> ; Convert e.g.
> ; '( ("Param1" "Value1")
> ; ("Param2" "Value2")
> ; ("Param3" "Value3") )
> ; to
> ; "Param1=Value1&Param2=Value2&Param3=Value3"
> ;
> ; The point of
> ; (rest (reverse (flatten (list "key" "=" "val" "&") ... )))
> ; is to get the ampersands only BETWEEN, not start or end.
> (if (empty? lst)
> ""
> (foldl string-append
> ""
> (rest (reverse (flatten (map (lambda (x)
> (list
> (form-urlencoded-encode (first x)) ; key
> "="
>
> (form-urlencoded-encode (second x)) ; value
> "&"))
> lst)))))))
>
> (check-expect (pairs->params-string '()) "")
> (check-expect (pairs->params-string '( ("foo" "bar" ) )) "foo=bar" )
> (check-expect (pairs->params-string '( ("Param1" "Value1") ("Param2"
> "Value2") ("Param3" "Value3") ))
> "Param1=Value1&Param2=Value2&Param3=Value3" )
> (test)
> _________________________________________________
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>