[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: why tail recursion matters and why Java isn't it, was Re: lispperformance was Re: problems with lisp
Pascal Costanza <firstname.lastname@example.org> asks in what I can only
hope is a fit of passion overcoming rational thought:
> Why should it be important to cover all cases?
Because programming language designers should not think they are a
whole lot smarter than the programmers who will use their language.
(Note: This wording even accommodates the design of Arc.)
Because many programmers are smart and creative, and such people do
unexpected things, the language designer cannot possibly anticipate
all the structures of data the programmer might create. In turn,
then, they cannot anticipate the iteration schemas that would be
appropriate for those data structures. And as a matter of sociology,
it is precisely these smart and creative programmers that a language
should try to attract, engage and keep, because they will push it
hardest and farthest.
I doubt you would want to use a programming language that *forbade*
the development of any data structure other than a list. This does
not prevent a language from *providing* the list as a useful
abstraction. But such a language should also provide a general means
of creating structured data, "to cover all cases".
I doubt you would want to use a programming language that *disallows*
the garbage collection of circular data. Language designers should
assume that sometimes there are good reasons for creating circular
data structures, and permit their collection (even if not actively
support it, as is true of some of the languages popular on this list)
just to "cover all cases".
Pushing even further, I would not want to use a programming language
that *prohibits* the creation of syntactic abstractions that better
capture constructs for a particular domain, especially new binding
constructs and control structures ("loops"). While the language no
doubt already supports pretty useful constructs for many purposes, I
would not want a barrier to creating a better lightweight embedded
language. A good language provides macros or templates just so it can
"cover all cases".
Now in any other context, I would imagine that it would be you, the
Common Lisp fan, making precisely this set of cases. So when did
covering all cases cease to be an objective of a general purpose
language? And if you buy into the above, then tail calls become
inevitable; a macro system without tail calls underneath is