[racket] Style. for/fold for/list for/lists
I think, that in semantic of for/..., I mean (for/... ... (values ...)), it is impossible.
Possible API could be
(for/collect ([a list] [b sum])
([i (in-list '(1 2 3 4)])
(cond
[(oddp? i) (a i) (b i)]
[(< (b) 10) (b 1)]))
Returns (values '(2 4) 8)
Inside body of (for/collect ([id option ...] ...) body)
(id val) = Add val to collection
(id) = return current collection value
For for/fold-like one may make
(define-collector fold [fld #:bind v #:inner v])
Then
(for/fold ([sum 0]) ([i (in-list '(1 2 3 4)]) ... (values (+ sum i)))
Become
(for/collect ([sum fold :initial 0]) ([i (in-list '(1 2 3 4)]) ... (sum (+ (sum) i)) ...)
But I cannot imagine, how to make this without closures and set!.
Суббота, 18 января 2014, 13:51 -05:00 от "J. Ian Johnson" <ianj at ccs.neu.edu>:
>Suffice it to say, my package does not have that expressive power. I'd be happy to collaborate with you to design a good extension to my package so that this kind of accumulation is easier.
>-Ian
>----- Original Message -----
>From: "Roman Klochkov" < kalimehtar at mail.ru >
>To: "J. Ian Johnson" < ianj at ccs.neu.edu >
>Cc: users at racket-lang.org
>Sent: Saturday, January 18, 2014 1:13:38 PM GMT -05:00 US/Canada Eastern
>Subject: Re[2]: [racket] Style. for/fold for/list for/lists
>
>It is great generalization for for/fold
>
>But still missed something like this:
>
>(iter (for i in l)
>(if (oddp i) (collect i into a) (collect i into b))
>(when (> i 10)
>(collect i into a))
>(finally (return a b)))
>
>Or in your for/acc
>(for/acc ([:type append] [:type append])
>([i (in-list l)])
>(if (odd? i) (values (if (> i 10) (list i i) (list i)) null)
>(values (if (> i 10) (list i) null) (list i))))
>
>I had to double condition and the result is not so transparent.
>
>Simple solution is:
>
>(define (make-collector init add post)
>(let ([a init])
>(case-lambda
>[(val) (set! a (add val a)]
>[() a])))
>
>(define (make-list-collector [init '()]) (make-collector init cons reverse))
>
>(let ([a (make-list-collector)]
>[b (make-list-collector)])
>(for ([i (in-list l)])
>(if (odd? i) (a i) (b i))
>(when (> i 10) (a i)))
>(values (a) (b)))
>
>But they say, that purity is the best and one should avoid set!... so this way is the dark way, isn't it?
>
>
>Суббота, 18 января 2014, 8:02 -05:00 от "J. Ian Johnson" < ianj at ccs.neu.edu >:
>
>
>
>
>
>
>You have hit limitations of the for/fold macros. I wrote an extension for controlling the way values get accumulated, along with post-processing like list reversal. Let me know what you think!
>
>https://github.com/ianj/nifty-macros/tree/master/for-acc
>-Ian
>----- Original Message -----
>From: Roman Klochkov < kalimehtar at mail.ru >
>To: users at racket-lang.org
>Sent: Sat, 18 Jan 2014 06:25:10 -0500 (EST)
>Subject: [racket] Style. for/fold for/list for/lists
>
>Where can I find style guide for these
>
>for/lists:
>
>I have to duplicate values names:
>
>(define-values ([(desc-args lengths add-data)
>(for/lists (desc-args lengths add-data) ([arg (in-list %args)])
>....)) is it ok? Or better
>(define-values ([(desc-args lengths add-data)
>(for/lists (a b c) (...) ...))
>
>?
>
>for/fold has no "return" clause. So I have to do
>(call-with-values
>(for/fold (acc1 acc2 sum) (...) ...)
>(lambda (acc1 acc2 sum) (reverse acc1) (reverse acc2) sum))
>
>And for/list doesn't allow to add several items to resulting list in one round.
>Even with for/fold it gives
>
>(reverse
>(for/fold (acc) ([item (in-list list)])
>(values (cons (get-val1 item)
>(cons (get-val2 item) acc)))))
>
>Awful, especially for reading.
>
>It is clumsy and unobvious.
>In Common Lisp iterate I could do
>(iter (...)
>(collect (foo) into acc1)
>(collect (bar) into acc2)
>(summing ... into sum)
>(finally (return acc1 acc2 sum)))
>
>http://common-lisp.net/project/iterate/doc/index.html
>
>Is there something similar?
>
>--
>Roman Klochkov
>
>
>--
>Roman Klochkov
--
Roman Klochkov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20140119/852635e5/attachment-0001.html>