Ah, you are of course right. Somehow I thought about `for/list` and
returning lists and then doing something on the returned list, instead
of simply doing it _inside_ the `for`. Apologies!

On 2/21/19 8:46 PM, Robby Findler wrote:
> For the record, `for` iterators go element-by-element. For example,
> this program does not construct anything that has all of the natural
> numbers in it:
>
> #lang racket
>
> (define my-stuffs-value
>   (hash 'telephone 3
>         'bluejeans 24
>         'house 100000
>         'computer 3000))
>
> (define my-estates-value
>   (for/sum ([i (in-naturals)]
>             [(k v) (in-hash my-stuffs-value)])
>     (printf "item ~a is worth ~a\n" i v)
>     v))
>
> my-estates-value
>
> On Thu, Feb 21, 2019 at 1:40 PM Zelphir Kaltstahl
> <zelphirkaltst...@gmail.com> wrote:
>> I don't think one can see `for` in Racket as equivalent to generators in 
>> Python.
>>
>> Generators in Python are used when you want to save memory by not producing 
>> all values at once, but want to go value by value (which to my knowledge 
>> Racket's `for` variants do not do, but I'd like to be corrected, if I am 
>> wrong about this, as it would mean, that those `for` are even more awesome 
>> than I knew.) They are more like lazy possibly infinite lists. I think lazy 
>> Racket has that and that there was some advice about not calling `length` on 
>> an infinite list.
>>
>> Python, I believe, has some kind of `Iterable` interface, which a generator 
>> satisfies and which specifies the method to call to get the next value. In 
>> Racket maybe one would have to do with a convention of how to get a next 
>> value from a lazy list.
>>
>> I believe something like the following could be an example. I did not yet 
>> think about macros, nor am I experienced with that, so maybe one can create 
>> something more elegant than what I am posting:
>>
>> ~~~
>> #lang racket
>>
>> ;; ================
>> ;; DATA ABSTRACTION
>> ;; ================
>>
>> ;; The value is always the first value of the generator.
>> (define get-value car)
>>
>> ;; A generator's producing procedure needs to be applied to get the
>> ;; next thing.
>> (define (get-next a-gen)
>>   ((cdr a-gen)))
>>
>> ;; A generator is only a tuple containing the current value and the
>> ;; procedure to create the next value
>> (define (make-gen proc start)
>>   (cons start
>>         (lambda ()
>>           (make-gen proc (proc start)))))
>>
>> (define STOP-SYMBOL 'none)
>>
>> ;; ========
>> ;; EXAMPLES
>> ;; ========
>>
>> ;; An infinite list of numbers.
>> (define natural-numbers
>>   (make-gen (lambda (x) (+ x 1))
>>             0))
>>
>> ;; A limited list of natural numbers.
>> (define (limited-natural-numbers limit)
>>   (make-gen (lambda (x)
>>               (cond [(< x limit) (+ x 1)]
>>                     [else STOP-SYMBOL]))
>>             0))
>>
>> ;; Print a certain amount of natural numbers.
>> (define (print-natural-numbers natural-numbers limit)
>>   (let ([current-number (get-value natural-numbers)])
>>     (cond
>>       [(and (symbol? current-number) (symbol=? current-number STOP-SYMBOL))
>>        (displayln "No more numbers available!")]
>>       [(< current-number limit)
>>        (displayln current-number)
>>        (print-natural-numbers (get-next natural-numbers) limit)]
>>       [else
>>        (displayln "Done")])))
>> ~~~
>>
>> Here the conventions are the structure of the generator and the stop symbol. 
>> In Python those are already taken care of by the standard library's 
>> generator interface.
>>
>>
>> On Wednesday, February 20, 2019 at 10:10:16 PM UTC, Jens Axel Søgaard wrote:
>>> Den ons. 20. feb. 2019 kl. 22.25 skrev Dave McDaniel <mcdani...@gmail.com>:
>>>> Hello,
>>>>
>>>> I have interest in picking up racket and have done some koans and also 
>>>> have been doing the racket track on exercism.
>>>>
>>>> There is a fairly simple exercise called `etl` on exercism related to 
>>>> taking a hash for scoring scrabble letters and unpacking it into a 
>>>> flatter, more efficient structure for lookups.
>>>>
>>>> The input hash has score as the key and a list of letters of that score as 
>>>> the value.  The output is a hash of letter -> score.  One pair per letter 
>>>> instead of one pair per score.
>>>>
>>>> It was easy enough to solve with `for-each` using side-effects to update a 
>>>> mutable hash, however I think using a generator is a cleaner approach and 
>>>> doesn't require mutability.
>>>
>>> FWIW here is a solution using immutable hashes. I see `for` and friends as 
>>> Racket "generators".
>>>
>>> /Jens Axel
>>>
>>>
>>> #lang racket
>>> (require racket/hash)
>>>
>>> ; In Scrabble each letter gives a certain number of points.
>>> ; In the old data we have for each point a list of numbers,
>>> ; that awarded the given number of points.
>>>
>>> (define old-data
>>>   ; list of associations from point to list of strings (letters)
>>>   '((1  "A" "E" "I" "O" "U" "L" "N" "R" "S" "T")
>>>     (2  "D" "G")
>>>     (3  "B" "C" "M" "P")
>>>     (4  "F" "H" "V" "W" "Y")
>>>     (5  "K")
>>>     (8  "J" "X")
>>>     (10 "Q" "Z")))
>>>
>>>
>>> ; Each point list needs to be transformed to a
>>> ; hash table from letters to points.
>>>
>>> (define (transform association)
>>>   (match association
>>>     [(list point letters ...)
>>>      (for/hash ([letter letters])
>>>        (values (string-downcase letter) point))]))
>>>
>>> ; Now we only need to combine the hash lists.
>>> (define ht
>>>   (apply hash-union
>>>        (hash)
>>>        (for/list ([association old-data])
>>>          (transform association))))
>>>
>>> (define (lookup letter)
>>>   (hash-ref ht letter #f))
>>>
>>> (lookup "e")
>>> (lookup "x")
>>>
>>>
>>>
>> --
>> You received this message because you are subscribed to the Google Groups 
>> "Racket Users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to racket-users+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to