Curious why begin0 is a core form rather than a macro
I guess it’s difficult to do that efficiently due to multiple values?
How would an expansion of (begin0 e0 e ...) look like?
(call-with-values (lambda () e0) (lambda vs e ... (apply values vs))) should be functionally equivalent.
Yeah, much simpler to keep begin0 - apply is expensive.
Is it also equivalent in the case (begin0 e0) where e0 is a tail call?
Well, doesn’t matter - one can use the long form only if there is more than one subexpression.
Right, yes. I imagine begin0 is useful for the compiler, and there’s little reason not to expose it directly.
It is pretty simple to handle for a byte code interpreter.
I would admittedly hope that the bigger expression using call-with-values would be compiled exactly the same way as begin0, but I don’t know if the Racket optimizer actually does that optimization, especially since I doubt the call-with-values code appears very often in the wild.
Even trickier to find out now, that Chez is the backend.
I found there’s a way to see the optimizer output—you have to set an environment variable and compile a module. I think it’s PLT_SHOW_CP0 or something like that.
Nice tip.
Ah, it’s PLT_LINKLET_SHOW_CP0.
Hmm. Here is begin0 in Chez: https://github.com/cisco/ChezScheme/blob/68fe2d780c3b891bad493dd97457e3a2d4af88a3/examples/compat.ss#L31
(define-syntax begin0
(syntax-rules ()
((_ x y ...) (let ((t x)) y ... t))))That’s not equivalent to a Racket begin0.
No, in fact it looks like begin0 for Racket-on-Chez is defined here, and it does, in fact, expand into call-with-values: https://github.com/racket/racket/blob/020c75792ca4649ed0b6994aa095cb3d02793be8/racket/src/cs/rumble/begin0.ss
I suspect the ChezScheme turns the single value case into something reasonable.
?!?
I haven’t seen that and don’t know why it would happen, so I recommend “Don’t Allow”!
The context: I picked “Open…” then got a file window. Clicked through the correct folder. Then entered a search term in the text field used to filter results.
Digging a little. It seems macOS will display these dialogs when access to certain folders is attempted. Similar situation here: https://github.com/atom/atom/issues/17687 So I guess, it’s just the way things work.
A bit confusing though.
From reading that issue, the only way we can avoid that is by adding some paths to be excluded from whatever directory traversal it was doing
@mflatt I played with RacketCS and found that function that returns multiple values won’t work well with cp0 when callsite is at top level. Is there a way to improve this?
For instance:
(define-values (foo bar) (values 1 2))
(+ foo 10)cp0 could propagate foo, reducing (+ foo 10) to 11 at compile time.
However, if we have
(define (call) (values 1 2))
(define-values (foo bar) (call))
(+ foo 10)then cp0 is stuck at
(letrec ([call (lambda () (#2%values 1 2))])
(variable-set!/define call121 call 'consistent)
(call-with-module-prompt (lambda () (#2%values 1 2))
'(foo bar) '(constant constant) foo120 bar119)
(let ([foo (#3%$object-ref 'scheme-object foo120 9)])
(call-with-module-prompt
(letrec ([procz122 (lambda () (#2%+ foo 10))])
(lambda () (#%call-with-values procz122 print-values118))))
(#2%void)))(presumably due to call-with-module-prompt?)