
Can someone provide some details on how for
for hash sequences provide both the key and value? I’d like to do something similar for a custom stream. I’m not sure if it’s just the stream returning multiple values or a list that’s destructured by for
or perhaps something else? For example, would stream-map
accept multiple values as well (assuming it’s just a stream)?

It’s a sequence that produces multiple values

streams (not sequences) are single-valued

A for/sequence
form would be handy for implementing custom sequences that produce multiple values


@samth stream in general can be multi valued

The ones in the standard library just decide to not support it

we should just fix that

Also I’d still like a for/sequence
form to construct sequences where I don’t want to pay the cost of memoizing the elements

https://github.com/racket/racket/pull/3333\|https://github.com/racket/racket/pull/3333 was an attempt to do that, but I don’t know if I should port stuff from the stream-values library to the standard library

yes, for/stream/values
seems like a strict improvement on for/stream

Well, it’s slower :(

why is it slower?

Memoizing multiple values

@notjack I should create a variant that doesn’t have memoization. That’s very easy to do

a variant of for/stream
? I actually don’t think that’s a good idea. If memoization in streams is optional, what’s the point of having separate stream and sequence APIs?

Sequence supports non stream. That’s the only reason for the concept iiuc

So if you want to create a sequence, creating a non memoizing stream is one of the best way

I would rather write (for/sequence ([x ...]) ...)
than (for/stream #:no-memoize ([x ...]) ...)
Keeps the conceptual split simpler IMO


Have a question about syntax-parse
.
I have:
(define-syntax-parse-rule (test1 (main sub ...))
(list (list '(main sub) ...)))
(test1 (1 2 3 4))
;=> '(((1 2) (1 3) (1 4)))
And this works as expected.
Now, let’s add one more ellipsis, and it no longer works:
(define-syntax-parse-rule (test2 (main sub ...) ...)
(list (list '(main sub) ...) ...))
(test2 (1 2 3 4) (4 5 6 8))
;=> syntax: incompatible ellipsis match counts for template in: ...
I understand why it errors, but would it be possible for this to work?
Also, what are possible workarounds? One answer is doing code generation in a syntax class. Another is awkwardly creating main*
whose attribute arity matches sub
. Do I miss other options?

I don’t know the answer to this but I’m curious about the expected output. If it were (test2 (1 2 3) (4 5 6))
then I can see that the expected output is '(((1 2) (4 3)) ((1 5) (4 6)))
what about your example?

Hmm, that’s not the output that I expect, but I can see that it’s a sensible output.

Yeah, nvm then. The property x => y
then x ... => y ...
simply doesn’t hold for syntax-parse
.

ah so you want ellipsis saturation from the outside rather than from the inside

yep

So the workaround for this case would be:
(define-syntax-parse-rule (test2 clause:parse-this-thing ...)
(list clause.code-gen ...))

where parse-thing-thing
generates the code like test1

It’s annoying when parse-this-thing
requires additional information from other syntax fragments. Cuz I need to reparse clause
within the #:with
clause.

E.g.,
(define-syntax-parse-rule (test2 sth raw-clause ...)
#:with ({~var clause (parse-this-thing #'sth)} ...) (attribute raw-clause)
(list clause.code-gen ...))