From: Vladimir Zolotykh
Subject: EVAL-WHEN and using SPECIAL
Date: 
Message-ID: <3E242629.1010207@eurocom.od.ua>
Hi

Let me ask two simple questions:

First
--------------------------------
Is there a difference between the following two fragmenst:

   (eval-when (:compile-toplevel :load-toplevel :execute)
     (require :foo)
     (setq foo::bar '(#|Something|#)))

and

   (eval-when (:compile-toplevel :load-toplevel :execute)
     (require :foo))

   (eval-when (:compile-toplevel :load-toplevel :execute)
     (setq foo::bar '(#|Something|#)))

I see the difference in ACL62 but I don't understand it.
The :foo package is defined in :foo module.

Second
--------------------------------
In the following code

   (defparameter *month-lengths*
       (vector 31 28 31 30 31 30 31 31 30 31 30 31))

   (defun month-length (month year)
     (declare (special *month-lengths*))  ;;; [1] ;;;
     (if (/= month 2) (aref *month-lengths* (1- month))
       (if (null (zerop (mod year 4))) 28
	(if (null (zerop (mod year 400))) 29 28))))

What's the advantages of using SPECIAL declaration (if any)? I can't
figure out what're they might be. NB. I'm not concerned about the
purpose of code itself, I used it just to illustrate the usage of
SPECIAL.

Thanks in advance

-- 
Vladimir Zolotykh

From: Joe Marshall
Subject: Re: EVAL-WHEN and using SPECIAL
Date: 
Message-ID: <adi3hf2z.fsf@ccs.neu.edu>
Vladimir Zolotykh <······@eurocom.od.ua> writes:

> Hi
> 
> Let me ask two simple questions:
> 
> First
> --------------------------------
> Is there a difference between the following two fragmenst:
> 
>    (eval-when (:compile-toplevel :load-toplevel :execute)
>      (require :foo)
>      (setq foo::bar '(#|Something|#)))
> 
> and
> 
>    (eval-when (:compile-toplevel :load-toplevel :execute)
>      (require :foo))
> 
>    (eval-when (:compile-toplevel :load-toplevel :execute)
>      (setq foo::bar '(#|Something|#)))
> 
> I see the difference in ACL62 but I don't understand it.
> The :foo package is defined in :foo module.

There is a subtle difference.  When the first form is read, the symbol
FOO::BAR is interned.  Then the form is evaluated.  Since the FOO
package doesn't exist yet, you have a problem.

In the second example, the first form is read, but symbol FOO::BAR is
not in this form, so it is not interned.  The form is evaluated and
the FOO package is instantiated.  Then the second form is read, but
since the FOO package is instantiated, the symbol FOO::BAR may be
interned without a problem.

Incidentally, the first form could be rewritten as:

    (eval-when (:compile-toplevel :load-toplevel :execute)
      (require :foo)
      (set (intern "BAR" (find-package "FOO")) '(#|Something|#)))

> Second
> --------------------------------
> In the following code
> 
>    (defparameter *month-lengths*
>        (vector 31 28 31 30 31 30 31 31 30 31 30 31))
> 
>    (defun month-length (month year)
>      (declare (special *month-lengths*))  ;;; [1] ;;;
>      (if (/= month 2) (aref *month-lengths* (1- month))
>        (if (null (zerop (mod year 4))) 28
> 	(if (null (zerop (mod year 400))) 29 28))))
> 
> What's the advantages of using SPECIAL declaration (if any)? I can't
> figure out what're they might be. 

Since DEFPARAMETER globally DECLAIMS *MONTH-LENGTHS* as special, the
special declaration has no effect.  Since *month-lengths* is a
free-variable in the function month-length, the symbol-value of
*month-lengths* will be referred to, so the special declaration is
doubly useless. 

> NB. I'm not concerned about the purpose of code itself, I used it
> just to illustrate the usage of SPECIAL.

One use of a special declaration is when you have a `forward
reference' to a DEFVAR or DEFPARAMETER and for some reason you don't
want to arrange for the symbol to be declaimed special beforehand.
For instance you could put this an a `macros' file:

(defmacro with-foo ((foo-form &rest options) &body body)
  `(LET ((*CURRENT-FOO* (CREATE-FOO ,foo-form ,@options)))
     (DECLARE (SPECIAL *CURRENT-FOO*))
     ,@body))

But not have the DEFVAR for *CURRENT-FOO* until some other file.  When
the macros file is loaded, even files compiled in the wrong order will
continue to work.

Another use is to `patch' code.


(defun function-a (a b c)
  (let ((x  (compute-something)))
    (some-function a b)))

(defun some-function (d e)
   (function-b d e 42))

(defun function-b (f g h)
   (some-computation)
   ...
   (new-code-here  f g x)   ;; code added
   ...)

Now FUNCTION-B needs access to X in FUNCTION-A, but since A doesn't
pass it to SOME-FUNCTION, you can't get at it.  But suppose for some
reason you can't change SOME-FUNCTION.  The cheesy solution here is to
declare X to be special in FUNCTION-A and in FUNCTION-B.  (The `right'
solution is to rewrite the code, but there have been times where that
is simply not possible.)
From: Thomas A. Russ
Subject: Re: EVAL-WHEN and using SPECIAL
Date: 
Message-ID: <ymiiswr8srs.fsf@sevak.isi.edu>
Joe Marshall <···@ccs.neu.edu> writes:
> 
> One use of a special declaration is when you have a `forward
> reference' to a DEFVAR or DEFPARAMETER and for some reason you don't
> want to arrange for the symbol to be declaimed special beforehand.
> For instance you could put this an a `macros' file:
> 
> (defmacro with-foo ((foo-form &rest options) &body body)
>   `(LET ((*CURRENT-FOO* (CREATE-FOO ,foo-form ,@options)))
>      (DECLARE (SPECIAL *CURRENT-FOO*))
>      ,@body))
> 
> But not have the DEFVAR for *CURRENT-FOO* until some other file.  When
> the macros file is loaded, even files compiled in the wrong order will
> continue to work.

Another use, which is also supported by this example, is to have special
variables that are not global variables.  In this case, there would not
be anyplace with a DEFVAR for *CURRENT-FOO*.  Instead, one has a special
variable that is only accessible from a dynamic call that has a binding
of that special.

This can be useful as a way of making sure that code that references the
special only runs in an environment in which the special variable has
been setup properly.  If you invoke a function from outside such an
environment that sets the special variable, then you will get an error
that no such variable exists, whereas with a global declaration no such
warning is possible.

-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Marco Antoniotti
Subject: Re: EVAL-WHEN and using SPECIAL
Date: 
Message-ID: <3E244225.3080508@cs.nyu.edu>
Joe Marshall wrote:
> Vladimir Zolotykh <······@eurocom.od.ua> writes:
> 
> 
>>Hi
>>
>>Let me ask two simple questions:
>>
>>First
>>--------------------------------
>>Is there a difference between the following two fragmenst:
>>
>>   (eval-when (:compile-toplevel :load-toplevel :execute)
>>     (require :foo)
>>     (setq foo::bar '(#|Something|#)))
>>
>>and
>>
>>   (eval-when (:compile-toplevel :load-toplevel :execute)
>>     (require :foo))
>>
>>   (eval-when (:compile-toplevel :load-toplevel :execute)
>>     (setq foo::bar '(#|Something|#)))
>>
>>I see the difference in ACL62 but I don't understand it.
>>The :foo package is defined in :foo module.
> 
> 
> There is a subtle difference.  When the first form is read, the symbol
> FOO::BAR is interned.  Then the form is evaluated.  Since the FOO
> package doesn't exist yet, you have a problem.

Just to be nitpicking.

1 - REQUIRE is still deprecated.
2 - REQUIRE does not necessarily create a package named "FOO".

so the above has a lot of assumptions built in (e.g. that somewhere in 
the files loaded as a result of REQUIREing :foo there is a MAKE-PACKAGE 
of "FOO").

Cheers

-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
715 Broadway 10th Floor                 fax  +1 - 212 - 998 3484
New York, NY 10003, USA                 http://bioinformatics.cat.nyu.edu
                     "Hello New York! We'll do what we can!"
                            Bill Murray in `Ghostbusters'.
From: Barry Margolin
Subject: Re: EVAL-WHEN and using SPECIAL
Date: 
Message-ID: <2uXU9.20$Lf6.488@paloalto-snr1.gtei.net>
In article <················@cs.nyu.edu>,
Marco Antoniotti  <·······@cs.nyu.edu> wrote:
>
>
>Joe Marshall wrote:
>> Vladimir Zolotykh <······@eurocom.od.ua> writes:
>> 
>> 
>>>Hi
>>>
>>>Let me ask two simple questions:
>>>
>>>First
>>>--------------------------------
>>>Is there a difference between the following two fragmenst:
>>>
>>>   (eval-when (:compile-toplevel :load-toplevel :execute)
>>>     (require :foo)
>>>     (setq foo::bar '(#|Something|#)))
>>>
>>>and
>>>
>>>   (eval-when (:compile-toplevel :load-toplevel :execute)
>>>     (require :foo))
>>>
>>>   (eval-when (:compile-toplevel :load-toplevel :execute)
>>>     (setq foo::bar '(#|Something|#)))
>>>
>>>I see the difference in ACL62 but I don't understand it.
>>>The :foo package is defined in :foo module.
>> 
>> 
>> There is a subtle difference.  When the first form is read, the symbol
>> FOO::BAR is interned.  Then the form is evaluated.  Since the FOO
>> package doesn't exist yet, you have a problem.
>
>Just to be nitpicking.
>
>1 - REQUIRE is still deprecated.
>2 - REQUIRE does not necessarily create a package named "FOO".
>
>so the above has a lot of assumptions built in (e.g. that somewhere in 
>the files loaded as a result of REQUIREing :foo there is a MAKE-PACKAGE 
>of "FOO").

It's not an assumption, the OP said it flat-out: "The :foo package is
defined in :foo module."

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Marco Antoniotti
Subject: Re: EVAL-WHEN and using SPECIAL
Date: 
Message-ID: <3E2455D7.3010308@cs.nyu.edu>
Barry Margolin wrote:


>>so the above has a lot of assumptions built in (e.g. that somewhere in 
>>the files loaded as a result of REQUIREing :foo there is a MAKE-PACKAGE 
>>of "FOO").
> 
> 
> It's not an assumption, the OP said it flat-out: "The :foo package is
> defined in :foo module."

Sorry. I missed that.

-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
715 Broadway 10th Floor                 fax  +1 - 212 - 998 3484
New York, NY 10003, USA                 http://bioinformatics.cat.nyu.edu
                     "Hello New York! We'll do what we can!"
                            Bill Murray in `Ghostbusters'.
From: Damien Kick
Subject: Re: EVAL-WHEN and using SPECIAL
Date: 
Message-ID: <ovwuibgp2w.fsf@email.mot.com>
Marco Antoniotti <·······@cs.nyu.edu> writes:

> Just to be nitpicking.
> 
> 1 - REQUIRE is still deprecated.
> 2 - REQUIRE does not necessarily create a package named "FOO".

I apologize for the newbie-nature of this questions but what are some
endorsed alternatives to (REQUIRE :FOO)?
From: Kaz Kylheku
Subject: Re: EVAL-WHEN and using SPECIAL
Date: 
Message-ID: <cf333042.0301141128.40f08bb2@posting.google.com>
Vladimir Zolotykh <······@eurocom.od.ua> wrote in message news:<················@eurocom.od.ua>...
> Hi
> 
> Let me ask two simple questions:
> 
> First
> --------------------------------
> Is there a difference between the following two fragmenst:
> 
>    (eval-when (:compile-toplevel :load-toplevel :execute)
>      (require :foo)
>      (setq foo::bar '(#|Something|#)))

Note that the Lisp reader has to scan this entire expression before it
is fed to the evaluator. The action of reading includes resolving all
symbol names like FOO::BAR to symbol objects. Therefore, if you are
depending on the :foo module to define the "FOO" package, that won't
work, since the effects of the REQUIRE don't happen until the form is
evaluated. It is an error to try to read the expression FOO::BAR if
the package named "FOO" does not exist.
 
>    (eval-when (:compile-toplevel :load-toplevel :execute)
>      (require :foo))
> 
>    (eval-when (:compile-toplevel :load-toplevel :execute)
>      (setq foo::bar '(#|Something|#)))
> 
> I see the difference in ACL62 but I don't understand it.
> The :foo package is defined in :foo module.

And of course here you have interleaved the reading and evaluation to
some extent, to bring about the right ordering.
 
> Second
> --------------------------------
> In the following code
> 
>    (defparameter *month-lengths*
>        (vector 31 28 31 30 31 30 31 31 30 31 30 31))
> 
>    (defun month-length (month year)
>      (declare (special *month-lengths*))  ;;; [1] ;;;
>      (if (/= month 2) (aref *month-lengths* (1- month))
>        (if (null (zerop (mod year 4))) 28
> 	(if (null (zerop (mod year 400))) 29 28))))
> 
> What's the advantages of using SPECIAL declaration (if any)?

Absolutely none; take it out. The defparameter definition already
marks the symbol as having dynamic binding, so the declaration is
redundant.

Also, since the vector is immutable, the author ought to have
considered using the notation #(31 28 31 30 ...) instead of calling
the VECTOR constructor, and also the use of DEFCONSTANT rather than
DEFPARAMETER. DEFPARAMETER means that whenever the module is reloaded,
the variable should be reset to the specified value.

More comments: don't use the NULL function to test a boolean variable
for falsehood; use the NOT function instead.

For clarity and brevity, you might want to rewrite

  (not (zerop EXPR)) 

simply as 

  (/= EXPR 0).

Or, seeing that you have both clauses in the if construct---consequent
and alternative---you can simply take out the NOT and reverse their
order. You then have positive divisibility tests:

  (if (/= month 2)
    (aref *month-lengths* (1- month))
    (if (zerop (mod year 4)) 
      (if (zerop (mod year 400)) 
        28 29)
      28))

And of course the two conditions can be lumped together, since you are
trying to detect one special case, the leap year; everything else
returns 28.

   (if (and (= 0 (mod year 4))
            (/= 0 (mod year 400)))
     29
     28)

Let's now turn our attention to your leap detection algorithm, which
is broken. :) The year 1900 is not a leap year, yet your algorithm
concludes that it is. The real logic is this: a leap year is one that
is divisible by four, but not divisible by one hundred, unless it is
divisible by four hundred:

  (declaim (inline divisible))

  (defun divisible (q d) (zerop (mod q d)))

  (if (and (divisible year 4)
           (or (not (divisible year 100))
               (divisible year 400)))
    29 28)

Notice how the second clause of the AND has the form (or (NOT X) Y),
in other words, ~X ^ Y.   This is logically equivalent to X -> Y, or
if X, then Y. Which makes sense: it asserts the relationship ``if a
leap year divisible by 100, then it's divisible by 400''. So we could
factor in the IF operator, using it only with one argument, as a
purely logical connective:

  (if (and (divisible year 4)
           (if (divisible year 100)
               (divisible year 400))) ;; note parallel indentation
    29 28)

This is now perhaps a more understandable leap year expression: ``a
year is always divisible by four, and if it is divisible by 100, it is
also divisible by 400''. However, the reader of the code has to
recognize that IF is being used logically, rather than as a control
mechanism to evaluate only one of two subordinate expressions. The
reverse transformation from (if (not X) Y) to (or X Y) is more common,
sufficiently so to call it an idiom, I might say.

Could COND be used profitably to express this calculation? A
resounding yes. You have to start at the 400, and work down to the 4.

   (cond
     ((divisible-by year 400) 29)
     ((divisible-by year 100) 28)
     ((divisible-by year 4) 29)
     (t 28))

I like this formulation best.
From: Barry Margolin
Subject: Re: EVAL-WHEN and using SPECIAL
Date: 
Message-ID: <9bWU9.10$Lf6.399@paloalto-snr1.gtei.net>
In article <················@eurocom.od.ua>,
Vladimir Zolotykh  <······@eurocom.od.ua> wrote:
>First
>--------------------------------
>Is there a difference between the following two fragmenst:
>
>   (eval-when (:compile-toplevel :load-toplevel :execute)
>     (require :foo)
>     (setq foo::bar '(#|Something|#)))
>
>and
>
>   (eval-when (:compile-toplevel :load-toplevel :execute)
>     (require :foo))
>
>   (eval-when (:compile-toplevel :load-toplevel :execute)
>     (setq foo::bar '(#|Something|#)))
>
>I see the difference in ACL62 but I don't understand it.
>The :foo package is defined in :foo module.

In the first case, the entire expression is read before anything is
executed.  So it refers to FOO::BAR before the FOO package has been
defined, which should cause an error.  In the second case, the package is
defined by the first expression, so the second expression can be read
successfully.

>Second
>--------------------------------
>In the following code
>
>   (defparameter *month-lengths*
>       (vector 31 28 31 30 31 30 31 31 30 31 30 31))
>
>   (defun month-length (month year)
>     (declare (special *month-lengths*))  ;;; [1] ;;;
>     (if (/= month 2) (aref *month-lengths* (1- month))
>       (if (null (zerop (mod year 4))) 28
>	(if (null (zerop (mod year 400))) 29 28))))
>
>What's the advantages of using SPECIAL declaration (if any)? I can't
>figure out what're they might be. NB. I'm not concerned about the
>purpose of code itself, I used it just to illustrate the usage of
>SPECIAL.

The SPECIAL declaration serves no purpose, because DEFPARAMETER
automatically proclaims the variable special.  It's not even necessary for
documentation purposes, because the use of * around the name is the
convention for globally special variables.

BTW, unless you're worried that the calendar is going to change, it seems
like DEFCONSTANT would be more appropriate for it.

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Rudi Schlatte
Subject: Re: EVAL-WHEN and using SPECIAL
Date: 
Message-ID: <877kd74s4a.fsf@semmel.constantly.at>
Vladimir Zolotykh <······@eurocom.od.ua> writes:

> --------------------------------
> Is there a difference between the following two fragmenst:
>
>    (eval-when (:compile-toplevel :load-toplevel :execute)
>      (require :foo)
>      (setq foo::bar '(#|Something|#)))
>

When this form is read, the reader tries to find (or create) a symbol
bar in package foo, which does not exist.  The require form has not
yet been evaluated, since the form has not even been completely read.

> and
>
>    (eval-when (:compile-toplevel :load-toplevel :execute)
>      (require :foo))

After this first form is read, the require form is evaluated, and
presumably some files are read.


>    (eval-when (:compile-toplevel :load-toplevel :execute)
>      (setq foo::bar '(#|Something|#)))

Now, this form can be read, since the package foo exists.

> I see the difference in ACL62 but I don't understand it.
> The :foo package is defined in :foo module.

Hope that helps,

Rudi