About the usage of throw/catch 
Author Message
 About the usage of throw/catch

Hello,
at my university, a computer scientist says the usage
of throw/catch in Lisp constitutes "dirty programming".
Could someone who has been programming in Lisp for a long
time tell me if she's right ? If it is so, why should it
be considered as "dirty programming" ?
Thanks in advance.

--
===============================================================================

Batiment 710, UFR Informatique, Universite Claude Bernard Lyon 1
43 boulevard du 11 novembre 1918, 69622 Villeurbanne cedex, France



Tue, 25 Jun 2002 03:00:00 GMT  
 About the usage of throw/catch


Quote:
>Hello,
>at my university, a computer scientist says the usage
>of throw/catch in Lisp constitutes "dirty programming".
>Could someone who has been programming in Lisp for a long
>time tell me if she's right ? If it is so, why should it
>be considered as "dirty programming" ?

Like most generalizations, it's wrong.  CATCH and THROW can be abused, like
GOTO's in many languages.  Many uses of CATCH and THROW in earlier Lisps
were for error handling, which should now be done using the condition and
restart mechanisms.  Also, BLOCK and RETURN-FROM may be applicable in many
cases.

The main reason he may be saying they're "dirty" is because they're
dynamic, not lexical like BLOCK/RETURN-FROM.  Catch blocks are therefore
like special variable bindings -- an implicit part of an interface that's
not obviously apparent in the calling sequence.

--

GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.



Tue, 25 Jun 2002 03:00:00 GMT  
 About the usage of throw/catch
On Fri, 07 Jan 2000 17:51:21 +0100, Alexis ARNAUD

Quote:

>Hello,
>at my university, a computer scientist says the usage
>of throw/catch in Lisp constitutes "dirty programming".
>Could someone who has been programming in Lisp for a long
>time tell me if she's right ? If it is so, why should it
>be considered as "dirty programming" ?
>Thanks in advance.

CATCH and THROW have their place, but starting programmers will
probably not have need to use them often. The conditions system now
should replace these operators for exception handling uses, and macros
and operators like UNWIND-PROTECT, WITH-OPEN-FILE, etc. probably use
these operators internally.

I think of CATCH and THROW a bit like GO. They are primitive
operations on which all non-local transfer of control can easily be
built. They can be used to do things like modify the language (create
a new language). For most programming, I think you can stick with the
conditions system, provided your CL implementation supports this (it's
part of the ANSI spec). BTW, Corman Lisp 1.3 (and PowerLisp) do not
support condtions. Corman Lisp 1.4 (available soon) does support them.

I think Lisp's CATCH and THROW were at least partly the inspiration
for the exception handling of C++ and Java, which also use the names
catch and throw, for similar, albeit somewhat more complex, purposes.
Catch and throw based exception handling is the state of the art in
these other languages. As usual, Lisp has left them in the dust with
the far more expressive and better-designed condition architecture.
The basic important elements of non-local control are boiled down to
their fundamentals: Conditions, Restarts, Handlers. Each one becomes a
first-class object. I anticipate that it will take another 10 years or
so for this advance to make it into some mainstream language (unless
of course some Lisp manages to make it to the mainstream before then).

Roger Corman



Tue, 25 Jun 2002 03:00:00 GMT  
 About the usage of throw/catch

Quote:
> Hello,
> at my university, a computer scientist says the usage
> of throw/catch in Lisp constitutes "dirty programming".
> Could someone who has been programming in Lisp for a long
> time tell me if she's right ? If it is so, why should it
> be considered as "dirty programming" ?

Using throw/catch when you could you block/return-from is probably
suboptimal, but otherwise throw/catch is a perfectly fine way of doing
dynamic transfer of control.  The other possibility would be to use the
condition system.

-- Harley



Tue, 25 Jun 2002 03:00:00 GMT  
 About the usage of throw/catch

Quote:
> The basic important elements of non-local control are boiled down to
> their fundamentals: Conditions, Restarts, Handlers. Each one becomes a
> first-class object. I anticipate that it will take another 10 years or
> so for this advance to make it into some mainstream language (unless
> of course some Lisp manages to make it to the mainstream before then).

Actually, Smalltalk has had this model for about 20 years with the only
difference being that you might have a slightly more flexible set of restart
options (Smalltalk has return to the throwing context, return to the
catching context, throw a different exception, continue computation within
the context of the handler - although these may be the ones available in the
Lisp system, as well).  The terminology is different, with "conditions"
corresponding to subclasses of the class Exception in the Smalltalk world.
And each exception is an object which can hold any sort of data.  The
performance of exceptions is quite good in most implementations as well
(generally faster than in C++, although that's damning with quite faint
praise).  Of course, whether or not one considers Smalltalk to be a
"mainstream language" is debatable.  And you're probably right about the
primitive languages taking at least another 10 or so to catch up...

faa



Tue, 25 Jun 2002 03:00:00 GMT  
 About the usage of throw/catch

Quote:



> > The basic important elements of non-local control are boiled down to
> > their fundamentals: Conditions, Restarts, Handlers. Each one becomes a
> > first-class object. I anticipate that it will take another 10 years or
> > so for this advance to make it into some mainstream language (unless
> > of course some Lisp manages to make it to the mainstream before then).

> Actually, Smalltalk has had this model for about 20 years with the only

Well, the Lisp machine had these for decades, too.
Unfortunately the C++ crowd looked at the Lisp condition system
and they decided *not* to include continueable exceptions (exceptions
in C++ terminate the context - in Lisp handler gets called and
from there you can continue, if you like - in C++ you can't continue).
They asked some TI hackers and they told them that this was rarely needed.
How stupid. ;-) I use this facility all the time.

Common Lisp has a nice condition system.

Rainer Joswig, ISION Internet AG, Harburger Schlossstra?e 1,
21079 Hamburg, Germany, Tel: +49 40 77175 226



Wed, 26 Jun 2002 03:00:00 GMT  
 About the usage of throw/catch

Quote:
>in C++ terminate the context - in Lisp handler gets called and
>from there you can continue, if you like - in C++ you can't continue).
>They asked some TI hackers and they told them that this was rarely needed.
>How stupid. ;-) I use this facility all the time.

The language MAINSAIL (machine independent SAIL) (yes, derived from
Stanford's 1970-era SAIL) has continuable exceptions also.

Please list (at least in prose) some of the USES you guys
have found for continuable exceptions -- I think there are
some pretty neat things you can do, "obvious" ONCE someone
has pointed them out!

(if you are going to talk about "continuations", please
at least define it somewhat -- I've never quite "gotten" them.)

David



Wed, 26 Jun 2002 03:00:00 GMT  
 About the usage of throw/catch

| at my university, a computer scientist says the usage of throw/catch in
| Lisp constitutes "dirty programming".

  it continues to puzzle me that people who are willing to accept that in
  any field worth studying, there will always be a limit to how much _one_
  person can know, for simple logistical reasons: it takes too much time to
  learn it all, like much longer than a human lifetime.  yet in computer
  science, that which one person, typically less than 30 years of age,
  doesn't know is somehow bad, unworthy, dirty, etc.  I'm inclined to
  believe that such people are inherently unable to deal with complexity
  beyond their own immediate grasp, and as such should not be dealing with
  computer science in the first place, since the whole field is all about
  managing complexity far beyond direct human capabilities, despite the
  evidence we see from dummies who want to learn "programming" in 21 days.

  ask your "computer scientist" whether the use of exceptions is also bad.
  while you're at it, ask her if the RETURN statement in C is dirty, too.
  and if the problem is that GOTO's are bad, what about WHILE?  WHILE is no
  more than dressed-up version of GOTO.  THROW and CATCH are similarly a
  form of GOTO that are not only dressed up, they have university degrees.

#:Erik



Wed, 26 Jun 2002 03:00:00 GMT  
 About the usage of throw/catch
Obviously, from reading the other postings, opinions differ.

I weigh in on the side of thow/catch being "dirty".  I also
weigh in on the presumably more controversial side of
even return-from as being "dirty", not to mention a
go outside of the originating tagbody.

The "dirtiness" arises partly from the lack of reusability of the resulting
code.  It also arises because all the intervening unwind-protect code sequences
must be executed "during" the non-local transfer, EVEN if the user doesn't
THINK he wrote any (they are used in macros, and something akin to them must be
used to "unbind" the bindings of special variables (in almost all
implementations that support special variables)).

A "clean" piece of code in any language should, ideally, never, EVER, for ANY
arguments whatsoever,  do a non-local transfer of control,
of any kind.   REASON: suppose you want to use that piece of code
to compute the "answer vector" to a suitable vector of "argument lists".
Any non-local transfer of control will mean that, unless "all" of the vector
elements properly "work", even if the "answer" computed is "you gave me bad
arguments", then not all of the answers will be computed: you can't "split" the
control and "throw" for "some" elements, and not for others, UNLESS some
explicit futzing is done by every such user of the code.  Even if the language
supports restarts, it is harder to use the original function.

Also, a "clean" piece of code should NEVER, EVER, either "run out of stack
space" (somebody neglected to put a check in for available stack space, at the
minimum) or run "forever" (somebody forgot to
put in a "max compute time allowed" piece of code), or run out of
memory (either ram or disk)  and "crash" or "throw".   Further, a
clean piece of code should NEVER, EVER get a divide by zero, or
floating point overflow "exception" or any similar situation.

The advantage to only writing "clean" pieces of code is also that it is often
easy to show a function is "clean" if all the functions it invokes are clean.
Done properly, the entire application then tells the user either the "right"
answer(s), or "because of ... the answer could not be computed."  The second
answer is far better than a meaningless answer that the user is misled to
believe is right, or a compute loop, or a core dump, or other {*filter*} behavior.

Just as "clean" code is far easier to build when building on "clean" parts,
using "dirty" code leads to more "dirty" code to try to fix up what wasn't done
right in the first place. Unfortunately, some popular languages, such as c and
c++, are full of "dirty" primitives, and it is hard to write "clean" code in
such languages. Lisp has far fewer "dirty" language elements, and even has a
substantial number of language elements that help hide low-level "dirtiness" so
the larger piece is "clean".

It is essentially impossible, in almost all popular languages, to program
without using any assignment statements. It is not even hard in any lisp that
supports tail-recursion, to write LARGE pieces of complicated code that do no
assignments (setq, setf, push, incf, etc) or destructive operations (nreverse,
rplaca, etc), but confine themselves to iteration via tail-recursion or
mapping, and data "modification" via binding.
Of course, inside the implementation, assignments will be happening,
but THOSE are not the ones (typically) that cause the bugs in applications.  As
an "extremist", I consider most assignments to be
"dirty", even if they are "only" to local variables.  

Again, the reason is the same as for throws, gotos, etc.  Although the problem
is in some ways less severe, such assignments cause the compiler or other code
transformers to be very limited in the range of what they can do.  Its too
hard, typically, in the presence of assignments, to be sure that a code
transform has done the "right" things. So the compiler generates inferior code.

In fact, the whole NOTION of "variables" is a bad idea: it constitutes a
"premature optimization" decision, made by the programmer, that MAY, or MAY
NOT, be a good idea.  And its hard for even good compilers to undo the
optimization, and be sure they haven't damaged the semantics of the program.
Instead, consider the language of mathematics, where infinite series are
"normal", and a function which gets from "earlier" elements in one or more
series to later ones. Such a formulation is just as powerful and expressive.
But, it allows the compiler to decide how to "fold" the series elements into
registers, or memory, or actual vectors.  Further, a change in the program can
then make the compiler revise its earlier decisions, even though almost all the
source code is identical.  

Said again: in all of mathematics, except for those branches that study the
semantics of computer programs, there is no "assignment" notion. And its done
that way because it is easier for people to understand "timeless" (although
infinite) series, than assignment.

This may all sound "esoteric" and "theoretical" -- but, I assure you, it is
not. I have written many large programs, and debugged many written by others,
and have learned to hate the assignment statement, the uninitialized vector,
the unitialized variable, the non-local transfer of control, the "dirty"
primitives, and the "dirty" subsystems.  Clean code is possible, and it also is
far less buggy, and far easier to add new features, or explain to someone else
how it works.

Compilers, (I've written my share) have to go to extrodinary lengths to
overcome the problems introduced by assignments and pointers. You will find, in
fact, that a good lisp compiler will normally, for the same application,
produce code that runs faster than c++ or c, because, primarily, both c and c++
pass many "pointers" around, and the compiler cannot normally figure out wheter
a value is altered by a call, or not, so it presumes it MIGHT have been, and
"reloads" the value. Although lisp is "ALL pointers", in fact, they are not
nearly so odious to a lisp compiler as the pointers in c and c++ are to them,
with the result that the usual application runs faster in lisp than in c or
c++.  

Actually, lisp also wins over the others because there is more time for the
programmer to experiement with different data structures, since he spends less
time chasing screwball memory corruption problems, and other such time wasters.

Finally, all that said, there ARE good uses for throw/catch, etc. Things that
are of no value disappear from lisp, as lisp is still a growing, and changing
language, and will probably still be getting better a hundred years from now.
By then, the lisp library of "standard" functions, macros, types, methods,
constants, classes, combination methods, etc. will probably be in the tens of
thousands, and it may no longer be possible for any human programmer to ever
learn the entire language. But, if there are ever programs that put human
programmers out of a job, its a sure bet that those programs will be written in
a "lisp" language. (That is likely to incite flames from some quarters, so I'd
better add the usual IMO).  

Rather than flame me with "your favorite language is better than lisp", give me
the name of the language and the url where I can get the syntax and semantics -
I'm very interested, if its one I don't know.

I'm not  a "computer scientist".  Just a programmer with a mathematics degree,
as "computer science" didn't exist when I went to college. My first paid job as
a programmer was 1965, but I had designed and built computing devices several
years earlier.  

But I have some firm beliefs:

To be a good programmer, it is NECESSARY to:
   1. read most of the CACM issues from 1950 through 1970.
   2. read all of Donald Knuth's "The Art of Computer Programming".
   3. learn lisp (preferably both common lisp and scheme),
      and learn it well. (at least clos or  flavors)
   4. read everything by Edjkstra Dijskra.
   5. learn algol (60 and 68), cobol, fortran, pl/1, c, c++, snoball,
       smalltalk, prolog, and at least 3 different assembly languages.
       Also, learn at least 6 other languages not in the above list.
   6. learn denotational semantics.
   7. At least once:
          A. write an operating system
          B. write a macro assembler
          C. write a compiler
          D. write a tight real-time program (say less than 100
               machine instructions, average, available per intterrupt,
               with the interrupt coming on "irregular" basis)
           E. write a simulation of some complex system
           F. write a database engine, with a query language, and
               with transactions that either commit or roll back  when the    
                  power cord is removed while the database is in the middle
              of one or more  transactions.
           G. write at least one set of numerical routines to compute,
                efficiently and correctly, a set of operations that should
                include several of the trigonometic functions and similar
               things.
           H. write at least one "moderately large" program in assembly
               language, or microcode, or similar low-level languge.
           I.   design at least one digital logic circuit, which is complex
               enough to be a real programmable cpu,  BUILD IT, and
               use it to do SOME useful task, by writing some application
               for the machine.
           J. Port a large program from one platform to another (large: not
               less than 250,000 lines of code, preferably larger)

           K. Formally prove a small program correct,  (small: say from 400
               to a 1000 lines).  By correct, it must be proved that: under
               all possible inputs (for which there must be a formal spec
              which delineates which are "legal" and which are "not", it must
              always identify the illegal inputs with a suitable message, and
...

read more »



Thu, 27 Jun 2002 03:00:00 GMT  
 About the usage of throw/catch

Quote:

>Please list (at least in prose) some of the USES you guys
>have found for continuable exceptions -- I think there are
>some pretty neat things you can do, "obvious" ONCE someone
>has pointed them out!

The Lisp Machine makes extensive use of them.  For instance, the OPEN
function has a restart that retries opening with a new filename, and the
system has a standard handler for FILE-NOT-FOUND that prompts for a new
filename and invokes this restart.  There's a restart for UNBOUND-VARIABLE
that assigns the variable and retries.  And aborting back to a
read-eval-print loop is done using the condition restart mechanism.

--

GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.



Fri, 28 Jun 2002 03:00:00 GMT  
 About the usage of throw/catch


Quote:
> Obviously, from reading the other postings, opinions differ.

that's one point we can agree on

Quote:
> I weigh in on the side of thow/catch being "dirty".  I also
> weigh in on the presumably more controversial side of
> even return-from as being "dirty", not to mention a
> go outside of the originating tagbody.

i would prefer not to be too dogmatic about this.  a lot depends on the
compiler you are using.  one thing i like about throw / catch (or, even
better, a good exception system) that it keeps the code clearer: you
concentrate on the logic of the code you write, check for exceptional
conditions and deal with them where  appropriate, rather than disfigure
it with checking for them and passing them on at every level in the call
chain.  at least with throw / catch you have a language construct that
lets the compiler know that there are irregularities in the control
flow, information that can be exploited in the data flow analysis

Quote:
> The "dirtiness" arises partly from the lack of reusability of the resulting

why is it not reusable?  those are well defined constructs, with the
language standard specifying pretty clearly how it has to be handled

Quote:
> code.  It also arises because all the intervening unwind-protect code sequences
> must be executed "during" the non-local transfer, EVEN if the user doesn't
> THINK he wrote any (they are used in macros, and something akin to them must be
> used to "unbind" the bindings of special variables (in almost all
> implementations that support special variables)).

so?  i woyld rather have the language look after this than have to do it
myself

Quote:
> A "clean" piece of code in any language should, ideally, never, EVER, for ANY
> arguments whatsoever,  do a non-local transfer of control,
> of any kind.   REASON: suppose you want to use that piece of code
> to compute the "answer vector" to a suitable vector of "argument lists".
> Any non-local transfer of control will mean that, unless "all" of the vector
> elements properly "work", even if the "answer" computed is "you gave me bad
> arguments", then not all of the answers will be computed: you can't "split" the
> control and "throw" for "some" elements, and not for others, UNLESS some
> explicit futzing is done by every such user of the code.  Even if the language
> supports restarts, it is harder to use the original function.

beautiful philosophy, but what are you going to do when deep deep deep
in the control structure you encounter a situation that simply can't be
handled any more?  passing an error code back, checking it out at the
caller level, only to pass it on to the nect level, does nothing but
obfuscate the code.  i would even argue that throw / catch and
exceptions improve the reusability of your code:  you can write all your
utility routines under the assumption that they can proceed with the
task they are supposed to do.  any exceptional situation is handled by
the programmer supplied exception handlers.  when you write a program
that has to deal with those situations, you better know where you have
to insert code to handle exceptions

Quote:
> ...

--

Hartmann Schaffer

It is better to fill your days with life than your life with days



Fri, 28 Jun 2002 03:00:00 GMT  
 About the usage of throw/catch


Quote:

> | at my university, a computer scientist says the usage of throw/catch in
> | Lisp constitutes "dirty programming".

.../...
>   ask your "computer scientist" whether the use of exceptions is also bad.
>   while you're at it, ask her if the RETURN statement in C is dirty, too.
>   and if the problem is that GOTO's are bad, what about WHILE?  WHILE is
no
>   more than dressed-up version of GOTO.  THROW and CATCH are similarly a
>   form of GOTO that are not only dressed up, they have university degrees.
> #:Erik

If the French "computer science" teachers have not changed since the last
time I saw them (13 years ago), I can tell you that indeed a lot of them
will find all those words dirty. In fact they consider that the whole
concept of programming to produce something useful is a rather disgusting
idea.

Ok they may have changed...

Marc Battyani



Fri, 28 Jun 2002 03:00:00 GMT  
 About the usage of throw/catch

| I also weigh in on the presumably more controversial side of even
| return-from as being "dirty", not to mention a go outside of the
| originating tagbody.

  I'd like an example of a GO outside of the "originating TAGBODY" that you
  consider dirty.  (hint: maybe you don't know the language very well...)

| The "dirtiness" arises partly from the lack of reusability of the
| resulting code.

  reusable code is best defined as _functions_ that you can call from other
  bodies or code than the body of code it was originally designed to serve.

  reusable code is worst defined as code that can be copied (i.e., cut and
  paste) from one body of code to another -- yet that is what most people
  consider it to be, mostly because they don't have sufficiently powerful
  function concepts and engage in programming-by-cut-and-paste themselves.

  "reusable code" is nothing more than a new name for "write library code
  whenever you can" which is really nothing more than a way of expressing
  the age-old concept of "abstraction".  of course, when you change focus
  or angle, but keep staring at the same old thing, you need a new name so
  the people who got disappointed the first few times won't notice the very
  same thing you've all been staring at.

| A "clean" piece of code in any language should, ideally, never, EVER, for
| ANY arguments whatsoever, do a non-local transfer of control, of any kind.

  and _I_ think this argument is nothing more than the extremely na?ve
  argument used when people want 100% security or want to abolish accidents
  completely, and then they go hunting for someone to sue whenever a
  security violation or an accident happens, as if nature itself offended
  them by not submitting to their wishful thinking.

  the answer to such folly as "if only the world were ideal..." is simply:
  "if only the ideals were wordly...".

  I'm not afraid to implement what I think will have an ideal _interface_
  using whatever dirty tricks are _necessary_ (but none beyond that, of
  course).  I don't _want_ people to peek inside my function bodies and
  reuse the code with cut and paste, nor do I want people to {*filter*} with the
  code so there will be hundreds of incompatible versions hacked on by
  people who have no regard for the abstract task it was designed to
  perform -- I want people to call the function when they can and call me
  if they can't.

  the desire to abolish accidents is _highly_ irrational.  the same goes
  for the desire never to see "dirty" code.  what it means is that somebody
  else should pay an enormous price for the wishful thinking to come true,
  which is quite typical of irrational political desires.  for some reason,
  the United States is the only country on earth where accidents don't
  happen -- it's always somebody's fault, and you can sue that somebody for
  _neglect_.  the same goes for "dirty" code -- if you have to code so
  verbosely that you can't finish typing in finite time, that's somehow
  better than using a safe mechanism for non-local transfer of control --
  and the result is the same as the litigous American society: people lose
  the ability to deal with the exceptional that is still within the normal.

  this is not to say that certain tasks cannot be written in some "ideal"
  way according to some otherwordly school of thought, but the belief that
  anybody uses non-local transfer of control _wantonly_ is offensive to any
  competent craftsmen.

#:Erik



Fri, 28 Jun 2002 03:00:00 GMT  
 About the usage of throw/catch

Quote:
> at my university, a computer scientist says the usage of throw/catch
in
> Lisp constitutes "dirty programming".

Since Lisp, CL at least, is accurately characterized as being a ball
of mud and mud is wet dirt, much of lisp is "dirty".  What of it?

-andy

Sent via Deja.com http://www.deja.com/
Before you buy.



Fri, 28 Jun 2002 03:00:00 GMT  
 About the usage of throw/catch


| I also weigh in on the presumably more controversial side of even
| return-from as being "dirty", not to mention a go outside of the
| originating tagbody.

  I'd like an example of a GO outside of the "originating TAGBODY" that you
  consider dirty.  (hint: maybe you don't know the language very well...)

| The "dirtiness" arises partly from the lack of reusability of the
| resulting code.

OK.

(defun foo(&aux x y)
  (setq y 1)
   (tagbody
       (setq x #'(lambda (z)
              (fiddle-faddle x y z)
              (when (<  z 100)
                         (go  gag)
              )
              (1+ z)
        )               )
   {*filter*}
          (setq y (funcall x (* y  2)))
   )
)

I phrased it in a way subject to misintrepretation.  Since the
dynamic scope of a tag ends with the dynamic scope of the
tagbody, it is not legal tn CL to create closures over recursive
tagbodies, and go to tags for tagbodies that have been exited.
(Although I strongly suspect some implementations do not detect
the problem, and some may even support it properly.).

I should have sait, something like:
"not to mention a go which is not in the same binding contour of
of the target of the go (that is, not inside a closure, let, progv,
let*, or similar construct that must cause the execution of the go
to do something more than a simple transfer of control."

Of course, that would then widen the discussion beyond the level
of understanding of the original poster.

As you have suggested I do not know CL, I will admit that it is a long
learning experience - I'm on my third copy of Steele's manual, as the
bindings keep falling apart.  My first CL introduction was pre-Mary Poppins
edition. (late 1970's or early 1980's) My first Lisp goes back
considerably earlier.

Note I left fiddle-faddle undefined.

Suppose it were:

(defun fiddle-faddle (op v1 v2)
     (funcall op (+ 3  v1  ( foo (+ 17 v2)) ))
)

Thus, foo is called recursively, so there are multiple closures and
tagbodies active.  I haven't properly "designed" or debugged, or
tested this code.  I'm not sure it teminates, but I THINK it does.

As to "throw/catch" being "needed".  That is true, WHEN you
have to glue together stuff in a hurry, and can't change the interfaces
to some of it.  

Some poster accused me also of "living in an ivory tower".  Having
shipped several database engines, several compilers, and several
operatings systems, and miscellaneous other work, I assure you I
can get it out the door, with warts and all, as well as anyone I know.

BUT: it is far better to make the result value have one or more
"exceptional" values (such as null in ANSII SQL, or the NANs of
IEEE floating point arithmetic).  The operations all "propagate" the
exceptional VALUE, without any non-local control transfer.  

I find it obvious, that since IEEE floating point arithmentic is often
used for vector and matrix operations, on lots of numbers, and since
SQL is often called on to operate on entire sets of rows, that the
support is there, for EXCEPTIONAL VALUES.   As I said in the
first post on this issue: non-local transfer of control is dirty, because
it does not "reuse" well.

Said in a more sophisticated way, incomprehensible probably to the
original poster, neither functors nor combinators in general, nor
any function that maps a function over a set of values can easily
use any function that sometimes throws, unless the function is first
"cleaned up" by wrapping a catch, return exceptional value piece
around it.  And repetitively "cleaning up" every time I reuse a function
means the function has a bad behavior.  

I also NEVER cut and paste - in such circumstances, I use one of
several techniques: virtual machines, macros, or application specific
code generators, or, sometimes, compiler-compilers (I've designed,
and implemented, 3 different ones so far - based on different
formal language techniques).

Finally: I may be "ivory tower", but I've shipped product with zero bugs
reported, for a major computer software vendor, and with many
"enhancement" requests reported.   The project shipped on time.
Over 600 productions; multi-threaded, and it just worked.  I guess
I got "lucky".



Sat, 20 Jul 2002 03:00:00 GMT  
 
 [ 18 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Good form using CATCH and THROW ?

2. Catch, Throw, and File-Size

3. Catch...Throw and the ANS standard

4. CATCH/THROW, good or bad?

5. CATCH/THROW opinions

6. What about another CATCH and THROW

7. CATCH & THROW

8. Tagged CATCH and THROW

9. CATCH / THROW

10. CATCH/THROW

11. Suggested kernel implementation using CATCH and THROW

12. Multiprogramming impact of CATCH and THROW

 

 
Powered by phpBB® Forum Software