I think it is clear what I am after:
(let (displaying)
(defun display-non-reentrantly (n)
(unless displaying
(let ((displaying t)) ;; <== main objective
...possibly reentrant code...))))
ie, I want to avoid setting 'displaying' first to t and then back to
nil. I tried declaring it special and dynamic-extent and putting the
declarations here, there, and everywhere, but no luck.
Can do?
kenny
--
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Kenny Tilton wrote:
> I think it is clear what I am after:
>
> (let (displaying)
> (defun display-non-reentrantly (n)
> (unless displaying
> (let ((displaying t)) ;; <== main objective
> ...possibly reentrant code...))))
>
> ie, I want to avoid setting 'displaying' first to t and then back to
> nil. I tried declaring it special and dynamic-extent and putting the
> declarations here, there, and everywhere, but no luck.
(defvar *displaying* nil)
(defun display-non-reentrantly (n)
(unless *displaying*
(let ((*displaying* t))
...)))
Is the naive way. You could wrap the whole thing up in a macro which
avoids the (visible) DEFVAR.
You could do something more sophisticated (but not necessarily better)
with something like
(defun display-non-reentrantly (...)
(locally (declare (special %displaying%))
(unless (and (boundp '%displaying%) %displaying%)
(let ((%displaying% t))
...))))
Again, wrapped up in a macro if you do it a lot. My
local-dynamic-state stuff (www.tfeb.org/lisp somewhere) can help with
this sort of approach.
Yet another approach is something like:
(defvar *stack* '())
(defmacro noting-on-stack ((name &optional val) &body code)
`(let ((*stack* (cons (cons ',name ,val) *stack*)))
,@body))
(defun stack-property (prop)
(let ((found (assoc prop *stack*)))
(if found (values (cdr found) t) (values nil nil))))
And then something like:
(defun display-non-reentrantly (...)
(unless (stack-property 'display-non-reentrantly)
(noting-on-stack (display-non-reentrantly t)
...)))
Note: all the above was just typed straight into a web browser, it
probably has paren errors and worse.
--tim
"Tim Bradshaw" <··········@tfeb.org> writes:
> My local-dynamic-state stuff (www.tfeb.org/lisp somewhere) can help
> with this sort of approach.
To free others from poking around:
http://www.tfeb.org/lisp/hax.html#DYNAMIC-STATE
By the way, the layout here is nice:
http://www.tfeb.org/lisp/index.html
Aside from just being enjoyable to look at, it coaxed me into reading
more.
--
Steven E. Harris
Tim Bradshaw wrote:
> Kenny Tilton wrote:
>
>>I think it is clear what I am after:
>>
>>(let (displaying)
>> (defun display-non-reentrantly (n)
>> (unless displaying
>> (let ((displaying t)) ;; <== main objective
>> ...possibly reentrant code...))))
>>
>>ie, I want to avoid setting 'displaying' first to t and then back to
>>nil. I tried declaring it special and dynamic-extent and putting the
>>declarations here, there, and everywhere, but no luck.
>
>
> (defvar *displaying* nil)
>
> (defun display-non-reentrantly (n)
> (unless *displaying*
> (let ((*displaying* t))
> ...)))
>
> Is the naive way.
Right, sorry. That I knew about. I was looking for a lazy way to toss
off the same just by inserting the right magical DECLARE.
>
> You could do something more sophisticated (but not necessarily better)
> with something like
>
> (defun display-non-reentrantly (...)
> (locally (declare (special %displaying%))
> (unless (and (boundp '%displaying%) %displaying%)
> (let ((%displaying% t))
> ...))))
Hmmm, I get "%displaying% unused" from the AllegroCL compiler with:
(defun display-non-reentrantly (n)
(locally (declare (special %displaying%))
(print `(depth ,n))
(unless (and (boundp '%displaying%) %displaying%)
(let ((%displaying% t))
(when (< n 2)
(display-non-reentrantly (1+ n)))))))
...and when kicked off it indeed recurses to depths 0, 1, 2. Anyway,
looks like a toplevel defvar is as simple as it is going to get.
kenny
--
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Kenny Tilton <·······@nyc.rr.com> writes:
> I think it is clear what I am after:
>
> (let (displaying)
> (defun display-non-reentrantly (n)
> (unless displaying
> (let ((displaying t)) ;; <== main objective
> ...possibly reentrant code...))))
>
> ie, I want to avoid setting 'displaying' first to t and then back to
> nil.
But would you want to avoid using LETF (instead of the inner LET)?
This is a case for it (well, at this time of the morning, this
_seems_ to be a case for it...).
---Vassil.
--
Vassil Nikolov <········@poboxes.com>
Hollerith's Law of Docstrings: Everything can be summarized in 72 bytes.