@hi has joined the channel
@rxg has joined the channel
How do I add syntax to a namespace?
(define-syntax-rule (switch-arguments a b)
(list b a))
(define (wrap-syntax a b)
(eval `(switch-arguments ,a ,b)))
(define namespace (make-base-namespace))
(namespace-set-variable-value! 'wrap-syntax wrap-syntax #t namespace #t)
(define with-syntax-defined '(begin
(define-syntax-rule (switch-arguments a b)
(list b a))
(wrap-syntax 1 2)))
(wrap-syntax 1 2) ;; -> '(2 1)
(eval with-syntax-defined namespace) ;; -> '(2 1)
(eval '(wrap-syntax 1 2) namespace) ;; -> fails because switch-arguments isn't defined
@wlbberman the problem isn’t that you haven’t added switch-arguments
to the namespace, it’s that the implementation of wrap-syntax
calls eval
with the current namespace, which is not the namespace you’ve created. Passing a namespace to eval
does not also set current-namespace
inside the evaluated code to that namespace.
That said, using eval and namespaces is not something you should need to do except in very specific use cases, like writing an editor like DrRacket that evals user code as they’re typing it.
what are you trying to do?
Also note that (wrap-syntax 1 2)
above actually doesn’t work
It looks like you evaluate this in an interactive session rather than a Racket module?
Wait, really?
Passing the namespace argument to eval
should work, no?
Ohhhh I see what you meant now
Nvm
(honestly I think the namespace argument to eval
should be required)
(it’s too easy to assume you’ll get it from the right place automatically)
I’m building a custom repl inside a larger program to interact with bits of it in a custom way
Correct, it was done in a repl
@notjack your explanation makes sense. I was calling eval on the read code with a custom namespace to introduce bindings. I’ll likely modify the input and then eval it in the current namespace it looks like.
are you trying to make sure the repl has various built-in library functions and macros available?
Built in library functions as well as my own functions
(define (make-optimizer-querier-namespace optimizer)
(define (enable . args)
(optimizer-enable-optimization! optimizer args))
(define (disable . args)
(optimizer-disable-optimization! optimizer args))
(define (call . args)
(apply optimizer args))
(define (available-optimizations)
(optimizer-get-available-optimizations optimizer))
;; TODO this needs to be formatted
(define (view-optimization . args)
(optimizer-get-optimization optimizer args))
(define (help)
"TODO: Insert standard help message here")
(define namespace (make-base-namespace))
(define (add-to-namespace symbol value)
(namespace-set-variable-value! symbol value #t namespace #t))
(add-to-namespace 'enable enable)
(add-to-namespace 'disable disable)
(add-to-namespace 'call call)
(add-to-namespace 'available-optimizations available-optimizations)
(add-to-namespace 'view-optimization view-optimization)
(add-to-namespace 'help help)
namespace)
Really just proxying a set of function calls to a specific object
To avoid making a custom namespace, is it possible to define syntax that only applies in a particular scope?
Re: the file guard procedure in make-security-guard
: https://docs.racket-lang.org/reference/securityguards.html?q=make-security-guard#%28def._%28%28quote._~23~25kernel%29._make-security-guard%29%29
That procedure must accept a list containing symbols like 'exists
, 'write
, or 'delete
. The manual does not spell out the semantics of the list to great detail, so I want to be sure I’m reading contextual clues correctly.
Is it correct that if the list does NOT contain 'exists
, then the symbols represent ALL effects that WILL occur if you don’t throw an exception in the guard?
It represents the effects that might occur (which is I think what you mean, just trying to be clear).
@wlbberman I recommend doing what you’re doing with modules and namespace-require
What makes it a “might” as opposed to “will”?
rather than with namespace-set-variable-value!
It might fail before it got to the effect, for example.
Gotcha, thanks much.
Taking a look at it. Thanks!
It would be cool to have a print-definition or show-definition function for a procedure.
I asked a similar question a week or so ago. You can do the following to store the body of procedures that you define (struct annotated-procedure (procedure body)
#:property prop:procedure (struct-field-index procedure))
(define-syntax-rule (annotated-lambda formals . body)
(annotated-procedure (lambda formals . body)
'(lambda formals . body)))
To be clear here, the important part is prop:procedure
Just like this. I think this is an interesting way for beginners to explore the system. If it only applies to procedures defined by yourself, then it’s not useful for this kind of purpose. https://stackoverflow.com/questions/33707068/how-can-i-view-the-definition-of-a-function-in-lisp-sbcl
Ah yep. That is a perk of common lisp. Not sure if there’s a racket analogue