473,838 Members | 1,637 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Is anything easier to do in java than in lisp?

After many years of using LISP, I'm taking a class in Java and finding
the two roughly comparable in some ways and very different in other
ways. Each has a decent size library of useful utilities as a standard
portable part of the core language, the LISP package, and the java.lang
package, respectively. Both have big integers, although only LISP has
rationals as far as I can tell. Because CL supports keyword arguments,
it has a wider range of string search utilities etc. where :key and
:test and :start :end etc. are parametric instead of fixed or
special-cased here but not there. The only major differences I see are
speed and interactivity:

Speed comparisons on FreeBSD Unix:

javac or java takes appx. 24 seconds to start up the first time, then
is virtually instant subsequent times within a short time span.
However even on immediate re-runs, javac takes between 2 and 7 seconds
to compile a very small file (23 lines total, only 10 lines of actual
code).

CMUCL takes appx. 2 seconds to start up the first time, then is
virtually instant subsequent times within a short time span.
Recompiling a 33-line file runs so blindly fast that even with
*error-output* diverted to bit sink so as to suppress listing of each
function compiled, its limited only by 19200 bps printout of the return
value.
(let ((*error-output* (make-broadcast-stream))) (compile-file "tabsp.lisp "))
#p"/home/users/rem/JavaWork/tabsp.x86f"

You need to re-start java every time you want to compile and every time
you want to run what you compiled, you can't just leave the jvm running
and load tasks into it. Consequently, if you go away from java for a
minute to edit the source to recompile it, etc., then you're back to 24
seconds start-up again when you want to compile what you edited, a
royal pain! By comparison, you can stay in CMUCL and do almost
everything there, so you don't have to suffer even the two-second
first-time-start ever again during a session.

Interactivity: In CL (and virtually any LISP since the original), you
can sit in a read-eval-print loop composing and trying one line of code
at a time, storing the results of correct computation in global
variables to feed into the next step of composing&tryin g. By
comparison, in java you have to switch back and forth between editing
the source of not just what you want to test but a whole test rig
around it to make a "complete program", compiling that "complete
program" to bytecode, and running that "complete code" just to see if
you got one line of new code correct. Comparing the instant feedback
when typing one new LISP form into the R-E-P, against the 24+ second
turnaround to try one new line of java code, LISP is a *big* winner!

So I ask, is there any particular kind of task where java has an
advantage over LISP? The only thing I can think of is networking. I've
heard that java has networking built into the language, things like
sockets, TCP/IP, HTTP, etc., whereas they aren't part of CL per se and
need to be supplied by various vendors on the side. So is this true,
that java is better than CL for networking stuff? Also, is there any
other area where java beats CL?

Well, there's Unicode, which is built into java but not CL, but I have
no use for it at present so that doesn't count. But I'd like to write
some Web-networking code to replace the hack I currently use where lynx
is run as a sub-process under CL and lynx does all the work of handling
cookies etc. If java can do all that directly more easily than CL, I
might give it a try.
Jul 17 '05
73 8103
* RobertMaas wrote:
javac or java takes appx. 24 seconds to start up the first time, then
is virtually instant subsequent times within a short time span.
However even on immediate re-runs, javac takes between 2 and 7 seconds
to compile a very small file (23 lines total, only 10 lines of actual
code).
Are you using a machine with rather small real memory?
You need to re-start java every time you want to compile and every time
you want to run what you compiled, you can't just leave the jvm running
and load tasks into it. Consequently, if you go away from java for a
minute to edit the source to recompile it, etc., then you're back to 24
seconds start-up again when you want to compile what you edited, a
royal pain! By comparison, you can stay in CMUCL and do almost
everything there, so you don't have to suffer even the two-second
first-time-start ever again during a session.


.... This would imply you are, I think - something is causing the
cached fs pages to be flushed rather aggressively.

I don't build Java stuff, but I sit next to people who do, and they
don't see these issues with Sun's 1.4.x JDK. *But* we have sensibly
configured development machines - I think they all have 4GB memory.

--tim
Jul 17 '05 #21
Ryan J. Bovorasmy wrote:
I must admit that when I first began learning lisp, it
seemed almost backward to me: the way the syntax is set up, you have to
write the first thing you want to do last, and the last thing you want to
do first:

;;lisp
(car (cdr foo))

// C++ (assume I've made a linked list with push & pop type methods)
var = llist.rest();
return var.first();


After some days of use it will become easier to write what you want.
If you want the second element of a list (the first of the rest that is)
you can say "hey I need the rest"
(rest foo)

Then move your cursor to the left and tell Lisp that you are looking for
the first element:
(first (rest foo))
André
--
Jul 17 '05 #22
> From: "Ryan J. Bovorasmy" <zo****@sdf-eu.org>
1) More people know C/C++ than lisp.
Why is that? CL is easier to learn than C/C++, so why would anybody
choose C instead of CL to learn in the first place?
2) Java is like C/C++, therefore it is cheap/fast/easy for people to learn.
If somebody already is content with C, can tolerate the need to write a
whole program just to test one new line of code, can tolerate the need
to write your own conversion from input to output format (using the
built-in printf to print the pieces presumably) to see whether a
structure was built correctly, can tolerate needing to compile the
whole program then run it separately just to see the printfs to see
whether the one line of new code works correctly, why would they seek a
different language such as java, instead of stick with what they
already find good enough?

On the other hand, if somebody doesn't like the facts about C that I
mentionned above, why would one switch to a language that is even
worse, not only do you have to write a main function which is a
complete program, but you must embed it in a class, which must have the
same name as the file you put this all in, and the declaration on main
must be exactly right, and it takes ten times longer just to start up
the compiler? If you don't like C for those reasons, you really would
like try a new line of code in three seconds instead of half a minute,
why would you ever switch to java?
Another thing I noticed about using Java (the few times I have), is
that it is extraordinarily easy to write a standard-looking GUI.
Unfortunately that works only on compatible systems which support the
kind of GUI that java assumes. For example, I have no access to any
java GUI here on VT100 dialup into Unix shell account. And if you use
CGI to make your application available to the whole net, your nice GUI
can't be used, you have to use HTML FORMs, which are just as easy to
generate and process in LISP as in java. So one way your program can't
be used on the kind of account I have, and the other way LISP is just
as good as java, so where's the advantage to java if you want to allow
everyone to use your program?
lisp still has a lot of "ancient" terminology embedded into the
language that a lot of beginning programmers are likely to find
confusing.
You mean like FIRST (formerly called CAR) and REST (formerly called CDR)?
You mean like MAP and APPLY and FUNCALL (FUNction CALL)?
I do have one nit about CL terminology: The internal structure that is
represented externally by dotted-pair notation, i.e. (first . rest),
should be called a STANDARD PAIR, not a CONS. The function name CONS is
short for CONStruct, which is ambiguous, and defining it to make a CONS
cell makes the circular definition horrid. But I suppose you can
actually avoid that by using LIST* everywhere you would otherwise use
CONS, remembering that the * in that name looks a bit like a glorified
dot, reminding you that it makes something that prints as a dotted list
instead of a regular list, and in the two-argument case it makes
something that prints as just a dotted pair, the shortest possible
dotted list.

Please tell me specifically what "ancient" terminology you object to in
CL.
when I first began learning lisp, it seemed almost backward to me:
the way the syntax is set up, you have to write the first thing you
want to do last, and the last thing you want to do first:
;;lisp (car (cdr foo))
You don't have to nest function calls like that. You can write each
function call as a separate assignment:

(setq tmp (cdr foo))
(setq result (car tmp))

You have the same options in C or java as in lisp.

(setq result (fun3 (fun2 (fun1 input))))
result = fun3(fun2(fun1( input))));

(setq tmp1 (fun1 input)) tmp1 = fun1(input);
(setq tmp2 (fun2 tmp1)) tmp2 = fun2(tmp1);
(setq result (fun3 tmp2)) result = fun3(tmp2);

There's no difference between CL C/C++ and java in that respect.

You can't do this in C, but you can in CL and java:
(let* ((tmp1 (fun1 input)) double tmp1 = fun1(input);
(tmp2 (fun2 tmp1)) double tmp2 = fun2(tmp1);
(result (fun3 tmp2))) double result = fun3(tmp2);
result) return result;
(I've assumed the types of those are double-precision floating point.
In java you need to declare the type for each variable, whereas in CL
you can just use generic variables initially and declare the type only
when it really is needed to speed up a slow part of your program.)
I actually prefer lisp to Java so far, if only because of the fact
that:
1. It has aspects of a functional language.
Static methods in java are much like ordinary functions in lisp, except
they don't have keyword arguments which means you must look up a host
of almost-the-same functions instead of just one function with a bunch
of keywords you can mix in any form. But most of the API has instance
methods instead of static methods, so for example if you want to find
the index where str1 occurs within str2, you're forced to re-write
(setq index (search str1 str2))
not as
index = String.indexOf( str1, str2)
but as
index = str2.indexOf(st r1)
gee, it's even backwards from CL convention there.

Anyway, back to lack of keywords, so every combination of what would be
keywords in CL becomes a totally separate functionName and/or
argumentList in java. For example:
int String.indexOf( int ch)
int String.indexOf( int ch, int fromIndex)
int String.lastInde xOf(int ch)
int String.lastInde xOf(int ch, int fromIndex)
whereas in CL you have a single function:
(position item sequence &key :from-end :test :test-not :start :end :key)
which not only works on strings, with :from-end making the difference
between indexOf and lastIndexOf, but :test :test-not and :key aren't
even available in java, and this same function works on all kinds of
sequences, not just strings, but other vectors, and linked-lists, too.
In Java if you want to do this same thing with vectors or linked-lists,
you probably need to write the function yourself, because as far as I
can tell java.lang doesn't have a class for vectors nor for linked
lists, and I don't know where else to find something like
Vector.indexOf or LinkedList.inde xOf etc.

LISP also has:
(search sequence1 sequence2 &key :from-end :test :test-not :key
:start1 :end1 :start2 :end2)
for which java implementes only a small portion of the cases as:
int String.indexOf( String str)
int String.indexOf( String str, int fromIndex)
int String.lastInde xOf(String str)
int String.lastInde xOf(String str, int fromIndex)
Suppose you want to find the first or last occurrance of some name,
ignoring case. In CL it's trivial:
(search "robert" "Hi, this is Robert Maas here" :test #'char-equal)
how would you do that in java except by writing your own nested loop
from scratch?? How come the java API doesn't already include this??
2. It makes working with lists easy.


Indeed, in java working with linked lists must be an awful pain.
Either your list can contain only one kind of element, so you declair
your own class to include link-cells whose data pointer is of that
type, or you use the generic Object type and deal with having to write
code that explicitly checks the case of every element at runtime.

And I just noticed: The arguent to indexOf isn't a character at all,
it's an integer!! At least in CL you can directly pass a character
object as argument to function that searches for that character within
a string, instead of coercing it to an integer first!!
In CL, if you pass an integer instead of a character, it looks for that
integer, not the character with that ASCII code, for example:
(position 65 '(#\A #\B 65 66))
will find the 65 instead of the #\A, returning 2 instead of 0 as the
index where it found that number.
Jul 17 '05 #23
Ro********@Yaho oGroups.Com wrote:
If somebody already is content with C, can tolerate the need to write a
whole program just to test one new line of code, can tolerate the need
to write your own conversion from input to output format (using the
built-in printf to print the pieces presumably) to see whether a
structure was built correctly [snip] How would you see that in lisp without using the introspector running in
an interactive environment? Is there any real difference between lisp
debugging environments that allow introspection and Java debugging
environments that allow introspection in this regard? Other than there
are very few lisp compilers put out without interactive introspection,
but the standard Java compiler has its debugger as a separate
application, this isn't an issue. Similarly you're out on compile speed
by between one and two orders of magnitude (.5 to 5 seconds, not half a
minute). Loading and compiling a lisp code into ACL on my machine takes
about as long as the same size of Java, the gain is many free lisp
environments allow incremental compile during debug and introspection,
whereas the free Java compiler doesn't. Commercial Java environments do.

There is a distinction between language, environment, implementation and
libraries. Lisp has always shipped with an interactive introspective
environment, it took to the mid-to-late '90s for the compiled languages
to catch up, but they pretty well have. Some Java environments have gone
further, for example supporting backwards stepping debugging so you can
try your code, find it has a bug, step backwards to before the buggy
line, edit & recompile, the continue stepping forwards.
For example, I have no access to any java GUI here on VT100 dialup into
Unix shell account. Nor could you send SMS on a 'wind up' telephone. If your clients want
GUIs, then GUI they must have. If they want to use VT100, use something
suitable for that. But I don't think the ideas in lisp should be
restricted to yesteryears' technology.
And if you use
CGI to make your application available to the whole net, your nice GUI
can't be used, you have to use HTML FORMs, which are just as easy to
generate and process in LISP as in java. Or easier. But then there are mutant forms of Java such as JSP that are
intended to make web programming easier by giving the equivalent of
quote and qquote in XML. (though the syntax is so ugly and they mix
abstraction layers so badly I've never used JSP)

There isn't anything like the support for web applications in Lisp than
there is in Java. I haven't used CGI itself for nearly a decade; once
you have anything more than a simple form and want a DB backend, you end
up using a framework. There is some interesting work done is lisp with
continuations for web programming, but continuations aren't part of
Common Lisp, and that's seems more equivalent to the XML based
frameworks that writing pure Java servelets.
So one way your program can't
be used on the kind of account I have, and the other way LISP is just
as good as java, so where's the advantage to java if you want to allow
everyone to use your program? Most of the world's populace don't have access to any computer, so you
won't be programming at all by the argument of lowest common technology.

People expect more than can be delivered through an HTML form, let alone
VT100.
You mean like FIRST (formerly called CAR) and REST (formerly called CDR)?
You mean like MAP and APPLY and FUNCALL (FUNction CALL)? Or lambda, which is so old it's ancient Greek. The problem's more one
that there is another abstraction- programmers are taught that a program
is 'like a recipe', so how can a recipe take part of the cookbook as an
ingredient? You have to think different to use lisp, and too many people
are taught to program rather than taught to think.
From: "Ryan J. Bovorasmy" <zo****@sdf-eu.org>
when I first began learning lisp, it seemed almost backward to me:
the way the syntax is set up, you have to write the first thing you
This is similar to a very old argument: programming by query or navigation.

lisp/Prolog/SQL you say 'I want the first part of the rest of the list'.
C/C++/Java/CODASYL 'I have a list, I will navigate through it until I
have the second element, then return that element'

Lisp syntax structures its calls starting with the result (though the
effect is still procedural), Java syntax structures its calls starting
with your arguments.

The best response to this is 'programmers enjoy a challenge'.

On the other hand, the Java syntax fits in with the model of
program-as-recipe, and how real world navigation (which is something
human brains are good at) works. People like working that way, as it
fits in with their congnative model of how the software executes.
Anyway, back to lack of keywords, so every combination of what would be
keywords in CL becomes a totally separate functionName and/or
argumentList in java. This is more a lack of optional arguments, rather than keyword arguments.

IDEs also help in the other aspect that keywords do, by showing the
programmer what the names of the arguments are. Not much use on a VT100,
but on any current machine it's adequate.
In Java if you want to do this same thing with vectors or linked-lists,
you probably need to write the function yourself, because as far as I
can tell java.lang doesn't have a class for vectors nor for linked
lists, and I don't know where else to find something like
Vector.indexOf or LinkedList.inde xOf etc. Collections are in the utility package, java.util. All the features you
say you need to write yourself are provided. Now-a-days, Java's biggest
advantage is the size of its libraries.
Suppose you want to find the first or last occurrance of some name,
ignoring case. In CL it's trivial:
(search "robert" "Hi, this is Robert Maas here" :test #'char-equal)
how would you do that in java except by writing your own nested loop
from scratch?? How come the java API doesn't already include this??
Probably because no one needs to do it that often. You can convert both
to lower-case, but if you wanted fast you'd have to do it as you said.
How come the lisp standard doesn't include {threads, UI, reg ex, ...}?
Nothing is complete, and the standard libraries support the things
people seem to need at the time. As CL isn't case sensitive by default,
is supports case insensitive searches, as Java supports the version of
Unicode that was current at its inception, it has other character string
facilities that CL lacks.
2. It makes working with lists easy.

Indeed, in java working with linked lists must be an awful pain.
Either your list can contain only one kind of element, so you declair
your own class to include link-cells whose data pointer is of that
type, or you use the generic Object type and deal with having to write
code that explicitly checks the case of every element at runtime.

You tend to use the singly polymorphic dispatch mechanism. It's not as
elegant as generic functions, but it's not something you notice- the
main difference is that the generic function definition has to be placed
into an 'interface' and (if using Java version<1.5) you have to 'cast'
(coerce) the elements in the list to the interface type. It's more
typing, less elegant syntax, but no more cognitive effort.
And I just noticed: The arguent to indexOf isn't a character at all,
it's an integer!! At least in CL you can directly pass a character
object as argument to function that searches for that character within
a string, instead of coercing it to an integer first!! The coercion from char to int is automatic; this is a convenience to
counter the effect of having only one set of primitive arithmatic
operations- as all arithmetic is performed as int, you'd have to coerce
back to char if you passed the result of a bit mask etc.. As to whether
exposing such low level details is a good design policy, that's a
different matter, but it simplifies the compiler design, and the
interface to the API is the way it is to make it easier to use. In CL
you'd have to explicitly perform the conversions.
In CL, if you pass an integer instead of a character, it looks for that
integer, not the character with that ASCII code, for example:
(position 65 '(#\A #\B 65 66))
will find the 65 instead of the #\A, returning 2 instead of 0 as the
index where it found that number.

Strings are objects that wrap arrays of UTF-16 encoded characters, not
ASCII, nor are they lists of typed objects as in your example. You can't
create a string in Lisp with numbers in it, a string is a vector of
characters, each with a unique character point value in some encoding,
just like in Java.

If you are comparing function rather than syntax (which is horribly
verbose for this and many other cases), then the equivalent of your Lisp
'find the position of the first occurrence of the integer 65 in the list
....' is:
java.util.Array s.asList(new Object[]{
new Character('A'),
new Character('B'),
new Integer(65),
new Integer(66),
}).indexOf(new Integer(65))
That will return 2 instead of 0, just like in Lisp.

(normally I'd use a script to generate such lists in Java, with lisp
being the scripting language of choice)

If you want to compare two things, your arguments carry more weight if
you actually compare like with like. Saying things like 'Java is bad
because you'd have to implement lists yourself because I don't know
where the library is in Java' or 'Java development environments don't
support object introspection' isn't going to help your point, only show
you haven't done your research.

Most languages, Java included, are destined to evolve into lisp or
remain niche languages. After 50 odd years, the rate of evolution seems
faster than ever.
Pete
Jul 17 '05 #24
> From: Kenny Tilton <kt*****@nyc.rr .com>
The OP (that's me) was wondering if anything was /actually/ easier in Java. That is
cruel since Java is such a simple, powerless language, but c.l.l. is
a hotbed of savagery and demonic ritual torture.
What, are you calling me cruel??

Anyway, so-far only three ideas have turned up:
- GUIs, which however are useless to me here on VT100 dialup into Unix shell.
- Applets, ditto, can't run applets in lynx.
- Network connections (sockets, TCP/IP, HTTP, cookies, etc.), aha some
application area where I might be able to write a program that I never
got around to doing in LISP because it would have required too much
effort.

Regarding the two directions of writing expressions that involve a
daisy chain (pipeline) of function/program calls, one way illustrated
by Unix pipeline notation or successive SETQs in interactive LISP
session, and the other illustrated by nested functional notation:
These may be compared to the two ways of solving a path-finding
problem, either starting from the starting pointing and hill-climbing
toward the goal, or backtracking from the goal trying to find the
starting point.
"I live on what is left over after taxes are taken from the money I
earn."
I need to live, on what? Expendable income.
live = use(expInc);
Error, expInc unbound variable.

But where does expendable income come from? Gross income minus taxes.
live = use(deducttaxes (grossIncome));
Error, grossIncome unbound variable.

But where does gross income come from? Earnings.
live = use(deducttaxes (wages(labor)))
Error, labor unbound variable.

How much did I work? 10 hours.
live = use(deducttaxes (wages(10)))
Horay, I can live 5 hours on that amount of income, oops!!
Of course Hemingway would say, "Kenny earned money. They took out
taxes. He lived on the rest. In the rain."


Kenny worked.
shell% kennyLabor
10 hours

Due to his work, Kenny earned money.
shell% kennyLabor | wageCalc
$150

They took out taxes.
shell% kennyLabor | wageCalc | taxDeduct
$47

He lived on the rest.
shell% kennyLabor | wageCalc | taxDeduct | liveInSFBayArea
5 hours

In the rain.
shell% kennyLabor | wageCalc | taxDeduct | liveInSFBayArea > /dev/null

P.S. IMO keyword arguments, as in CL, are a much better way to do
function/method overloading than having fixed combinations of argument
types as in java, both because you get 2**n possible combinations with
only n keywords whereas in java if you wanted all 2**n combos you'd
need to explicitly declare all 2**n different methods, and because it
doesn't matter if two or more different arguments are of the same time
you can *still* have one or the other in CL whereas in java it's
impossible to do that because there'd be ambiguity in the overloading
due to two forms having exactly the same number and types of arguments.
Jul 17 '05 #25
Tim Bradshaw <tf*@cley.com > writes:
* RobertMaas wrote:
javac or java takes appx. 24 seconds to start up the first time, then
is virtually instant subsequent times within a short time span. ... You need to re-start java every time you want to compile and every time
you want to run what you compiled, you can't just leave the jvm running
and load tasks into it. Consequently, if you go away from java for a
minute to edit the source to recompile it, etc., then you're back to 24
seconds start-up again when you want to compile what you edited, a
royal pain! ...
... This would imply you are, I think - something is causing the
cached fs pages to be flushed rather aggressively. I don't build Java stuff, but I sit next to people who do, and they
don't see these issues with Sun's 1.4.x JDK. *But* we have sensibly
configured development machines - I think they all have 4GB memory.


"Sensibly configured ... 4GM" -- is there some automatic irony
there?

I don't have 24 second start-up for Java, but it is noticeably
slow compared to Lisp.

-- jd

Jul 17 '05 #26
Some things I find easier to do in Java:

* Threads
* GUIs
* XML processing
* Structuring systems (packages, nested class definitions)
* Little, local classes

Major lacks in Java:

* Macros
* Concise notation for functions or similar.
* Lists [Yes I know about java.util.List]
* Source code syntax for data
[Java has some for numbers, strings, arrays, but not for
Collections, Maps, instances of arbitrary classes.]

A couple of people mentioned large libraries as one of
Java's biggest advantages. They're also one of Java's
biggest disadvantages.

-- jd
Jul 17 '05 #27
Jeff Dalton wrote:
* Source code syntax for data
[Java has some for numbers, strings, arrays, but not for
Collections, Maps, instances of arbitrary classes.]


I take it you mean the result of using print with *print-readably* true.

It works, I suppose, but try doing it for hash tables - in SBCL, at least,
the result involves "#.", which makes me unlikely to use it for
network-received data. In all fairness, Java fell off the haystack a mile
ago, but is there some way to fix this other than to write my own
(print)?
Jul 17 '05 #28
> From: "John Harlow" <si********@hot mail.com>
It takes me less than a second to recompile a large application with
hundreds of source files. I have no idea why your apps take so long
to compile, but it's surely not because of java per se.


Maybe you've just used java a moment before, so all the pages of the
jvm and compiler are still in fast cache? Or maybe you are on a
computer where several other users also use java on a regular basis, so
at any given moment one of them is likely to either be using java at
the moment or ran java just a moment before. In any case, here where
java is hardly ever used, if I wait a few minutes since I last used
java, then try to use it again, there's a multi-second delay for it to
even start up:

% more T.sh
date
javac OneLine.java
date
% ls -lt OneLine.*
1 -rw------- 1 rem user 17 May 19 11:54 OneLine.java
% more OneLine.java
class OneLine {}
% sh T.sh
Wed May 19 12:12:46 PDT 2004
Wed May 19 12:12:57 PDT 2004
% ls -lt OneLine.*
1 -rw------- 1 rem user 188 May 19 12:12 OneLine.class
1 -rw------- 1 rem user 17 May 19 11:54 OneLine.java

That's appx. eleven seconds to start up javac then compile an
essentially empty java source file. Do you believe me now?
Jul 17 '05 #29
> From: Kristian Elof Sxrensen <el**@image.d k>
Thats one of the reasons why java programmers have been using the
jikes compiler instead for the most recent 6-7 years ,-)
I did a 'whereis' here on Unix and it seems not to be present. I have
less than 20 megabytes remaining on my personal account, and I'll need
most of it myself. How much total does jikes require to install, both
source and result after installing?
The other reason is that it produces much more informative error
messages than javac does.
javac's compiler messages have been enough for me so-far. For example,
it warns me that my whole class needs to be declared abstract because I
have at least one abstract method within it, or because it extends an
abstract class but fails to define all the abstract methods from it.
And for local syntax errors, the line number is sufficient to go back
into emacs and find the offending line.
What takes 24 seconds to restart?
javac or java, if neither has been used recently The actual time
varies, sometimes as long as 24 seconds, more commonly 8-15 seconds.
Let me try the shell script I wrote the other day and see how long it
takes when I haven't used java at all for many hours:
% more T.sh
date
javac OneLine.java
date
% more OneLine.java
class OneLine {}
% sh T.sh
Sat May 22 14:03:23 PDT 2004
Sat May 22 14:03:57 PDT 2004
Gee, a full 34 seconds, give or take a second!
The read-eval-print way of hacking is the single largest productivity
enhancer I have found in CL as compared to java.
I agree. If you're experimenting with some really complicated part of
the API you've never used before, it makes the difference between "can
do" and "give up".
Optional arguments and keyword arguments.
Optional arguments are usually not so wonderful, but keywords arguments
are a **big** win! In fact for self-documenting code, optional
non-keyword arguments may actually be a bad idea. They are for things
you don't often use, right? Well if you don't often use them, then you
often forget what they are for. But keyword arguments remind you what
they are for. Compare for example in current CL:
(read-line netstream nil nil t)
It's pretty obvious that first optional argument is the stream, both
because you use it often enough to remember it, and because the actual
argument says something like that. But it's a pain to remember what the
other three optional arguments are. What if it were like this instead:
(read-line :INPUT-STREAM netstream :EOF-ERROR-P nil :EOF-VALUE nil
:RECURSIVE-P t)
Now you can just look at it and see what those arguments are, instead
of trying to guess, or running to the manual and spending several
minutes just to analyze this one line of code. For user-defined
functions with varying number of argument, there *is* no manual, and
the next programmer hasn't memorized all of this programmer's
conventions and function definitions, and shouldn't, and it's a pain to
have to look up each function definition to see what those optional
arguments are for.
CLOS dispatches on the type of the instance where java dispatches on
the type of the reference.
I don't quite understand what you mean here. In java, the compiler
enforces the rule that you can implicitly cast to a superclass, because
that will always work, but to downcast you need to explicitly cast,
which generates runtime code to throw an exception if the object isn't
really of the type you're trying to cast it to. But in fact at runtime,
regardless of whether you downcasted or not in the source, which
overridden method really gets called is determined solely by the actual
type of the object, not how the reference variable or expresion was
declared or cast.

Or are you talking about overloading, where it's the number and
sequence of declared types that determines which override-set gets
searched in the first place?

I guess I need a slightly more detailed explanation of what you are
saying about java before I understand your intent.

RM> is there any other area where java beats CL?
Anything that needs kernel threads.


Hmm, I've never used kernal threads, except when using the RUN-PROGRAM
function to call some other (non-CL) program from inside CL. Maybe it's
a case of since CL doesn't have it and I use CL it never occurred to me
that I needed it, just as non-LISP programmers don't understand why
having a near-universal READ and PRINT is useful, or why having actual
SYMBOLs at runtime is useful, etc., which we LISP programmers take for
granted and use all the time and don't want to live without.
Jul 17 '05 #30

This thread has been closed and replies have been disabled. Please start a new discussion.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.