From: Kenny Tilton
Subject: How to?: Quicky specials
Date: 
Message-ID: <Qlz4d.42322$Ot3.30100@twister.nyc.rr.com>
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

From: Tim Bradshaw
Subject: Re: How to?: Quicky specials
Date: 
Message-ID: <1095950530.289402.35440@k17g2000odb.googlegroups.com>
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
From: Steven E. Harris
Subject: Re: How to?: Quicky specials
Date: 
Message-ID: <jk4fz59t1e3.fsf@W003275.na.alarismed.com>
"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
From: Kenny Tilton
Subject: Re: How to?: Quicky specials
Date: 
Message-ID: <XZB4d.42336$Ot3.24818@twister.nyc.rr.com>
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
From: Tim Bradshaw
Subject: Re: How to?: Quicky specials
Date: 
Message-ID: <1095954356.234920.119080@k17g2000odb.googlegroups.com>
Kenny Tilton wrote:

> (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)))))))
>

I think you need asnother special declaration (in fact I'm sure you do)
inside the LET.
Sorry, my mistake.
From: Vassil Nikolov
Subject: Re: How to?: Quicky specials
Date: 
Message-ID: <lzy8j0w88q.fsf@janus.vassil.nikolov.names>
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.