Is there a propagators library (a la Sussman) for racket?
I was working through the following example from <https://eighty-twenty.org/2015/01/25/monads-in-dynamically-typed-languages|Monads in Dynamically-Typed Languages> : #lang racket
(define (fail) (list))
(define (return x) (list x))
(define (bind xs f) (append-map f xs))
(define-syntax do
(syntax-rules (<-)
[ (_ mexp) mexp ]
[ (_ var <- mexp rest ...) (bind mexp (λ (var) (do rest ...))) ]
[ (_ mexp rest ...) (bind mexp (λ (dummy) (do rest ...))) ]
[ (_ #:guard exp rest ...) (if exp (do rest ...) (fail)) ]
))
(do i <- '(1 2 3 4 5)
#:guard (odd? i)
(return (* i 2)))
and I encountered an error that implied the 3rd rule was being matched for #:guard
. Swapping the 3rd and 4th rule solved the problem, but it made me wonder whether it was just a simple error that the author didn’t test, or if possibly something changed in Racket since the article was written. I’m also confused about how keywords are handled in the context of macros. I tried adding #:guard
to the literal list, and naturally that failed. Is #:guard
a pattern variable or a literal here?
#:guard
is a literal, in the same sense that numbers of strings are.
But mexp
matches #:guard
because a pattern variable matches anything
Keep in mind that this information is usually expanded into functions via macros and might not be readily available.
r6rs records seem to have some introspection around, but I did not try yet
Ok, thanks. The author must’ve posted the incorrect version before testing it.
In <https://docs.racket-lang.org/syntax/Optional_Keyword_Arguments.html|1.2.2 Optional Keyword Arguments> I’m not really seeing the benefit of the use of ~optional
and ~seq
i.e. I think the following: (define-syntax (mycond stx)
(syntax-parse stx
[(mycond (~optional (~seq #:error-on-fallthrough who:expr))
clause ...)
(with-syntax ([ error? (if (attribute who) #'#t #'#f) ]
[ who (or (attribute who) #'#f)])
#'(mycond* error? who clause ...))]))
is less clear than: (define-syntax (mycond stx)
(syntax-parse stx
[ (_ #:error-on-fallthrough who:expr clause ...)
#'(mycond* #t who clause ...) ]
[ (_ clause ...)
#'(mycond* #f #f clause ...) ]))
Maybe the former scales up better than the latter?
If there are a lot of keyword argument sets then it helps a lot.
Is there an example of this? Looking at the example in 1.2.2, it seems like it might even be messier as you add keywords i.e. a combinatorial explosion.
Especially if you want to change them in a bunch of different orders.
(define-syntax (my-thing stx)
(syntax-parse stx
[(_ {~or {~optional {~seq #:aaa aaa} #:defaults ([aaa #'missing])}
{~optional {~seq #:bbb bbb} #:defaults ([bbb #'missing])}} ...)
#''(aaa bbb)]))
;;; repl
> (my-thing)
'(missing missing)
> (my-thing #:aaa 1)
'(1 missing)
> (my-thing #:aaa 1 #:bbb 2)
'(1 2)
> (my-thing #:bbb 2)
'(missing 2)
> (my-thing #:bbb 2 #:aaa 1)
'(1 2)
>
I think there could/should be more examples that show this usage.
1.2.5 shows it in more detail https://docs.racket-lang.org/syntax/More_Keyword_Arguments.html
(and variety)
In the example from 1.2.2 I think it will produce a better diagnostic error when misused.
Pull request submitted finally. I had to clean up my git workflow first.
@pdgonzalez872_rackets has joined the channel