Re: Comparing Lisp conditions to Java Exceptions



Peter Schuller <peter.schuller@xxxxxxxxxxxx> writes:

> But 'significant' means real practical stuff.

Then what kind of error do you signal when you get a hardware memory error
in an operation that is supposed to not signal any error, but that discovers
it has an incorrect result?

Java sweeps this under the rug of "runtime exceptions", but that makes it
hard to do type dispatch, and even harder in a world that is entirely
single-inheritance, since it assures that you cannot do

ARITHMETIC-EXCEPTION
/
RUNTIME-EXCEPTION FLOATING-POINT-EXCEPTION
\ /
RUNTIME-FLOATING-POINT-EXCEPTION

Instead you must have

EXCEPTION
/ \
RUNTIME-EXC STATIC-EXC
/ \
RUNTIME-ARITHMETIC-EXC STATIC-ARITHMETIC-EXC
...

Are you arguing that this is "better"?

Here's what I have to say about the design of "practical" stuff:

You cannot, through linguistic definition, make the Universe be other
than it is. All the ISO standards in the world will not make the world
single-inheritance. All the requirements in the world to declare all
possible conditions at compile time will not make those the only possible
conditions. The world is not static. I prefer a programming language
that is not either.

Nothing keeps you from annotating your program with exceptions based on what
YOU want to say about YOUR programs. Nothing keeps you from writing a
post-processor that assures that all your connectivity is solid according to
YOUR standards.

The question is not that here. You are (apparently) alleging that the
language (by which you can read "all people") should adhere to your theory.
You are advocating a theocracy. We have tried to design a language that
separates church from state.

> .. in real applications,
> error handling is very important. A networking server must be able to deal
> with sockets errors without terminating; a mail user agent must be able
> to differentiate between expected real-life problems (i.e., networking
> issues) and internal bugs. Unfortunately, I have personally found the
> error handling situation lacking in Lisp (aswell as Ruby and Smalltalk). It
> is not that the condition system in and of itself has a problem; it is rather
> how it is used and documented.

If you worry about these things, you need to be in a serious
discussion with your implementor about what situations are not
catchable. They SHOULD only be signaling fatal things using ERROR or
SERIOUS-CONDITION. You should be able to "catch" (but not necessarily
restart) those things. If you want to catch things without losing
state, you need to move these dynamic handlers inward in your program
to the nearest point where you don't mind the setup overhead but can
wrap around an operation you want to be restartable.

This is an issue of HOW you do it, not whether you can do it.

Curiously, although you don't say it, Java has the opposite problem. It
isn't about how but whether, because the language thinks it knows better
than the programmer. It forces me to NOT write code that will handle errors
that it thinks it cannot signal. That doesn't mean those errors won't
occur--the REAL WORLD determins what errors can occur [abstractly, I mean,
not as a language manifestiation]. But it means Java won't let you signal
them "in program" and won't let you negotiate how to handle them "in program",
and so forces yuu implement, extralinguistically, the support you want.
This does not seem to me practical for an expressional programming language,
and is why I classify Java as an high-level assembly language--to be used
but not seen. Your mileage may vary.

> Specifically, the problem is that the conditions signaled by a function is
> almost never documented!

This is not a problem of the language. You can easily force them to be
documented:

(DEFPACKAGE RIGID-LISP
(:USE COMMON-LISP)
(:SHADOW DEFUN)
(:EXPORT CAR CDR CONS ... RIGID-DEFUN ...)) ;<--better done programmatically,
; but you get the idea

(DEFMACRO RIGID-DEFUN (NAME CONDITIONS BVL ...) ...)

How easy is it to do the equivalent in Java to relax the standard if you
don't want it?

> I am not talking about every single possible problem
> that might occurr as a result of internal library bugs or bugs in calling
> code.

I am.

What solid program expects its libraries to be bug-free? Do you believe
that, by a bit of time and care, including the careful application of some
sort of induction, it's possible to build an infallible system?

The problem with proving programs correct is not the math, it's the
willingness to encode in logic all the possible ways a program can fail.

> But the *EXPECTED* conditions that *ARE* going to happen in real life.

That doesn't sound very rigorous or practical.

> In this regard, I must say that I find Java exemplary.

I find it exemplary, too--of something I'd least like to use. Heh.

But, you know, I'm not saying it shouldn't be used. I just question that
using it will provide all the things people think it will.

> Given a function that operates on a stream, or a file, or any kind
> of external resource, there is documentation as to how these error
> conditions are handled (be it by returning some special value or by
> throwing an exception).

Good documentation can be solved by commerce. If there is a market, people
will buy it. But if no one is springing for serious dollars for doc, then
don't think that you can fix this through the language design process.
It's been tried, I'm sure. I think Ada wanted a lot of doc. COBOL, too.
And you don't see those ruling the day.

And indeed, Java has lots of doc, but it's not always structured in the way
that's most useful. There turns out to be great value in documentation that
is not 100% aligned with the structure of the modules. I'm not discounting
the need for this structured doc, too--CLHS does it. I have internal doc
in my code that does this. But it is not all people are asking for when they
want doc. And language standards can't require it.

In 1980's, TECO used to require documentation on every function. And Emacs
Lisp, as a consequence, has this flavor. Emacs Lisp code is much more heavily
documented than other lisp dialects.

We tried to encourage documentation in Common Lisp by adding DOCUMENTATION
functions and whatnot, but that hasn't led people to do what they won't do
anyway.

And in this day of a tight economy, the price of excess will be squeezed out
of everything. If you can make time to market without such excess, that's
what will happen. You don't fix this by making the language more cumbersome;
that just makes the language an impractical vehicle for commercial use.

> This is information I, as someone
> writing calling code, MUST know in order to write robust and correct code.

Then talk to your vendor and tell him how much you'd pay.

Because I'm ASSUMING you mean you have no lisp on your desk now because you
won't pay for anything that is less than that. Or else I assume your meaning
of "must" is synonymous with a sense of optionality, since if you buy without
requiring it, YOU are making it optional, not required.

Lisp vendors react to money, not rhetoric in the design of their product.

The only Lisp dialect I know that specified all the conditions it signaled
in low-level code as Zetalisp, on the lisp machine, and it went bankrupt
years ago. (Not for that reason, but the point is that it has been tried.
And while it was useful, it didn't make the language so valuable that it
survived other, much more petty, market pressures.)

> Consider this fictional pseudo-Java code that is part of a fictional
> RDBMS backed lookup server similar to LDAP (or POP3 or whatever):
>
> ...
> A couple of things to note:
>
> * The code is able to differentiate between I/O errors having to do with the
> communication with the client, from database related errors caused by
> the attempt to access the database. In ths context of the server, these are
> logically quite different errors and must be treated differently.

Lisp lets you do the same. It does not standardize the behavior. Contact
your vendor and ask what conditions are signaled. They can tell you.
It is certainly EASY to tell you at the blunt level of an overall condition
like I/O error or SQL error. Lisp probably gives you hugely more refined
recovery than other languages. But these aspects are not part of standards
of today, so don't look to Lisp to answer your questions. Look to the
vendor. (It's not even clear that expecting standards to fix things would
work--it would impede the rapid change and responsiveness to the market
that comes from leaving it under vendor control.)

> * If the SQLException was thrown due to some underlying I/O problem,
> this information is not lost; in fact it would be reported as the
> causal exception in a stacktrace.

Stacktrace? Ugh. How low-level is your error reporting? Lisp will give you
lots better ways to cope than this. I suggest that you have not scratched
the surface of what it has to offer you.

> But at this level in the calling code, all that is relevant is that it
> is a database > errors; we don't care whether the database is remote,
> local or in-memory or what possible errors the implementation might
> encounter. Thus we expect the database API (JDBC and the JDBC driver)
> to emit only SQLExceptions and subclasses thereof.

I disagree with this. An SQL error is if SQL makes a mistake. A hardware
error, for example, is a sign of a serious malfunction in your computer. If
you mask this as an SQL error, you will file the report in the wrong place,
and will wait much longer to handle it than you should. Lisp's theory, which
you can feel free to agree with or disagree with, but which is at the heart of
dynamic condition handling, is that you should handle precisely the errors
you expect and not others. If I do

(handling-foo-errors ()
(invoke-bar-facility #'foo-service))

and BAR masks out any FOO error, how will HANDLING-FOO-ERRORS ever get a
chance to correct it.

KEEP IN MIND, that unlike the Java or most any other condition system save
ones like Dylan that are Lisp-like, conditions are handled in the point on
the stack wher they are signaled, and the stack has not been unwound. So a
FOO error could be RECOVERED quietly without the containing BAR facility
knowing it even happened. That's unlike anything Java offers.

> Note that someone made a very good point in this thread about how the Common Lisp
> condition system allows two components to communicate via conditions, even though
> the intervening code has no knowledge or support of said communication.

Indeed, a number of such points are made in the condition papers at my web
site. You might read them.

> In this case we could have the calling code (the server)
> co-operate with the JDBC driver IF this was desirable.

As it could happen in Lisp, but it seems cumbersome and non-abstract.

> But in
> cases where it is NOT desirable, we instead run into the
> problems below.

In what case would it be non-desirable to a person who understands Lisp and
how it is SUPPOSED to be used to modify a bunch of intervening functions
that were not involved, just to make them more fragile against future code
change??

> How do I do this in Lisp?

It's possible to do all of those things you cite straightforwardly.

> Consider (and *PLEASE* correct me if I am misstaken on anything):
>
> * Reading the CLHS, the spec is only concearned with type errors when
> it comes to the I/O functions (read-line, read-byte, write-byte, etc).
> The exact condition signaled in case of a problem is entirely
> implementation dependent.

You are incorrect. "only concerned with" is not an appropriate aggregation.
Standards cost money. We had no more money to keep doing standards-making.
So we stopped at this point. CERTAINLY we cared about doing more. It cost
a minimum of $450,000 and 6 years of full-time work by editors, not counting
man-years of review time, a lot of travel time, in-person time at dozens of
meetings, email in the tens of thousands of messages, etc. to produce ANSI
Common Lisp. Do you want to pony up the next chunk of cash to continue
that process? You sell us short by saying we were "only concerned with"
this much.

> Thus, if I am to be portable
> I *cannot* do what the Java code does above,

Java (i.e., Sun) has spent HUGELY more than we did making this portable.
(AND, incidentally, Sun's Java process has not been as open as ours.)
Find us a funding source as generous as Sun and we'll get right on it.
Seriously, this is such a ridiculous comparison I can bearly stand it.

> unless i go out and investigate the
> situation for each and every Common Lisp I might want to support.

Money, money, money.

And every single person who GIVES AWAY free software in the world should
think about how they bring down the price of software because now the world
thinks it should get everything FOR FREE. Which means it's EVEN HARDER
to get funding.

If you don't think money is everything in this equation, you're
denying reality.

> * Taking sbcl as an example, I have uncovered no documentation as to
> what conditions are signaled by the various functions in sb-bsd-sockets
> (except nothing to the effect of "might signal some kind of condition").

There are two ways to answer here:

First, SBCL is itself harming the industry by catering to the notion that you
don't have to pay to acquire something. If you had had to pay money to them,
maybe you would not have bought it because market forces would have said
"it doesn't offer what I want" and maybe it would have gotten better because
it wanted those dollars. But since it isn't responsive to dollars in that way,
it doesn't respond to that kind of market force.

Second, I don't doubt that the SBCL (or any) maintainers would take
your cash directly to get what you want. But I'm betting you're so spoiled
by Sun giving away free Java that you think anyone can mount the resources
they've mounted to manage a free operation of that size. I don't mean to
say this in a way that maligns you, just that opens your eyes to the fact
that what you get from Sun is very commercially valuable and the fact that
they don't make you PAY that value, they recover it in other ways, makes you
mistakenly believe that ANYONE could muster that kind of value and give it
away and find some other way to recover the cost. The world isn't
that simple. So before you go praising Java, consider whether if Java were not
free from Sun or anyone, how much would you pay for it. Now imagine if you
paid that same amount for a Lisp how much more doc they could provide. But
you won't pay that for Lisp, and not because it doesn't add value, but because
you can get Java for free, and it drives down the cost you'd pay for Lisp or
anything.

There are other threads here talking about trying to find jobs. You're kidding
yourself if you don't think all this is interconnected.

I saw a thread where someone said he was charging $1/hr and wondered
if someone wanted to underbid him. That is the road to the death of
an industry. The problem right now is not that the US charges too
much, it's that the rest of the world charges too little. When their
standard of living comes up enough, and if people learn some sense and
stop making free software, then we CS people may be able to charge for
the value we provide. But as long as everyone is just scrambling for
enough to eat, and when they're not eating and not working they think
it's appropriate to just give stuff away, the bottom will be forever
gone from the market.

Computer science people need to understand that they have something of
value that the world wants, and they need to charge for it. Not give
it away. Money is not evil. Money keeps people fed. Failing to charge
money won't mean other people don't get rich--it will just mean that no
one with computer science sensibilities will get rich. People who rule
the world will be people with no understanding of math, process, etc.
All the ethical force of a lot of bright people is presently hugely
misdirected due to the false god of free software.

And then it filters down to arguments like this where people try to
discuss value of things without discussing money. And compare things
they plan to pay no money to. Well, "zero" is in this equation a lot
(the amount you want to pay, mostly, but in a lot of places), and zero
tends to have non-linear effects on lots of equations, causing you to
misjudge things.

> Looking at the source code I can figure it

Lucky you can afford that. More value for free. No wonder again they
have no money coming in to support a doc effort.

> out, but even then (if I remember correctly, and I might not
> because this was a while ago) the exception hierarchy is mostly
> concerned with mirroring the possible return values of
> underlying syscalls, rather than offering a categorical
> hierarchy (i.e., differentiating "connection failed" from "some
> error happened during normal I/O on an open connection", etc -
> although in THIS case this is not offered by Java either).

Funny, I thought the "free software" answer to this was that YOU who want it
should contribute money or time to add what you want.

You sound like you're not holding up your end of the trade.

But then, you're not required to. Ain't "freedom" great?

> * If after having looked at the sb-bsd-sockets source code I make my
> code correct for the case of sbcl, (1) I am still only supporting sbcl,
> and (2) I have no clue how "official" the set of signalled exceptions
> is, or whether it might randomly change in a future release.

Ain't free software great? (did I say this already?)

Next time I'd withhold your funds from these evil folks.

> I have experienced the same thing with other Lisp variants

You've used others? But I thought it "MUST" have the doc you needed.
I guess "MUST" does in fact mean "doesn't really have to at all", as
I suspected above.

The free market is not a magic engine. It works only in one way. You
hold money back from people who don't give you what you want until they do.
When either they don't ask for money or you won't give it or you will freely
give it whether they give you what you want or not, I don't see how you
expect it to work. I've never seen "newsgroups" in any discussion of how
the free market works.

> (I've
> looked at a number of Scheme:s for example). In the case of Scheme
> the error handling *mechanisms* aren't even all that useful in some
> cases; and in the cases where the *mechanism* is powerful "enough"
> for my purposes, the documentation offers *no* clue as to actual
> error conditions signalled by the library. I haven't gone so far as
> to inspect the source code of all these Schemes I've looked at. The
> same goes for portability API:s like CLOCC and such - no "official"
> error signaling seems to exist, and who knows what might happen on
> different implementations. A cursory look at some of the source
> gave me the impression that's it is not just a documentation issue,
> but that the issue really isn't tackeled, and code will result in
> different conditions on different platforms (CL implementations).
>
> Am I the only one who feel this is a problem?

You're one of a small number who periodically don't understand the
economics and so barks up the wrong tree, aggravating people who have
given you stuff for free, wishing they'd give you more for free.

I don't like free software, but some people do. Even so, those people
who do have a moral code that says that when you don't like something,
you should fix it, not sit back and whine about it. That doesn't help.

So pick your paradigm. Like free software and work within it, or like
commercial software and spend your money where it will help.

And don't pretend that Java is a fair comparison to anyone. It isn't
a commercial endeavor per se. To understand Java, you must broaden your
view of the world wide enough that the money is accounted for. You have
to go wide enough to see all the consulting that goes into it. And you
have to understand that when it started, it didn't just survey available
languages for one to use, it made up a bunch of vaporware claims like
"write once, run eveywhere" which didn't turn out to be true. "write once,
debug everywhere" was soon after the motto. It's paid a lot to address
some of that, but the language continues to change when they promised it
wouldn't.

> Have I missed something?

Lots of things.

> How do people solve this problem when writing real programs in Lisp?

If they have a legitimate commercial need, they get in touch with their
vendor (by which I mean either a free software maker or a commercial seller,
incidentally, but either needs money to survive) and they tell them what
the missing feature is worth. Then the vendor says whether the amount they
have to offer is enough incentive. And then they do the rest, the part they
think is cheaper for them to do than to pay a vendor to do, themselves.

> For a while I have toyed with the idea of making my first "real"
> project a "Common Lisp Common Library" of sorts; which would be a
> portable library with various functionality that is often very
> practical, and which would have properly documented error
> conditions.

Just to give away? Do you think that will drive up or down the cost of
software? Do you think it will improve your ability to make money later?

What is your present source of funding?

If you think you'll sell this, do you think you'll add so much value or
make something so original that some free software "sniper" won't immediately
follow your effort with something free?

> It would also try to present a "Lisp:ish" API rather than "superficial" wrappers around
> various POSIX API:s. In short, my goeal would be to be able to write code similar to
> the following and have it be portable (excuse any broken indentation and the fact that
> it probably wouldn't even compile):
>
> (defun listen-loop (socket)
> (handler-case
> (loop (start-thread #'handle-client (accept socket)))
> (io-error (ioe) (log-error ioe)))
>
> (defun handle-client (stream)
> (unwind-protect
> (handler-case
> (progn
> ... authenticate and parse request
> (handler-case
> (let ((stuff (get-stuff client-request)))
> (write-line stream "+OK data follows")
> ... write data)
> (database-error
> (dbe)
> (progn
> ... log the problem
> (write-line stream "-ERR internal server error"))))
> (flush stream))
> (io-error (ioe) (log-error ioe)))
> (handler-case (close stream) (io-error () nil))))
>
> (Things like (with-open-stream ...) to guarantee that the stream is
> closed would clean that up a bit)
>
> Does anybode agree with me, even a little? Should I just not bothering doing
> something like this because nobody would be interested anyway?

If you want my bet:

People are interested in bleeding you dry for anything you want to
offer for them to use for free.

As to paying, the only way to find out is to do it and see what comes.
There is no way to ask the question in advance and trust the answer.
It might work, but if you asked and people said "I'll pay" probably six
other people will rush to compete with you. And maybe no one really will
pay, and all six will lose. Or maybe there will be a big market. But
that might be true even if no one responded. comp.lang.lisp is not the
market, and arguably not even representative of the market.
.



Relevant Pages

  • Re: casts
    ... This is why most shit programmers refuse to learn languages including ... C Sharp and Java. ... compiler in a later edition of Visual Basic, ... language for processing data. ...
    (comp.lang.c)
  • Re: C, really portable?
    ... > Wait, is Java a modern language superior to C, or is it still ... It is a much better OO language than C++, ... It depends what you are doing, Java aims for rigorous portability - the same ... regardless of platform. ...
    (comp.lang.c)
  • Re: Is anybodys favorite computer programming language not included here?
    ... to talk about getting me some paying work writing Java classes. ... and could be copied to a script (as in Java BeanShell or Lisp PROG). ... >> please post a followup saying what language it is, ... Server: "Mother, ...
    (comp.programming)
  • Re: Difference between .NET and Java
    ... My Java2 knowledge is ... Microsoft intermediate language is opened for language developers to ... .NET is compiled to MSIL - this is analogous to Java ... similarities between the CLR and the Win32 API. ...
    (comp.lang.java.programmer)
  • Re: Basic inheritance question
    ... used 'this' in C++ and Java. ... but in Python it doesn't. ... language, they would write a lot of ten liners that is changed a LOT ... Add three levels of inheritence and a couple globals and you'll find out ...
    (comp.lang.python)