From: danb
Subject: Objects of type FUNCTION can't be dumped into fasl files.
Date: 
Message-ID: <2ffd15de-6e55-48cb-9d5c-4f714617328e@e67g2000hsa.googlegroups.com>
I want to write a macro that defines a helper function
to be called by another macro or another of the main
macro's helpers.  It's supposed to allow the user to
extend a declarative pattern-specification language,
so the function being defined will transform a user-
defined pattern into some other known pattern.  When
the main pattern-processing function encounters a
pattern it doesn't recognize, it'll look for a custom
pattern processor defined by this helper-defining macro.

What's the bestest/simplest way to do that?  I thought the
defining macro could create a lambda and deposit it in a
global hashtable, but, whenever I try to compile a call
to the helper-defining macro, sbcl complains that it can't
store a lambda in the fasl file.  Why does sbcl think it has
to store a function object in a fasl file?  What's wrong with
creating a lambda in a macro, and what's the alternative?

--Dan

------------------------------------------------
Dan Bensen
http://www.prairienet.org/~dsb/

From: danb
Subject: Re: Objects of type FUNCTION can't be dumped into fasl files.
Date: 
Message-ID: <382c8f92-9d11-4694-82c5-6f08bcbe2588@l64g2000hse.googlegroups.com>
On Apr 20, 12:21 pm, danb <·········@gmail.com> wrote:
> whenever I try to compile a call to the helper-
> defining macro, sbcl complains that it can't
> store a lambda in the fasl file.

Okay, I wrapped the expanded code in an
(eval-when (:load-toplevel :execute) ...) form,
and it's working in a fresh load directly into sbcl
(not through slime).

Does anyone know what's the best way to safely obliterate
all traces of a package?  Even after the code worked
in a new plain sbcl process, it's still having problems
in the old slime/sbcl process, even though I unused the
library package from the client package, then recompiled
the library, then recompiled the client package.

--Dan

------------------------------------------------
Dan Bensen
http://www.prairienet.org/~dsb/
From: Pascal Bourguignon
Subject: Re: Objects of type FUNCTION can't be dumped into fasl files.
Date: 
Message-ID: <87r6d0wa8k.fsf@hubble.informatimago.com>
danb <·········@gmail.com> writes:

> On Apr 20, 12:21 pm, danb <·········@gmail.com> wrote:
>> whenever I try to compile a call to the helper-
>> defining macro, sbcl complains that it can't
>> store a lambda in the fasl file.
>
> Okay, I wrapped the expanded code in an
> (eval-when (:load-toplevel :execute) ...) form,
> and it's working in a fresh load directly into sbcl
> (not through slime).
>
> Does anyone know what's the best way to safely obliterate
> all traces of a package?  Even after the code worked
> in a new plain sbcl process, it's still having problems
> in the old slime/sbcl process, even though I unused the
> library package from the client package, then recompiled
> the library, then recompiled the client package.

As you put it, there is no easy way.

You would have to scan all the objects in the image to find all the
symbols coming from this package, all the functions that have been
named with such a symbol, all lambda that uses one of these symbols,
all the data object defined from, or with stuff from this
package.  Mind CLOS objects, methods, etc.

If you would accept a weaker request, DELETE-PACKAGE could be used,
but of course, this won't clean up these symbols and data objects.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

"What is this talk of "release"?  Klingons do not make software
"releases".  Our software "escapes" leaving a bloody trail of
designers and quality assurance people in its wake."
From: Thomas A. Russ
Subject: Re: Objects of type FUNCTION can't be dumped into fasl files.
Date: 
Message-ID: <ymizlrlh3g2.fsf@blackcat.isi.edu>
danb <·········@gmail.com> writes:

> Does anyone know what's the best way to safely obliterate
> all traces of a package?

Restart the lisp environment and reload.

There are other, less radical solutions, but they will be more
complicated and are prone to leave things lying around.  You could try
deleting the package that contains the symbols naming everything.  That
should get rid of most things, although if you have added methods to
symbols from other packages, they won't be gone unless you track them
down individually and do a remove-method on them.

Pointers to library objects will also not go away on their own, so if
you retain any references, they will still be problematic.  That is why
the safest method is to restart.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: danb
Subject: Re: Objects of type FUNCTION can't be dumped into fasl files.
Date: 
Message-ID: <5d7fe83f-f849-4d2f-8b71-cafb0a8983fc@j22g2000hsf.googlegroups.com>
On Apr 22, 6:31 pm, ····@sevak.isi.edu (Thomas A. Russ) wrote:
> danb <·········@gmail.com> writes:
> > Does anyone know what's the best way to safely obliterate
> > all traces of a package?

> You could try deleting the package

I got "that name does not refer to any package" errors
after doing that, so there must have been something around
that was still looking for it.

> added methods
> Pointers to library objects

Thanks.

Talk about annoying Heisenbugs.  As soon as I added a couple
FORMAT commmands to chase down the bug, it disappeared.
Everything's working now, but I have no idea why.  I did
change a reference to a special variable so that it's
evaluated after expansion instead of during, but compiling
a call to the macro still generated an error, so that didn't
seem to fix the problem.  The error only disappeared when
I threatened to flush it out and squish it.

--Dan

------------------------------------------------
Dan Bensen
http://www.prairienet.org/~dsb/
From: Kaz Kylheku
Subject: Re: Objects of type FUNCTION can't be dumped into fasl files.
Date: 
Message-ID: <1bae1513-3362-47de-9f08-480bebfb0a6f@m36g2000hse.googlegroups.com>
On Apr 20, 10:21 am, danb <·········@gmail.com> wrote:
> What's the bestest/simplest way to do that?  I thought the
> defining macro could create a lambda and deposit it in a
> global hashtable, but, whenever I try to compile a call
> to the helper-defining macro, sbcl complains that it can't
> store a lambda in the fasl file.

The wording of this interpretation of the error message is slightly
misleading. A lambda expression can certainly be part of program
source code. What you have done is embed a function object as a
literal in program source code. Function objects can't be literals.
You can have string literals, list literals, vector literals, even
struct literals. But not function literals.

To represent a function object in source code, you have to use an
expression which evaluates to a function.

> Why does sbcl think it has to store a function object in a fasl file?

Probably because you asked it to do that.

> What's wrong with creating a lambda in a macro

There is nothing wrong with a lambda expression in a macro expansion.
The problem is that you are evaluating that lambda expression, so that
the expansion gets the resulting function rather than that lambda
expression.

> and what's the alternative?

Insert the lambda expression itself into the macro-expansion, ensuring
that it's in an evaluation context.

The details vary depending on what kind of form you are inserting this
lambda expression into, and in what position.

There is an intermediate way to obtain static objects into a program.
Just because something can't be a literal doesn't mean it has to be
computed at run time, or that you have to implement your own
initialization hacks to compute it once and then store it in a global
variable for future use. Take a look at the special form LOAD-TIME-
VALUE.   LOAD-TIME-VALUE encapsulates load-time initialization.  With
LOAD-TIME-VALUE, you can get the value of a computed expression, which
could be a function, to behave almost as if it were a literal object.
The expression wrapped in a LOAD-TIME-VALUE form is evaluated when the
module is loaded. The value is then retained in some hidden memory
location associated with that LOAD-TIME-VALUE form; whenever the
program evaluates that LOAD-TIME-VALUE, it simply returns the object
that was remembered at load time.

In your case, the solution is probably a lot simpler, since the
problem likely stems from some simple evaluation mixup.
From: danb
Subject: Re: Objects of type FUNCTION can't be dumped into fasl files.
Date: 
Message-ID: <9be78eea-378a-4fca-914b-088152b2c7b9@m3g2000hsc.googlegroups.com>
On Apr 20, 12:21 pm, danb <·········@gmail.com> wrote:
> When the main pattern-processing function encounters a
> pattern it doesn't recognize, it'll look for a custom
> pattern processor defined by this helper-defining macro.

Oh, DUH!  The definer macro wasn't creating the lambda
in compile-file, but other macros were trying to use it.

Now I have (eval-when (:load-toplevel :execute) ...)
wrapped around the bodies of all the macros that use the
helper function, so none of the code is expanded until
it's loaded into memory.  It seems to work.

Is that a sane thing to do, or a noobish hack?
Leaving macros unexpanded means the fasl file is smaller,
right?  What happens to defuns in compile-file?

--Dan

------------------------------------------------
Dan Bensen
http://www.prairienet.org/~dsb/
From: Thomas A. Russ
Subject: Re: Objects of type FUNCTION can't be dumped into fasl files.
Date: 
Message-ID: <ymi7ielhq6e.fsf@blackcat.isi.edu>
danb <·········@gmail.com> writes:

First a disclaimer that I've only been following this thread with 1/4 of
a brain, so I may have missed some things.

> On Apr 20, 12:21 pm, danb <·········@gmail.com> wrote:
> > When the main pattern-processing function encounters a
> > pattern it doesn't recognize, it'll look for a custom
> > pattern processor defined by this helper-defining macro.
> 
> Oh, DUH!  The definer macro wasn't creating the lambda
> in compile-file, but other macros were trying to use it.
> 
> Now I have (eval-when (:load-toplevel :execute) ...)
> wrapped around the bodies of all the macros that use the
> helper function, so none of the code is expanded until
> it's loaded into memory.  It seems to work.

This seems a bit odd.

More typical is that if you have macros which use helper functions as
part of the expander, you would need to wrap the definition of the
helper functions in the EVAL-WHEN.  Something along the lines of

(eval-when (...)
  (defun compute-my-macro-expansion (...)
     `(...)))

(defmacro my-macro (...)
   (compute-my-macro-expansion ...))


> Is that a sane thing to do, or a noobish hack?
> Leaving macros unexpanded means the fasl file is smaller,
> right?  

But that also removes most of the point of using macros.  You want them
to expand into the code at compile time so that the resulting code ends
up being compiled.  I recall one colleague (Bill Long) who was a master
of macrology.  For most of the rest of us, the fasl files were slightly
smaller in size than the source files they came from.  In his code, the
fasl files were typically three times a big....

> What happens to defuns in compile-file?

They get compiled into functions?  I'm not sure exactly what you are
trying to find out with this question.  The compiler puts a compiled
(generally binary) version of the function code into the file, along
with appropriate hooks so that the runtime can access and call it as
appropriate.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: danb
Subject: Re: Objects of type FUNCTION can't be dumped into fasl files.
Date: 
Message-ID: <875acbd9-2af0-4cc6-bd41-ff2564d90172@k13g2000hse.googlegroups.com>
On Apr 25, 11:09 am, ····@sevak.isi.edu (Thomas A. Russ) wrote:
> I've only been following this thread with 1/4 of a brain

Apparently more than I used to actually write the code.
Please don't ask what I was thinking.  It didn't occur to me
until later (when I read the documentation) that the "eval"
in "eval-when" might really mean "eval" instead of "process",
i.e. "do whatever normally occurs at this stage".

> > Now I have (eval-when (:load-toplevel :execute) ...)
> > wrapped around the bodies of all the macros that use the
> > helper function, so none of the code is expanded until
> > it's loaded into memory.  It seems to work.

> This seems a bit odd.

So I discovered.  Apparently "noobish hack" was the right answer.

> More typical is that if you have macros which use helper functions as
> part of the expander, you would need to wrap the definition of the
> helper functions in the EVAL-WHEN.

I've seen that elsewhere, but it hasn't been a problem in this case.
It seems to occur when the macro is called in the same file it's
defined in, and that wasn't happening here.  One of the helper
functions was *raising* the error from a call in another file.

> > Leaving macros unexpanded means the fasl file is smaller,
> > right?

> But that also removes most of the point of using macros.
> You want them to expand into the code at compile time so that
> the resulting code ends up being compiled.

Right.  I was just trying to avoid the problem with saving a
function object by not calling the macro that creates the object
in the first place.  See below.

> I recall one colleague (Bill Long) who was a master of macrology.
> For most of the rest of us, the fasl files were slightly smaller
> in size than the source files they came from.  In his code, the
> fasl files were typically three times a big....

That should be every Lisper's goal in life.

> > What happens to defuns in compile-file?

> They get compiled into functions?  I'm not sure exactly what you are
> trying to find out with this question.  The compiler puts a compiled
> (generally binary) version of the function code into the file

sbcl complained that I was trying to make it store a function
*object*
in the fasl file.  I had a macro that creates functions, and defun
defines functions, so I was trying to figure out what the difference
was.

My initial reaction was to *suppress* creation of the lambda so sbcl
couldn't save it, and would save the lambda-creation code instead.
But now that I'm *forcing* its creation, things seem to be working.
The code returned by the definer macro is wrapped in an "eval-always"
form, so I guess it creates the function object, the other macros
use it through the helper function, and the compiler doesn't
need it anymore, so it doesn't complain about having to store it.
Unfortunately, I couldn't figure that out from the error message.

Thanks for the help.

--Dan

------------------------------------------------
Dan Bensen
http://www.prairienet.org/~dsb/
From: Pascal Bourguignon
Subject: Re: Objects of type FUNCTION can't be dumped into fasl files.
Date: 
Message-ID: <87wsmlsrgs.fsf@hubble.informatimago.com>
danb <·········@gmail.com> writes:

> On Apr 20, 12:21 pm, danb <·········@gmail.com> wrote:
>> When the main pattern-processing function encounters a
>> pattern it doesn't recognize, it'll look for a custom
>> pattern processor defined by this helper-defining macro.
>
> Oh, DUH!  The definer macro wasn't creating the lambda
> in compile-file, but other macros were trying to use it.
>
> Now I have (eval-when (:load-toplevel :execute) ...)
> wrapped around the bodies of all the macros that use the
> helper function, so none of the code is expanded until
> it's loaded into memory.  It seems to work.
>
> Is that a sane thing to do, or a noobish hack?
> Leaving macros unexpanded means the fasl file is smaller,
> right?  What happens to defuns in compile-file?

It's implementation dependent, so ask your implementation:

(macroexpand '(defun f (x) (* x 2)))
-->
(LET NIL
 (SYSTEM::REMOVE-OLD-DEFINITIONS #1='F)
 (SYSTEM::EVAL-WHEN-COMPILE 
   (SYSTEM::C-DEFUN 'F (SYSTEM::LAMBDA-LIST-TO-SIGNATURE '#2=(X))))
 (SYSTEM::%PUTD #1# (FUNCTION F (LAMBDA #2# (DECLARE (SYSTEM::IN-DEFUN F)) (BLOCK F . #3=((* X 2))))))
 (EVAL-WHEN (EVAL)
  (SYSTEM::%PUT #1# 'SYSTEM::DEFINITION (CONS '(DEFUN F #2# . #3#) (EXT:THE-ENVIRONMENT))))
 'F)

this is what gets compiled and written into the fasl file. (but the
eval-when-compile of course).   

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

PLEASE NOTE: Some quantum physics theories suggest that when the
consumer is not directly observing this product, it may cease to
exist or will exist only in a vague and undetermined state.