-
Notifications
You must be signed in to change notification settings - Fork 28
Dynamic Context and With Macros
lisp123
It says on the CLiki Page: "with-foo" -> create a dynamic context with a foo. If I want to write with-food, would it be something like this? (defmacro with-foo (&body body) (let ((foo 'something)) (declare (special foo)) ,@body))
lisp123
Or does it mean simply (defmacro with-foo (&body body) (declare (special foo)) ,@body))
lisp123
(sorry for the minor mistakes, but just typing it fast to give the point of these examples)
beach
It usually means that the macro takes the name of a lexical variable.
beach
And it usually means that something is destroyed upon exit, so there is usually an UNWIND-PROTECT in there.
beach
Look at WITH-OUTPUT-TO-STRING for instance.
beach
A stream is created and closed upon exit.
lisp123
beach: Got it, thanks. That example helps
beach
Pleasure.
Disconnected
You have joined the channel
lisp123 has joined ([email protected])
Topic: Common Lisp questions answered here! (Lisp-Koans #u"https://github.com/google/lisp-koans") (CL-on-Exercism #u"https://exercism.io/tracks/common-lisp") (Online-Tutorial #u"http://cliki.net/Online+Tutorial") (Books #u"http://cliki.net/Lisp+Books")
phoe set the topic at: 21 May 2021 at 6:00 pm
Mode: +nt
Created at: 19 May 2021 at 8:00 pm
pjb
lisp123: what cliki page/
pjb
?
lisp123
pjb: https://www.cliki.net/naming+conventions
pjb
The notion of dynamic context is not necessarily implemented with a dynamic binding. It can often be, but it could be implemented otherwise.
pjb
lisp123: dynamic = time ie. execution time ; lexical = space ie. the program source.
pjb
lisp123: so you just could have: (defmacro with-foo (&body body) (unwind-protect (progn (acquire-foo) ,@body) (release-foo))) lisp123 pjb: Thanks, when you put it that way, its not too hard to write. What did you mean by "it could be implemented otherwise."? The only other alternative I sometimes use is having a leixcal scope for a variable but then put only macros within that scope so that they have access to those variables pjb lisp123: a macro such as with-open-file or with-output-to-string, will indeed take a variable name. The macro doesn't assume whether that variable name has been declared special or not. So it will establish a binding that can be dynamic or lexical. This is not this aspect that is qualified in the cliki page.. But the fact that for the time during which the macro executes, there is a file that is open, and the stream bound to that variable. pjb lisp123: otherwise = for example unwind-protect as in my example. lisp123 pjb: Got it, thanks pjb lisp123: again, with-foo = we have a foo available dynamically = from the start time of the execution of the macro to then end time of the execution of the macro, there will be some foo available. pjb lisp123: notably: this foo will be available even in functions called from the body (functions that are outside of the lexical scope). lisp123 Would that not require the variable to be declared special? pjb Not at all. lisp123 ah I got it -> because the body is within the scope of the macro yes? pjb Notably, the foo in question could be outside of the current process. It could be a ressource on a server. pjb lisp123: the body will be within some lexical scope defined by the macro, indeed, but foremost, it will be used during the execution of the macro (within its dynamic scope). pjb For example, the macro could be: (defmacro with-foo (&body body)
(call-with-foo (lambda (the-foo) ,@body)))
pjb
in that case, the body won't be in the lexical scope of the call-with-foo function.
lisp123
That makes sense. So let's say it was a resource on the server, outside of the current process, -> would it not not need to be named to be used?
lisp123
So in the ,@body, how would one reference the server I guess
lisp123
In your last example
pjb
of course, if it's needed, the macro will take more parameters, possibly variable names to let the body reference the resource.
pjb
but if the resource is sufficiently unique, it could be implicit. There could be an API to access it.
lisp123
Got it! That makes sense. Thanks for clearing that up re 'with-foo' macros and around acquiring / releasing resources
pjb
For example: (with-daylight (print 'hello)) --> (progn (when (< (compute-sunset) (get-universal-time)) (sleep (- (compute-sunrise) (get-universal-time)))) (print 'hello))
pjb
global resource, implicitely accessed, and purely dynamic (temporal).
pjb
Run codes only during daylight…
lisp123
Nice! Thanks, makes perfect sense. I really never thought of dynamic context like that, but it is definitely a very useful technique when put that way