Discussion:
Can compiler macros make use of type declarations?
Chaitanya Gupta
2017-11-06 20:43:03 UTC
Permalink
Let's say I have created a function called `FOO`:

(defun foo (x)
...)

To optimize this function, I write a compiler macro. Can I make use of
type declarations that users of `FOO` might have made for the argument
`X` that is passed in to it?

That is, let's say `FOO` is used like this:

(let ((a (something-that-returns-an-integer)))
(declare (integer a))
(foo a))

The compiler macro for `FOO` cannot make any optimizations on the
value of `A`, but can it take advantage of the fact that `A` is
declared as in `INTEGER` here?

Chaitanya
Steve Losh
2017-11-06 21:24:31 UTC
Permalink
Check out Bike's compiler-macro library, specifically the `form-type`
function: https://github.com/Bike/compiler-macro
Post by Chaitanya Gupta
(defun foo (x)
...)
To optimize this function, I write a compiler macro. Can I make use of
type declarations that users of `FOO` might have made for the argument
`X` that is passed in to it?
(let ((a (something-that-returns-an-integer)))
(declare (integer a))
(foo a))
The compiler macro for `FOO` cannot make any optimizations on the
value of `A`, but can it take advantage of the fact that `A` is
declared as in `INTEGER` here?
Chaitanya
Chaitanya Gupta
2017-11-07 03:23:35 UTC
Permalink
Post by Steve Losh
Check out Bike's compiler-macro library, specifically the `form-type`
function: https://github.com/Bike/compiler-macro
This is exactly what I was looking for. Thanks a ton!

Chaitanya
Post by Steve Losh
Post by Chaitanya Gupta
(defun foo (x)
...)
To optimize this function, I write a compiler macro. Can I make use of
type declarations that users of `FOO` might have made for the argument
`X` that is passed in to it?
(let ((a (something-that-returns-an-integer)))
(declare (integer a))
(foo a))
The compiler macro for `FOO` cannot make any optimizations on the
value of `A`, but can it take advantage of the fact that `A` is
declared as in `INTEGER` here?
Chaitanya
Steve Haflich
2017-11-07 05:00:27 UTC
Permalink
A compiler-macro, just like a regular macro, receives an &environment
argument which is supposed to contain (amongst other things) the
lexical and global properties of bindings in the environment in which
the macro is expanded. In the original language definition proposed
by CLtL there was an environment access interface with functions
like variablle-information which could return (for instance) what is
known about the type of A in the lexical environment in which FOO is
expanded.

Unfortunately, the environment access system in CLtL was
underspecified, there were no existing implementations, and no one was
sure an implementation was even possible without imposing large
efficiency hits at compile time. So we of X3J13 removed it from the
standard.

Duane Rettig of Franz later implemented a portable open-source sane
environment module inspired by the original CLtL specification. This
can be used to write a portable CL code walker of any kind, but it
won't do you any good unless the code walker that is your favorite
implementation's compiler happens to use it. But fortunately, several
implementations provide documented environment access interfaces built
into their compilers. Unfortunately, these interfaces are not defined
by the standard, so their use generally makes code nonportable.

BTW, a plain INTEGER type declaration is often not as effective as
you'd expect because INTEGER type is the union of FIXNUM and BIGNUM.
Arithmetic on the former can generally be inlined in a few machine
instructions (particularly if the integer range can be narrowed
further) but if any arguments or the result could be bignums, further
runtime type tests and/or callouts will be generated.


On Mon, Nov 6, 2017 at 12:43 PM, Chaitanya Gupta
Post by Chaitanya Gupta
(defun foo (x)
...)
To optimize this function, I write a compiler macro. Can I make use of
type declarations that users of `FOO` might have made for the argument
`X` that is passed in to it?
(let ((a (something-that-returns-an-integer)))
(declare (integer a))
(foo a))
The compiler macro for `FOO` cannot make any optimizations on the
value of `A`, but can it take advantage of the fact that `A` is
declared as in `INTEGER` here?
Chaitanya
Antoniotti Marco
2017-11-07 08:26:53 UTC
Permalink
There is a portable (*) re-implementation of the Environment API (including the re-normalization of Franz return values switch) in CLAST.

http://clast.sf.net

Cheers
--
MA
Post by Steve Haflich
A compiler-macro, just like a regular macro, receives an &environment
argument which is supposed to contain (amongst other things) the
lexical and global properties of bindings in the environment in which
the macro is expanded. In the original language definition proposed
by CLtL there was an environment access interface with functions
like variablle-information which could return (for instance) what is
known about the type of A in the lexical environment in which FOO is
expanded.
Unfortunately, the environment access system in CLtL was
underspecified, there were no existing implementations, and no one was
sure an implementation was even possible without imposing large
efficiency hits at compile time. So we of X3J13 removed it from the
standard.
Duane Rettig of Franz later implemented a portable open-source sane
environment module inspired by the original CLtL specification. This
can be used to write a portable CL code walker of any kind, but it
won't do you any good unless the code walker that is your favorite
implementation's compiler happens to use it. But fortunately, several
implementations provide documented environment access interfaces built
into their compilers. Unfortunately, these interfaces are not defined
by the standard, so their use generally makes code nonportable.
BTW, a plain INTEGER type declaration is often not as effective as
you'd expect because INTEGER type is the union of FIXNUM and BIGNUM.
Arithmetic on the former can generally be inlined in a few machine
instructions (particularly if the integer range can be narrowed
further) but if any arguments or the result could be bignums, further
runtime type tests and/or callouts will be generated.
On Mon, Nov 6, 2017 at 12:43 PM, Chaitanya Gupta
Post by Chaitanya Gupta
(defun foo (x)
...)
To optimize this function, I write a compiler macro. Can I make use of
type declarations that users of `FOO` might have made for the argument
`X` that is passed in to it?
(let ((a (something-that-returns-an-integer)))
(declare (integer a))
(foo a))
The compiler macro for `FOO` cannot make any optimizations on the
value of `A`, but can it take advantage of the fact that `A` is
declared as in `INTEGER` here?
Chaitanya
--
Marco Antoniotti, Associate Professor tel. +39 - 02 64 48 79 01
DISCo, Università Milano Bicocca U14 2043 http://bimib.disco.unimib.it
Viale Sarca 336
I-20126 Milan (MI) ITALY

Please check: http://troncopackage.org

Please note that I am not checking my Spam-box anymore.
Please do not forward this email without asking me first
Chaitanya Gupta
2017-11-07 19:04:36 UTC
Permalink
On 7 November 2017 at 13:56, Antoniotti Marco
Post by Antoniotti Marco
There is a portable (*) re-implementation of the Environment API (including the re-normalization of Franz return values switch) in CLAST.
http://clast.sf.net
Thanks, CLAST looks like a very useful library.

Chaitanya
Post by Antoniotti Marco
Cheers
--
MA
Post by Steve Haflich
A compiler-macro, just like a regular macro, receives an &environment
argument which is supposed to contain (amongst other things) the
lexical and global properties of bindings in the environment in which
the macro is expanded. In the original language definition proposed
by CLtL there was an environment access interface with functions
like variablle-information which could return (for instance) what is
known about the type of A in the lexical environment in which FOO is
expanded.
Unfortunately, the environment access system in CLtL was
underspecified, there were no existing implementations, and no one was
sure an implementation was even possible without imposing large
efficiency hits at compile time. So we of X3J13 removed it from the
standard.
Duane Rettig of Franz later implemented a portable open-source sane
environment module inspired by the original CLtL specification. This
can be used to write a portable CL code walker of any kind, but it
won't do you any good unless the code walker that is your favorite
implementation's compiler happens to use it. But fortunately, several
implementations provide documented environment access interfaces built
into their compilers. Unfortunately, these interfaces are not defined
by the standard, so their use generally makes code nonportable.
BTW, a plain INTEGER type declaration is often not as effective as
you'd expect because INTEGER type is the union of FIXNUM and BIGNUM.
Arithmetic on the former can generally be inlined in a few machine
instructions (particularly if the integer range can be narrowed
further) but if any arguments or the result could be bignums, further
runtime type tests and/or callouts will be generated.
On Mon, Nov 6, 2017 at 12:43 PM, Chaitanya Gupta
Post by Chaitanya Gupta
(defun foo (x)
...)
To optimize this function, I write a compiler macro. Can I make use of
type declarations that users of `FOO` might have made for the argument
`X` that is passed in to it?
(let ((a (something-that-returns-an-integer)))
(declare (integer a))
(foo a))
The compiler macro for `FOO` cannot make any optimizations on the
value of `A`, but can it take advantage of the fact that `A` is
declared as in `INTEGER` here?
Chaitanya
--
Marco Antoniotti, Associate Professor tel. +39 - 02 64 48 79 01
DISCo, Università Milano Bicocca U14 2043 http://bimib.disco.unimib.it
Viale Sarca 336
I-20126 Milan (MI) ITALY
Please check: http://troncopackage.org
Please note that I am not checking my Spam-box anymore.
Please do not forward this email without asking me first (cum grano salis).
Chaitanya Gupta
2017-11-07 19:01:49 UTC
Permalink
Post by Steve Haflich
A compiler-macro, just like a regular macro, receives an &environment
argument which is supposed to contain (amongst other things) the
lexical and global properties of bindings in the environment in which
the macro is expanded. In the original language definition proposed
by CLtL there was an environment access interface with functions
like variablle-information which could return (for instance) what is
known about the type of A in the lexical environment in which FOO is
expanded.
Unfortunately, the environment access system in CLtL was
underspecified, there were no existing implementations, and no one was
sure an implementation was even possible without imposing large
efficiency hits at compile time. So we of X3J13 removed it from the
standard.
Duane Rettig of Franz later implemented a portable open-source sane
environment module inspired by the original CLtL specification. This
can be used to write a portable CL code walker of any kind, but it
won't do you any good unless the code walker that is your favorite
implementation's compiler happens to use it. But fortunately, several
implementations provide documented environment access interfaces built
into their compilers. Unfortunately, these interfaces are not defined
by the standard, so their use generally makes code nonportable.
Thank you for sharing this piece of CL history. I never knew CLtL had
an environment access facility.
Post by Steve Haflich
BTW, a plain INTEGER type declaration is often not as effective as
you'd expect because INTEGER type is the union of FIXNUM and BIGNUM.
Arithmetic on the former can generally be inlined in a few machine
instructions (particularly if the integer range can be narrowed
further) but if any arguments or the result could be bignums, further
runtime type tests and/or callouts will be generated.
Yes I realized this too recently.. the performance gains with fixnum
are pretty good!

Chaitanya
Post by Steve Haflich
On Mon, Nov 6, 2017 at 12:43 PM, Chaitanya Gupta
Post by Chaitanya Gupta
(defun foo (x)
...)
To optimize this function, I write a compiler macro. Can I make use of
type declarations that users of `FOO` might have made for the argument
`X` that is passed in to it?
(let ((a (something-that-returns-an-integer)))
(declare (integer a))
(foo a))
The compiler macro for `FOO` cannot make any optimizations on the
value of `A`, but can it take advantage of the fact that `A` is
declared as in `INTEGER` here?
Chaitanya
Chaitanya Gupta
2017-11-09 08:18:11 UTC
Permalink
So thanks to the replies on this I now know that most of the popular
Lisps do support inspecting the environment to figure out declared
types.

But what about inferred types (e.g. in CMUCL, SBCL)? Do these Lisps
provide a way to know the inferred type of a variable if no
declaration was made explicitly?

Chaitanya
Post by Chaitanya Gupta
(defun foo (x)
...)
To optimize this function, I write a compiler macro. Can I make use of
type declarations that users of `FOO` might have made for the argument
`X` that is passed in to it?
(let ((a (something-that-returns-an-integer)))
(declare (integer a))
(foo a))
The compiler macro for `FOO` cannot make any optimizations on the
value of `A`, but can it take advantage of the fact that `A` is
declared as in `INTEGER` here?
Chaitanya
Antoniotti Marco
2017-11-09 08:39:18 UTC
Permalink
CMUCL and SBCL have the Environment API somewhat available (*)

You can see whether they store the inferred values in there.

Marco

(*) Again, you can have a look at CLAST to see how to access it; I know: it is a shameless plug.
Post by Chaitanya Gupta
So thanks to the replies on this I now know that most of the popular
Lisps do support inspecting the environment to figure out declared
types.
But what about inferred types (e.g. in CMUCL, SBCL)? Do these Lisps
provide a way to know the inferred type of a variable if no
declaration was made explicitly?
Chaitanya
Post by Chaitanya Gupta
(defun foo (x)
...)
To optimize this function, I write a compiler macro. Can I make use of
type declarations that users of `FOO` might have made for the argument
`X` that is passed in to it?
(let ((a (something-that-returns-an-integer)))
(declare (integer a))
(foo a))
The compiler macro for `FOO` cannot make any optimizations on the
value of `A`, but can it take advantage of the fact that `A` is
declared as in `INTEGER` here?
Chaitanya
--
Marco Antoniotti, Associate Professor tel. +39 - 02 64 48 79 01
DISCo, Università Milano Bicocca U14 2043 http://bimib.disco.unimib.it
Viale Sarca 336
I-20126 Milan (MI) ITALY

Please check: http://troncopackage.org

Please note that I am not checking my Spam-box anymore.
Please do not forward this email withou
Chaitanya Gupta
2017-11-09 09:17:53 UTC
Permalink
I tried this on SBCL:

(defun bar (x)
x)

(define-compiler-macro bar (&whole form x &environment env)
(when (symbolp x)
(print (multiple-value-list (clast:variable-information x env))))
form)

The form below, with the declaration, prints type information correctly:

(compile nil
(lambda ()
(let ((y 10)) (declare (fixnum y)) (bar y))))
Post by Antoniotti Marco
(:LEXICAL T ((TYPE . FIXNUM)))
However, the one below with no declarations, doesn't give any info:

(compile nil
(lambda ()
(let ((y 10)) (bar y))
(let ((y '(1 2 3))) (bar y))
(let ((y 'foo)) (bar y))))
Post by Antoniotti Marco
(:LEXICAL T NIL)
(:LEXICAL T NIL)
(:LEXICAL T NIL)
So I guess that, at least on SBCL, this is not possible.

Chaitanya


On 9 November 2017 at 14:09, Antoniotti Marco
Post by Antoniotti Marco
CMUCL and SBCL have the Environment API somewhat available (*)
You can see whether they store the inferred values in there.
Marco
(*) Again, you can have a look at CLAST to see how to access it; I know: it is a shameless plug.
So thanks to the replies on this I now know that most of the popular
Lisps do support inspecting the environment to figure out declared
types.
But what about inferred types (e.g. in CMUCL, SBCL)? Do these Lisps
provide a way to know the inferred type of a variable if no
declaration was made explicitly?
Chaitanya
Post by Chaitanya Gupta
(defun foo (x)
...)
To optimize this function, I write a compiler macro. Can I make use of
type declarations that users of `FOO` might have made for the argument
`X` that is passed in to it?
(let ((a (something-that-returns-an-integer)))
(declare (integer a))
(foo a))
The compiler macro for `FOO` cannot make any optimizations on the
value of `A`, but can it take advantage of the fact that `A` is
declared as in `INTEGER` here?
Chaitanya
--
Marco Antoniotti, Associate Professor tel. +39 - 02 64 48 79 01
DISCo, Università Milano Bicocca U14 2043 http://bimib.disco.unimib.it
Viale Sarca 336
I-20126 Milan (MI) ITALY
Please check: http://troncopackage.org
Please note that I am not checking my Spam-box anymore.
Please do not forward this email without asking me first (cum grano salis).
Antoniotti Marco
2017-11-09 10:02:19 UTC
Permalink
Post by Chaitanya Gupta
(defun bar (x)
x)
(define-compiler-macro bar (&whole form x &environment env)
(when (symbolp x)
(print (multiple-value-list (clast:variable-information x env))))
form)
(compile nil
(lambda ()
(let ((y 10)) (declare (fixnum y)) (bar y))))
Post by Antoniotti Marco
(:LEXICAL T ((TYPE . FIXNUM)))
(compile nil
(lambda ()
(let ((y 10)) (bar y))
(let ((y '(1 2 3))) (bar y))
(let ((y 'foo)) (bar y))))
Post by Antoniotti Marco
(:LEXICAL T NIL)
(:LEXICAL T NIL)
(:LEXICAL T NIL)
So I guess that, at least on SBCL, this is not possible.
Seems plausible. I am not an expert on CMUCL/SBCL type inference, but I’d wager that it does not propagate types as we expect.
BTW. LW behaves in the same way (plus: thank you; I discovered a shortcoming of CLAST LW wrapping that I just fixed).

Marco
Post by Chaitanya Gupta
Chaitanya
On 9 November 2017 at 14:09, Antoniotti Marco
Post by Antoniotti Marco
CMUCL and SBCL have the Environment API somewhat available (*)
You can see whether they store the inferred values in there.
Marco
(*) Again, you can have a look at CLAST to see how to access it; I know: it is a shameless plug.
So thanks to the replies on this I now know that most of the popular
Lisps do support inspecting the environment to figure out declared
types.
But what about inferred types (e.g. in CMUCL, SBCL)? Do these Lisps
provide a way to know the inferred type of a variable if no
declaration was made explicitly?
Chaitanya
Post by Chaitanya Gupta
(defun foo (x)
...)
To optimize this function, I write a compiler macro. Can I make use of
type declarations that users of `FOO` might have made for the argument
`X` that is passed in to it?
(let ((a (something-that-returns-an-integer)))
(declare (integer a))
(foo a))
The compiler macro for `FOO` cannot make any optimizations on the
value of `A`, but can it take advantage of the fact that `A` is
declared as in `INTEGER` here?
Chaitanya
--
Marco Antoniotti, Associate Professor tel. +39 - 02 64 48 79 01
DISCo, Università Milano Bicocca U14 2043 http://bimib.disco.unimib.it
Viale Sarca 336
I-20126 Milan (MI) ITALY
Please check: http://troncopackage.org
Please note that I am not checking my Spam-box anymore.
Please do not forward this email without asking me first (cum grano salis).
--
Marco Antoniotti, Associate Professor tel. +39 - 02 64 48 79 01
DISCo, Università Milano Bicocca U14 2043 http://bimib.disco.unimib.it
Viale Sarca 336
I-20126 Milan (MI) ITALY

Please check: http://troncopackage.org

Please note that I am not checking my Spam-box anymore.
Please do not forward this email without asking me first (cum grano salis).
Martin Simmons
2017-11-09 11:12:57 UTC
Permalink
Compiler macros are expanded too early to get inferred type info. For
example,

(let ((y 10)) (loop (bar y) (setq y :not-a-fixnum)))
--
Martin Simmons
LispWorks Ltd
http://www.lispworks.com/
Post by Chaitanya Gupta
(defun bar (x)
x)
(define-compiler-macro bar (&whole form x &environment env)
(when (symbolp x)
(print (multiple-value-list (clast:variable-information x env))))
form)
(compile nil
(lambda ()
(let ((y 10)) (declare (fixnum y)) (bar y))))
Post by Antoniotti Marco
(:LEXICAL T ((TYPE . FIXNUM)))
(compile nil
(lambda ()
(let ((y 10)) (bar y))
(let ((y '(1 2 3))) (bar y))
(let ((y 'foo)) (bar y))))
Post by Antoniotti Marco
(:LEXICAL T NIL)
(:LEXICAL T NIL)
(:LEXICAL T NIL)
So I guess that, at least on SBCL, this is not possible.
Chaitanya
On 9 November 2017 at 14:09, Antoniotti Marco
Post by Antoniotti Marco
CMUCL and SBCL have the Environment API somewhat available (*)
You can see whether they store the inferred values in there.
Marco
(*) Again, you can have a look at CLAST to see how to access it; I know: it is a shameless plug.
So thanks to the replies on this I now know that most of the popular
Lisps do support inspecting the environment to figure out declared
types.
But what about inferred types (e.g. in CMUCL, SBCL)? Do these Lisps
provide a way to know the inferred type of a variable if no
declaration was made explicitly?
Chaitanya
Post by Chaitanya Gupta
(defun foo (x)
...)
To optimize this function, I write a compiler macro. Can I make use of
type declarations that users of `FOO` might have made for the argument
`X` that is passed in to it?
(let ((a (something-that-returns-an-integer)))
(declare (integer a))
(foo a))
The compiler macro for `FOO` cannot make any optimizations on the
value of `A`, but can it take advantage of the fact that `A` is
declared as in `INTEGER` here?
Chaitanya
--
Marco Antoniotti, Associate Professor tel. +39 - 02 64 48 79 01
DISCo, Università Milano Bicocca U14 2043 http://bimib.disco.unimib.it
Viale Sarca 336
I-20126 Milan (MI) ITALY
Please check: http://troncopackage.org
Please note that I am not checking my Spam-box anymore.
Please do not forward this email without asking me first (cum grano salis).
Stelian Ionescu
2017-11-09 11:38:56 UTC
Permalink
Post by Martin Simmons
Compiler macros are expanded too early to get inferred type info. For
example,
(let ((y 10)) (loop (bar y) (setq y :not-a-fixnum)))
Would it be against the standard to do some type analysis before expanding compiler macros ? Without that, compiler macros can only make optimization decisions based on arguments which are literal values, which is still useful but not in all cases.
--
Stelian Ionescu a.k.a. fe[nl]ix
Quidquid latine dictum sit, altum videtur.
Martin Simmons
2017-11-09 12:04:55 UTC
Permalink
Post by Stelian Ionescu
Post by Martin Simmons
Compiler macros are expanded too early to get inferred type info. For
example,
(let ((y 10)) (loop (bar y) (setq y :not-a-fixnum)))
Would it be against the standard to do some type analysis before expanding
compiler macros ?
Probably not against the standard, but not much analysis is possible.
Afterall, you have to expand macros and compiler macros before their
expansions can be analyzed. You can't infer the type of a variable unless you
know the types of all of the values assigned to it.
Post by Stelian Ionescu
Without that, compiler macros can only make optimization
decisions based on arguments which are literal values, which is still useful
but not in all cases.
Yes, that's really all they can be used for.
--
Martin Simmons
LispWorks Ltd
http://www.lispworks.com/
Chaitanya Gupta
2017-11-09 12:18:17 UTC
Permalink
Post by Martin Simmons
Compiler macros are expanded too early to get inferred type info. For
example,
(let ((y 10)) (loop (bar y) (setq y :not-a-fixnum)))
Right. That makes sense. So it seems declarations is the way to go if
you want to make type based optimizations.

Chaitanya
Post by Martin Simmons
--
Martin Simmons
LispWorks Ltd
http://www.lispworks.com/
Post by Chaitanya Gupta
(defun bar (x)
x)
(define-compiler-macro bar (&whole form x &environment env)
(when (symbolp x)
(print (multiple-value-list (clast:variable-information x env))))
form)
(compile nil
(lambda ()
(let ((y 10)) (declare (fixnum y)) (bar y))))
Post by Antoniotti Marco
(:LEXICAL T ((TYPE . FIXNUM)))
(compile nil
(lambda ()
(let ((y 10)) (bar y))
(let ((y '(1 2 3))) (bar y))
(let ((y 'foo)) (bar y))))
Post by Antoniotti Marco
(:LEXICAL T NIL)
(:LEXICAL T NIL)
(:LEXICAL T NIL)
So I guess that, at least on SBCL, this is not possible.
Chaitanya
On 9 November 2017 at 14:09, Antoniotti Marco
Post by Antoniotti Marco
CMUCL and SBCL have the Environment API somewhat available (*)
You can see whether they store the inferred values in there.
Marco
(*) Again, you can have a look at CLAST to see how to access it; I know: it is a shameless plug.
So thanks to the replies on this I now know that most of the popular
Lisps do support inspecting the environment to figure out declared
types.
But what about inferred types (e.g. in CMUCL, SBCL)? Do these Lisps
provide a way to know the inferred type of a variable if no
declaration was made explicitly?
Chaitanya
Post by Chaitanya Gupta
(defun foo (x)
...)
To optimize this function, I write a compiler macro. Can I make use of
type declarations that users of `FOO` might have made for the argument
`X` that is passed in to it?
(let ((a (something-that-returns-an-integer)))
(declare (integer a))
(foo a))
The compiler macro for `FOO` cannot make any optimizations on the
value of `A`, but can it take advantage of the fact that `A` is
declared as in `INTEGER` here?
Chaitanya
--
Marco Antoniotti, Associate Professor tel. +39 - 02 64 48 79 01
DISCo, Università Milano Bicocca U14 2043 http://bimib.disco.unimib.it
Viale Sarca 336
I-20126 Milan (MI) ITALY
Please check: http://troncopackage.org
Please note that I am not checking my Spam-box anymore.
Please do not forward this email without asking me first (cum grano salis).
Joshua TAYLOR
2017-11-09 12:31:59 UTC
Permalink
Post by Chaitanya Gupta
(defun foo (x)
...)
To optimize this function, I write a compiler macro. Can I make use of
type declarations that users of `FOO` might have made for the argument
`X` that is passed in to it?
(let ((a (something-that-returns-an-integer)))
(declare (integer a))
(foo a))
The compiler macro for `FOO` cannot make any optimizations on the
value of `A`, but can it take advantage of the fact that `A` is
declared as in `INTEGER` here?
There has been plenty of discussion about how you might access the
environment, etc., to get this information, and whether it's portable,
etc. Depending on your use case, you could make use of the [THE]
special operator at the call site, and you'd be guaranteed to have it
available to the compiler macro. That is, you'd now write

(foo (the fixnum a))

That works regardless of what environment introspection you can get,
because you see (THE FIXNUM A) when you're expanding the compiler
macro, and from that you could check the type, and if the use case is
that it's very important to do some optimization at compile time, this
might be an acceptable tradeoff.

[THE]: http://www.lispworks.com/documentation/HyperSpec/Body/s_the.htm
--
Joshua Taylor, http://www.cs.rpi.edu/~tayloj/<div
id="DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2"><br />
<table style="border-top: 1px solid #D3D4DE;">
<tr>
<td style="width: 55px; padding-top: 13px;"><a
href="https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail&utm_term=icon"
target="_blank"><img
src="Loading Image..."
alt="" width="46" height="29" style="width: 46px; height: 29px;"
/></a></td>
<td style="width: 470px; padding-top: 12px; color: #41424e;
font-size: 13px; font-family: Arial, Helvetica, sans-serif;
line-height: 18px;">Virus-free. <a
href="https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail&utm_term=link"
target="_blank" style="color: #4453ea;">www.avast.com</a>
</td>
</tr>
</table><a href="#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2" width="1"
height="1"></a></div>
Loading...