Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Wolfram language has a very different syntax that Matlab or really any other programming language, and it has a lot of lisp-like metaprogramming capability. It's not as well thought-out as a proper lisp like Clojure, it's verbose and there's a lot of weird corner cases.

The editor is very different as well: Mathematica pioneered the notebook concept that was copied by Jupyter, and the Mathematica user experience is still much more comprehensive and tightly integrated than anything else.

For linear algebra, they both use Intel MKL under the hood and get exactly the same performance.



Not only would I not call Clojure a "proper lisp" but since it doesn't run any Lisp code and lacks fundamental Lisp data structures (e.g conses), I wouldn't even call it a Lisp.


You're about 10 years late to this debate, which has largely been settled.


Completely tangential, but Clojure is definitely a Lisp, and it does have cons https://clojuredocs.org/clojure.core/cons


A Clojure cons is something completely different to a Lisp cons.

https://stackoverflow.com/questions/34347985/clojure-no-cons...


It is not completely different, but rather quite similar [1]. Clojure adds the concept of protocols, which it uses to abstract over cons cells (and it requires that the second element of the cell is an ISeq rather than an arbitrary object).

[1]: You can see the implementation of Clojure's cons cell here: https://github.com/clojure/clojure/blob/clojure-1.9.0/src/jv...


(cons 1 2) is doing what in Clojure?

In Lisp cons cells are the basic data type from which lists, trees, cyclic lists, etc. are created,

In Clojure it's not.


First, in Scheme, vectors are not made of cons cells.

Second, in Clojure, you can certainly make lists, trees etc. from cons cells. It's just that vectors and maps are more common.

Third, Clojure is not only a Lisp (https://clojure.org/about/lisp), but an exceptionally good one at that. I'm amazed that some people find that controversial. I love Scheme and Clojure, and the thought that they're not both Lisps -- something immediately obvious to any long-time Lisper like me -- strikes me as patently bizarre. Clojure is not only a very good Lisp, but celebrated among Lispers for facilitating Lisp's rise in popularity in recent years.


> First, in Scheme, vectors are not made of cons cells.

Lisp, too, has vectors not made of cons cells.

> make lists, trees etc. from cons cells

It's just that they aren't. Clojure uses persistent lazy sequences not made of cons cells as its basic data structure. And it has strange behavior:

  user=> (conj '(1 2) 0)
  (0 1 2)
  user=> (cons 0 '(1 2))
  (0 1 2)
Thus we have the same external representation.

  user=> (class (conj '(1 2) 0))
  clojure.lang.PersistentList
  user=> (class (cons 0 '(1 2)))
  clojure.lang.Cons
But they are of different class?

  user=> (class (cons 1 2))
  IllegalArgumentException Don't know how to create ISeq from: java.lang.Long  clojure.lang.RT.seqFrom (RT.java:542)
When we call cons with two args we get a Java error with a line number?

Does not look like Lisp to me.

> Clojure is not only a very good Lisp

It's a good programming language, but not a very good Lisp - since it is mostly incompatible and lacks a lot of the usual Lisp features.


> When we call cons with two args we get a Java error with a line number?

Clojure requires that the second element in the pair be an ISeq.

> since it is mostly incompatible and lacks a lot of the usual Lisp features.

I and many others disagree, including Clojure's designers, who designed it as a Lisp. Homoiconicity, macros, S-expressions and FP make a language a Lisp. OCaml and SML are about as different as Scheme and Clojure, yet no one thinks they're not both MLs.


> Clojure requires that the second element in the pair be an ISeq.

Lisp doesn't have such a requirement and does not have 'ISeqs'.

> I and many others disagree,

That does not make a convincing argument, since you have never used an actual Lisp - as you recently said.

> including Clojure's designers, who designed it as a Lisp.

Derived from Lisp mostly as a blend of FP, Java hosting/integration and Lisp ideas.

> Homoiconicity, macros, S-expressions and FP make a language a Lisp.

Lists are deprecated in Clojure (for maps, sets, vectors, ...), No interpreter, no Lisp down to the metal, no Lisp in Lisp, no images, core Lisp data structures look different, different API, different syntax, impoverished REPL, strange numerics, Java leaking in many places, lots of compromises because of implementing it on top of a not-Lisp-friendly VM, ...

Lisp derived, but Lisp looks & feels a bit different.


What do you mean by "it doesn't run any Lisp code"?

For what it's worth, both Wikipedia and the official Clojure website call Clojure a dialect of Lisp (https://en.wikipedia.org/wiki/Lisp_(programming_language), https://clojure.org/)


Pick any book with has the name Lisp on it, take example code and try to run it in Cloure.

Chance that it does not work is high.

Now change the code that it runs. Chance that you had to rewrite the code mostly is high.

It's a dialect of Lisp in the sense that it is an incompatible branch / fork with a Java runtime (it's a hosted language) and a bunch of newer functional data structures replacing old-fashioned lower-level stuff from Lisp.


Take Lisp code written in the last 50 years and odds are that Common Lisp, Emacs Lisp or Scheme can run it with zero/minimal/moderate modifications.

Clojure needs a total and complete rewrite which doesn't only affect the syntax but program logic. Thus Clojure does not run Lisp code. How can it be a Lisp when it does not run Lisp code?


I've actually ported some Clojure code to Common Lisp no later than two weeks ago and it was pretty much as straightforward (if not more) as porting R5RS to CL. In my (admittedly limited) experience both CL and Clojure favor a certain high-level coding style with complicated macros versus the more simplistic style of Scheme. Contrast CL's loop construct, Clojure's for statement and Scheme's typically more recursive approach to iteration.

You're welcome to draw the line wherever you want, maybe for you conses are mandatory in a Lisp language but I don't really understand what you hope to gain from this discussion. I might as well say "tail call optimization is absolutely mandatory in any self-respecting Lisp, therefore CL isn't a proper Lisp dialect".

This is effectively the same level of discussion as a Java programmer saying that C++ isn't "true OOP" or an Haskell enthusiast claiming that Scheme isn't a true functional language because it allows side-effects. It's just silly gatekeeping that doesn't lead anywhere interesting.


The chance that you can port code without actually rewriting it is pretty slim. But then, people have been rewriting Lisp code to run in C++.

If you want TCO in CL then use one of the dozen implementations which supports it.

People btw. used to write some non-trivial code which ran in both Scheme and CL with the help of a Scheme on top CL, a compatibility layer or a translator. But that's now relatively rare.


But C++ in fact isn't true OOP (and neither is Java), and Scheme isn't a functional language.


This argument only works if you think of "Lisp" as a single, linearly developing language. It hasn't been that for decades. (That's why they created "Common" Lisp, after all.)

Lisp is a family of languages - within which Scheme and CL are just as syntactically incompatible as CL and Clojure.


CL was created such that it is compatible with a main line of Lisp dialects (those btw. have usually Lisp in their name) -> Lisp 1, Lisp 1.5, MacLisp, ZetaLisp then Common Lisp.

Other Lisps in that main line are Portable Standard Lisp, Le-Lisp, Emacs Lisp, ISLisp, ...

There are quite a few branches with less (Scheme) or more incompatible languages (ML, Dylan, Clojure, ...).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: