Needle is a new language that was discussed at LL2. The feature list reads like everything I've ever wanted in a language: multiple dispatch, continuations, macros and static typing plus the all usual features you'd expect. Impressive piece of work created by someone who's obviously got a great understanding of modern programming languages.
Posted to object-functional by Noel Welsh on 11/14/02; 9:45:25 AM
First of all, it's trivial to implement multiple dispatch as a library object in any language that supports reflection.
Second, multiple dispatch is often presented as a better alternative to the Visitor pattern. However, Visitor is statically type-safe and multiple dispatch is not. The moment you use multiple dispatch you throw static typing out the door.
However, Visitor is statically type-safe and multiple dispatch is not. The moment you use multiple dispatch you throw static typing out the door.
Bzzzt! This is incorrect. Examples of statically type-safe multiple-dispatch languages include Needle and EML.
Multiple dispatch support modularity in a way neither OO nor FP address. If you have a table with rows being operations and columns being types, OO allows you to fill columns at a time, FP to fill rows at a time and multiple dispatch to fill cells at a time. So I think multiple dispatch is the unity of OO and FP, at least for modularity concerns. See SICP section 2.4.3.
Surely the success of a programming language is as uncontrollable as the success of any of our other activities in the world. Excellence is not always recognized or rewarded. Being in the right-place at the right-time is really important. Being persistent is really important (Was it on the 3rd or 4th attempt that Oak/Java finally attached to a successful project?).
We know all this - the strange thing is how much we want to believe this doesn't apply to programming languages.
My main goal with Needle is to write the language that I want to program in. Obviously, Needle will get the features that I, personally, like a lot: macros, multimethods, static typing, continuations, higher-order functions. But getting all that implemented isn't really what I'm primarily interested in (though I am interested in that, and have learned a lot).
What really interests me is the standard library. In practice, the ease of programming is in the libraries. Example: Python is an okay language (it's like Smalltalk's dumber cousin) and it kind of sucks in terms of design, with a lot of ad-hoc'd up protocols, but they're all *actually there*. So it has a rich library set and I can turn to it immediately when I need to hack. This is a *big* win, and a reason I use it as much as I use Ocaml, despite liking ML a lot more than Python. My goal with Needle is to see what kind of maximum-leverage libraries I can write when I have everything I want in a language. I mean to put things like parser combinators, constraint sublanguages, concurrency, and other really extremely powerful ideas right into the core libraries.
One of the things that surprised me was that a lot of Todd Proebsting's potential "disruptive technlogies" were things I was already contemplating for Needle's standard library. It felt like he was reading my mind, though I guess if you are looking for things to seriously raise the abstraction level of programs you don't have a big list. The big difference is that I think of these as things you build from macros, HOFs and call/cc, and he thinks that they should be basic language features.
p.s. Of course you also need extensive libraries :)
From a syntax standpoint, Needle seems to be leaning to a more common looking syntax - i.e. towards a syntax with Java-esque qualities.
Chris: I'm familiar with Goo, and talk with Jonathan Bachrach regularly. Needle *is* a reaction to Dylan, except that I went in the "more static" direction rather than the "more dynamic" direction.
Strictly speaking, maybe, but if I recall the ML-sub paper correctly, it's full of type exceptions in the list examples which are not that far from dynamic typing: that is you do get "a message not understood" error at runtime even if it is written by the programmer in an explicit routine that issues an exception. Making the locations of runtime type errors explicit is better than risking them all the time as in fully dynamic languages, but it is a bit remote from the ideal of fully static typing.
Also multiple dispatch seems likely to suffer from implicit type errors if not exhaustive: if you do not declare all combinations explicitely, which may be inconvenient, you may get the wrong version called, where there should be a type error.
For instance
Food Meat Vegs
Animal Carnivore Herbivore
we want a multiply dispatched feed: (Animal * Fodd), so we declare:
feed : (Carnivore * Meat) = ... feed : (Herbivore * Vegs) = ... feed : (Animal * Food) = raise "I'm not statically typed"
all well, but then we add
Animal Omnivore
the compiler won't tell you to add a routine, but call feed (Animal * Food) which is really a type error (a _different_ one from what the "raise" catches). Neither the OO visitor pattern, nor the ML datatype inspection suffer from this problem.
If you are exhaustive, you solve this one, but you have to declare explicitely (exception raising) implementations for (Carnivore * Vegs) and (Herbivore * Meat). Of course if the hierarchies have a few more classes, it's N*M combinations to declare explicitely...