From: Peter Keller on
Hello,

I've run into a hard symbol resolution problem concerning packages and I would
request some help in solving it.

Let me describe the situation.

I have two packages: X and Y.

Y uses X and X exports a subset of its symbols.

X exports a macro Z which Y uses to create a function sZ in Y. sZ uses symbols
out of Y and X.

A function in X is passed the symbol name (only) of sZ, and it needs to invoke
it.

How?

When the codes in X and Y are in the same package, I know how to do this, it is
when they are different that I do not.

Thank you.

-pete
From: Scott L. Burson on
On Jun 27, 1:09 pm, Peter Keller <psil...(a)cs.wisc.edu> wrote:
> Hello,
>
> I've run into a hard symbol resolution problem concerning packages and I would
> request some help in solving it.
>
> Let me describe the situation.
>
> I have two packages: X and Y.
>
> Y uses X and X exports a subset of its symbols.
>
> X exports a macro Z which Y uses to create a function sZ in Y. sZ uses symbols
> out of Y and X.
>
> A function in X is passed the symbol name (only) of sZ, and it needs to invoke
> it.
>
> How?

Why is it that, at the point where you need to invoke the function,
you have only its symbol-name?

If the answer is that you have implemented some kind of interpreter in
Lisp -- which is really the only good answer -- then the interpreter
needs to have a notion of what package to intern symbols in. Then, at
the point of invocation, you have the symbol rather than just its
name.

Passing around strings which are names of functions to be called is
not generally good practice, for reasons I think you have already
realized.

-- Scott
From: Pascal J. Bourguignon on
Peter Keller <psilord(a)cs.wisc.edu> writes:
> I've run into a hard symbol resolution problem concerning packages and I would
> request some help in solving it.
>
> Let me describe the situation.
>
> I have two packages: X and Y.
>
> Y uses X and X exports a subset of its symbols.
>
> X exports a macro Z which Y uses to create a function sZ in Y. sZ uses symbols
> out of Y and X.

Wrong! A package doesn't export macros. A package exports symbols!


> A function in X is passed the symbol name (only) of sZ, and it needs to invoke
> it.
>
> How?
>
> When the codes in X and Y are in the same package, I know how to do this, it is
> when they are different that I do not.

Packages are totally irrelevant.

Packages are used only at READ-TIME.

Anything that occurs at RUN-TIME, such as calling a function and
passing it a symbol has nothing to do with packages.

http://www.flownet.com/gat/packages.pdf


Otherwise, the age old advise that you should have listened to, is to
define packages in a separate source file. But in your case, it would
even not help, since you don't even have any problem.


(in-package "CL-USER")

(defpackage "X"
(:use "CL")
(:export "Z")) ; see, no macro here, just a symbol name!

(defpackage "Y"
(:use "CL" "X"))

(in-package "X")

(defmacro z (&body b)
`(progn
(princ "Z says: ")
,@b
(terpri)))

(defun f (g)
(funcall g "got it?"))

(in-package "Y")

(defun sz (x)
(z
(princ x)))


(x::f 'sz)
prints:
Z says: got it?


Notice that you didn't give us any reason why to use macro and a
function name. Check it. Perhaps you only need a function and a
closure.


--
__Pascal Bourguignon__ http://www.informatimago.com/
From: Peter Keller on
Scott L. Burson <gyro(a)zeta-soft.com> wrote:
> On Jun 27, 1:09?pm, Peter Keller <psil...(a)cs.wisc.edu> wrote:
>> Hello,
>>
>> I've run into a hard symbol resolution problem concerning packages and I would
>> request some help in solving it.
>>
>> Let me describe the situation.
>>
>> I have two packages: X and Y.
>>
>> Y uses X and X exports a subset of its symbols.
>>
>> X exports a macro Z which Y uses to create a function sZ in Y. sZ uses symbols
>> out of Y and X.
>>
>> A function in X is passed the symbol name (only) of sZ, and it needs to invoke
>> it.
>>
>> How?

> Why is it that, at the point where you need to invoke the function,
> you have only its symbol-name?
>
> If the answer is that you have implemented some kind of interpreter in
> Lisp -- which is really the only good answer -- then the interpreter
> needs to have a notion of what package to intern symbols in. Then, at
> the point of invocation, you have the symbol rather than just its
> name.

In my case, I've implemented a master/worker paradigm with distributed
processes. The master process packs up the worker's task data along with the
symbol associated with the function on the worker side and sends it to the
worker process in an RPC-like model. I use cl-serializer, so I actually do send
the target function's symbol to the client side, which arrives uninterned--it
could just have easily been the string of the function's name though.

The worker process now has to resolve the symbol into the function and apply
it. It is the internals of the master/worker system which performs the actual
invocation of the function associated with the symbol. The master process and
the worker process are the same executable (using SBCL, made with
save-lisp-and-die) with different code flow depending upon argv and so they
have the same idea of their symbols and functions concerning symbol-function.

My problem lies in that the master/worker library is package X, and the
application built on it is package Y. When Y creates the RPC call sender and
receiver (in Y's package namespace) using the appropriate macro from X, how
does X's internals invoke it?

I suppose I could bind the value of *package* into the task structure from the
master to the worker, and the worker could use that while interning the symbol
same and using symbol-function on it, but I went down that road for a bit and
couldn't get it working. Should I try again?

> Passing around strings which are names of functions to be called is
> not generally good practice, for reasons I think you have already
> realized.

In C, I would just associate a function pointer with the string in a hash table
and use that since there is no notion of namespaces (and don't forget the
master and worker are the exact same executable). In Lisp (to which I'm new),
it is confounded somewhat, so I'd like to know how to solve it.

I agree with you it isn't good practice in a normal environment, but
ultimately, my process space is basically distributed across machines. I don't
have a choice of which I am aware.

I could force the application to be written into the same package as the
master/worker library, but that s bad from my point of view. I'd like to keep
them separate.

Thank you.

-pete


From: Peter Keller on
Pascal J. Bourguignon <pjb(a)informatimago.com> wrote:
> Peter Keller <psilord(a)cs.wisc.edu> writes:
>> I've run into a hard symbol resolution problem concerning packages and I would
>> request some help in solving it.
>>
>> Let me describe the situation.
>>
>> I have two packages: X and Y.
>>
>> Y uses X and X exports a subset of its symbols.
>>
>> X exports a macro Z which Y uses to create a function sZ in Y. sZ uses symbols
>> out of Y and X.
>
> Wrong! A package doesn't export macros. A package exports symbols!

This is something I realize, but don't fully understand the consequences of
yet.

> http://www.flownet.com/gat/packages.pdf

Yeah, I found this just a bit ago and am carefully trying to understand it.

> Otherwise, the age old advise that you should have listened to, is to
> define packages in a separate source file.

I infact did do the above. And no, it didn't help.

> (in-package "CL-USER")
>
> (defpackage "X"
> (:use "CL")
> (:export "Z")) ; see, no macro here, just a symbol name!
>
> (defpackage "Y"
> (:use "CL" "X"))
>
> (in-package "X")
>
> (defmacro z (&body b)
> `(progn
> (princ "Z says: ")
> ,@b
> (terpri)))
>
> (defun f (g)
> (funcall g "got it?"))
>
> (in-package "Y")
>
> (defun sz (x)
> (z
> (princ x)))
>
>
> (x::f 'sz)
> prints:
> Z says: got it?
>
>
> Notice that you didn't give us any reason why to use macro and a
> function name. Check it. Perhaps you only need a function and a
> closure.

I gave a better explanation of my situation in another post in this thread.

-pete