Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Declaring type of top-level (special) variables?

16 views
Skip to first unread message

Adam Warner

unread,
Apr 12, 2002, 7:30:07 AM4/12/02
to
Hi all,

Quick question. I'm trying to set a top-level variable of type integer (in
the expectation that when I perform a division upon the variable I will
obtain an integer result):

(defparameter *variablename* 1)

Now variablename has type FIXNUM. I'd like to set that to INTEGER. I've
tried declare but the compiler complains about it being in the top level
(CMUCL: Error: Misplaced declaration).

Many thanks,
Adam

Kent M Pitman

unread,
Apr 12, 2002, 7:40:26 AM4/12/02
to
Adam Warner <use...@consulting.net.nz> writes:

I'm not sure what you mean by the variablename has type FIXNUM.

By default, no variable ever has any type; that is, all variables hold
any type of object unless you go to work to promise you will make them
contain only a restricted type. With no declarations at all, you
should always get full integer arithmetic if you simply make no
declarations at all.

In Lisp, objects have types, not variables. All you can do with variables
is promise to only put certain types of arguments in them.

Even _if_ you did:

(defun f (x y)
(declare (fixnum x y))
(+ x y))

this would not mean that the result would be a fixnum. Doing
(+ most-positive-fixnum 1)
will yield a bignum even though both most-positive-fixnum and the literal
constant 1 are known to be fixnums.

What you are saying you want [general arithmetic] is incompatible with the
question you are asking [doing needless declarations].

Show the actual code you are using.

Adam Warner

unread,
Apr 12, 2002, 8:47:50 AM4/12/02
to
Kent M Pitman wrote:

>> Quick question. I'm trying to set a top-level variable of type integer
>> (in the expectation that when I perform a division upon the variable I
>> will obtain an integer result):
>>
>> (defparameter *variablename* 1)
>>
>> Now variablename has type FIXNUM. I'd like to set that to INTEGER. I've
>> tried declare but the compiler complains about it being in the top
>> level (CMUCL: Error: Misplaced declaration).

Fantastic. A reply from Kent M Pitman :-)

> I'm not sure what you mean by the variablename has type FIXNUM.

In the CMUCL interpreter (initial * is a prompt):

* (defparameter *variablename* 1)
*VARIABLENAME*

* (type-of *variablename*)
FIXNUM

Another example:

* (defparameter *variablename* 1.1)
*VARIABLENAME*

* (type-of *variablename*)
SINGLE-FLOAT

> By default, no variable ever has any type; that is, all variables hold
> any type of object unless you go to work to promise you will make them
> contain only a restricted type. With no declarations at all, you should
> always get full integer arithmetic if you simply make no declarations at
> all.

OK. I guess this is what it means when people say Lisp is not statically
typed. I can't create a variable that will only hold an integer (if I put
a real number into the variable it will become real instead of truncating
the result).

> In Lisp, objects have types, not variables. All you can do with
> variables is promise to only put certain types of arguments in them.

Understood. Thanks. I'll modify the value to be placed in the variable
instead of expecting the variable to only contain a value of a certain
type.

My understanding of how type-based compiler optimisations would work must
be mistaken as well. I imagined you would be able to declare variables to
be a certain type at the top level. It must be that if you use declare the
compiler can work out for itself if a variable is only ever used to store
a certain type.

Thanks,
Adam

Rene de Visser

unread,
Apr 12, 2002, 9:06:39 AM4/12/02
to
Try declaim,

I seem to remember CMUCL doesn't like declare at the top level.

Rene.

"Adam Warner" <use...@consulting.net.nz> wrote in message
news:a96gf0$mvrb$1...@ID-105510.news.dfncis.de...

Julian Stecklina

unread,
Apr 12, 2002, 9:57:02 AM4/12/02
to
Adam Warner <use...@consulting.net.nz> writes:

> * (defparameter *variablename* 1)
> *VARIABLENAME*
>
> * (type-of *variablename*)
> FIXNUM

Not *variablename* is of type FIXNUM, but its content. In this example
type-of gets called with the argument 1 and this is of type FIXNUM.

> OK. I guess this is what it means when people say Lisp is not statically
> typed. I can't create a variable that will only hold an integer (if I put
> a real number into the variable it will become real instead of truncating
> the result).

The variable itself has no type. And when you store a float into a
variable which just holded an integer, not the variable changes type,
but its content.

Regards,
Julian
--
Meine Hompage: http://julian.re6.de

Ich suche eine PCMCIA v1.x type I/II/III Netzwerkkarte.
Ich biete als Tauschobjekt eine v2 100MBit Karte in OVP.

Erik Naggum

unread,
Apr 12, 2002, 10:36:29 AM4/12/02
to
* Adam Warner

| Quick question. I'm trying to set a top-level variable of type integer
| (in the expectation that when I perform a division upon the variable I
| will obtain an integer result):

This expectation cannot possibly be satisfied by a type declaration. You
will have to use a division operator that always returns an integer, such
as floor, ceiling, truncate, or round.

| (defparameter *variablename* 1)
|
| Now variablename has type FIXNUM. I'd like to set that to INTEGER.

This makes no sense, actually.

The value held in *variablename* is a (or has type) fixnum, but the
*variablename* does not. This is not how Common Lisp works.

| I've tried declare but the compiler complains about it being in the top
| level (CMUCL: Error: Misplaced declaration).

Top-level declarations are done with proclaim or declaim, not declare,
for whatever it might be worth. I think many other confusions need to be
dispelled, so this although it might have been a quick question, the
full answer is going to be quite lengthy...

///
--
In a fight against something, the fight has value, victory has none.
In a fight for something, the fight is a loss, victory merely relief.

Post with compassion: http://home.chello.no/~xyzzy/kitten.jpg

Duane Rettig

unread,
Apr 12, 2002, 11:00:15 AM4/12/02
to
Julian Stecklina <der_j...@web.de> writes:

> Adam Warner <use...@consulting.net.nz> writes:
>
> > * (defparameter *variablename* 1)
> > *VARIABLENAME*
> >
> > * (type-of *variablename*)
> > FIXNUM
>
> Not *variablename* is of type FIXNUM, but its content. In this example
> type-of gets called with the argument 1 and this is of type FIXNUM.

The best way to clarify this for one not used to Lisp is to
compare

(type-of *variablename*)

with

(type-of '*variablename*)

--
Duane Rettig Franz Inc. http://www.franz.com/ (www)
1995 University Ave Suite 275 Berkeley, CA 94704
Phone: (510) 548-3600; FAX: (510) 548-8253 du...@Franz.COM (internet)

Christopher C. Stacy

unread,
Apr 12, 2002, 11:16:00 AM4/12/02
to
>>>>> On Sat, 13 Apr 2002 00:47:50 +1200, Adam Warner ("Adam") writes:
Adam> * (defparameter *variablename* 1)
Adam> * (type-of *variablename*)
Adam> FIXNUM

This is telling you that you have stored a fixnum in
that variable, not that the variable is only capable
of storing a fixnum. Variables can contain any data type.

It's as if you had asked: (type-of 1)

Adam> OK. I guess this is what it means when people say Lisp is not
Adam> statically typed. I can't create a variable that will only hold
Adam> an integer (if I put a real number into the variable it will
Adam> become real instead of truncating the result).

Right - Lisp does not do type coercion based on variable declarations.
You can, however, use DECLARE to promise to the compiler that you will
only put a certain type of data into a variable. If you lie and put
something else there, anything could happen: at that point the program
is allowed crash or give wrong results.

Fernando Rodríguez

unread,
Apr 12, 2002, 12:26:19 PM4/12/02
to
On Fri, 12 Apr 2002 23:30:07 +1200, Adam Warner <use...@consulting.net.nz>
wrote:


>(defparameter *variablename* 1)
>
>Now variablename has type FIXNUM.

Nope. :-) You're mixing the variable and the contents of the variable. If
you're familiar with C/C++, it might help considering all variables in lisp as
pointers to void that can point to everything.

So, *variablename* is a pointer that points to 1. When you ask type-of, you
are asking the type of the pointed-at data.

If you have Ansi common lisp by Paul Graham, check the chapter "Why lisp has
no pointers". If not, buy it. ;-)


-----------------------
Fernando Rodriguez

Joe Marshall

unread,
Apr 12, 2002, 2:56:17 PM4/12/02
to

"Adam Warner" <use...@consulting.net.nz> wrote in message
news:a96gf0$mvrb$1...@ID-105510.news.dfncis.de...

Doesn't (declaim (type integer *variablename*)) work?

Kent M Pitman

unread,
Apr 12, 2002, 4:38:01 PM4/12/02
to
"Joe Marshall" <prunes...@attbi.com> writes:

It won't keep (TYPE-OF *VARIABLENAME*) from [correctly] returning
FIXNUM because Adam has completely misunderstood the question that
TYPE-OF asks. See the other replies on this issue: It's hard to tell
because of some of the conceptual confusions, but it looks to me like
his purpose in making the declaration is to broaden, not constrain,
the type. In that regard, no action is needed at all, and what you
suggest, while it works for people who want it, is not what he wants
so would not work for him. It would only confuse him more.

Adam Warner

unread,
Apr 12, 2002, 5:26:20 PM4/12/02
to
Christopher C. Stacy wrote:

> Adam> OK. I guess this is what it means when people say Lisp is not
> Adam> statically typed. I can't create a variable that will only hold
> Adam> an integer (if I put a real number into the variable it will
> Adam> become real instead of truncating the result).
>
> Right - Lisp does not do type coercion based on variable declarations.
> You can, however, use DECLARE to promise to the compiler that you will
> only put a certain type of data into a variable. If you lie and put
> something else there, anything could happen: at that point the program
> is allowed crash or give wrong results.

Thanks Christopher and all. I guess this means by using DECLARE I could
create programs with unintended security holes (buffer overflows, etc.)
Certainly not the kind of functionality I was looking for (where I could
enforce a specific type on a variable).

Regards,
Adam

Frode Vatvedt Fjeld

unread,
Apr 12, 2002, 5:44:32 PM4/12/02
to
Adam Warner <use...@consulting.net.nz> writes:

> Certainly not the kind of functionality I was looking for (where I
> could enforce a specific type on a variable).

Perhaps something like this does what you want:

(defvar *my-variables-place*)

(defun my-variables-accessor ()
*my-variables-place*)

(defun (setf my-variables-accessor) (value)
(check-type value integer)
(setf *my-variables-place* value))

(define-symbol-macro *my-variable* (my-variables-accessor))

Now (setf *my-variable* x) will always check that x is an
integer. This scheme can be used to enforce pretty much any policy.

--
Frode Vatvedt Fjeld

Erik Naggum

unread,
Apr 12, 2002, 6:20:27 PM4/12/02
to
* Adam Warner

| I guess this means by using DECLARE I could create programs with
| unintended security holes (buffer overflows, etc.)

No. Please hold your conclusions until you know what kinds of things are
declared in Common Lisp. For your edification: Through all my years of
Common Lisp study and use, approaching 15, now, I have never seen or
heard of any security-related problems in Common Lisp systems that could
be traced back to misdeclaring types, and you would have to go to such
lengths to be able to overflow a buffer that it had to be done with full
intent and premeditation, not by the kind of accident that produces
security holes in languages that require serious effort to aim your
high-powered machine gun away from your feet.

| Certainly not the kind of functionality I was looking for (where I could
| enforce a specific type on a variable).

Well, this is not how Common Lisp declarations work in the first place.

What do you want to happen? Should the compiler yell at you for not
storing the appropriate type of object in a variable? That is simply not
how Common Lisp systems work, either.

For the time being, please ignore declarations completely. They have
much more potential to confuse you than to illuminate you at this point.
It might be instructive to regard every function as returning objects of
type t and every caller as passing objects of type t, and to think about
what this would do to your code. When you have thought about this for a
while, you realize what it takes to implement a Common Lisp system in
safe mode, and why it is a fantastic feature of the language that you can
ex(ect the language substrate to catch all of your violations for you.
You should therefore not even _try_ to request anything less than maximum
safety until you have learned to write code that is equeally defensive
yourself. If you include the following in all your source files, you
should never have any problems:

(declaim (optimize safety))

When you have learned to write safe code yourself and know how to ensure
that your functions operate within a world of known types, you can start
declaring your types and turning the safety down. If you find that you
need better performance, you are jumping the gun. The Common Lisp way is
to write correct code before you write fast code. If you spend only half
as much time as you would getting fast C++ code correct on making correct
Common Lisp code fast, you would get approximately equally good
performance, so this is not the overall loss that it seems to be to
someone who is used to writing fast and incomplete or incorrect code.

Barry Margolin

unread,
Apr 12, 2002, 7:06:11 PM4/12/02
to
In article <32276388...@naggum.net>, Erik Naggum <er...@naggum.net> wrote:
>* Adam Warner
>| I guess this means by using DECLARE I could create programs with
>| unintended security holes (buffer overflows, etc.)
>
> No. Please hold your conclusions until you know what kinds of things are
> declared in Common Lisp. For your edification: Through all my years of
> Common Lisp study and use, approaching 15, now, I have never seen or
> heard of any security-related problems in Common Lisp systems that could
> be traced back to misdeclaring types, and you would have to go to such
> lengths to be able to overflow a buffer that it had to be done with full
> intent and premeditation, not by the kind of accident that produces
> security holes in languages that require serious effort to aim your
> high-powered machine gun away from your feet.

If you combine excessive type declarations with (declaim (optimize (safety
0) (speed 3))), a compiler that does good optimization could possibly
produce code with the types of problems that Adam was worried about. But
like Erik, I've never actually heard of this happening in practice.

--
Barry Margolin, bar...@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.

0 new messages