[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

multiple declarations for the same variable

Jim Newton

4/7/2016 2:40:00 PM

I'm looking at

http://clhs.lisp.se/Body/d_typ...

And I find the following line:

--> If nested type declarations refer to the same variable, then the value of the variable must be a member of the intersection of the declared types.


I think this is normally talking about two declarations each with a different scope where the scopes are overlapping. However, does it also apply to the same variable being listed twice in the same declaration?

(defun foo (x)
(declare (type array x) (type sequence x))
...)

Does this means that x is declared as a vector as vector is the intersection of array and sequence?

I.e., can "nested" be construed to include that one declaration is nested inside itself?

Perhaps there is somewhere else where this is clarified?

Potentially, a code walker would like to assume this case doesn't happen, as it is sufficiently rare. So a code walker iterating from left to right, might accidentally assume that right-most declaration has precedence over the left-most.



7 Answers

Jim Newton

4/7/2016 3:13:00 PM

0

There is also the following sentence:
--> The meaning of a type declaration is equivalent to changing each reference to a variable (var) within the scope of the declaration to (the typespec var)

Which seems to imply that if x is declared as both type A and type B then a usage of x
is both equivalent to (the A x) and also (the B x), which seems to me to either mean
(the A (the B x)) or equivalently (the (and A B) x).

Does anyone agree or disagree with my interpretation?

Pascal J. Bourguignon

4/7/2016 10:04:00 PM

0

Jim Newton <jimka.issy@gmail.com> writes:

> I'm looking at
>
> http://clhs.lisp.se/Body/d_typ...
>
> And I find the following line:
>
> --> If nested type declarations refer to the same variable, then the
> value of the variable must be a member of the intersection of the
> declared types.
>
>
> I think this is normally talking about two declarations each with a
> different scope where the scopes are overlapping. However, does it
> also apply to the same variable being listed twice in the same
> declaration?

That would seem logical.

> (defun foo (x)
> (declare (type array x) (type sequence x))
> ...)
>
> Does this means that x is declared as a vector as vector is the intersection of array and sequence?

Yes.


> I.e., can "nested" be construed to include that one declaration is nested inside itself?


(locally (declare d1 .. dn) . b)
<=> (locally (declare d1)
(locally (declare d2)
â?¦
(locally (declare dn)
. b)))

or can you see any property of the generated code that would be
different?


> Perhaps there is somewhere else where this is clarified?
>
> Potentially, a code walker would like to assume this case doesn't
> happen, as it is sufficiently rare. So a code walker iterating from
> left to right, might accidentally assume that right-most declaration
> has precedence over the left-most.


--
__Pascal Bourguignon__ http://www.informat...
â??The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.� -- Carl Bass CEO Autodesk

Pascal J. Bourguignon

4/7/2016 10:04:00 PM

0

Jim Newton <jimka.issy@gmail.com> writes:

> There is also the following sentence:
> --> The meaning of a type declaration is equivalent to changing each
> reference to a variable (var) within the scope of the declaration to
> (the typespec var)
>
> Which seems to imply that if x is declared as both type A and type B then a usage of x
> is both equivalent to (the A x) and also (the B x), which seems to me to either mean
> (the A (the B x)) or equivalently (the (and A B) x).
>
> Does anyone agree or disagree with my interpretation?

Agree. It's logical.

--
__Pascal Bourguignon__ http://www.informat...
â??The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.� -- Carl Bass CEO Autodesk

Kaz Kylheku

4/7/2016 10:33:00 PM

0

On 2016-04-07, Pascal J. Bourguignon <pjb@informatimago.com> wrote:
> Jim Newton <jimka.issy@gmail.com> writes:
>
>> I'm looking at
>>
>> http://clhs.lisp.se/Body/d_typ...
>>
>> And I find the following line:
>>
>> --> If nested type declarations refer to the same variable, then the
>> value of the variable must be a member of the intersection of the
>> declared types.
>>
>>
>> I think this is normally talking about two declarations each with a
>> different scope where the scopes are overlapping. However, does it
>> also apply to the same variable being listed twice in the same
>> declaration?
>
> That would seem logical.
>
>> (defun foo (x)
>> (declare (type array x) (type sequence x))
>> ...)
>>
>> Does this means that x is declared as a vector as vector is the intersection of array and sequence?
>
> Yes.

Maybe it should be erroneous in this situation: multiple type declarations
for the same variable in the same declare.

How can we be sure it's not a typo in the following?

(defun foo (x y)
(declare (type integer x) (type string x))
...)

Maybe it was supposed to be (type sequence y)! The question is, what is
the *intent*? If the programmer intends intersection, why didn't the
programmer just express that with the type construction and operator?

(At the very least, I hope we can agree that it deserves a warning
in the case that the intersection is empty.)

>> I.e., can "nested" be construed to include that one declaration is nested inside itself?
>
>
> (locally (declare d1 .. dn) . b)
><=> (locally (declare d1)
> (locally (declare d2)
> â?¦
> (locally (declare dn)
> . b)))

While that is true, there can be forms inserted in places in the
nested locally such that it no longer corresponds to a single locally.

There are multiple scopes there; it's only equivalent because those
scopes have no content.

This nested form could be a way to escape the diagnostic:

(locally (declare (type ... x) (type ... x) ...) ;; error

(locally (declare (type ... x))
(locally (declare (type ... x)) ...)) ;; OK; programmer likely means it.

(locally (declare (type (and ... ...) x))) ;; likewise, of course.


> or can you see any property of the generated code that would be
> different?

Yes. If some variant is deemed as requiring a diagnostic, then any
generated code which is obtained anyway has formally undefined behavior,
even if that variant plausibly expresses the same intent as another
variant, and the generated code is identical.

Barry Margolin

4/8/2016 2:25:00 PM

0

In article <20160407151208.180@kylheku.com>,
Kaz Kylheku <545-066-4921@kylheku.com> wrote:

> On 2016-04-07, Pascal J. Bourguignon <pjb@informatimago.com> wrote:
> > Jim Newton <jimka.issy@gmail.com> writes:
> >
> >> I'm looking at
> >>
> >> http://clhs.lisp.se/Body/d_typ...
> >>
> >> And I find the following line:
> >>
> >> --> If nested type declarations refer to the same variable, then the
> >> value of the variable must be a member of the intersection of the
> >> declared types.
> >>
> >>
> >> I think this is normally talking about two declarations each with a
> >> different scope where the scopes are overlapping. However, does it
> >> also apply to the same variable being listed twice in the same
> >> declaration?
> >
> > That would seem logical.
> >
> >> (defun foo (x)
> >> (declare (type array x) (type sequence x))
> >> ...)
> >>
> >> Does this means that x is declared as a vector as vector is the
> >> intersection of array and sequence?
> >
> > Yes.
>
> Maybe it should be erroneous in this situation: multiple type declarations
> for the same variable in the same declare.
>
> How can we be sure it's not a typo in the following?
>
> (defun foo (x y)
> (declare (type integer x) (type string x))
> ...)
>
> Maybe it was supposed to be (type sequence y)! The question is, what is
> the *intent*? If the programmer intends intersection, why didn't the
> programmer just express that with the type construction and operator?

The most likely reason is that the code was generated automatically,
e.g. by a macro, and the two type declarations came from different
places.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

Kaz Kylheku

4/8/2016 11:24:00 PM

0

On 2016-04-08, Barry Margolin <barmar@alum.mit.edu> wrote:
> In article <20160407151208.180@kylheku.com>,
> Kaz Kylheku <545-066-4921@kylheku.com> wrote:
>
>> On 2016-04-07, Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>> > Jim Newton <jimka.issy@gmail.com> writes:
>> >
>> >> I'm looking at
>> >>
>> >> http://clhs.lisp.se/Body/d_typ...
>> >>
>> >> And I find the following line:
>> >>
>> >> --> If nested type declarations refer to the same variable, then the
>> >> value of the variable must be a member of the intersection of the
>> >> declared types.
>> >>
>> >>
>> >> I think this is normally talking about two declarations each with a
>> >> different scope where the scopes are overlapping. However, does it
>> >> also apply to the same variable being listed twice in the same
>> >> declaration?
>> >
>> > That would seem logical.
>> >
>> >> (defun foo (x)
>> >> (declare (type array x) (type sequence x))
>> >> ...)
>> >>
>> >> Does this means that x is declared as a vector as vector is the
>> >> intersection of array and sequence?
>> >
>> > Yes.
>>
>> Maybe it should be erroneous in this situation: multiple type declarations
>> for the same variable in the same declare.
>>
>> How can we be sure it's not a typo in the following?
>>
>> (defun foo (x y)
>> (declare (type integer x) (type string x))
>> ...)
>>
>> Maybe it was supposed to be (type sequence y)! The question is, what is
>> the *intent*? If the programmer intends intersection, why didn't the
>> programmer just express that with the type construction and operator?
>
> The most likely reason is that the code was generated automatically,
> e.g. by a macro, and the two type declarations came from different
> places.

That could still be root caused to what is effectively a misuse of the
macro; i.e. the macro could be benefitting from the diagnostic,
nopt having to implement it itself (other than for a clearer
message, which pertains to the macro rather than to the expansion).

Pascal J. Bourguignon

4/9/2016 12:09:00 AM

0

Kaz Kylheku <545-066-4921@kylheku.com> writes:

> That could still be root caused to what is effectively a misuse of the
> macro; i.e. the macro could be benefitting from the diagnostic,
> nopt having to implement it itself (other than for a clearer
> message, which pertains to the macro rather than to the expansion).

It would be more useful to have type inference and the compiler or REPL
indicating the infered type of the definitions given (or in this case,
for the variables defined inside the functions).

(defun f (x)
(if (zerop x)
1
(* x (f (- x 1)))))
--> F
;; Infered type for F: (function (number) number)
;; Infered type for X: number
;; Warning: F may not terminate when (typep X '(and number (not real)))


Notice that such an "infered type" is meaningless for lisp per-se:

(handler-case (f "foo")
(error () 'foo)) --> foo ; is conforming and meaningful.

it's just part of the amenities an implementation could provide for
newbie programmersâ?¦


(defun f (x)
(if (<= x 1)
1
(* x (f (- x 1)))))
--> F
;; Infered type for F: (function (real) real)
;; Infered type for X: real


(defun f (x)
(check-type x integer)
(if (<= x 1)
1
(* x (f (- x 1)))))
--> F
;; Infered type for F: (function (integer) integer)
;; Infered type for X: integer



Again, still useless for a conforming lisp program such as:

(handler-bind ((type-error (lambda (condition)
(declare (ignore condition))
(invoke-restart 'abort))))
(f "foo"))
--> ; no value.

but if that may make newbies (or "type insecure" types) happyâ?¦

--
__Pascal Bourguignon__ http://www.informat...
â??The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.� -- Carl Bass CEO Autodesk