From: ·············@gmail.com
Subject: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <7f395c25-1b84-45f2-a7bf-538d4665da41@b64g2000hsa.googlegroups.com>
Hi,

I am wondering how to package the following problem:

I have two classes, one describing an RF match network and one
describing a general 2-port network.  Each class has a method Zin to
calculate the input impedance.  But, the calling is slightly
different:
(zin *match-network*)  vs (zin *two-port-network* z-load).
as one does not need an input parameter, and the other one does (that
stems from the nature of the problem: the match network has an
inherent property: its load, while the two-port network does not).

So, I am assuming that the defgeneric will contain an &optional to
handle the variable argument list.

My next question is how to package the above.  I would like each class
in its own file, and thus its own asd file.  But where to put the
defgeneric then?

Thank you,

Mirko

From: Jochen Schmidt
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <c77c481e-93fa-493e-af62-4dc5d9891d84@s8g2000prg.googlegroups.com>
On 17 Mrz., 20:58, ·············@gmail.com wrote:
> Hi,
>
> I am wondering how to package the following problem:
>
> I have two classes, one describing an RF match network and one
> describing a general 2-port network.  Each class has a method Zin to
> calculate the input impedance.  But, the calling is slightly
> different:
> (zin *match-network*)  vs (zin *two-port-network* z-load).
> as one does not need an input parameter, and the other one does (that
> stems from the nature of the problem: the match network has an
> inherent property: its load, while the two-port network does not).
>
> So, I am assuming that the defgeneric will contain an &optional to
> handle the variable argument list.
>
> My next question is how to package the above.  I would like each class
> in its own file, and thus its own asd file.  But where to put the
> defgeneric then?

A third file which defines the abstract protocol behind ZIN & Co.

--
Jochen Schmidt
CRISPYLOGICS
Julienstr. 1, 90419 Nuremberg

Fon +49 (0)911 517 999 82
Fax +49 (0)911 517 999 83

mailto:(format nil "~(····@~36r.~36r~)" 870180 1680085828711918828
16438) http://www.crispylogics.com
From: Thomas A. Russ
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <ymi8x0ggbu4.fsf@blackcat.isi.edu>
·············@gmail.com writes:

> I have two classes, one describing an RF match network and one
> describing a general 2-port network.  Each class has a method Zin to
> calculate the input impedance.  But, the calling is slightly
> different:
> (zin *match-network*)  vs (zin *two-port-network* z-load).
> as one does not need an input parameter, and the other one does (that
> stems from the nature of the problem: the match network has an
> inherent property: its load, while the two-port network does not).

How inherent is this property?  Would it be part of the definition of
the network, or would it be something supplied externally?

> So, I am assuming that the defgeneric will contain an &optional to
> handle the variable argument list.

Well, as Pascal indicates, you really have two different impedance
functions, and the second parameter is not truly optional.  If you call
ZIN on a two-port network without specifying the optional load
parameter, presumably your computation will fail.  That doesn't seem to
describe a parameter that is optional.

So, assuming that is the case, then you really do need to know which of
the two forms of ZIN you are calling.  And that makes them not really
part of the same generic function.  As the caller, you really shouldn't
have to know which method the dispatch will give you in order to
properly supply the arguments.

So, I would perhaps call them something like ZIN and ZIN-FOR-LOAD.  They
may or may not even need to be generic functions, depending on how
widely they are shared.

Of course, one further option would be if the load really is an inherent
property of the two-port network.  I mean whether it is inherent enough
a part of the given network that one would consider specifying it as
part of the network description itself.  If so, then it wouldn't need to
be an argument at all.  I suspect, however, that this is not the case.


> My next question is how to package the above.  I would like each class
> in its own file, and thus its own asd file.  But where to put the
> defgeneric then?

I would put it in a separate file, one that defines a number of such
generic functions as the interface to your larger functionality.

Actually, in practice, I generally don't bother with defgeneric at all
and just use the implicit definition that comes from defmethod, but SBCL
complains about that particular style omission.  But that has its own
minor drawbacks with respect to documentation.


-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: ·············@gmail.com
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <5a464686-1c84-48e3-9360-33d139361fb1@k13g2000hse.googlegroups.com>
On Mar 17, 7:38 pm, ····@sevak.isi.edu (Thomas A. Russ) wrote:
> ·············@gmail.com writes:
> > I have two classes, one describing an RF match network and one
> > describing a general 2-port network.  Each class has a method Zin to
> > calculate the input impedance.  But, the calling is slightly
> > different:
> > (zin *match-network*)  vs (zin *two-port-network* z-load).
> > as one does not need an input parameter, and the other one does (that
> > stems from the nature of the problem: the match network has an
> > inherent property: its load, while the two-port network does not).
>
> How inherent is this property?  Would it be part of the definition of
> the network, or would it be something supplied externally?
>
> > So, I am assuming that the defgeneric will contain an &optional to
> > handle the variable argument list.
>
> Well, as Pascal indicates, you really have two different impedance
> functions, and the second parameter is not truly optional.  If you call
> ZIN on a two-port network without specifying the optional load
> parameter, presumably your computation will fail.  That doesn't seem to
> describe a parameter that is optional.
>
> So, assuming that is the case, then you really do need to know which of
> the two forms of ZIN you are calling.  And that makes them not really
> part of the same generic function.  As the caller, you really shouldn't
> have to know which method the dispatch will give you in order to
> properly supply the arguments.
>

OK, but how would one then handle the following contrived case:

Suppose I want to draw pictures and lines on a display.  For pictures
I just apply the draw method, but for lines, I may want to specify the
line thickness (as I said, the example is contrived).

It seems that I am thus forced to specify draw-picture and draw-line
methods, instead of just draw for each of them.

The issue is not a show-stopper for me.  I was just surprised that
just providing the object class and specifying (or not) an argument is
not enough data for the compiler to figure out which method to apply.
My reading (of Successful Lisp, for example) lead me to believe that
this was allowed.

Mirko
From: Paul Donnelly
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <87prtrk7a7.fsf@plap.localdomain>
·············@gmail.com writes:

> OK, but how would one then handle the following contrived case:
>
> Suppose I want to draw pictures and lines on a display.  For pictures
> I just apply the draw method, but for lines, I may want to specify the
> line thickness (as I said, the example is contrived).
>
> It seems that I am thus forced to specify draw-picture and draw-line
> methods, instead of just draw for each of them.

Presumably your picture and line objects keep track of their own
geometry and are drawn with (draw picture) and (draw line),
respectively. There's no point in having a class if that class doesn't
store any data. I'm just sidestepping your example, of course, but I'm
having trouble understanding why it would be helpful to use a generic
function if it were necessary to call it differently depending on the
type of the object. That doesn't seem very generic to me. Consider:

(defclass picture (graphic)
  ...)

(defclass line (graphic)
  ...)

(defgeneric draw (graphic)
  (:method ((picture picture)) ...)
  (:method ((line line)) ...))

(defparameter *list-of-graphics* (list (make-instance 'picture)
                                       (make-instance 'line)
                                       (make-instance 'line)
                                       (make-instance 'picture)
                                        ...))

(dolist (g *list-of-graphics*)
  (draw g))

This is the kind of situation I envision calling a generic function
in. I don't know the type of the object I'm drawing (I could check at
run-time, but that's what generic functions do for me) and don't need to
worry about it.

> The issue is not a show-stopper for me.  I was just surprised that
> just providing the object class and specifying (or not) an argument is
> not enough data for the compiler to figure out which method to apply.

I don't think it would be a problem for the Lisp system. I think the
reasoning is that it would be pointless. If you're inspecting the type
of your object and collating it with data from some other source,
there's no point in automatic dispatch based on type... you've already
done what the generic function would do and might as well type a few
more letters in the function name.
From: ·············@gmail.com
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <acdbf690-ad8e-4957-b75a-ffea137e694e@b1g2000hsg.googlegroups.com>
On Mar 18, 6:21 pm, Paul Donnelly <·············@sbcglobal.net> wrote:
> ·············@gmail.com writes:
> > OK, but how would one then handle the following contrived case:
>
> > Suppose I want to draw pictures and lines on a display.  For pictures
> > I just apply the draw method, but for lines, I may want to specify the
> > line thickness (as I said, the example is contrived).
>
> > It seems that I am thus forced to specify draw-picture and draw-line
> > methods, instead of just draw for each of them.
>
> Presumably your picture and line objects keep track of their own
> geometry and are drawn with (draw picture) and (draw line),
> respectively. There's no point in having a class if that class doesn't
> store any data. I'm just sidestepping your example, of course, but I'm
> having trouble understanding why it would be helpful to use a generic
> function if it were necessary to call it differently depending on the
> type of the object. That doesn't seem very generic to me. Consider:
>
> (defclass picture (graphic)
>   ...)
>
> (defclass line (graphic)
>   ...)
>
> (defgeneric draw (graphic)
>   (:method ((picture picture)) ...)
>   (:method ((line line)) ...))
>
> (defparameter *list-of-graphics* (list (make-instance 'picture)
>                                        (make-instance 'line)
>                                        (make-instance 'line)
>                                        (make-instance 'picture)
>                                         ...))
>
> (dolist (g *list-of-graphics*)
>   (draw g))
>
> This is the kind of situation I envision calling a generic function
> in. I don't know the type of the object I'm drawing (I could check at
> run-time, but that's what generic functions do for me) and don't need to
> worry about it.
>
> > The issue is not a show-stopper for me.  I was just surprised that
> > just providing the object class and specifying (or not) an argument is
> > not enough data for the compiler to figure out which method to apply.
>
> I don't think it would be a problem for the Lisp system. I think the
> reasoning is that it would be pointless. If you're inspecting the type
> of your object and collating it with data from some other source,
> there's no point in automatic dispatch based on type... you've already
> done what the generic function would do and might as well type a few
> more letters in the function name.

Maybe I should look at it the following way:  separate content from
presentation.  Thus, the line would be defined by its coordinates, the
picture by its RGB (or HSV) pixel values.  The presentation would be
*defined* by thickness, colour, linestyle and color-map respectively.
Then a simple, unified draw method would suffice.

Mirko
From: Pascal J. Bourguignon
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <7cskynnm0m.fsf@pbourguignon.anevia.com>
·············@gmail.com writes:

> On Mar 17, 7:38 pm, ····@sevak.isi.edu (Thomas A. Russ) wrote:
>> ·············@gmail.com writes:
>> > I have two classes, one describing an RF match network and one
>> > describing a general 2-port network.  Each class has a method Zin to
>> > calculate the input impedance.  But, the calling is slightly
>> > different:
>> > (zin *match-network*)  vs (zin *two-port-network* z-load).
>> > as one does not need an input parameter, and the other one does (that
>> > stems from the nature of the problem: the match network has an
>> > inherent property: its load, while the two-port network does not).
>>
>> How inherent is this property?  Would it be part of the definition of
>> the network, or would it be something supplied externally?
>>
>> > So, I am assuming that the defgeneric will contain an &optional to
>> > handle the variable argument list.
>>
>> Well, as Pascal indicates, you really have two different impedance
>> functions, and the second parameter is not truly optional.  If you call
>> ZIN on a two-port network without specifying the optional load
>> parameter, presumably your computation will fail.  That doesn't seem to
>> describe a parameter that is optional.
>>
>> So, assuming that is the case, then you really do need to know which of
>> the two forms of ZIN you are calling.  And that makes them not really
>> part of the same generic function.  As the caller, you really shouldn't
>> have to know which method the dispatch will give you in order to
>> properly supply the arguments.
>>
>
> OK, but how would one then handle the following contrived case:
>
> Suppose I want to draw pictures and lines on a display.  For pictures
> I just apply the draw method, but for lines, I may want to specify the
> line thickness (as I said, the example is contrived).

See the second option of my first answer in this thread.
http://groups.google.com/group/comp.lang.lisp/msg/68b8c21f039d6dfb?dmode=source

> It seems that I am thus forced to specify draw-picture and draw-line
> methods, instead of just draw for each of them.

No, you can encapsulate your lines in a thicky-line object.



> The issue is not a show-stopper for me.  I was just surprised that
> just providing the object class and specifying (or not) an argument is
> not enough data for the compiler to figure out which method to apply.
> My reading (of Successful Lisp, for example) lead me to believe that
> this was allowed.

And nothing prevents you to define your generic function with optional or rest arguments:

(defgeneric zin (network &rest other-args))

(defmethod zin ((self two-port-network) &rest other-args)
  (destructuring-bind (zload) other-args
    (two-port-network-formula self zload)))

(defmethod zin ((self match-network) &rest other-args)
  (destructuring-bind () other-args
    (match-network-formula self)))



-- 
__Pascal Bourguignon__
From: Paul Donnelly
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <87tzj4k9to.fsf@plap.localdomain>
·············@gmail.com writes:

> My next question is how to package the above.  I would like each class
> in its own file, and thus its own asd file.

Maybe I'm reading you wrong, but are you sure you understand how ASDF
works? Classes normally go in files with an extension like ".lisp", and
you only need one .asd file to specify which .lisp files make up the
system. For that matter, Lispers don't usually put each class in its own
file (that's more of a Java thing).
From: ·············@gmail.com
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <7c32e154-b127-4cc1-8ca9-b1734f58dc5d@u69g2000hse.googlegroups.com>
On Mar 17, 11:08 pm, Paul Donnelly <·············@sbcglobal.net>
wrote:
> ·············@gmail.com writes:
> > My next question is how to package the above.  I would like each class
> > in its own file, and thus its own asd file.
>
> Maybe I'm reading you wrong, but are you sure you understand how ASDF
> works? Classes normally go in files with an extension like ".lisp", and
> you only need one .asd file to specify which .lisp files make up the
> system.


The reason I went with asd files (and I could be wrong) is that each
class has its   dependency tree.  Now, I could include that dependency
tree in the utility asd file (utility being the package/file that uses
the defined classes).  But that would expose the class' implementation
to the outside world.  In a nutshell, I was trying to hide the class
implementation (package dependencies) by defining its asd file.

> For that matter, Lispers don't usually put each class in its own
> file (that's more of a Java thing).

Hmm, I like a class/file because of file simplicity.  But I am a new
lisper, and I could be missing something.

Thanks,

Mirko
From: Pascal Costanza
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <649v5gF2a9ovpU1@mid.individual.net>
·············@gmail.com wrote:
> On Mar 17, 11:08 pm, Paul Donnelly <·············@sbcglobal.net>
> wrote:
>> ·············@gmail.com writes:
>>> My next question is how to package the above.  I would like each class
>>> in its own file, and thus its own asd file.
>> Maybe I'm reading you wrong, but are you sure you understand how ASDF
>> works? Classes normally go in files with an extension like ".lisp", and
>> you only need one .asd file to specify which .lisp files make up the
>> system.
> 
> 
> The reason I went with asd files (and I could be wrong) is that each
> class has its   dependency tree.  Now, I could include that dependency
> tree in the utility asd file (utility being the package/file that uses
> the defined classes).  But that would expose the class' implementation
> to the outside world.  In a nutshell, I was trying to hide the class
> implementation (package dependencies) by defining its asd file.
> 
>> For that matter, Lispers don't usually put each class in its own
>> file (that's more of a Java thing).
> 
> Hmm, I like a class/file because of file simplicity.  But I am a new
> lisper, and I could be missing something.

Yes, what you're missing is that source code in Common Lisp is typically 
a lot more compact than in Java, so it's not "economic" to have a 
different file per class. Each file would contain only about 20-30 
lines, or so (just a gut estimate, not rooted in any statistics). That 
doesn't make a lot of sense.

Furthermore, since there is no tight association between methods and 
classes, and sometimes it's not even clear to which class a method 
belongs, the organization of files along classes can even lead to 
unnecessary, imaginary design "conflicts."

A rule of thumb is that each file should be a "logical" unit, depending 
on what a logical unit is for a given library or application. Such 
logical units shouldn't be too fine-grained. It's not unusual that what 
is contained in a package in Java and is typically spread over several 
class files is just one source file or two in Common Lisp.


Pascal

-- 
1st European Lisp Symposium (ELS'08)
http://prog.vub.ac.be/~pcostanza/els08/

My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: John Thingstad
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <op.t77s2lzwut4oq5@pandora.alfanett.no>
P� Tue, 18 Mar 2008 14:32:22 +0100, skrev <·············@gmail.com>:

>
> Hmm, I like a class/file because of file simplicity.  But I am a new
> lisper, and I could be missing something.
>

In my experience many classes collaborate to create a interface. Then  
separating them in separate files conceals this and just makes it more  
awkward to grasp dependencies and maintain it.

--------------
John Thingstad
From: ·············@gmail.com
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <84a63d76-02e4-404a-a909-891866474bd3@m34g2000hsc.googlegroups.com>
On Mar 18, 9:57 am, "John Thingstad" <·······@online.no> wrote:
> På Tue, 18 Mar 2008 14:32:22 +0100, skrev <·············@gmail.com>:
>
>
>
> > Hmm, I like a class/file because of file simplicity.  But I am a new
> > lisper, and I could be missing something.
>
> In my experience many classes collaborate to create a interface. Then
> separating them in separate files conceals this and just makes it more
> awkward to grasp dependencies and maintain it.
>
> --------------
> John Thingstad

I think that applies when one is working in terms of patterns.  In my
case, these are meant to be fairly independent utilities.  Time (&
experience) will tell.

Mirko
From: Pascal Costanza
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <6485q1F2aoamvU1@mid.individual.net>
·············@gmail.com wrote:
> Hi,
> 
> I am wondering how to package the following problem:
> 
> I have two classes, one describing an RF match network and one
> describing a general 2-port network.  Each class has a method Zin to
> calculate the input impedance.  But, the calling is slightly
> different:
> (zin *match-network*)  vs (zin *two-port-network* z-load).
> as one does not need an input parameter, and the other one does (that
> stems from the nature of the problem: the match network has an
> inherent property: its load, while the two-port network does not).
> 
> So, I am assuming that the defgeneric will contain an &optional to
> handle the variable argument list.
> 
> My next question is how to package the above.  I would like each class
> in its own file, and thus its own asd file.  But where to put the
> defgeneric then?

Do you really need a generic function here? The two call sites are 
obviously syntactically different, in that invocations of the function 
for one class _always_ has an argument more than invocations for the 
other class. So you always have to be aware which kinds of objects you 
are talking to. This means that you might as well use two different 
functions with different names, because you don't get any benefit from 
the genericity provided by generic functions...


Pascal

-- 
1st European Lisp Symposium (ELS'08)
http://prog.vub.ac.be/~pcostanza/els08/

My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Pascal Bourguignon
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <87prtsvpyy.fsf@thalassa.informatimago.com>
·············@gmail.com writes:
> I am wondering how to package the following problem:
>
> I have two classes, one describing an RF match network and one
> describing a general 2-port network.  Each class has a method Zin to
> calculate the input impedance.  But, the calling is slightly
> different:
> (zin *match-network*)  vs (zin *two-port-network* z-load).
> as one does not need an input parameter, and the other one does (that
> stems from the nature of the problem: the match network has an
> inherent property: its load, while the two-port network does not).

Well, even if the z-load is not an inherent property of the
two-port-network, you could still add it as an attribute to that
object.

(defgeneric zin (network))

(defclass network ()
   (...)
   (:documentation "An abstract network"))

(defclass match-network (network)
   (...))

(defmethod zin ((network two-port-network))
   (match-network-zin-formula  (inherent-property network)))


(defclass two-port-network (network)
   ((z-load :accessor z-load :initarg :z-load)
     ...))

(defmethod zin ((network two-port-network))
   (two-port-network-zin-formula (z-load network)   
                                 (other-inherent-property network)))



Another way would be to encapsulate the two-port-network into a
zinable-two-port-network:

(defclass zinable-two-port-network ()
  ((two-port-network :initarg :two-port-network :accessor two-port-network)
   (z-load :initarg :z-load :accessor z-load)))

(defmethod zin ((znetwork zinable-two-port-network))
  (two-port-network-zin-formula
       (z-load znetwork)   
       (other-inherent-property (two-port-network znetwork))))

so you can keep the rest of the system pure, with z-load-less
two-port-networks, and the part that computes zins may deal only with
zinable objects.  You wouldn't define a zin method directly on
two-port-network.



> So, I am assuming that the defgeneric will contain an &optional to
> handle the variable argument list.
>
> My next question is how to package the above.  I would like each class
> in its own file, and thus its own asd file.  But where to put the
> defgeneric then?

I'd have a common superclass: there are probably common properties.
You can define generic functions there, and perhaps even give 
default methods.


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

"Logiciels libres : nourris au code source sans farine animale."
From: ·············@gmail.com
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <5a88e4dd-e870-4043-8bbb-e1a10b17ee6d@d62g2000hsf.googlegroups.com>
On Mar 17, 3:58 pm, ·············@gmail.com wrote:
> Hi,
>
> I am wondering how to package the following problem:
>
> I have two classes, one describing an RF match network and one
> describing a general 2-port network.  Each class has a method Zin to
> calculate the input impedance.  But, the calling is slightly
> different:
> (zin *match-network*)  vs (zin *two-port-network* z-load).
> as one does not need an input parameter, and the other one does (that
> stems from the nature of the problem: the match network has an
> inherent property: its load, while the two-port network does not).
>
> So, I am assuming that the defgeneric will contain an &optional to
> handle the variable argument list.
>
> My next question is how to package the above.  I would like each class
> in its own file, and thus its own asd file.  But where to put the
> defgeneric then?
>
> Thank you,
>
> Mirko

Thank you to all that replied.

I think I will settle (for now) on just making a superclass with a Zl,
assign it, and calculate Zin with a uniform interface.

OTOH, I think what I was hoping for was something like Fortran
95/2003's INTERFACE block:

In fortran, one writes codes in modules, each consisting of its own
data, and associated subroutines and functions.  Now, one cannot
compile and link two modules with that will result in a naming
conflict, even though, in principle the two subroutine calls can be
differentiated by their argument types.

But, what one can do, is to define a procedure INTERFACE block in each
module.  In this block, one defines procedure the name, as visible
from the outside world.  So, in fortran, the code structure would be
as follows:

module two_port_network

type two_port_network
 ... variable declarations
end type

interface zin ;; *** watch this
   module procedure two_port_network_zin
end interface

contains
   suboutine two_port_network_zin
...
end module

and similarly for the match_network.  Now, I can use
zin(two_port_network, zl) and zin(match_network).

In other words, in each module I use the long, specific names, but
then via the interface block, I simplify them to a generic name, and
the compiler figures it all out in the end.

I am guessing that I could implement this via a superclass and
a :before (or :after, or :around, or :confused, or :lost).

I'll let the above ferment, and then taste it.

Mirko
From: Pascal J. Bourguignon
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <7c8x0goxkd.fsf@pbourguignon.anevia.com>
·············@gmail.com writes:
> [...]
> But, what one can do, is to define a procedure INTERFACE block in each
> module.  In this block, one defines procedure the name, as visible
> from the outside world.  So, in fortran, the code structure would be
> as follows:
>
> module two_port_network
>
> type two_port_network
>  ... variable declarations
> end type
>
> interface zin ;; *** watch this
>    module procedure two_port_network_zin
> end interface
>
> contains
>    suboutine two_port_network_zin
> ...
> end module
>
> and similarly for the match_network.  Now, I can use
> zin(two_port_network, zl) and zin(match_network).
>
> In other words, in each module I use the long, specific names, but
> then via the interface block, I simplify them to a generic name, and
> the compiler figures it all out in the end.
>
> I am guessing that I could implement this via a superclass and
> a :before (or :after, or :around, or :confused, or :lost).
>
> I'll let the above ferment, and then taste it.

You can implement this via a simple generic function.

(defmacro define-interface (name class function) 
  `(defmethod ,name ((self ,class) &rest args)
        (apply (function ,function) self args)))

(define-interface zin two-port-network two-port-network-zin)
(define-interface zin match-network    match-network-zin)

(zin (make-instance 'match-network) z-load)
(zin (make-instance two-port-network))

That is, if all you want is the syntactic suggar that provides.

-- 
__Pascal Bourguignon__
From: ·············@gmail.com
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <3603e39f-2f5c-41a5-b176-e5aa73ba0ce0@d62g2000hsf.googlegroups.com>
On Mar 18, 11:34 am, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> ·············@gmail.com writes:
> > [...]
> > But, what one can do, is to define a procedure INTERFACE block in each
> > module.  In this block, one defines procedure the name, as visible
> > from the outside world.  So, in fortran, the code structure would be
> > as follows:
>
> > module two_port_network
>
> > type two_port_network
> >  ... variable declarations
> > end type
>
> > interface zin ;; *** watch this
> >    module procedure two_port_network_zin
> > end interface
>
> > contains
> >    suboutine two_port_network_zin
> > ...
> > end module
>
> > and similarly for the match_network.  Now, I can use
> > zin(two_port_network, zl) and zin(match_network).
>
> > In other words, in each module I use the long, specific names, but
> > then via the interface block, I simplify them to a generic name, and
> > the compiler figures it all out in the end.
>
> > I am guessing that I could implement this via a superclass and
> > a :before (or :after, or :around, or :confused, or :lost).
>
> > I'll let the above ferment, and then taste it.
>
> You can implement this via a simple generic function.
>
> (defmacro define-interface (name class function)
>   `(defmethod ,name ((self ,class) &rest args)
>         (apply (function ,function) self args)))
>
> (define-interface zin two-port-network two-port-network-zin)
> (define-interface zin match-network    match-network-zin)
>
> (zin (make-instance 'match-network) z-load)
> (zin (make-instance two-port-network))
>
> That is, if all you want is the syntactic suggar that provides.
>
> --
> __Pascal Bourguignon__

I think this is very close to what I am looking at.

As to the source of my confusion/question, see my response to Pascal
Constanza and Thomas.

Thanks,

Mirko
From: Thomas A. Russ
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <ymi4pb3fp66.fsf@blackcat.isi.edu>
···@informatimago.com (Pascal J. Bourguignon) writes:

> You can implement this via a simple generic function.
> 
> (defmacro define-interface (name class function) 
>   `(defmethod ,name ((self ,class) &rest args)
>         (apply (function ,function) self args)))
> 
> (define-interface zin two-port-network two-port-network-zin)
> (define-interface zin match-network    match-network-zin)
> 
> (zin (make-instance 'match-network) z-load)
> (zin (make-instance two-port-network))
> 
> That is, if all you want is the syntactic suggar that provides.

Unfortunately, and as I am sure Pascal realizes, the main problem that
you have with such an interface is that you are then forced to,
essentially, undo some of the method dispatch logic if you ever want to
write something like:

(defun print-impedance (network)
  (format t "Impedance of ~A is ~F~%" network (zin network)))

Instead you either have to do the ugly

(defun print-impedance (network &optional load)
  (format t "Impedance of ~A is ~F~%"
          network
          (typecase network
             (match-network (zin network))
             (two-port-network (zin network load)))))


But we can instead solve this perhaps more elegantly by making
PRINT-IMPEDANCE also a generic function and then add methods for that:

(defmethod print-impedance ((network match-network))
  (format t "Impedance of ~A is ~F~%" network (zin network)))

(defmethod print-impedance ((network two-port-network) &optional load)
  (format t "Impedance of ~A is ~F~%" network (zin network load)))

But now we are in the position of having to propagate the difference up
through every function or method that wants to use ZIN.  So, in effect,
you really do have two different methods for computing ZIN, depending on
the type, and everyone who wants to use the different type needs to be
aware of that difference.

So what is the benefit of using the same name?  It just means that the
difference, instead of being explicitly identified by the name of the
generic function, is instead implicitly hidden in the special
combination of optional arguments that need to be specified.  So this
seems to actually fly contrary to the spirit of generic functions by
making the arguments NOT interchangeable and forcing the caller to know
which particular method will be chosen by the generic function in order
to get the arguments right.  We are now purposefully exposing some of
the internal dispatch logic and requiring the caller to KNOW which
particular method will be called, but without giving the caller any
syntactic knowledge with which to make this decision.

If the implementation of the methods changes by the addition of other
types with ZIN, but still different arguments, then every caller needs
to be modified to account for the change.




-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: ·············@gmail.com
Subject: Re: Where to file one defgeneric for two classes and two packages
Date: 
Message-ID: <929326ee-a674-4638-8f65-e84357012d91@m36g2000hse.googlegroups.com>
On Mar 18, 10:00 pm, ····@sevak.isi.edu (Thomas A. Russ) wrote:
> ····@informatimago.com (Pascal J. Bourguignon) writes:
>
> > You can implement this via a simple generic function.
>
> > (defmacro define-interface (name class function)
> >   `(defmethod ,name ((self ,class) &rest args)
> >         (apply (function ,function) self args)))
>
> > (define-interface zin two-port-network two-port-network-zin)
> > (define-interface zin match-network    match-network-zin)
>
> > (zin (make-instance 'match-network) z-load)
> > (zin (make-instance two-port-network))
>
> > That is, if all you want is the syntactic suggar that provides.
>
> Unfortunately, and as I am sure Pascal realizes, the main problem that
> you have with such an interface is that you are then forced to,
> essentially, undo some of the method dispatch logic if you ever want to
> write something like:
>
> (defun print-impedance (network)
>   (format t "Impedance of ~A is ~F~%" network (zin network)))
>
> Instead you either have to do the ugly
>
> (defun print-impedance (network &optional load)
>   (format t "Impedance of ~A is ~F~%"
>           network
>           (typecase network
>              (match-network (zin network))
>              (two-port-network (zin network load)))))
>
> But we can instead solve this perhaps more elegantly by making
> PRINT-IMPEDANCE also a generic function and then add methods for that:
>
> (defmethod print-impedance ((network match-network))
>   (format t "Impedance of ~A is ~F~%" network (zin network)))
>
> (defmethod print-impedance ((network two-port-network) &optional load)
>   (format t "Impedance of ~A is ~F~%" network (zin network load)))
>
> But now we are in the position of having to propagate the difference up
> through every function or method that wants to use ZIN.  So, in effect,
> you really do have two different methods for computing ZIN, depending on
> the type, and everyone who wants to use the different type needs to be
> aware of that difference.
>
> So what is the benefit of using the same name?  It just means that the
> difference, instead of being explicitly identified by the name of the
> generic function, is instead implicitly hidden in the special
> combination of optional arguments that need to be specified.  So this
> seems to actually fly contrary to the spirit of generic functions by
> making the arguments NOT interchangeable and forcing the caller to know
> which particular method will be chosen by the generic function in order
> to get the arguments right.  We are now purposefully exposing some of
> the internal dispatch logic and requiring the caller to KNOW which
> particular method will be called, but without giving the caller any
> syntactic knowledge with which to make this decision.
>
> If the implementation of the methods changes by the addition of other
> types with ZIN, but still different arguments, then every caller needs
> to be modified to account for the change.
>
> --
> Thomas A. Russ,  USC/Information Sciences Institute

I see.  I think that I should define a circuit from the network by
terminating it with a load (that sort of makes sense.  A network by
itself is just an intellectual construct.  One has to connect it to an
external circuit in order for it to be useful).  Then, a simple ZIN
makes sense.

Thanks,

Mirko