12 comments

[ 3212 ms ] story [ 1944 ms ] thread
Borrow checker in Rust? Implicits in Scala?
Clojure 1.0 was released in 2009 and included multimethods (ad hoc polymorphism / multiple dispatch), which predates Julia by a few years.
Common Lisp and Dylan had multimethods for decades, and were both strong influences on Julia, unlike Clojure.
Dylan was also a strong influence on R's S4 object system.
A lot of these languages didn't introduce their "big idea." I think their inclusion makes sense but the article could be clearer about it.

—Comptime exists in Lisps and I think C++ had it before Zig. Zig's contribution, IMO, is in using it to simplify the language. My impression is that they don't have a dedicated generic mechanism as a result.

—Multiple dispatch exists in Clojure but predates it. Apparently all dispatch in Julia is technically multiple dispatch and is consequently much optimized.

—Optionals long predate Swift (as he acknowledges) and are notably a part of the ML family. I don't know much about Swift, and the author doesn't really make it clear why he found Swift Optionals easier to pick up.

—Structural typing existed in dynamic languages, as he acknowledges.

I'm actually not sure that Lisp got to images first. Smalltalk is younger than Lisp but old enough that Lisp was still evolving. According to The Evolution of Smalltalk [0], the very first version of Smalltalk had images. I'd be curious as to whether the author or anyone else has a good source on the first Lisp with images?

[0]: https://dl.acm.org/doi/10.1145/3386335

Can someone more intelligent than me explain how multiple dispatch differs from function overloading?
In function overloading, like in Java or C#, the method is picked at compile time based on the static types of the parameters. In multiple dispatch, the function is chosen at runtime based on the runtime type of the parameters.
Dynamic mutliple dispatch takes into account the dynamic type rather than the static type as you would in say-C++ style function overloading. The single dispatch equivalent is function overloading vs virtual calls.
> In LISP, everything is a linked list

Atoms are linked lists?

Most of that are also old Lisp idioms&features, minus the static type system:

* compile time code, in Common Lisp with macro, reader-macros or via EVAL-WHEN -> at compile-time the whole Lisp system is available

* multiple dispatch -> introduced with CLOS

* when-let, when-let*, if-let, let-bind, ... are older macros

* structural typing: what Python, Ruby does -> CLOS does that, too. Even earlier object systems like Flavors. See also Smalltalk.

* adding methods to an existing class, outside the class definition -> CLOS has open classes. methods are not defined 'inside' classes, thus there is no 'inside'

* Homoiconicity -> easy

* image-based development -> see Interlisp ( https://interlisp.org ) for an extensive approach

the last thing 'everything is a hash table' is not common in Lisp, though there are languages where the key-value mapping is the central data type, like in Frame systems (see FRL)