Calling itself a Clojure is a pretty bold statement.
Clojure is one of the most revolutionary programming languages of the last decade, I can't see how this mini-toy-language packaged as a Go library can be compared to the mighty Clojure with a straight face.
Transducers and Spec are two great examples of what Clojure's community is best at. There's a practicality of purpose and single mindedness of philosophy at play in the language's evolution here. Making simple easy.
To my mind though, Clojure brought clarity to the JVM on issues of concurrency, state, mutability, object orientation and persistence and for that I will always love it.
Isn't the idea that all mutation must either be local or transactional rather revolutionary? In a sense, Erlang is like that, too, but Clojure took the idea much further. It is pretty clear that that's Clojure's the main idea.
Isn't Miranda pure-functional? Because Clojure is imperative (-functional). Saying you can't mutate is very different from saying you can mutate whatever you like, whenever you like, as long as its transactional or not observable.
And SIGPLAN papers don't really count. A revolutionary product is not the same as a revolutionary idea. Implementing ideas that have never been productized is still revolutionary.
If I'm not mistaken, ETS tables allow the same kind of mutation as Clojure's atoms -- i.e., they are atomic, but still mutations. Haskell is pure-functional, which is something very different from the functional-imperative Clojure and Erlang.
"If I'm not mistaken, ETS tables allow the same kind of mutation as Clojure's atoms"
ETS tables are usually out-of-(Erlang-)process. You are sending messages to them to update them and query them, and those processes are each functional, so it's still functional. IIRC there's a mode where it runs "in process" with you, but it's still conceptually behind the same interface. (Which raises interesting questions about what exactly is "mutable" or "not mutable", which IMHO ultimately get best answered by Rust.)
What Erlang is not is pure. You can query an ETS table, send it a command to mutate, then run the exact same query again and get a difference response. The message passing makes things impure, even though every individual component of the system is immutable-functional. And there are some other impure functions in Erlang as well, of course, like the functions to get the current time, but the message passing is in some sense the fundamental introduction of impurity at the architectural level.
> The message passing makes things impure, even though every individual component of the system is immutable-functional.
That's how you think about it, but allowing mutation and allowing blocking interaction with processes are exactly the same, as blocking interaction with processes is the same having as continuations, and continuations alone are all you need for mutation, even if you imagine things to be immutable. Like monads, continuations are a universal effect. An otherwise pure language with continuations is indistinguishable from an imperative language, i.e., it is imperative.
Both Clojure and Erlang are functional-imperative languages, but unlike other imperative-functional languages (like ML), they have been designed with concurrency in mind, and the mutations they support are transactional (or at least atomic(.
It's also spawned the recent interest in immutability. Via Om it's had a considerable effect on how Facebook has developed React and its ecosystem, for example.
To me the most important contribution of Clojure is to not focus on OO or FP at all, but instead on data.
Data is a first class citizen of the language: data literal is part of its syntax, and it uses powerful persistent data structures behind that.
Programming with Clojure is what has made me realise that data is really what matters after all. None of that FP or OO discourse should deviate us from that reality check that computing is all about data-in/data-out. Pull the plug and/or battery of your computer and see what remains next time you power it up.
So yes, Clojure may not be revolutionary in itself, it does rely on the shoulders of giants. It is however setting a new standard in terms of being successful in bringing together a very well thought out set of features and philosophy to bring the focus of programming back towards the real complexity, instead of the accidental one created by how we think.
I wrote Clojure full-time for a few years. I was lucky to do so and get paid to learn such an interesting language and paradigm of software development.
Aside from the points you mention, of which I agree, there is one other point I took away from the experience that many would disagree with: I really, really missed static typing.
So that's the main reason I don't use Clojure as much any more and went back to other languages with a different model of typing. But I learned so much and it changed the way I work in other languages.
Clojure is an interesting intersection of two ideas: Lisp, and pure functional programming.
It is not pure, but it is much closer to this than other lisps and it is immutable by default with efficient functional data structures. CL and Schemes are not this way.
I think a revolutionary aspect of it is not a technical one but a social one: is has destygmatized lisp a lot, and lots of people are jumping to it.
Source: I played for a while around 2008 with common lisp and web apps, and while the tooling (hunchentoot, elephant, etc.) was solid, my completely subjective assessment was that the community languished and it was very hard for newbies.
EDIT: Why was I downvoted? Explanations enable enhancement more than punishment... Is it for the reddit-like "source:"? I really dont get it.
It is a matter of implementation and tooling, not language.
Anyone is free to create a native AOT compiler for Clojure.
In fact many attempted to do so, but have given up due to the effort it means bringing a full eco-system up to speed to what Clojure already enjoys in JVM, .NET and JS runtimes, libraries and tooling.
Specially in quality of generated native code and GC implementations.
Clojure can compile to Javascript and .NET, so that's 3 major platforms, being among the most portable languages available.
That it doesn't compile to Go, that's because Go isn't a good compilation target. Besides being a subpar language that ignored the last 30 years of research at least, it wasn't designed to be a platform for other languages. If you're looking for disappointments, you aren't looking in the right direction ;-)
> Clojure itself is dynamically typed, which means it ignores a large chunk of research itself.
It does not. PL research is about how to construct type systems if you choose to construct them. There's plenty of research in untyped languages, too (for a recent, pretty exciting example, see Dedalus, which is the language semantics at the core of Eve).
(1) "I love functional programming! Therefore, newer languages that aren't following in the mold of Haskell are conceptually antiquated."
... yet...
(2) "I don't care about static typing. Therefore, it's cool to ignore the trend of most major languages moving in that direction over the past decade."
Then of course the Rust and Swift guys would tell you that Clojure is an anachronism for relying on garbage collection. Etc, etc...
All of these trade-offs, at the level on which they're commonly discussed on HN and other forums, are matters of subjective preference. And that's okay. Disrespecting other communities for their subjective preferences, while trying to give it the objective veneer of "You've ignored the latest 'advances'!", is just pretentiousness.
> of course the Rust and Swift guys would tell you that Clojure is an anachronism for relying on garbage collection.
I assure you, we would very much not. (The Rust team, anyway. I haven't seen that kind of nonsense out of the Swift team either, and it'd make even less sense, as Swift is technically garbage collected.)
I absolutely agree with the silliness behind "you've ignored the latest advances!" and I also know that the latest advances in research very often yield no advances in practice. I also agree that mocking other languages is usually a sign for having little experience with many project and team types, and with not being able to see the bigger picture.
But that doesn't mean that you can't discuss the tradeoffs, or that they're just subjective preferences. Someone who really understands Rust would never say that GCs are an anachronism, as they would be very much aware of the cost Rust pays for the ability to maintain safety when a GC can't be used. But that's not a subjective preference, either. A language like Rust knowingly sacrifices convenience and development speed to be able to target certain kinds of applications.
> Besides being a subpar language that ignored the last 30 years of research at least
Can beef that up with some arguments? The creators of Go are not ignorant, they just decided consciously to create a language easy enough for recent graduates to be productive quickly.
From a science point of view, the only valid reason why clojure cannot compile to Go is that nobody cared to implement that.[1] Well, either that, or the people who considered doing that realized that compiling a programming language to a Chinese board game is equivalent to using an abacus and abandoned the idea .... ;)
Please. They didn't ignore the research they just decided against it. You might say that they were paying more attention to the last 30 years of experience.
The right solution would've been to go for algebraic data types or at least nullable types. The justification for not going down the former route was that they overlapped too much with interfaces, which is a justification I'm not exactly convinced by. Algebraic data types would make error handling in Go a heck of a lot more pleasant to boot.
He said 3 platforms, but he meant (and listed, so the meaning was obvious) 3 languages, some of which are indeed portable to a very large number of platforms.
Correct me if I'm wrong, but ClojureScript is implemented from scratch and independently of "big" Clojure. If it is so - to run Clojure on other systems you have to implement everything, which makes no sense at all.
I find it quite annoying that for a language that is meant to be "parasitic" there is no simple way to port it to any target. There are a few Clojures around that target e.g. C, but they are more "lookalikes" than the real thing. And ClJS is a separate codebase.
It would be cool if Clojure was one and the same thing and then had a backend to support generic platforms - this way you would have ClojureJVM, ClojureNET, ClojureGO, whatever, with different levels of support and speed, but at least you could share the code. For example, maybe the Go version could have only :aot and write Golang sources.
Mmmh yeah but what is the alternative? To not have access to the JVM ecosystem?
You could make an analogous argument for C not being portable, since it uses an ecosystem of tools and libraries that might not be portable to all systems.
The alternative is that the ecosystem itself is written in Clojure (or at least the most important parts of it).
Of course, you will always have a set of points at which the language needs to call lower-level functionality, but you should keep that set as small as possible, to make the ecosystem easier to port.
And in the modern "client/server" world, you really need this, because systems are often heterogeneous, and you often need to move one piece of code to another part of the system which runs on a different runtime.
Clojure is not just a Lisp on the JVM. Clojure is a Lisp but also much more: Readable persistent vectors, hash maps, and sets. Protocols, records, and anonymous (reified) instances of protocols/interfaces. Sequences as a common unifying and extensible abstraction for iteration. Transients, transducers, multimethods with ad-hoc and extensible hierarchies. Namespaces and vars with metadata. Atoms, Agents, Refs, and the STM. Reducers and fork-join. AOT compilation to Java bytecode along with dynamic loading of any code. Now clojure.spec and more, and this is just stuff built into the language.
All of those could have been and a lot of them are libraries in the CL ecosystem though(with varying degrees of quality unfortunately). I feel the reason clojure is a separate language at all is because it would be pretty hard to get a lot of non-lispers interested in a collection of lisp libraries, while getting them to try a new language especially on a familiar platform is relatively easier, especially if you are a talented speaker like Rich and some of the other early clojure adopters.
Other reasons might include the fact that the CL ecosystem in late 10 years ago was light-years behind what it is now. And of course people have an irrational repulsion to some characteristics, like the reader upcasing all symbols by default, which has caused me 0 problems other than the fact that I though it was weird in the beginning.
No disrespect to clojure, it probably got a lot of people interested in common lisp and scheme as a result of existing, but that's my view of things.
Most of those features were already present in Common Lisp in the mid-80's.
The main advantages of Clojure are the libraries from JVM/.NET, having a few parenthesis replaced by square brackets and charismatic community speakers like Rich and David.
I'd argue the main advantage is the consistent focus on making pragmatic engineering decisions and the focus on building a community who are equally pragmatic.
I've got a bunch of Clojure apps that I wrote ~5 years ago that still work on the latest version of Clojure with the latest libraries. That is pragmatic engineering.
Cursive, the Clojure IDE built on top of IntelliJ, is an amazing bit of work when you consider it is written by one guy. Again the clever use of leverage.
A focus on everyday immutability and easily reasoned concurrency makes building and reasoning about medium sized applications much easier.
Etc etc.
For a language not backed by an industry titan it has done an amazing job.
Sure when you look at something like spec there isn't a whole lot of "secret sauce" - almost all of it has been done before (I remember the big Microsoft push for runtime contracts over a decade ago). Despite this I predict it will have a huge impact on overall codebase quality.
Clojure is a Lisp but also much more: Readable persistent vectors, hash maps, and sets.
This is kind of oxymoronic - because those things make it less of a lisp. And to be frank, if you don't think
(vector 1 2 3)
is readable, then I don't think you really get lisp.
Protocols
A greenspunning of OO features with a different name because Hickey doesn't get OO (probably never made it through to the bit SICP where you implement objects, or read the "closures are a poor mans object" koan).
90% of the rest of what you list can be found in in various lisps - often all in the same place (racket, common lisp).
Hickey doesn't get OO? You obviously aren't familiar with is work as he makes it clear that he worked professionally with OO in Java and C++ on large projects for more than 10 years before working on Clojure.
Does working in two pseudo OO Languages for 10 years make you an expert in OO? In one of his talks he mentions that he ended up writing java in such a way that all his classes were static ones. Again, he clearly hadn't figured out that instantiating an immutable object is a way of partially applying multiple related functions at once.
A brief look at this site for the other "OOFeatureButNotOOBecauseItHasADifferentName" finds this gem
Clojure multimethods are a simple yet powerful mechanism for runtime polymorphism that is free of the trappings of OO, types and inheritance.
This guy just doesn't get it and I am tired of him being held up as an authority.
Neither he nor I ever claimed he was an OOP expert. I was merely defending him from your accusation that he doesn't get OOP at all. I think it's the other way round - maybe you don't get Rich Hickey's innovative contributions. Clojure is a reaction against the OOP approach in general, not limited to the implementations in Java and C++. If you'd followed his work you would have noticed that many times he defines the OOP problem as the conflation of data and functions. Tying up data and methods in classes and objects creates complexity which Clojure was designed to untangle. In that he has succeeded where CL failed. Clojure is arguably the first lisp to gain mainstream adoption and for that alone Rich Hickey deserves the respect of all lisp/scheme advocates.
The venerable master Qc Na was walking with his student, Anton. Hoping to prompt the master into a discussion, Anton said "Master, I have heard that objects are a very good thing - is this true?" Qc Na looked pityingly at his student and replied, "Foolish pupil - objects are merely a poor man's closures."
Chastised, Anton took his leave from his master and returned to his cell, intent on studying closures. He carefully read the entire "Lambda: The Ultimate..." series of papers and its cousins, and implemented a small Scheme interpreter with a closure-based object system. He learned much, and looked forward to informing his master of his progress.
On his next walk with Qc Na, Anton attempted to impress his master by saying "Master, I have diligently studied the matter, and now understand that objects are truly a poor man's closures." Qc Na responded by hitting Anton with his stick, saying "When will you learn? Closures are a poor man's object." At that moment, Anton became enlightened.
I regard rusts structs + traits as an object system. But I understand why they chose to not mention objects at all - they don't want to conjure up images of Java boiler plate and heavy mutation, which is sadly what it means to most people now.
I feel like data and behaviour is very much tied together in a rust struct. With the right visibility modifiers it can be completely opaque - it's literally a black box you are sending messages to. The methods are attached to the object in my mind.
But I am by no means a rust expert. I'm curious is to why you think the data and behaviour are not tied together.
Because you can have free functions that take plain data. So you can have methods or you can have free functions. This is why it's à la carte - you can choose if you use methods or free functions. You can choose if your data has behavior or not.
Right, absolutely. I am by no means claiming rust is an OO language, just that I would consider the structs + traits thing a way of making objects. I suppose I could have been more precise - it's not an object system by itself but it certainly can be very easily used as one. I think for a systems langauge they did a very fine job in designing that part of it.
What is your definition of "object system"? I'm afraid it seems open enough to include any system for polymorphism.
(As an aside: I am the author of several Rust trait RFCs & I have read "Traits: Composable Units of Behaviour," though "How to make ad-hoc polymorphism less ad-hoc" is more relevant to Rust. Your smugness about this toward the other poster is not appreciated.)
My definition is the same as the CS literature expressed in SIGPLAN, OOPSLA and ECOOP papers, written by people doing OOP language research since the mid-70s. No need to invent my own.
As for the other poster, sorry if it appears like that. I did not offended anyone and provided information where to read more about trait systems.
HN comments are not big enough to provide an history of OOP systems, their similarities and differences.
I've been kind of aggressive in response to your comments, because I've found them condescending, but I think what we're actually revealing is that the way you're using "object-oriented" is ontologically discontinuous with the conception of languages derived from their formal semantics as I understand it. Features with the same formal semantics (Rust traits & Haskell type classes), expressed through distinct syntax, can correspond to different concepts in the ontology of languages which object-orientation exists within.
I might be tempted to say that object-orientation has no explanatory value - "it just means polymorphism!" - but I think what's more accurate is to say that its explanatory value operates within a distinct discourse from the discourse I am familiar with.
> Your smugness about this toward the other poster is not appreciated.
I don't see him being smug at all. Is it smugness to suggest reading material to someone when they've shown ignorance of a topic? People do that to me here often from time to time and I don't interpret it as "smugness".
It is when you make the recommendation in a tone which is didactic, patronizing, and superior. That's the definition of smug (I've also found your comments somewhat smug).
If you find it smug that's really your problem. It's a bit tiresome to see people talking about OO when they haven't educated themselves about OO at all. Which is probably why I don't like Rich Hickeys talks, incidentally.
Then travel back in time to 2003 and read the European Conference on Object-Oriented Programming (ECOOP) paper "Traits: Composable Units of Behaviour" for a possible view on traits long before Rust was born.
The way programming languages do information hiding, polymorphism, method/function dispatch, data modelling is also part of OOP and there are several ways to combine them.
OOP is so much more than just plain objects and classes.
The implementation of traits described in that paper is totally different from the implementation of traits in Rust. Rust has adopted an ontology and syntax familiar to programmers in object oriented programming to make accessible a form of polymorphism which is quite different.
In fact, the same concept exists in Haskell, where it is called "type classes." (In this case, I think the adoption of OO terminology is harmful to comprehension, rather than helpful). Are we to believe that Haskell is object-oriented also? Is there a language with polymorphic abstraction that is not object-oriented in your formulation?
At 1:01:01 on the first lecture he discusses how Haskell relates to OOP in regards of subtyping and generic polymorphism and how although different on the surface they share those CS concepts in their own ways.
I've seen SPJ's talk. You might notice that in the moment you site, he says that OO and parametric polymorphism are both polymorphism systems. Rust and Haskell are both parametric systems, not OO systems, in SPJ's formulation (and mine). The slide is literally a venn diagram of the two concepts and the abstractions they can encode.
What is an example of a language with polymorphism you do not consider to be object oriented? I'm not really interested in being linked to media I've already seen, I'm trying to suss out what you think object oriented means. As far as I can tell, it means "polymorphism," and well - yes I think polymorphism is a great idea, but I don't think its what most people mean when they say "object-oriented."
(Also, if Haskell type classes are interfaces, then so are Rust traits. They have the same semantics. But you've already said that Rust traits are traits.)
Again, it might be concepts developed in OOP languages, but I'm still not using objects. I never said I'm not using OOP, which is a stronger claim. I said I'm not using objects.
If you're unwilling to let go of your pre-conceived notions of what syntax is supposed to be, sure. I find clojure code really ugly, like it secretly wants to be javascript but can't commit to it. Pure s-expression code is very pleasing on the eyes once you get used to it.
If you're unable to let go of biases formed by previous experiences - why should i listen to you? I find clojure code really beautiful, like by letting go pre-conceived notions of "everything is a list" had really unleashed the power of concise, immutable and predictable data structures. Pure s-expression code puts unnecessary mental strain on a developer because a multitude of semantics is attached to single kind of parens without any practical or pragmatic reason to do so, as if early lispers didn't have other kinds of parens or didn't have other useful data structures and subsequently a need to denote them concisely.
These just sound like complaints from a typical novice to LISP. LISP syntax is made of nested lists (an AST) and atoms. Representing sequential types as atoms with ugly reader macros based on the implementation of said sequential types strikes someone who knows a real LISP language as an ugly and ignorant thing to do.
If you find real LISP code unreadable because it doesn't look like javascript - because you can't tell when your sequence is a linked list or an array when there's no curly braces - I suggest learning to read and write LISP code and understand how LISP works. A real LISP I mean, not clojure.
Again, other LISPs have data structures aren't from linked list. A complete myth that that they only use linked lists.
These sound just like ramblings of typical elitist. If your main concern is to have language that only appeals to other elitists - you'll take that language to grave with you.
Syntax is something novices judge the language by. Their criticism is not always valid, but if language can make concessions that don't undermine it's core values but lower the learning curve - there is literally no reason to not make these concessions. No reasons apart from elitism and purism that is and those are just plain stupid.
Clojure is great example of lisp that is easier to grasp (one of main reason being sane use of data literals) but still remains lisp all the way down to it's core.
I don't know if understanding LISP is really elitism. I don't think it requires some great intellect to get it. I think the key reason people have the attitude against the syntax is because they learned languages that looked a certain way, and to them - that's programming damn it.
I mean LISP syntax is objectively much more simple. I think if you were to sit programming novices - with no pre-conceived notions - infront of an s-expression language and an ALGOL looking one, you wouldn't find much difference on which is easier to learn.
I genuinely think people have difficulty letting go of stuff when they learn LISP. When I first started I thought all the parens were silly as well, and I thought stuff like sweet-expressions [1] were clearly the way forward and it was only those stuffy old elitist scheme programmers who couldn't see it. But over time I saw that the simplicity and regularity of s-expressions made it worth it.
Clojures awkward smashing together of javascriptish syntax into LISP reminds me of nothing so much as training wheels on a bicycle. Sure I suppose you can call those of us who ride a bicycle with two simple wheels "elitsts" and accuse of rejecting "convenience", but to be honest when I see people defending ugly literals and complicating the syntax of a LISP language, I can't help but suggesting that they learn to ride a damn bike.
> I don't think it requires some great intellect to get it
yeah, exactly, it doesn't. which makes lisp elitism very awkward.
> LISP syntax is objectively much more simple
things can be too simple, to the point where it is counter productive and harmful. example - why do you need all these weird symbols to represent numbers 1234567890? seems like 1 does the job just fine. unary arithmetic is trivial - just stitch numbers together and you have addition, just repeat them X times and you have multiplication. no need for weird shenanigans with symbols changing because of trivial operations.
> Clojures awkward smashing together of javascriptish syntax
i genuinely think you have difficulty letting go of your biases. all clojure did was designate two more kinds of parens to mean something useful in a language. it's a tradeoff between being pure lisp and being easier to grasp while still remaining lisp. but i can see now, tradeoffs are hard to understand for elitists/purists.
i wonder if every time when you buy a keyboard/laptop you're ripping off those damn [] and {}. because your arguments are unreasonable enough to think that might actually be true.
> > I don't think it requires some great intellect to get it
> yeah, exactly, it doesn't. which makes lisp elitism very awkward.
The thing is, people sometimes use elitism as a synonym for chauvinism, which it isn't.
"Lisp is easy, everyone should use it for everything" doesn't, by itself, meet the definition elitism because it doesn't refer to some small elite group being somehow better than others.
Well, too stupid to be computer programmers, that much is true.
That sort of statement is tech elitism, not Lisp elitism. Usually out of frustration when dealing with trolls.
I don't believe that there are any programmers who genuinely can't deal with Lisp syntax at least as well as they deal with any other syntax.
There are only trolls who lie in making that claim, and there are trolling non-programmers who tell the truth.
Simplified syntax is mostly a threat to those who hold mastery of some arcane syntax as their principal intellectual achievement: i.e. advanced newbies.
The fact that exactly the same semantics can be expressed in a syntax that lesser newbies can learn in a day is a big threat to someone who spent months memorizing some syntax, because it means something in which they take pride as a great value is actually worthless "fool's gold".
If you're a professional who does a lot of numeric work with arithmetic expressions, working in S-exps will make you grumble, but you can do it.
i'll just repeat what i've said before - lisp purism is not a valid reason to not adopt data literals for useful data structures. there is nothing inherently worse about [1 2 3] over (vector 1 2 3) in terms of "the lisp idea", but it is order of magnitude easier to work with in terms of ability to scan structure of code.
There is nothing wrong with shorthand notations which don't disturb the surrounding Lisp syntax (don't introduce strange ambiguities and precedence issues into it and so on: and there is room to even do that a little bit).
Lisp has those short-hand notations. There is nothing worse about 'X over (quote X).
The only thing wrong with [1 2 3] -> (vector 1 2 3) is that it's somewhat of an unimaginative waste of these [ ] characters.
As others have mentioned, all of those are in Common Lisp, either built-in or with with libraries readily available in Quicklisp. Quicklisp didn't exist back then, so it wasn't so easy as it is today, but most of the libraries already existed.
Don't get me wrong, I understand the convenience of having all of that built in, minus the crusty parts of Common Lisp, but as far as language features go, I'd say it was evolutionary, not revolutionary.
I have no idea how anyone can claim clojure is revolutionary or call it "the mighty clojure" with a straight face. I can only assume this post was written in jest.
It has macros that...look pretty powerful to me? What's your issue with them?
> doesn't share with Lisp the code-as-data philosophy
Can you flesh out your objections a bit more?
Edit: For the sake of anyone reading this later, the comment I was replying to originally said Zygomys wasn't a lisp, which seemed a bit odd. It has since been edited to say Zygomys isn't Clojure, which is quite correct.
Agreed. The comment I replied to was (at the time) disputing Zygomys's status as a lisp; it's since been changed to questioning Zygomys's claim to be a Clojure-equivalent, which I quite agree with.
Perhaps a better analogy would be Groovy, rather than Clojure? (Of course, Groovy isn't "cool" these days, so I guess there's not much marketing juice in comparing your new language to it...)
Well, at one time it aimed to be quite a bit more. As I recall there was a lot of envy of dynamic language in general and Ruby in particular when Groovy first got popular.
There was even a Groovy on Rails framework, just to make the longing more obvious. From memory, Groovy only reinvented itself as a scripting language some years later.
The way I understood it, the mention of Clojure was by analogy — Zygomys is to Go as Clojure is to Java (based on the same runtime, tight integration, but altogether different languages). I didn't interpret this to mean that Zygomys is anything like Clojure.
if x + y == 8 { (println "we add up") } else { (println "wat?" ) }
really seems to combine syntaxes in a super-confusing manner ... The "if" is not in an s-expression, but the println call is? And there are blocks denoted using C-style braces mixed in ... I think this would take a while to get used to. :)
Clojure is a language which compiles to JVM byte code, which is also the platform that java compiles to, so (as consequence of that) they can interoperate.
But I don't think Clojure was meant as a replacement for Java or some kind of extension of the Java language or some sort of CoffeeScript for Java.
Clojure is a powerful functional programming language with lots of new paradigms and original ideas - quite at the opposite spectrum of the object-oriented Java.
Although I don't program in it, my C++ coding skills and more importantly architectural skills, improved dramatically after learning Clojure.
So the title of the article is incorrect (and click-bait-y).
Thank you. I tend to do interactive mathy things, and find the infix being the default at the repl cuts down on keystrokes and speeds up the interaction. Anything within {} curly braces is treated as infix, and infix is the starting mode at the repl. You can freely mix (prefix) and {infix} as you wish. For longer math expressions this does tend to help readability.
Like what? Off the top of my head, Rust, Haskell and F# are probably the only ones that come close, and they're about as popular as the Lisps (i.e. not).
> you should have try to popularize lisp like 10-20 years ago.
Programmers want familiar syntax and infix notation while Lisps want homoiconicity. It's never going to happen.
It's funny because people fear and loathe Lisp's parenthesis, while after a month of using Lisp, you don't see parens anymore (they're mostly for the parser).
> It's funny because people fear and loathe Lisp's parenthesis, while after a month of using Lisp, you don't see parens anymore (they're mostly for the parser).
With parinfer, you stop looking at the parens in about an afternoon, I guess, and start reading indentation as in python. At some points, you look at opening parens as alignment markers, and from time to time you need to close something before what is inferred, but always in the same line, I.e., you want:
(Foo (bar) baz))
Instead of:
(Foo (bar baz)))
But generally, it is just magic! And multiline parsing in your head is just gone.
>Programmers want familiar syntax and infix notation
Programmers wanted batch punchcards processing over timesharing interactive terminals, programmers wanted legacy and compatibility over innovation and modernization. Programmers wanted ugly write-compile-run-test in 70s terminal emulator stuff over live interactive graphical in-place debuggers. Face it, programmers are stupid and can't learn new technologies.
>Red does compare itself to LISP in many ways, true.
Not only compares, it does extend many things which Lisp failed to do when it became unpopular.
>But Clojure, for example, is actually popular enough that places use it for real work, today
Yes, and this is very good, because it gives many people idea that programming may be much better than they used to. My position here is that Clojure is only the beginning.
Ok, what I wanted to show is Red's parse is more than just pattern matching, since you can execute regular Red code in parsing rules, walk around the input and other things.
You can check it's features here: http://www.red-lang.org/2013/11/041-introducing-parse.html
I'm certainly not familiar with Rebol/Red, but every single time I've been introduced to them as "modern incarnations of Forth", and AFAICR they conserve right-to-left function application and the concept of dictionaries as dialects of the language, don't they?
Red is modern incarnation of Rebol, which is it's own unique language. It was influenced by Forth, true, but this is only influencing, Rebol has much more of it's own ideas than taken from others.
> Programmers wanted batch punchcards processing over timesharing interactive terminals, programmers wanted legacy and compatibility over innovation and modernization.
wow, really, all of them? that is amazing. tell me more!
> So, do you find things programmers are using in their daily work good?
i find programmers using full spectrum from horrible to amazing. the reasons some people stay on lower end of that spectrum range from psychological to business constraints. i think more interesting question is why is it that while considering yourself being somewhere in the upper end of the spectrum you decide to shit on lisp, which arguably is the starting point of everything you deem good.
I don't shit on lisp, I've been for lisp since I discovered it many years ago. I'm against new worthless implementations presenting lisp as language only capable to parasite on other platforms, without having it's own real thing.
To me lisp is an idea, which ironically found it's best implementation (from what I've seen so far) in Rebol.
>could it be you haven't yet realized it's actually not worthless?
could be, I didn't even run it, but the problem is your implementation limited by underlying platform and if it wasn't made with lisp in mind (and this is the case) result will have tons of limitations.
>would you elaborate what exactly makes clojure a parasite on jvm?
Maybe it's ok for JVM, but I can tell you what makes it less lisp (and the reason is parasitism): absence of tail recursion.
but that would only matter if those limitations outweighed the advantages of developing with lisp?
> absence of tail recursion
so from "clojure is worthless parasite on jvm" we're down to "clojure is a lisp which i haven't tried yet but it's on jvm so i think it lacks tail recursion"
>but that would only matter if those limitations outweighed the advantages of developing with lisp?
Yes, and I doubt this Zygomys can reload code in runtime because of limitations of it's platform.
>so from "clojure is worthless parasite on jvm" we're down to "clojure is a lisp which i haven't tried yet but it's on jvm so i think it lacks tail recursion"
It's not not predominantly a functional programming language and has no rich set of immutable, persistent data structures.
So, it's no Clojure. But it is young. It may become a clojure but it seems presumptuous at this stage..