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