Re: Seeking computer-programming job (Sunnyvale, CA)

S

Series Expansion

Well, people, I am out of here. All Java and Lisp programmers here (at
least the ones that know how to have normal conversations), I am sorry
for all the noise that I provoked by putting wood on the fire. And I
don't intend to ever get into a flame war like this again. It is just
pointless and plain stupid, because, if people are flaming, it means
they are so religiously attached to their beliefs that they won't take
any of your arguments seriously and they will conveniently ignore all
good explanations you give.

That explains your own earlier instances of flaming, then. However I
don't believe it explains "Lew"s.
And, yes Series, I've just shut up, and, if this makes you happy, even
better. If you want to respond to this and say that this last post
proves that I have no more arguments against your arguments, that I
can't disprove your theories, that the only arguments that I had was
to personally attack you and the Java language with not reason at all,
then I beg you, PLEASE do this, take this opportunity to say to
everyone that you were right all the time and that I was wrong.
Seriously. I will NOT try to convince anyone otherwise.

Curious, since I suspect that you don't believe that to be the case.
Regardless, your stopping arguing does not prove Lisp inferior; it
merely means you are no longer actively trying to *dis*prove that.

Perhaps you should take some time to formulate some truly cogent
arguments, ones that address some of the key points I have made, and
return eventually, rather than quit. I see two possible avenues of
attack:

1. attempting to directly address the reasoning about how certain
tradeoffs directly follow from the code-substitution behavior of
macros and their arguments; or
2. attempting to argue that despite the pitfalls that I noted, macros
provide rewards that more than offset the costs and risks imposed
by those pitfalls.

I'd wager that option 2 offers a far greater likelihood of success,
since the arguments you'd be attacking in option 1 appear to be just
about ironclad.

Option 2 amounts to satisfactorily answering: "What really useful
things can macros do that functions that take one or more closures as
arguments cannot do?"
 
K

Kaz Kylheku

Why put it in the source code then?

Good question. One reason you might have to live with this would be that your
team, boss, or customer has imposed the requirement that Seamus MacRae
Imaginary Lisp will be used for the project, rather than ANSI Common Lisp.
 
S

Series Expansion

In the twenty years I read usenet, I never saw anybody as dumb as
Series Expansion.  Even gavino makes some progress sometimes.

Remarkable. A lucid and cogent argument is "rebutted" not with reason
but with a particularly uninspired and unimaginative ad hominem
argument.
Series: you haven't noticed the numerous examples given in those posts
where defmethod was used to define additionnal methods to a generic
function.

Was not defmethod used to define individual polymorphic variations,
but defgeneric used to create the dispatch table that called one or
another version depending upon the argument types?

Regardless, explicitly managed dispatch tables appeared in the post by
anonymous_c_lisper, and their very presence inherently raises the
questions that I asked.
 
B

Bent C Dalager

It appears to me, admittedly after only cursory examination, that this
subthread is quickly devolving into Great SWT Program Redux. I would
suggest that participants can save themselves a lot of time if they
just read the whole "Great SWT Program" discussion on c.l.j.p from
late 2007, rather than try to recreate the thing from scratch.

Cheers,
Bent D
 
S

Seamus MacRae

Alessio said:
It gets you more or less what it gets you in Java:

- the subclass intherits the slots (fields) of the superclass
- the methods applicable on the superclass are also applicable on the
subclass
- the subclass can have its own slots

Delegation gets you these too.
- the subclass can have methods specialized on it

Generic functions get you this too, and with multiple dispatch if you
want it.
You can in Java too, using reflection.

Java doesn't encourage you to.
There is a "is-a" relationship.

Perhaps in the programmer's mind, but it may as well just be part of the
project documentation and not be in the source code and it would still
do as good a job in a language whose compiler does not and cannot
enforce type-safety. Variables are untyped, so can hold any value
whatsoever at least insofar as the compiler is concerned, so there's no
need to inherit so that your class's instances will be assignable to
particular variables declared as being of a supertype; there's no such
thing as a variable type anyway.
Read carefully what I wrote above and ask yourself if your statement
above is true.

Your public insinuation that I'm a liar is rude and unwelcome. Please
refrain from engaging in such behavior in the future.
 
L

Lars Enderin

Seamus said:
You're right though about the productivity of this debate. It's like
evolutionists vs. creationists: one side has logic and evidence on its
side, the other unshakable faith, and neither will budge. We'll never
give up our logic and evidence and apparently you'll never give up your
faith. And since there are no important public policy issues at stake,
your continuing to argue is pointless.

It's ironic, really, that when you write something which seems to make
sense, you have got it exactly backwards: You are obviously the one
arguing from faith and faulty reasoning. The others know what they are
talking about, from actual experience. This applies to all topics here:
emacs, Lisp, Unix, xterms. You have no clue in any of these areas.
 
S

Series Expansion

You should have

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.
 
A

Alessio Stalla

Delegation gets you these too.

Yes, and that's true in Java, too. That's totally orthogonal to the
claim that "inheriting from a class gets you very little in Lisp".
Generic functions get you this too, and with multiple dispatch if you
want it.

Sure, but generic functions respect class hierarchy! If I have a
method specialized on A, it will be invoked on A and its subclasses,
unless there's a more specific method for one of the subclasses. So
subclassing gives you access to the behavior of methods, that you
wouldn't have if you didn't subclass. Just like in Java.
Java doesn't encourage you to.

Neither does Lisp.
Perhaps in the programmer's mind,

and in the class hierarchy, which exists in the system's state and not
only in the programmer's mind...
but it may as well just be part of the
project documentation and not be in the source code

(defclass A (B) ()) is source code, and declares that every A "is-a"
B: every thing you can do with a B, you can do with an A too.
and it would still
do as good a job in a language whose compiler does not and cannot
enforce type-safety. Variables are untyped, so can hold any value
whatsoever at least insofar as the compiler is concerned, so there's no
need to inherit so that your class's instances will be assignable to
particular variables declared as being of a supertype; there's no such
thing as a variable type anyway.

But there's a *value* type, and the fact that object X is of class A
or B *does* change runtime behavior, or else classes would be
completely useless. If there's a DRAW method specialized on SHAPE, and
my object is of class CIRCLE, whether CIRCLE inherits or not from
SHAPE *does* change what will happen when I call DRAW with it as a
parameter. I completely fail to see your point here.
Your public insinuation that I'm a liar is rude and unwelcome. Please
refrain from engaging in such behavior in the future.

I'm not saying you're a liar; I'm saying that some of your assumptions
are objectively wrong, and I'm trying to give you evidence of that. I
can stop if you want - I don't get nothing back if you understand.

Alessio
 
K

Kaz Kylheku

["Followup-To:" header set to comp.lang.lisp.]
Pillsy said:
Pillsy wrote:
Pillsy wrote: [...]
This, at least, is a potential problem, but in practice it's never
caused me any difficulty.
*deep sigh*

Every time a serious problem is mentioned, you tend to dismiss it with
little more than a hand-wave.

One thing I've discovered is that the things I think are going to be
problems when I start learning a language (or don't know it at all
yet) end up being pretty different from the things that I actually
learn are problems after working with it for a while.

This statement is also little more than a hand-wave. In a way it's even
less convincing than many of the other non-evidence-based arguments
against what I've said, in that it's entirely subjective.
No, I mean, by 2009 standards. It just looks a little crufty.

"A little" crufty? Nevermind looks -- it also feels (more than) a little
crufty, like trying to drive a real full-size automobile using one of
those little gadgets for commanding radio-controlled toy cars*.

Well, emacs does, and I doubt there's anything that adding SLIME to
emacs can do to change that.

* James Bond did this in at least one movie. I wouldn't recommend that
any lesser man ever attempt it.
I might, but if I wanted it to inherit from Number, I could certainly
choose to have it inherit from Number. I'm just not sure that's the
way to go from a design standpoint, though admittedly I haven't
thought about the question a whole lot..

Taking it as a given that Complex should be a subtype of Number, how
else would you go about doing it?

Are you asking about implementation strategies about how to add
this ANSI CL feature to Seamus MacRae Imaginary Lisp.
Well, actually, I don't suppose that even makes sense. CLOS apparently
has a notion of subclass, but to have a notion of subTYPE you kind of
need, well, types.

Not really. Class and type are only an implementation distinction that
exists in languages for historic reasons. E.g. C++ has ``basic types''
and ``class types''. Lisp is the same way. Originally, everything had
type. When OO was introduced in the 1980's, eventually, everything
had a class as well.

What is the class of 3?

[2]> (class-of 3)
#<BUILT-IN-CLASS INTEGER>

What is the type of 3?

[3]> (type-of 3)
(INTEGER 0 16777215)

Class is understood to be a type concept related to participation in the object
system. Built-in things like symbols and numbers have both type and class. If
you don't want to use OO in your design, you can largely ignore that objects
have class.

A class object's type and class are the same thing:

(defclass foo () ())

(type-of (make-instance 'foo)) -> foo

Are complex numbers a subtype of numbers?

(subtypep 'number 'complex) -> T ;; Yes!
assignable to Number variables in Java. Since everything is assignable
to every variable in Lisp, this consideration goes away, and just having
both implement plus methods will let you use them interchangeably in
code using plus on variables.

So the lack of static typing saves you a little bit of work coding your
type system.

Lack of static typing saves work in the type system too? Wow. It does not only
saved work in the non-type-system parts of the program!
You still ought to think through your type system, even if

There isn't a Lisp macro called THINK which will do this for you,
but I hear they are working on it.
your type system will be completely invisible to the compiler, or your
program won't work. And penny you saved writing "extends Number;" or its
equivalent up front is owed with interest down the line, as a dollar
spent debugging run-time errors to the effect "String does not
understand the method: plus".

You keep asking people for rational evidence. Where is your rational
evidence that these errors are such a threat?

I agree that there is a nonzero probability that you will be
confronted with an error like ``foo does not understand the method bar''.

The questions are:

1. How much of a threat is this? Can we quantify this risk in numbers?
I.e. if we eliminate the problem, what is the benefit?
How important is this compared to all other risks facing the
development of this software?

2. What are the costs of preventing this problem with static typing?
Are there risks, and what are they?

You are asserting that there are no costs, or risks, only benefits,
as if you could banish type mismatch errors with static typing in such a way
that all else remains equal.

Don't accuse others of having no rational evidence, if you haven't
properly done the cost/benefit analysis.

People who have actual years of experience with dynamic typing find that the
actual threat from type mismatch errors is small compared to the inconvenience
of working with static typing.
I hate all-caps names, except on final static fields where they belong.

Of course, you'd normally just write number and complex in your Lisp program,
but you can write in caps also. In discussion threads in the Lisp newsgroup, we
find it very useful to write symbol names in caps, because it's typographically
clear that the word is a symbol.

If fonts could be used, we could write COMPLEX in lower case letters instead,
but use a typewriter font.

The Lisp reader is configurable with respect to case treatment in symbol names.
The default behavior is to fold everything to upper case, for historic reasons.
So Foo, FoO, fOO, foo and FOO all denote the symbol object whose name is the
character string "FOO". The default behavior in the Lisp printer (also
customizeable) is to print the symbol as FOO.
This wasn't compilation; this was "defgeneric" forms generated by
something. (Macros?)

Macros are a part of compilation.

What is the difference between, say:

synchronized (obj) { ... code .. }

and

(synchronized obj ... code ...)

Java's synchronized block construct is a de facto macro. The difference is
that it's hard-wired into the compiler. The compiler recognizes the
synchronized keyword and parses the construct into some kind of tree into which
it inserts monitor enter and leave calls, and a try/finally.

Lisp lets the programmer assign custom code transforming actions to symbols, so
the compiler is extended as part of the program. Thus we can write our own
synchronized block construct. This is done by writing a macro.

A macro does, in Lisp, exactly that which in another language
would be done by adding a new phrase structure rule to the
parser, along with a syntax-directed-translation action
to go with that rule.

A Lisp macro is even compiled to native code, so that it
runs fast at compile time.

The difference is that you don't have to rebuild the compiler to integrate this
custom syntax. It's just something that is defined in the program. The custom
syntax doesn't create any ambiguities in the grammar. It's denoted by a symbol.
The symbol can be put into a package. You are not adding a new reserved keyword
like ``synchronized'' to the language.

Lisp even has local macros restricted to a lexical scope.
Bison generates C source files.

The point is that the C generated by bison is a derived object, not
a primary file.

The generated code isn't ``source''. The source is what is maintained
in the .y file.

So, there is the view that the generated code doesn't belong in version control.

You're having problems with Bison and version control because you have no clue
what should go into version control and what shouldn't.
You mean, there are two programs with the same name that are otherwise
as different as night and day?

I saw elsewhere in this thread that you were shown a screenshot of Emacs and
you still denied it was Emacs.

The only Emacs is Seamus MacRae Imaginary Emacs. Anything else is a lie
that someone made up, complete with fake screenshots created with
an image editor.
The compiler compiles the

(foo foo) (bar bar)
(foo foo) (baz baz)

stuff, but what generates it? Apparently sometimes it's done manually.
Other times you've suggested it's auto-generated somehow, perhaps by
Lisp macros. Regardless, it gets modified to add a dispatch for
print-object.

An organized reference manual for Seamus MacRae Lisp would be helpful,
instead of the collage assembled from these fleeting glimpses of
what it is about.
 
P

Pillsy

Pillsy said:
Pillsy wrote: [...]
Pollyanna much?
Why do you keep insisting that I believe you instead of my own lying
eyes?
Your eyes lie? Or do you mean the other sense ... amblyopia then?
Anyway, you keep insisting I believe you instead of what reason and
logic says follows from your own prior statements...

If you think I'm lying about what problems I've experienced, this
conversation couldn't be more pointless. If you don't think I'm
lying, the only other option is that your logic and reason are faulty.

IMO, when theory and practice differ, practice ought to trump theory,
not the other way around. YM evidently V.
[...]
Hey, hey, hey. Wait a minute here. Who said anything about defining a
new package?

I did. That's usually the way you manage namespaces in Common Lisp:
you make a package, you suck in everything you need in the package,
export everything you want to expose, and then put IN-PACKAGE forms at
the top of all the source files that define functions, macros,
classes, et c. in that package.
I'm not interested in that. In the equivalent of Java code
such as:
package foo;
import java.util.Date;

Date today = new Date();
javax.sql.Date thingyDate = thingyFromDatabase.getDate();
I am interested in the "import java.util.Date;" and the "javax.sql.Date
thingyDate = thingyFromDatabase.getDate()" bits, or rather, their Lisp
equivalents, rather than the "package foo;" bit or its equivalent.

Believe it or not, different things are grouped differently in
different languages. When you define a namespace with the DEFPACKAGE
form, *that's* the place that you also say what other packages are
being used (roughly equivalent to Java's "import foo.*", AIUI), what
individual symbols are being imported, how conflicts are resolved, and
what symbols you want to export.
[...]
Except this was in response to, basically, "how does Lisp do import
foo;?". Apparently it was not actually an accurate answer to the posed
question!

That may be because the two language constructs aren't precisely
equivalent. I suspect this is ultimately because Java closely
intertwines a number of things that Lisp leaves separate.
The point is that the Lisp option is not conspicuously easier. At best
it's about on a par; in practice, the quantity of shifted characters is
likely to make it quite bit more awkward to type.

I'm not sure where you got the idea that anybody said it's
conspicuously easier. It looks about the same to me.

Cheers,
Pillsy
 
A

Alessio Stalla

You are in no position to be telling others what they should or should
not do.



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.

No. The fact that defmethod is a macro does not mean it remotely
modifies any code. defgeneric is a macro too, and many other Lisp
operators are, and none I know of remotely alters any code whatsoever.
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.


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.

What you mistakenly see as "tables" is really ONE way to define some
methods along with the generic function. It's totally optional.
You can write no such "table" as you name them, and write a bunch of
defmethod forms instead - it's the same. The real "dispatch tables"
are not apparent in source, like they are not in Java: they are state
maintained in the system's internals, just like in Java, C++ etc.
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.



That would constitute perhaps the worst possible failure: it silently
works incorrectly, neither alerting anyone to the conflict nor
satisfying everyone's requirements.

Where is it written that it *silently* works incorrectly? All
implementations I know of warn the user in case of redefinition of a
method.
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.

I make no sense of this. I'm only able to understand that your notion
of "package" is something that has no resemblance to what a package is
in Lisp. A package is a container of symbols, period. I repeat myself:
a package does not concern itself with functions, classes, variables,
methods, etc. etc. etc.
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.

Still makes no sense to me... packages have no methods.
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.

What is a public generic function? What is a public class? What is a
private method? This is not Java. *symbols* in a package can be
internal ("private") or exported ("public"). No other kind of Lisp
object I know of, besides symbols, bears the concept of
"public"/"private".
No, just to add a dispatch entry to call that method.

No. To add a method you call defmethod, period. No access to source
required.
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?

Again, no such table exists in source.
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.

"to do something that otherwise couldn't be done" is not to be taken
literally. It couldn't be done with limited resources by a reasonable
number of human beings. Of course being both Java and Lisp Turing-
complete, everything you can do with one you can do with the other, at
worst by emulation: I can theoretically rewrite the whole Java in
Lisp, or the whole Lisp in Java.
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?

No offense intended, but haven't you thought that maybe the
contradictions are between your assumptions and what other people say
to you?
x86 ... [a long digression about hardware]
But nobody can deny that there's a big difference between catching 100
bugs after hours of bug-hunting, dozens of debugging prints, and lots
of poring over stack traces and watched-variable logs, and catching 50
bugs that way and 50 instantly when you click "build" (or even when
you write the separate buggy lines of code!).
One could deny that 50% of all bugs are stealthy type errors, but since
we already did static typing these last few weeks, I won't get involved.
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:
http://portal.acm.org/citation.cfm?id=176454.176460
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.
 
S

Seamus MacRae

Alessio said:
What if the package system scoped generic "names", and those "names"
could be used to refer to verbs, nouns, pronouns, etc. etc.?

That would be even worse: not only would methods and classes both have
to be scoped, so thing.method() would have to have two scopes decided
somehow (and the type of "thing" cannot be a factor in compile-time name
resolution, since as far as the compiler is concerned it could be
anything), but method names and class names could now collide with one
another, and possibly with other things too!

At first this might not seem so bad, since nouns and verbs are mostly
nonoverlapping sets. But some common cases are exceptions: a jump vs. to
jump, for example.

There has been some example code and other text that collectively
implied that Lisp identifiers are not case-sensitive, which means that
using a Java-esque convention of Jump for the noun and jump for the verb
would not avoid a collision.

Worse, this also means JUMP for a global constant will collide with both.

What a mess!
I have the impression that those two people you're speaking about are
actively trying to remain "confused".

In at least one instance, that is not true.
the method MY:frobnodicate(MY:quux) is different from
the method MY:frobnodicate(YOUR:quux) which is different from
the method YOUR:frobnodicate(MY:quux) which is different from
the method YOUR:frobnodicate(YOUR:quux)

The methods, yes. It's the little bit of code containing the dispatch
table that concerns me. Someone has to add a (YOUR:quux YOUR:quux)
dispatch to MY:frobnobdicate, for example. If that someone is you, then
you may become a bottleneck in the development effort. If that someone
is the owner of YOUR, then everyone can trample your MY:frobnobdicate
garden. Either way, as team size increases there will be growing pains.

Add to that the misery of the user of these methods having to sort them
all out and explicitly scope at least part of at least three of them and
all of at least one of them.
Why? I'm curious.

Encapsulation, among other things I've already explained in previous posts.
Ditto.


Ditto.


Yes.

In Lisp you have

package.symbol

and stop. This means there's no difference between

package.className and
package.genericFunctionName

That's when you're referring to just one of those. I'm discussing the
commonplace situation when you're referring to one of each. Then you
need to specify 2 packages. Somehow.
Making it easy in all cases is better than making it easy in some
cases and hard in others, as a general rule.

If you could actually do that, the above sentence would actually be
relevant to this discussion.
Or you can define a general case and specialize only the cases that
interest you, only for the "pairs" (or tuples) that make sense for the
problem at hand.

The (foo foo) (bar bar) syntax does not allow to "define a general
case", save if all project objects inherit from some class, say Object,
and you put in a dispatch for (Object Object) (Object Object), and this
respects inheritance, so any call lacking a more specialized applicable
dispatch with arguments both inheriting from Object will get that dispatch.

Then the real fun begins: enforcing "NO CLASSES NOT DERIVED FROM
OBJECT!!" everywhere in the project. Unless CLOS already has an
omni-superclass like Java's java.lang.Object class.
Maybe then it's not information about class X, but about classes X, Y
and Z. It is precisely this kind of thing that is easy to express in
CLOS

It is easy to express precisely nowhere. CLOS lets you lump everything
to do with X, Y, and Z together in the same place. So? This might easily
end up meaning pretty much the whole project. So much for namespaces,
nevermind encapsulation, which we'd already given up on ages ago.
What reason on Earth would Thomas have to say it works fine if it
didn't?

I do not know, though strongly suspect "appearing to be the victor of a
particular Usenet pissing match" to be among his motives. Nonetheless,
what he claimed flies in the face of logic.
But if you confuse your personal preference with objective
truth, and write that "truth" in public, I - we - feel the need to
correct your claims.

That statement makes several insulting and false insinuations about me.

I'm glad that particular dispute is finally settled.
Subclassing a class DOES change the class, if you intend "class" as
the set of all possible instances of that type.

Sophistry. It doesn't change the base class itself, and indeed, code
that uses the base class won't be affected unless someone passes it a
reference to a derived-class instance.

Since there aren't separate "base" and "derived" generic functions in
Lisp, however, the above does not apply there, and the "base itself" IS
changed.

Uh-oh.
Not if you follow some convention in your team.

Given all the places things can be squirreled away, a) defining such a
convention to be both complete and consistent will be non-trivial and b)
so will enforcing it.

In fact, the potential complexity of the system you've described may
suffice to invoke the incompleteness theorem, ensuring that NO
convention could EVER be devised to be both complete and consistent.
This is not specific
to Lisp, conventions are needed in every language that allows more
than one way to do the same thing (IMHO, every serious language).

But the more ways there are to do a thing, the worse it gets; indeed,
you can easily get a combinatorial explosion like the one that nuked
perl as a viable language for large-scale development efforts.
Only if you let individual programmers do it at their whim. Just as if
there wasn't no convention among Java programmers in a team on how to
name packages, for example.

Java needs relatively few conventions BESIDES how to name packages. Lisp
will need a convention the documentation of which would consume 74,172
trees (plus or minus five) to print and massing 11.3 tons. Looking up
anything in the convention will take 1 month, 17 days, 3 hours and 11
minutes, plus or minus one, assuming it's found on average halfway
through. The one upside is that it will make one hell of a paperweight
or doorstop.

Yes. Thomas said you'd not use "close" for everything that closes, which
means Fun With Your Thesaurus time folks!
streams:close(file-stream)

This vs. Java's fileStream.close(). And you guys said *Java* is bloated
and looks like vomit?!
 
A

Alessio Stalla

Option 2 amounts to satisfactorily answering: "What really useful
things can macros do that functions that take one or more closures as
arguments cannot do?"

- Running some code in a dynamic context established by the macro
(e.g. some variables locally bound, some local functions defined, ...)
- Introducing new syntax (for example for DSLs).
- Moving some computation at compile time.
- Changing argument evaluation rules.
- Transforming user code (e.g. to Continuation Passing Style).

and there are many others. I encourage the Lisp Gods to add other
examples here :)

Alessio
 
S

Series Expansion


But object orientation revolves around two concepts: the encapsulation
of data along with its behavior in a class, and inheritance with
subtyping and is-a relationships.

The former obviously requires that methods be associated with a
particular class.

So you have objected to the first of the two pillars of object
orientation.

The second is severely cracked by having no static types of variables,
arbitrary polymorphism without requiring subclassing, and a few other
features that basically reduce class inheritance to code reuse.

So you have objected to one pillar and cracked the other, severely
damaging it.
No, they aren't defined by that.

Yes, they are. See above.

Yes. And I'm starting to get tired of being called a liar to my face
every five minutes.
You constantly infer nonsense.

Yes, he was an obvious troll hundreds of posts ago. That doesn't mean
some poor c.l.j.p reader couldn't be misled.

These tiresome personal attacks do not constitute rational arguments
in favor of either Lisp or Java, Paul.

That last is particularly noisome, accusing me of lying yet again and
imputing a motive of wide-scale sabotage. That is treading perilously
close to libel, Paul.
 
S

Series Expansion

No "poor c.l.j.p reader could be misled" if you'd just take this thread off of
c.l.j.p.  Please.

These tiresome personal attacks do not constitute rational arguments
in favor of either Lisp or Java, "Lew" and Paul.

I do not lie or mislead people. However, your frequently repeating
these false accusations against me seems to indicate that *you* do
those things.
 
A

Adlai

I have learned enough to have raised several objections that you have
failed to adequately address.

I do not need to. In the case of macros, it sufficed for me to look
into one particular similarity: that a macro invocation is replaced
with some code, inside which placeholders are replaced with copies of
the call's arguments, and then the result of the substitution is
compiled.

My concerns regarding macro use derive entirely from this one fact,
which you have not denied is true of Lisp macros.

Since my concerns do not hinge upon the macros in question having any
particular other feature than that one, and Lisp macros have that one,
my concerns are applicable to Lisp macros.

To address my concerns logically, you must actually address the
concerns themselves. Saying that "Lisp macros are different"
repeatedly does not constitute a logical argument, particularly when,
with respect to the salient feature described above, Lisp macros are
not different.

You've completely ignored GENSYMS. Lisp macros execute code which
instructs how to produce the expansion code, and thus are able to
avoid variable capture, multiple evaluation, and all the other
problems you mentioned.
I have done so when they were irrelevant, which occurred often. If you
wish me to pay more attention to something, you should endeavor to
make it relevant and then I shall in all likelihood do so. Meanwhile,
responding with posts that are even less relevant, such as ones full
of insults, shall tend have the opposite effect.

As far as I can tell, you're replying to every single post. It would
be a better use of everybody's time if you just ignored the irrelevant
posts, and only answered the relevant ones.

Also, it does seem to me that you haven't put much effort into
understanding the Lisp package system or CLOS. These are very
different in Lisp from how they are in other languages, so it helps to
have a familiarity with them before you denounce them. The package
system, for one thing, as has been said before, is just a package of
SYMBOLS. That's all. Packages don't store code within them, just names
of stuff.
Generic functions are irrelevant to the matter at hand, namely,
macros. Therefore it is unsurprising that I have not said much about
them.

People have mentioned gensym, which is completely relevant to macros,
and if I recall correctly, you're only replied once, saying that
gensyms are impossible -- yet they're all over "On Lisp":
http://paulgraham.com/onlisptext.html
That was one of the six [false beliefs about Java], and it occurred a few additional times,
though perhaps not from you. The others, as I recall, were: [...]

Since I see that you dislike it when I try to apologise for other
people's potential miscommunications, I won't do so.
This is an excellent example of an assertion unsupported by evidence,
of which you have made so many over the past few days.

I cite a page on Peter Norvig's site: http://www.norvig.com/java-lisp.html
He talks about a study done in a few different languages. One of the
results was that Lisp code for the test program was produced within
hours, while many of the submissions in other languages took days.

- Adlai
 
S

Series Expansion

You say you have personal experience with Emacs, but you probably only
used it before 1980's.

That is incorrect. I used it in the late 1990s, though only because I
had to (no physical access to the host, and no remote X capability).
 
S

Series Expansion

I used it in the 90s, contrary to gugamilare's uninformed speculation
on the matter.
Are you kids still squabbling?  Do I have to send you to your room?

These tiresome personal attacks do not constitute rational arguments
in favor of either Lisp or Java, "Lew".
You do realize that "Series" has done this before, and that no amount of proof
will get him to admit that he in any way has erred?  That there is no victory
with him?

These tiresome personal attacks do not constitute rational arguments
in favor of either Lisp or Java, "Lew".
Although I did achieve victory over him in this thread myself.

You did not. You currently hold the moral, tactical, AND strategic low
ground.
Seriously, forget about "Series".  He's not worth it.

These tiresome personal attacks do not constitute rational arguments
in favor of either Lisp or Java, "Lew".
Emacs is the best editor yet devised.

Except for all the other ones. (Except, in turn, vi and all line-
editors, and maybe Notepad).
You're just never going to get "Series"
to yield a millimeter even on points of basic fact.

These tiresome personal attacks do not constitute rational arguments
in favor of either Lisp or Java, "Lew".

Particularly calling me a liar.
Take comfort in the fact that he can never be real competition to you in the
programming work force.

These tiresome personal attacks do not constitute rational arguments
in favor of either Lisp or Java, "Lew".

[some final irrelevancies deleted]
 
S

Series Expansion

These tiresome personal attacks do not constitute rational arguments
in favor of either Lisp or Java, "Lew" and Paul.
 
S

Series Expansion

Series, I wish I had the time to respond in detail to each of your
posts and provide you with material so you could keep on lighting fire
to your pink bunny boxers.

I do not have pink bunny boxers.
However, time is limited, and I have a busy day ahead. I look forward
to reading your inspired verbal diarrhea

These tiresome personal attacks do not constitute rational arguments
in favor of either Lisp or Java, Adlai.
I'm loving it.

 -  Adlai

Does that mean that your post was a McFlame?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,436
Messages
2,571,696
Members
48,796
Latest member
Greg L.
Top