[racket] Looking for better designs to learn principles.

From: Sean Kanaley (skanaley at gmail.com)
Date: Sun Mar 15 11:01:06 EDT 2015

Ah, I should've said that performance is not ideal with either compose (or
thrush), since they build the entire e.g. 10 million long function chain
before calling it, so tail-recursive variants below

(define (iterate f n x)
  (for/fold ([x x])
            ([i n])
    (f x)))

or with the thread-through thingy

(define (iterate f n x)
  (for/fold ([x x])
            ([i n])
    (~> x f)))

With 128 MB default, DrRacket even ran out of memory with my compose
variant. Sorry!


On Sat, Mar 14, 2015 at 6:41 PM, Alexis King <lexi.lambda at gmail.com> wrote:

> There’s also the thrush function from the point-free package, which uses
> the argument order of the threading macro while providing the functional
> style of compose.
>
>
> http://pkg-build.racket-lang.org/doc/point-free/index.html?q=thrush#%28def._%28%28lib._point-free%2Fmain..rkt%29._thrush%29%29
> <http://pkg-build.racket-lang.org/doc/point-free/index.html?q=thrush#(def._((lib._point-free/main..rkt)._thrush))>
>
> On Mar 14, 2015, at 15:35, Sean Kanaley <skanaley at gmail.com> wrote:
>
> If "thread-through macro" refers to "
> http://www.greghendershott.com/2013/05/the-threading-macro.html" then I
> recommend a functional alternative called "compose":
>
> (define print/cdr
>   (match-lambda
>     [(cons x xs) (print x) xs]))
>
> (define print-two
>   (compose print/cdr print/cdr))
>
> The result is chained through naturally since the input and output type of
> the lower level function are equal.
>
> For any number of printings
>
> (define (print-n n)
>   (for/fold ([print-n identity])
>             ([i n])
>     (compose print/cdr print-n)))
>
> (define print-two (print-n 2))
>
> And for any number of anythings
>
> (define (iterate f n)
>   (for/fold ([chain identity])
>             ([i n])
>     (compose f chain)))
>
> (define print-two (iterate print/cdr 2))
>
>
> On Thu, Mar 12, 2015 at 2:25 PM, Don Green <infodeveloperdon at gmail.com>
> wrote:
>
>> ;Design A:
>> ;Rating: 1 out of 10
>> ;Poor because it uses set!
>> (define print-two
>>   (lambda (f)
>>    (print (first f))
>>    (set! f (rest f))
>>    (print (first f))
>>    (set! f (rest f))
>>    f))
>>
>> (void (print-two '(1 2))) ;=> 12
>> ;-------------------------
>> ;Design B:
>> ;Rating: 2 out of 10
>> ;Better because it nests expressions to avoid using set!
>> ;Poor because it less readable.
>> (define print-two
>>   (lambda (f)
>>     (print (first f))
>>     (print (first (rest f)))
>>     f))
>>
>> (void (print-two '(1 2))) ;=> 12
>> When called in situations that allow one expression only, enclose call
>> within a 'begin' expression.
>> ;-------------------------
>> ;Design C:
>> ;Rating: 3 out of 10
>> ;Is this an even better design because it is more readable than nesting
>> expressions as in Design B above?
>> (define (print-two f)
>>   (let* ([_ (print (first f))]
>>          [f (rest f)]
>>          [_ (print (first f))]
>>          [f (rest f)])
>>     f))
>> (void (print-two '(1 2))) ;=> 12
>> ;-------------------------
>> My questions are:
>> "Can you recommend a better method?"
>> "Can you recommend a better method using 'define with lambda'?"
>> "Does your better method use a macro?"
>> "Does your better method use a thread-through macro?"  If so, could you
>> please provide the definition of the thread-through macro.
>> THANKS!
>>
>>
>> ____________________
>>   Racket Users list:
>>   http://lists.racket-lang.org/users
>>
>>
> ____________________
>  Racket Users list:
>  http://lists.racket-lang.org/users
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20150315/edeba07b/attachment.html>

Posted on the users mailing list.