|
 |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>> ... that I hate seeing in a popular language. Backwards compatibility for a
>> language already rushed out the door is really a killer, IMO.
>
>> http://vijaymathew.wordpress.com/2009/03/13/dangerous-designs/
>
> In my little experience, trying to use a programming paradigm (eg. OOP)
> with a language which has no specific support for that paradigm (eg.
> traditional lisp or scheme, or C) only creates a ton of kludges.
Yeah, except these kludges are in the class files, because nobody wants to
break the JVM to get new features. Alternately, you get things like .NET
with a bunch of new features that are only available on Windows because
people doing Mono need time (and motivation) to reimplement. Hard to say
which mechanism is best.
> "The argument is that, using a very small number of rules for forming
> expressions and with a minimal syntax it is possible to support all
> possible programming paradigms. For instance, if the language has
> support for higher-order functions, closures and dynamic typing, we
> can implement object oriented programming without special language
> level syntactic support. Tail-call optimization elude the need for
> special looping constructs."
>
> sounds like you could argue in favor of languages like brainfuck which
> have a minimal set of instructions, yet are still Turing-complete.
If it's fast enough and you have sufficiently flexible macros, sure. Kind of
like the way C++ can use general purpose constructor and destructor
semantics to implement resource management.
> Eg. just because tail recursion is enough to perform any kind of
> looping construct doesn't necessarily mean that special looping constructs
> wouldn't be a useful tool.
I think if you look at the level he's speaking about here, i.e., the JVM
level, that objection goes away. Think about something like .NET only
supporting tail recursion in the CIL - all the *languages* would translate
looping stuff into tail recursion, just like right now C# translates
closures into nested class declarations invisibly.
And if you're familiar with LISP, and the power of its macro system, you can
see where he's coming from - LISP has a powerful looping construct (called
LOOP :-) that expands internally into the definition of a tail-recursive
function.
Something where you can't rewrite the source code at compile time to fit
your needs? No, doesn't work out to make a bunch of minimal things. It also
pushes the burden for figuring out optimizations back onto the runtime. For
example, in a C-style for loop, you can tell by looking at the source code
if there's an index variable that can be stored in a register and not pushed
to memory on each loop. (In Pascal, it's trivial, for example, due to "for"
being much simpler.) If you have a macro that turns every loop into tail
recursion, then the runtime/JIT/whatever now has to analyze the variables
coming in and the variables being passed in *all* the possible
tail-recursive calls to see if there's one that might be serving as a loop
index. On the other hand, you might also wind up with more opportunities to
optimize something that would be harder to express in something like C, so
the compiler needs to do as much work, but doesn't because the compiler
authors spent more time on other types of optimization. Sort of the
difference between generating optimal bytecodes from Java vs generating
optimal machine code from bytecodes, given the entire context of the program.
--
Darren New, San Diego CA, USA (PST)
My fortune cookie said, "You will soon be
unable to read this, even at arm's length."
Post a reply to this message
|
 |