You are in no position to be telling others what they should or should
not do.
Actually, you can, just nobody pointed it out yet. There's a defmethod
macro
Altering the behavior of that not-yours code via macro is hardly a
successful evasion of my point. In fact it compounds it, for not only
are you still effectively altering the behavior of that code, but
furthermore, you are causing changes at remote locations in the code
base via macro use, which I previously contended was a hazard of Lisp
macros and which your group repeatedly denied could happen. Yet now,
when it suits you, you admit that it can, indeed, happen.
A few things:
- The code is never yours to modify unless it's open-source; however,
the definitions of specific methods within a generic function that
your code uses are ALWAYS yours to modify, either by adding a :method
form to a defgeneric form in your source code, or by writing a
defmethod form yourself to supplant an existing generic fn.
Supplanting others' code is one of the capabilities that I had
previously noted to be fraught with hazard.
Furthermore, being able to define a method, but not append a dispatch
for it to a generic function, would not address the issue in which
such dispatch was essential to your plan.
It seems that it is not possible in Lisp to simultaneously avoid both
of the above issues.
- defgeneric and defmethod are both examples of machine-generated
code, in a very similar way to how the JVM bytecode generated by
Java's class definition syntax is "machine-generated".
The implication had been made that not only were tables like in
anonymous_c_lisper's code snippet compiled, like other Lisp source
code, to bytecode, but that those tables were themselves created or
modified by automated tools.
Lisp's object system is implemented all in "normal" non-OO Lisp
This has already been mentioned elsewhere, and while it does not help
you on the generic function modification issue, it actively hurts you
on the type-safety issue, since it corroborates my claim there that
the compiler cannot type-check CLOS code since it cannot safely make
assumptions about the presence or nature of any object systems in the
code.
I don't think it'll "fail"; just the first method for (frobnobdicate a-
foo a-quux) will be overwritten by the second method.
That would constitute perhaps the worst possible failure: it silently
works incorrectly, neither alerting anyone to the conflict nor
satisfying everyone's requirements.
Not necessarily. A defmethod form overriding or supplanting a generic
fn's capabilities will only apply to code within the package that
defmethod form appears in.
That is not possible. The defmethod body itself may be local to that
package, but the added dispatch table entry/ies will be local to the
package containing the generic function of which it is the newest
method-member.
Indeed, this raises the possibility that a reference to an object of a
type defined in the former package, and to which the method in
question applies, will escape into the system to eventually be
referenced by a variable in code defined in a different package.
Presumably the generic function is visible there, including the
dispatch entry for that particular type. However, you claim the method
body is inaccessible there. It follows that if that code invokes that
method on that variable, while it is holding that object, the dispatch
table entry will effectively be pointing nowhere.
In C, invoking a dangling function pointer tends to result in a crash.
Whereas I expect Lisp to be somewhat better behaved in a certain
sense, a run-time exception or similar occurrence seems likely.
This would also make it difficult to use polymorphic objects widely in
a system without importing a large number of packages just about
everywhere in the code base, effectively somewhat diluting the name-
collision-avoiding capabilities of the package system.
Not making it external means that other
programmers could :use the package that has useful code which
internally uses the new method, but they wouldn't have to worry about
the original functionality of the same generic function, and could use
the original version in their code.
But problems will arise if they invoke that generic function on an
object of a type for which that package had added a "private" version
of the method, as noted above.
It's possible that I'm wrong about the details
This seems likely, given the extreme dubiousness of the design
decision of enabling a public generic function to have dispatches to
private methods when called with certain combinations of public
classes.
You don't have to have access to the source code with the defgeneric
form to add a method.
No, just to add a dispatch entry to call that method.
Once you created your object, you'd just add a few more lines after
the class definition (as opposed to in the class definition for the
Comparable stuff, if I understood your Java example correctly). These
lines would consist of a defmethod for the generic fn you were
interested in extending to support your object -- for example,
(defmethod compare ((my-obj x) (my-obj y)) code-goes-here). This would
not break any previous functionality of the COMPARE generic fn, except
for overwriting any previous method when both arguments are my-objs --
but in this example that wouldn't be the case because you're making a
new class.
You omit to mention adding a dispatch to the generic function that
invokes your new method. Somewhere in the code base the generic
function's dispatch table lives, resembling anonymous_c_lisper's
example for a generic function named "frobnobdicate". This dispatch
table clearly needs to gain an entry for (my-obj my-obj) (my-obj my-
obj) to call your new method when both arguments are my-objs. How is
this entry to be added?
Yes. The post in question appears to be here:
http://groups.google.com/group/comp.lang.lisp/msg/0b8faad0d5e6dd1b
It is by gugamilare, not Kenneth Tilton, but it says, and I quote:
3) Java doesn't have macros.
Macros not only provide a way to make your applications
shorter or more readable, but they also make it possible
to do somethings that otherwise couldn't be done.
If there are computations that Lisp can perform using macros that Java
cannot perform, then either Java is not Turing-complete or Lisp
contains an oracle, and, by implication, the oracle is accessed
through a macro.
To the best of my ability to determine, an oracle would require
specialized hardware, which is not something a computer system would
magically grow inside its case as a consequence of the writing or
execution of any conceivable macro.
From this it follows that the insinuation by gugamilare was that Java
was not Turing complete.
I find it interesting that when one of you says something, I repeat
it, and another of you contradicts it, it frequently proves to have
originated with gugamilare. Perhaps you should settle your internal
disagreements first, rather than debate comp.lang.java.programmer with
a disunited front?
x86 ... [a long digression about hardware]
Type errors are only stealthy if one eschews the use of a language
with static type checking, of course.
For now, I leave you with another reference, an academic paper whose
conclusion, to my mind, indicates that implicitly-typed languages,
even statically-typed ones like OCaml, exhibit scaling problems caused
by supralinear growth with project size of type-error debugging
effort:
I don't have enough experience under my belt to debate type systems.
However,
let me guess: you're going to do it anyway? And make some utterly
preposterous claim?
I do know that using a good Lisp system -- and there are free
ones -- gets you the best of both worlds in type systems.
Yes, and yes. Particularly preposterous this time. It's
straightforward excluded middle: you can't simultaneously both have
and lack static type checking.
If a Lisp programmer decides one day that static typing is as good as
you say it is, it's trivial for them to write type-safe code in CL.
Without compiler type-checking, which Lisp lacks being dynamically
typed, it cannot be "trivial" to write type-safe code.
Please read and consider what I've said here.
I have done so, aside from the lengthy digression about x86 hardware.
It has not changed my mind, but that does not mean I didn't consider
it. It just means that I didn't find it convincing. I have explained
why, above.
I'm really trying to understand what it is that you're interested in
finding out. I'm sorry about a few posts where I behaved my age
(skateboards and spraypaint).
Fortunately, leaving your "mark" all over a usenet thread is not, in
most countries, going to get you arrested and sentenced to community
service.
Then again, for particularly egregious cases such as "Lew" perhaps a
form of "usenet community service" would not be an inappropriate form
of rehabilitation. We only lack a means of enforcing it.