Hi Jon,

Thanks for the very detailed explanation.  It does make good sense and is 
helpful in getting up to speed on racket in general.  Regarding the docs, 
it does not say "slight", but rather "can provide better", I read this as 
slight since it wasn't definitive--but I understand better now based on 
your description in which case (`for`) it is an optimization.

Thanks again,
Dave

An in-list 
> <https://docs.racket-lang.org/reference/sequences.html?q=in-list#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._in-list%29%29>
>  
> application can provide better performance for list iteration when it 
> appears directly in a for 
> <https://docs.racket-lang.org/reference/for.html?q=in-list#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._for%29%29>
>  
> clause.
>

On Wednesday, February 20, 2019 at 10:00:54 PM UTC-5, Jon Zeppieri wrote:
>
>
> On Wed, Feb 20, 2019 at 9:14 PM Dave McDaniel <mcdani...@gmail.com 
> <javascript:>> wrote:
>
>> Thanks Jon and Jen, This is a great!  I figured there must be a 
>> straightforward way to do this with a `for/hash` implementation.  I have 
>> not seen these 2 methods `in-hash` and `in-list` vs just using the hash or 
>> list without that sequence modifier.  Can you comment on what is going on 
>> with this `in-xxx` sequence modification?  The docs indicate that you get 
>> slightly better performance when using these with `for`, but its not clear 
>> why and in what situations you must use these modifiers rather than the 
>> underlying list or hash itself--is it always optional?
>>
>
> `in-hash` and `in-list` are optional, but, as you noted, they do make 
> iteration perform better.[*] This is because the various iterators can 
> generate better code if they know what kind of sequence they're dealing 
> with. If they don't know, they have to use generic sequence operations, 
> which are usually quite a lot less efficient. The difference is not slight. 
> (Do the docs say it is?) 
>
> That said, if you're only iterating over a small sequence, you won't 
> notice or care.
>
> You can see the difference in generated code by using the Macro Stepper in 
> Dr. Racket. Write something like:
> ```
> #lang racket/base
>
> (define (fast-foo xs)
>   (for/list ([x (in-list xs)])
>     x))
>
> (define (slow-foo xs)
>   (for/list ([x xs])
>     x))
> ```
>
> Then click on the Macro Stepper button and then click "End" to see the 
> fully expanded source, and compare the two different versions.
>
> [*] Rather, they make iteration perform better when they're used inside a 
> `for` loop. Outside of a `for`, they're just normal procedures. Inside, 
> they are syntax and direct code generation. You would _not_ get better 
> performance from:
>
> (slow-foo (in-list my-list))
>   than you would from
> (slow-foo my-list)
>
> ======
>
> However, it's not the case that the `in-<sequence>` syntax is always 
> optional. For example, if you have a hash, then
>
> (for ([(k v) hash]) ...)
>   and
> (for ([(k v) (in-hash hash)]) ...)
>
> will always have the same behavior (though not performance). But if you 
> want to iterate over explicit key/value _pairs_ (i.e., cons cells), then 
> you'd need to do:
>
> (for ([pair (in-hash-pairs hash)]) ...)
>
> since the default sequence interpretation for a hash is one that produces 
> two values (the key and value) per-iteration, instead of one that produces 
> a single cons cell value per-iteration.
>
> Point is, sometimes `in-<sequence>` is an optimization; in other cases, it 
> changes the actual way that the data structure is interpreted as a sequence.
>
> - Jon
>
>

-- 
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