From: Christian Lynbech
Subject: Code style question
Date: 
Message-ID: <m2bpsp80yc.fsf@defun.dk>
I stumbled across the following code (in the regex library by Kenneth
Parker) and would, out of curiosity, like to know what people think of it:

    (defun make-anchored-matcher (matchfn)
      #'(lambda (*str* *regs* *start* *end*
                 *start-is-anchor* *end-is-anchor*
                 *acceptfn* *hooks*)
          (declare (special *str* *regs* *start* *end*
                            *start-is-anchor* *end-is-anchor*
                            *acceptfn* *hooks*))
          (declare (ftype (function (fixnum) t) matchfn))
          (catch 'cease-matching
            (funcall matchfn *start*))))

and other functions would then also declare *end* and friends special.

This leads to a bunch of warnings about unknown variables in SBCL 1.0.22.

Any reason not to add a slew of 'defvar's to kill those warnings?


------------------------+-----------------------------------------------------
Christian Lynbech       | christian ··@ defun #\. dk
------------------------+-----------------------------------------------------
Hit the philistines three times over the head with the Elisp reference manual.
                                        - ·······@hal.com (Michael A. Petonic)

From: Paul Khuong
Subject: Re: Code style question
Date: 
Message-ID: <22ff7c3a-9370-4fa3-bb52-b5312dc6103e@p20g2000yqi.googlegroups.com>
On Feb 26, 2:14 pm, Christian Lynbech <·········@defun.dk> wrote:
>     (defun make-anchored-matcher (matchfn)
>       #'(lambda (*str* *regs* *start* *end*
>                  *start-is-anchor* *end-is-anchor*
>                  *acceptfn* *hooks*)
>           (declare (special *str* *regs* *start* *end*
>                             *start-is-anchor* *end-is-anchor*
>                             *acceptfn* *hooks*))
>           (declare (ftype (function (fixnum) t) matchfn))
>           (catch 'cease-matching
>             (funcall matchfn *start*))))
>
> and other functions would then also declare *end* and friends special.
>
> This leads to a bunch of warnings about unknown variables in SBCL 1.0.22.

Really? I'd expect a style-warning about matchfn, but nothing about
the specials. 1.0.25 behaves as expected. (declare (ftype (function
(fixnum) t) matchfn)), however, is wrong. The *variable* (not the
function) matchfn is of type (function (fixnum) t), so (declare
(type ...)) should be used.

Paul Khuong
From: Christian Lynbech
Subject: Re: Code style question
Date: 
Message-ID: <m28wnqc1lp.fsf@defun.dk>
>>>>> "Paul" == Paul Khuong <·······@gmail.com> writes:

Paul> On Feb 26, 2:14�pm, Christian Lynbech <·········@defun.dk> wrote:

>> This leads to a bunch of warnings about unknown variables in SBCL 1.0.22.

Paul> Really? I'd expect a style-warning about matchfn, but nothing about
Paul> the specials.

That was unclear on my part. The specials in 'make-anchored-matcher' are
matched by uses in other files like this:

    (defun gen-nlookahead-closure (childfn next)
      (make-nontext-closure
       :matcher
       #'(lambda (pos)
           (declare (fixnum pos)
                    (ftype (function (fixnum) t) next)
                    (special *end* *hooks*)
                    (fixnum *end*))
           (let ((*acceptfn* nil))
             (declare (special *acceptfn*))
             (if (not (catch 'cease-matching (funcall childfn pos)))
                 (funcall next pos)
               nil)))
       :initializer
       nil
       :linker
       #'(lambda (link-info)
           (setq childfn (resolve-instr link-info childfn))
           (setq next (resolve-instr link-info next))) ))

which is where SBCL (at least 1.0.22) complains about *end* (for
instance) being unknown. The warnings I mention are not coming from the
compilation of 'make-anchored-matcher'.


------------------------+-----------------------------------------------------
Christian Lynbech       | christian ··@ defun #\. dk
------------------------+-----------------------------------------------------
Hit the philistines three times over the head with the Elisp reference manual.
                                        - ·······@hal.com (Michael A. Petonic)
From: Tobias C. Rittweiler
Subject: Re: Code style question
Date: 
Message-ID: <87y6vqfrpq.fsf@freebits.de>
Christian Lynbech <...> writes:

> That was unclear on my part. The specials in 'make-anchored-matcher' are
> matched by uses in other files like this:
>
>     (defun gen-nlookahead-closure (childfn next)
>       (make-nontext-closure
>        :matcher
>        #'(lambda (pos)
>            (declare (fixnum pos)
>                     (ftype (function (fixnum) t) next)
>                     (special *end* *hooks*)
>                     (fixnum *end*))
>            ...)))
>
> which is where SBCL (at least 1.0.22) complains about *end* (for
> instance) being unknown. The warnings I mention are not coming from the
> compilation of 'make-anchored-matcher'.

Hi Christian!

Declarations are not necessarily processed sequentially. The standard
does not specify the order in which declarations are supposed to be
interpreted within one "declaration block"[1]. So the type declaration
in

  (declare (special *foo*) (fixnum *foo*))

or even in

  (declare (special *foo*))
  (declare (fixnum *foo*))

does really not belong to any binding (if *FOO* was not globally
proclaimed special.) In general this does not matter[2], and it's the
reason why the parse-declarations[3] library does currently not make the
effort to preserve orderness of declarations.

You can force sequential interpretation by means of LOCALLY:

  (locally (declare (special *foo*))
    (locally (declare (fixnum *foo*))
      ...))

  -T.


[1] I don't think there's a standard terminus for the head of LOCALLY,
    or bindings forms (LET, &c.) where declare expression are allowed.

[2] It does matter a whole lot more with environment access as DEFTYPE
    definitions can access the current compilation environment. Any
    environment proposal should probably address that matter. I do not
    know whether Duane Rettig's env-access proposal tackles this issue.
   
    (Duane, if you happen to read this footnote, did you deal with this
    problem?)

[3] http://common-lisp.net/project/parse-declarations/
From: ·····@franz.com
Subject: Re: Code style question
Date: 
Message-ID: <8f7fa95f-3664-4a20-bd9b-e08fdc4c9a15@n33g2000pri.googlegroups.com>
On Feb 28, 8:31 am, "Tobias C. Rittweiler" <····@freebits.de.invalid>
wrote:
> Christian Lynbech <...> writes:
> > That was unclear on my part. The specials in 'make-anchored-matcher' are
> > matched by uses in other files like this:
>
> >     (defun gen-nlookahead-closure (childfn next)
> >       (make-nontext-closure
> >        :matcher
> >        #'(lambda (pos)
> >            (declare (fixnum pos)
> >                     (ftype (function (fixnum) t) next)
> >                     (special *end* *hooks*)
> >                     (fixnum *end*))
> >            ...)))
>
> > which is where SBCL (at least 1.0.22) complains about *end* (for
> > instance) being unknown. The warnings I mention are not coming from the
> > compilation of 'make-anchored-matcher'.
>
> Hi Christian!
>
> Declarations are not necessarily processed sequentially.

This is trivially true, since declarations are not necessarily
processed.  There are exceptions, of course, and in the above example
the special declaration must not be ignored, but the fixnum
declaration could be ignored.  Thus the question of order is moot.

However, the concept of "processing" a declaration is also a little
bit misleading; the standard talks less of _when_  declarations are
applied but _where_ they are applied, as in "what is their scope"?  In
the above example, the scope of the two declarations is the same, that
is, they are both free declarations.

> The standard
> does not specify the order in which declarations are supposed to be
> interpreted within one "declaration block"[1]. So the type declaration
> in

Again, I wouldn't use the word "interpretation", since it may be
confused with something eval does.  The question is, what is the scope
of the declaration(s)?

>   (declare (special *foo*) (fixnum *foo*))
>
> or even in
>
>   (declare (special *foo*))
>   (declare (fixnum *foo*))
>
> does really not belong to any binding (if *FOO* was not globally
> proclaimed special.) In general this does not matter[2], and it's the
> reason why the parse-declarations[3] library does currently not make the
> effort to preserve orderness of declarations.
>
> You can force sequential interpretation by means of LOCALLY:
>
>   (locally (declare (special *foo*))
>     (locally (declare (fixnum *foo*))
>       ...))
>
>   -T.
>
> [1] I don't think there's a standard terminus for the head of LOCALLY,
>     or bindings forms (LET, &c.) where declare expression are allowed.
>
> [2] It does matter a whole lot more with environment access as DEFTYPE
>     definitions can access the current compilation environment. Any
>     environment proposal should probably address that matter. I do not
>     know whether Duane Rettig's env-access proposal tackles this issue.
>
>     (Duane, if you happen to read this footnote, did you deal with this
>     problem?)

I don't see it as a problem, and so I never dealt with it.  I don't
know why a compiler would consider these two declarations as applying
to anything but the same variable, with the same scope.

A more ambiguous question is: what variable does the following
declaration affect (which is of course a bouund declaration)?

 (let* ((x (foo))
        (y (bar x))
        (x (bas y)))
   (declare (fixnum x))
   ...)

Duane
From: Tobias C. Rittweiler
Subject: Re: Code style question
Date: 
Message-ID: <87vdqtcway.fsf@freebits.de>
Duane Rettig writes:

> On Feb 28, 8:31�am, "Tobias C. Rittweiler" <...> wrote:
> >
> > [2] It does matter a whole lot more with environment access as DEFTYPE
> > � � definitions can access the current compilation environment. Any
> > � � environment proposal should probably address that matter. I do not
> > � � know whether Duane Rettig's env-access proposal tackles this issue.
> >
> > � � (Duane, if you happen to read this footnote, did you deal with this
> > � � problem?)
>
> I don't see it as a problem, and so I never dealt with it.  I don't
> know why a compiler would consider these two declarations as applying
> to anything but the same variable, with the same scope.

I thought I could construct an example where it were ambiguous. But I
now I can't. Meh! :-)


I recall that the standard says that consequences are undefined if two
declaration specifiers contradict each other, but I cannot find any
reference. In the absence of such a paragraph, the behaviour of the
following is not totally clear:

  (declare (inline foo) (notinline foo))

  vs.

  (declare (notinline foo) (inline foo))

or even

  (declare (optimize (speed 1)))
  (declare (optimize (speed 3)))

  vs.

  (declare (optimize (speed 3)))
  (declare (optimize (speed 1)))

There's nothing that says that the later comming declaration should
prevail.


And environment access complicates the issue. Let's consider something
on the line of

  (deftype quux (&environment env)
    (if (declaration-information 'ENABLE-FROBBAGE env)
        '%unsafe-quux
        '%safe-quux))

What is the type specifier QUUX supposed to expand in the following
snippets:

  (declare (enable-frobbage t) (type quux *foo*))
  
  vs.

  (declare (type quux *foo*) (enable-frobbage t))

or

  (declare (enable-frobbage t))
  (declare (type quux *foo*))

  vs.

  (declare (enable-frobbage t))
  (declare (type quux *foo*))


> A more ambiguous question is: what variable does the following
> declaration affect (which is of course a bouund declaration)?
>
>  (let* ((x (foo))
>         (y (bar x))
>         (x (bas y)))
>    (declare (fixnum x))
>    ...)

I'd be inclined to say both. :-) How did the Franz people decide to deal
with this?

  -T.