Ask HN: Is clojure (lisp in JVM) next big thing?
There seems to be a lot of people even some intelligent ones who are lately talking about and exploring clojure, a new lisp dialect run in JVM. It looks really promising, but a lot of people especially lisp programmers have an inherent hatred in java. How is that? what do you think about this ``lisp in JVM''? Is the clojure the future of lisp?
81 comments
[ 3.7 ms ] story [ 158 ms ] threadThe reason arc is crashing and burning right now is that it doesn't address #2 at all. Plus, arc is suffering from an absentee benevolent dictator.
Of course it does. "Revisit[ing] the basic design tenets of Common Lisp and Scheme" is actual language design. Moreover, "fixing" CL and Scheme is not "low hanging fruit". It's a hard thing to do, and most people who try make a mess of things.
I agree here. Most people think fixing CL means making "let" use fewer parenthesis. (Clojure does this.)
Anyone that has used Lisp for more than 30 seconds knows that this is not a particularly worthwhile change. More syntax characters just to save two characters in a let binding? No thanks.
(BTW, you can always use destructuring-bind instead of let -- (destructuring-bind (foo bar baz) '(1 2 3) ...). There, you saved some parens!)
Honestly, Clojure doesn't sit really well with me. It tries to be different from both CL and Scheme simply for the sake of being different, which is pretty annoying. For example, look at the "definers". In CL, the scheme is pretty simple -- defun, defvar, defgeneric, defmethod, ... In Scheme, "define" is polymorphic, so it's all you ever need. In Clojure, the "definers" are just random words; def/defn, etc. Oh boy, we saved 3 characters! I am going to be so much more productive now!
Anyway, I will stick to CL for now.
For instance, data structures are immutable (not setq). If you need state, you have to use the software transactional memory system. These two features combine to make Clojure very safe for concurrency.
Clojure also uses sequences as it's primary object, which are more like "immutable" python generators than lisp lists.
Take a closer look, Clojure is actually quite nice.
While I enjoyed writing arc code, I'm in no hurry to see a huge infrastructure pop up around the language as it stands. What's the rush? Let pg and rtm take whatever time they need to build a language they are happy with.
Yeah, pg and rtm can do whatever they want. Meanwhile, I want a language I'm happy with.
Do you mean that it might hurt Clojure specifically, because it relies on Java's libraries in particular? Or was it a more general point?
The dangers of libraries are that they distract one's attention from the core language, and that they could conceal or perpetuate flaws in the core language.
I'm not saying that languages shouldn't have powerful libraries, btw, just that they may not be 100% upside.
they may even hurt.
I'm assuming you are referring to the maintenance and backward compatibility that is required as soon as you have libraries. Plus good libraries can be had even in bad languages - so it's not a good reflection of the language. Are you suggesting libraries should be a completely separate project with potentially many choices? The problem with this can be seen in Scheme. It's hard to move from project to project (job to job) when they use different implementations and those related libraries. Learning the related core libraries is often not worth it; if the scope of the project is small. Invariably libraries do not transfer well - maybe that is the problem that needs to be solved... Even with formalities like R5RS or R6RS core libraries are still implementation specific.
Plus, arc is suffering from an absentee benevolent dictator.
... You are missed over at the arclanguage forums. (http://arclanguage.org/item?id=8462) Specifically some direction for those of us that enjoy writing arc would be great. There are plenty of people that know and write arc - why not put them to work. What is your opinion of the community version of arc (http://github.com/nex3/arc/tree/master)? Do you use it? Is it blasphemy? Is this all just a giant social experiment to see what will happen to the language and community given no leadership and x-number of years?
It's pretty clear already: arc has failed.
Failed at what, exactly? Being a toaster?
You guys all seem to be projecting your own expectations about "language and community" onto Arc, none of which have to do with the stated goals of the project. What part of making-a-better-Lisp-where-better-mostly-equals-shorter-programs don't you understand?
1. A completed version of arc 2. 100 years since 1.
Wow, really? This seems way off base to me. The only reason I care about Clojure is 'persistent' data structures that give us some chance of writing code that /just, maybe, possibly/ will execute usefully on the 1024+-core boxes we're going to be using shortly. That's the only reason I care about it, and I'd say that's fundamentally the design of the language.
Lots of work is being done in areas such as JIT and adaptive optimization in the runtime environment. By targeting the JVM you get to take advantage of all that work put into optimization and thousands of libraries; it gets you a lot of leverage fast.
http://www.cio.com/article/print/454520
http://almaer.com/blog/the-next-big-language-theory-practice...
The trend has always been to easier and easier languages - I don't remember any case where a more complex language, no matter how useful, has become the next big thing.
The only thing that can make lisp popular is a framework or API based off it. Something that offers something new or something easier.
C is a simple language. Scheme is a simple language. Everything else is growing more complicated by the day.
My point was that the trend in popularity is towards less complex languages - i.e, languages that abstract away difficulty. In that respect, C++ is less complex than C.
That is a very anomalous definition of complexity. In truth, a language that is more complex may or may not be more abstract. For example, Prolog operates at a very high level of abstraction, and it is far less complex than a language like C++.
C++ is less complex than C
C++ allows programs to be written at a higher level of abstraction than C, but it is not less complex than C by any reasonable definition of "complexity". In fact, it is the very existence of the C++ tools for abstraction (classes, templates, virtual functions, MI) that cause much of C++'s language complexity. Perhaps you are conflating the complexity of the language with the complexity of a typical program written in that language?
Um, what?
I don't think you know much Ruby.
Please elaborate. I'd love to refute if there was something in there to refute. I really don't see how Lisp is inherently less (or for that matter, more) graspable on a fundamental level. Are you a neurologist? And do you have any actual experience with Lisp?
When particular concepts are represented by abstract concepts, and operations are executed on these concepts, that's where most people shut down. That's why many people don't go into programming - they are not able to easily deal with the abstractions that programmers have to deal with.
Languages that are similar to human languages - i.e, one word, one 'object' or 'concept' are easy for people to understand. A language like lisp is not even near to that - it depends completely on abstractions of concepts, and this is where the core difficulty for most people would lie.
For example, to take this example from wikipedia:
(list '1 '2 'foo)
The statement above is very difficult to reconcile with real world concepts, it's very difficult to put into the mental boxes we have grown up with.
Contrast with python:
if object is not null:
Languages don't have to be similar to english, but they have to be mentally mapable to models we already know. This is difficult to do with Lisp. With lisp, you have to understand new concepts. It's just not that easy for most people.
btw, if object is not null is closer to (nil? object) than to (list '1 '2 'foo)
lisp may not be simpler, it is more powerful. it is a distillation of the ideas that gave rise to computer languages.
Lisp is likely more powerful, but it is unlikely to become very popular in the form it currently exists in.
yes, lisp won't ever be more popular. just like "30 Rock" won't ever be more popular than "the office"
People who can't think in abstractions shouldn't become programmers, that's all. Besides using very simple DSLs, perhaps (ha!).
I don't see how arguing that people who aren't hard-wired to program have greater difficulty with Lisp than they do with languages with more exposure makes the case that Lisp is too complex.
I think you underestimate the leap that doing the kinds of abstraction needed for doing any kind of programming at all, and the very small differences between programming languages. There are probably many (most?) people to whom both "if object is not null:" and "(if foo 1 2)" will never be comprehensible. But I think the number of people who can understand the first but not the second or vice versa is negligible. And I think you can make just as good a case that Lisp is easier for the beginner to understand. We tend to think that non-Lisp languages are easier to understand because they are superficially similar to one another. But to the beginner they are just a jumble of symbols arranged in strange ways. The simplicity and consistency of Lisp forms may very well be more quickly comprehended by a mind undamaged by Java or C or any of those similar languages.
(if (not (nil? object)))
Is very simple to read, even if you hate parens.
If you have ever parsed a syntactic tree, you'll realize that it's inherently an s-expression. That means that everything you ever say, and all human communication for that matter, are s-expressions.
Sans the logic, operators, symbol quoting and observance of rules (first item is interpreted as a function), lisp is at its core as close to human language you'll ever get. Popularity depends on other things, but lisp doesn't break the way we think.
(defun factorial (n) (if (<= n 1) 1 (* n (factorial (- n 1)))))
Now imagine trying to explain that to a person who does not use a computer. Humans always start learning by looking for the objects, then applying an action on the object. With lisp, this object is not obvious, and the actions being applies are not obvious either.
That may be so, but what I was pointing out was how different they language structure was from traditional human languages.
person.buy(house, agency, contract)
agency.sell(house, contract, person)
house.sale(person, agency, contract)
contract.fulfil(house, person, agency)
Of course the decision is not taken based on what's easiest to explain to non computer users but rather on which object's encapsulated data is most affected by the operation, or which inheritance hierarchy should be used to look up the operation. In most non trivial cases that's extremely subjective. Being forced to make that decision _every time_ you call or write a function is a complete waste of intellectual effort.
Since there is always one name for what should happen (the name of the function) but potentially many objects that are involved in some capacity, it seems much more consistent to give a special syntactical place to the function rather than to any of the objects:
sell(house, person, contract) or if you prefer (sell house person contract)
'House' as an abstraction for a house is a good model. Performing an action on an abstraction should be in an intuitive manner, for example:
sell House
That's pretty clear. To cause the interaction between two objects, then one should place the action between the objects:
make "Agency" sell "House"
where 'make' is equivalent to calling a function. Now, let's bring in a contract
make "Agency" sell "House" using "Contract"
this OO model works in my opinion because there is one path between the objects, and the arguments describe the contents of the path.
make "Person" buy "House" using "TerribleContract"
I believe that programming languages are too flexible. I believe that programming languages should be constructed in a manner that forces you to abstract complex structures into aggregates of behaviour, where the input to these aggregates consist of a very low number of paths. Java, C+++ fail in this in that they allow you to break out of the abstraction hierachy. They allow you to have callbacks and inheritance and so on, which breaks the black-boxiness of your program.
A black-box should always take the same inputs and should always produce the same behaviour from those inputs. Now, what about other types of programming constructs?
Let's say I wanted to send a file to another PC using sockets:
create "File" using "/hello.txt"
As the next step I'm trying to open a port. However, a port has a number. I could try to do this:
create "Socket" using ("Port" using 8934)
"Port 8934" is something that can be merged together into a composite structure and so the user should be forced to do so:
"InputPort" is "Port" using 8934
create "Socket" using "InputPort"
make "Socket" send "File"
destroy "Socket"
This is an example of how I think a properly abstracted language should look like. Force single paths to all abstractions, and force abstraction use.
We all speak English here; you can say, "let's all speak like Yoda now." Quite easy, that is. But the underlying language doesn't need to change; other people can invent different rules and create different settings where these rules apply strictly.
So imperatively, your socket program is like this:
f = file("/hello.txt")
p = makeport(8934)
s = makesocket(p)
s.send(f)
s.destroy()
which is perfectly fine. This is basically a line by line translation from your English-looking pseudocode to this OO-code-looking pseudocode. Using s-expressions would make the whole process read much more like speaking:
Let's say I wanted to send a file: Using the socket that uses the port 8934, send the file hello.txt, and destroy the socket.
Plain English, right? Reorder into:
Destroy the socket that is used to send the file hello.txt and is created with port 8934.
Translate to s-expr:
(destroy-socket (send-file (make-file "hello.txt") using (make-socket (make-port 8934)))
I'm taking liberties with the send-file function syntax.
Looks ugly, but that's pretty close to the natural language representation. If you parse the syntactic tree it will almost overlap completely.
That said, since my own programming style in C-derived languages seems over the years to slowly be attempting to imitate s-expressions, I think a lot of the mental difficulty people mention is just being overly comfortable with the familiar.
If not, this will be really hard using any programming language.
Maybe the electrician just wired your brain wrong. You might want to try and get a refund.
Math is just a language, but it's a very difficult language for most human beings to learn because we don't naturally think using those type of expressions.
Lisp was created as mathematical notation for computers. It is based of a language that the most people have difficulty with in school.
I'm good at math, and I have no problem with lisp. I'm just pointing out that it will not be the next big thing because this type of thinking is not easy for most people to get into. Pythonic thinking on the other hand is easy for people to understand.
Complex systems should be modelled by reducing the complexity. What I mean is that one has to black-box certain parts of complex systems such that human minds can deal with the concepts effectively. Object oriented programming is a way of doing this, but it's not the perfect way.
some of the ideas i need to express in order to make a living are not so easily expressed in python:
http://news.ycombinator.com/item?id=343738
Since so little software is written in lisp, I can only conclude that the language doesn't actually make its users much more productive or that the significance of libraries is greater than pg wants to admit or that most brilliant programmers are rather ignorant when it comes to selecting their tools.
In my book, Lisp is great.
P.S. And I'll keep using it for future projects!
I'd respond by saying that lisp is an easier language to learn than C (for example) - they syntax is much more consistent.
If you had to do the same stuff in lisp, you'd face the same problems.
i learned lisp before C. i always found C to be very obtuse and arbitrary. for example:
1. why can't i define a function inside a function and then return it, why can't i define a function based on some conditional?
2. macros that are just text expansions are useless (well not useless but in comparison to lisp macros!)
3. no way to embed a mini language. or way, but too difficult. in lisp you don't even have to think about it. (a little query language, or a little configuration language, or a language to do gene annotations based on certain protein sequences that non-computer people can write in :)
4. you have to compile and use a debugger. in lisp you can change and run things as you write them.
5. recursion is unequivocally expensive.
6. can't write new iteration constructs (or you can by passing function pointers but it's limited and ugly)
7. no anonymous functions! c'mon!
etc etc
so the fact that lisp doesn't map into a preconceived model of understanding has very little practical significance ... C, by all measures, is less powerful and wouldn't allow me to do my work with reasonable amount of effort. neither would python btw. as i maintain a domain specific language that would have been very difficult to write in some other language.
But it does not change the fact that lisp is not easily accessible for most people, and that particular limitation of lisp is why it will not be 'the next big thing'.
On a personal note, I don't think that using DSLs is good programming practise. It is my opinion that this makes your code too specific to you and you force anyone trying to understand your code to first learn a new language - the one you just invented.
It's like comparing Seth Godins writing to the writings of Kant. There was a time when I was in philosophical mood and I bought the original German version of a book by Kant. Kant is often described as one of the great thinkers, but he sure is not one of the great writers. His sentences are long and unwieldy and it's very difficult to understand what he's trying to say. Seth Godin writes plainly, however, and he communicates his ideas clearly.
The core purpose of reading both their writings is to gain in knowledge, and when the sentence structure of one writing is so obscure that one can't even parse the sentence, then this purpose is not being achieved.
Writing a DSL is the same thing - if nobody else understands what you wrote, then, though you may have succeeded in communicating your meaning to the computer, you have failed in communicating to anybody else who may want to improve your code. And that second part of things is also an important part of programming.
i think DSL's are good for the same points you bring up. i am more concerned with the DSL ability to express a problem/solution. the DSL itself of course necessitates different expertise. just like there a lots of python users, but only a few people who work on the python core. or for that matter linux users vs the linux kernel team.
I'd rather have to learn a new small DSL language that lets me read and write exactly what is meant (the semantics of the language map almost directly to the language of the domain) than a big clunky API (apis are languages!) that will make my code littered with book-keeping tasks when I use it.
However, CL is a language specification, while Java is for better or worse much more than that.
What problems did you have learning Lisp?
My take on that was that the only reason people find Java easier is because it's more similar to other curly-brace languages, the ones they already know. If you take a newcomer to programming, Lisp just may actually be simpler. So the unwashed masses still have some hope.
Who knows what the future holds. Good luck indeed !
Unwashed masses have accepted to learned very complex frameworks and metaprogramming tools around Java; those stuff are not simpler than, say, Common Lisp. They learned it because the consensus (among their peers) was that these were professional tools, useful for one's career. If a Lisp ever gained that fashionability, it would no doubt be learned very quickly by those "unwashed" masses, even if most of them wouldn't ever reach the guru status.
That said I don't see Lisp becoming big. Scala probably has a better chance.
Scalalooks great on paper and is better than JAVA in my opinion. However in practice it still feels very heavy and kind of JAVA-ish. Not for me but perhaps a natural step for a lot of JAVA-developers.