On May 16, 8:15 pm, Paul Donnelly <
[email protected]> wrote:
[snip]
The fact that defmethod is a macro does not mean it remotely
modifies any code.
In and of itself, you are correct: it does not. However, I did not
base my remarks solely upon its being a macro. I also used your own
statement that it could be used to add more dispatches to the dispatch
table from anonymous.c.lisper. Taken together, those statements imply
that this particular macro can and does modify code.
So either it can, or you are incorrect about it adding more
dispatches, or you are incorrect about it being a macro.
The answer is, it doesn't modify any existing code.
The code at issue is:
This is quite clearly tabular data and anonymous.c.lisper himself
stated that it controls the dispatch of frobnobdicate method calls.
These observations, taken together, suffice to imply that it is a
dispatch table.
It's not tabular data -- it's a bunch of forms that have parallel
structure, and seem tabular because you're looking at nicely indented
code rather than this:
(defgeneric frobnobdicate(a b)

method((foo foo)(bar bar)).body)

method((foo foo)(baz baz)).body)

method((foo foo)(quux
quux)).body))
The resemlance to a table is only to illustrate to a human reader the
behaviour of the dispatch table generated by that code.
If you did that, then where would the macro put the dispatches?
In the running Lisp image. Lisp programs aren't just executed one
statement at a time -- there's an "image" of all the symbols, classes,
functions, closures, methods, etc that are in use at the time. This
(along with consing) does tend to slow down a lot of Lisp code, but
there are techniques for writing efficient code despite this (well-
optimized Lisp runs at a comparable speed to C).
If this were true, then the defmethod macro could not function in the
manner claimed. The macro can only replace source code with other
source code at compile time. For it to modify a dispatch table,
therefore, that dispatch table must be located in the source code. Its
only alternative is to generate run-time instructions to allocate and
construct dispatch tables, which has two consequences:
Again, it's not in the source code -- it's in the Lisp image. Lisp
source just includes macros, which modify the Lisp image to update (or
generate, if you're creating a new generic fn) the dispatch tables /in
the Lisp image/.
1. How are many uses of the same macro with the same method name
throughout the code base to coordinate? They must create and use a
single dispatch table, not one each, for that sort of scheme to
work.
They don't have to coordinate, because the generated code deals with
the dispatch table.
2. The dispatch tables are then being "faked" using ordinary
user-accessible run-time data structures, rather than being true
dispatch tables analogous to Java's or C++'s, which the compiler
and runtime generate and use and which are not user-accessible,
except, in C++, via unwise pointer manipulation. In particular,
the Lisp dispatch tables would not be "state maintained in the
system's internals, just like in Java, C++ etc."
Well, they are "state maintained in the system's internals". It's just
state that can be generated by code, the same way that code in Java or
C++ generates some state in the system's internals.
This implies that it will quietly do what is unlikely to be what the
programmers intended, without generating any overt warning or error
message. This is commonly called "failing silently". Instead of a
prompt diagnostic, the result is a logic error in the program, and a
greater amount of effort needed subsequently to debug this error.
The compiler will give a warning. Although LITERALLY it's silent,
there is quite the visual cue when little red underlines start
appearing in your code, and the compiler says that there are warnings.
Also the compiler will tell you precisely where the errors were
encountered, so you can find them quite easily.
That contradicts the previous, quoted statement about it "just"
overwriting a method.
OK, that's reading too much meaning into what I said. I meant "just
override ..." in the sense that it would generate valid code rather
than failing to compile at all.
I've actually been corrected about that. However, it would still apply
only to the currently running Lisp image. So if, for example, you were
using a library, and a DEFMETHOD form in your code extended the
library, somebody else working in a project with you could still use
the same library code, from the same file, as you and the DEFMETHOD
form in /your/ code would not affect them.
If that is the case, it can only be because Adlai was inaccurate in
describing packages to me.
See what I just wrote in teh previous paragraph.
This is contradicted by statements made elsewhere by yourself and
others, particularly, one claiming that a function and a class in the
same package can share the same name. If the package did not
distinguish among these, then that could not be the case.
They do share the same name. A package doesn't know the difference
between them. However, when EVAL hits a name, it knows the difference /
in context/ between a variable, function call, etc. The package
doesn't have to know.
Since that is based on a description of Common Lisp package behavior
that Adlai posted, you should endeavor to figure out which one of you
is apparently mistaken about packages. At this time I have no basis
for choosing either of your interpretations over the other.
I was mistaken, but not in the way that you thought.
Public = exported. Private = not exported.
These ideas don't translate so cleanly between Lisp and Java, because
only symbols are "public" or "private". The code itself is still
accessible to anybody who has the symbol reference.
So whereas there is arguably a distinction to be made, in practice
it's a pointless one: "the method is private" is more or less
synonymous with "the method's name is private".
Firstly, Lisp has a lot more freedom, in the sense that "private"
stuff is not inaccessible; this does mean that you have to rely on
people not to use private things in a way that will cause them to
break. However, multimethod dispatch is done in a very safe and
predictable way, so it's not a risk to allow user-defined code do
"call-next-method" to something which could be considered "private" to
an imported package.
You're forgetting that, by your own prior testimony, the defmethod
macro in turn adds the dispatch entry. So whether you do it by hand,
or have the macro do it for you, the dispatch table must be accessible
to you.
Yes, I could get to the dispatch table. I have no clue how to do it,
although I could find out by examining the macroexpansion of
DEFGENERIC and DEFMETHOD, and then essentially writing that code by
hand. However, this is not done, unless somebody wants to create their
own object system; it would be like editing the Java compiler by hand,
yourself.
Again, macros operate by transforming source, so if this were true,
the defmethod macro could not function in the manner you have claimed.
Lisp image != source. I've gone over this already.
That is not a valid argument against my reasoning. It is, rather, a
"cop-out". It is also an arrogant presumption on your part, purporting
to be able to speak for gugamilare as you have just done.
We assume (and I think I speak for others who have posted in response
to you and Seamus) that when somebody else says something that seems
wrong, it's a "thinko", rather than a real mistake. A thinko is like a
typo, but on the scale of ideas -- it's an easily identifiable
MISTAKE, that the person who made probably didn't intend that way.
gugamilare seems, from other things he's said in this group in the
past, to be more knowledgeable in Lisp than I am. If he writes
something that could be read a bit ambiguously, I'm assuming it's
because of a) the fact that English doesn't seem to be his first
language (which is NO PROBLEM WHATSOEVER, you just have to THINK), and
b) he's assuming that the people reading his comments are familiar
with basic Common Lisp concepts.
Of course not, since the contradictions in question are contradictions
between a statement made by one of you and a statement made by another
of you. No assumption that I made could alter either statement in any
such case -- you each said whatever you said.
For instance, supposing you were to say that the sky was green, and
gugamilare that it was blue, these statements would contradict,
independently of my own personal opinion on the matter or of any
assumptions on my part.
See what I said in my previous paragraph, it applies here too. By the
way, I would assume that somebody saying that the sky was green would
also be a THINKO -- maybe they meant to type blue, or meant to talk
about grass. These things happen when people are multitasking, as we
all often have to. I would assume that the person I'm talking with has
made a thinko unless they repeat the same mistake several times, in
different phrasings, and defend it when somebody tries to correct
them.
- Adlai