Hacker News new | ask | show | jobs
by laxentasken 3282 days ago
Started looking at getting into Racket and CL after reading up on lisp and there is something about it that really bugs me, in a good way. Sadly the train seems to have left the station regarding positions where you use lisp where I live. All is java and C-flavors.
4 comments

> All is java

Possible tip: sneak in ABCL when they're not looking. ABCL is a Common Lisp implementation for JVM, with (what seems like) relatively OK interop between Lisp and Java code.

Something makes me think they'll notice all the parens during a code review...
Write a reader macro that treats all [ ], { } and < > as if they were ( ), and the only thing they'll notice is that there's less parens/brackets than there should be in regular Java code...
There have been efforts to do something similar to create more "readable" S-expressions. I did work in Common Lisp for a number of years and didn't have any issues with the syntax but I rather like this idea:

http://readable.sourceforge.net/

why would one do that instead of using clojure?
Because as 'klibertp wrote, they're two vastly different languages, with different design decisions.

The whole thread is about primarily Common Lisp; people who enjoy the design choices made by the CL standardization committee and subsequent evolution of the language's ecosystem would most likely want to know that there exists a proper CL implementation for JVM.

but the person i replied to replied to a commenter lamenting the fact that there was nothing but java and c style development jobs instead of lisp inspired jobs. they weren't lamenting the lack of jobs specific to just common lisp. and to me, it doesn't make sense to "sneak in" an esoteric implementation of lisp on the jvm when clojure already exists. what makes people think that would be easier to sell at a place using java heavily?
I wouldn't call ABCL esoteric; it's as rightful JVM citizen as Clojure or Scala. That said, I agree it's much, much less popular in the JVM world, so it could be a harder sell.
Because, despite both being Lisps, Clojure and Common Lisp are vastly different languages, with different pros and cons.
of course they're different. i didn't say or imply otherwise. the original parent mentioned both racket and common lisp, again different languages, so it was clear they weren't looking just for common lisp and were more generally wanting for some lisp or scheme type of job. and i was asking a legitimate and honest question, as i see ABCL to be a much more esoteric and hard sell than clojure to a place heavy on java development.
You asked, "why would one use [ABCL]?" What I implied in my response (sorry for not stating it directly) was that one may prefer the particular feature set of CL over Clojure's.

As for being a hard sell - my personal experience is that if you're in a position that allows you to choose your implementation language, in most cases you can choose Brainfuck and nobody will care. As an example, I introduced F#, Erlang, Elixir and a bit of Prolog to a Python shop that way: all that mattered in these cases was whether the code worked, and it did, so no one complained. The Erlang microservice actually outlived the project it was written for by a year and a half.

On the other hand (still, in my experience) if you're not in a position where you can choose your language you're basically screwed, and should stop trying to convince your team to switch to something else. You have almost no chance of succeeding and a high chance of disrupting teamwork by pushing your opinions on others.

So I was thinking about the former situation, where you have some degree of freedom of choice and can decide the language on technical merits alone.

Common Lisp is vastly more powerful and better implemented.
Seems dead
> Seems dead

The latest release (1.5) was earlier this month.

plus:

it's common lisp. if the language spec hasn't changed, and your code works, you don't really need to change the interpreter.

ABCL's interoperability with Java is not part of the CL spec, but an add-on. This can make it easy to quickly get things done in a situation where Java libraries are the best tool for the task, but at the cost of portability between CL implementations.
Or just use Clojure, which is a nice Lisp (not CL) for the JVM
> which is a nice Lisp

Well, it's definitely a Lisp; however, I don't think the "nice" qualifier fits here.

Clojure has a few interesting features which are well integrated with each other, but it also comes with a lot of opinionated choices one might not like. Another thing - not a language issue per-se - is that relying on Java ecosystem can be painful (and ClojureScript, fortunately finally bootstrapped a while back, is not quite the same language).

Personally, I feel that, in pursuit of simplicity, Clojure dropped a lot of useful features. As an example, in both CL and Racket, you have 2-3 times more ways of structuring your code than in Clojure. This is important, because different parts of a codebase benefit from different structuring mechanisms - and the more choice you have, the easier it is to find the right one. In Clojure, all you have are maps and defrecord, with the latter being almost never used.

Of course, you have macros to combat this, but then you're put in the shoes of language inventor and implementer, which is a lot more complexity than most programmers would like to fight just to be able to order the function definition the way they want.

To summarize: in my opinion, Clojure did some things right but then got locked into that single track and refused to incorporate additional features (and lessons learned) from other Lisps. So no, I don't think it's a "nice Lisp." OTOH, it may well be a good language, especially if your problem and domain are a good fit for it.

It might be a nice language but not an especially nice Lisp. Lots of stuff from Lisp is missing: interpreter and compiler integrated, self hosting compiler written in Lisp, condition system with interactive error handling, nice object-system like CLOS, simpler numeric tower, good error messages, Lisp-like stack traces, image-based development with fast startup times, Tail Call Optimization, continuations, ... plus it has some strange design decisions with basic list data structures.

It's 'Lisp'-like where the basic primitive list processing has been replaced with a different higher-level data structure (persistent sequences) built on top of an alien infrastructure which leaks through everywhere and which was not developed for interactive programming (the JVM)... That was one of its original design decisions: being hosted on top of the JVM.

> It's 'Lisp'-like built on top of an alien infrastructure which leaks through everywhere...

Given it's Lisp (CL in particular) that's "built with alien technology"™, I'd say Clojure is built on top of terran architecture, with the usual human stuff leaking everewyhere... ;).

Would Common Lisp be Zerg or Protoss technology?
Xel'naga.
> some strange design decisions with basic list data structures

What are those?

Hopefully a Clojure user will correct me, but something like (1 2 3) has a single printed representation for slightly different data structures. You can construct something which prints as (1 2 3) and when you read it, then it is something else.

  user=> (list 1 2 3)
  (1 2 3)
  user=> (list? (list 1 2 3))
  true
  user=> '(1 2 3)
  (1 2 3)
  user=> (list? '(1 2 3))
  true
  user=> (cons 1 '(2 3))  
  (1 2 3)
  user=> (list? (cons 1 '(2 3)))
  false
It might not be a big deal, but from a language design view I would expect the single most important external data structure representation in Lisp - a list - is not overloaded with different data structures, where basic operators give different results. I personally would also think that in Lisp the predicate list? is fundamental and returns true for everything which looks printed like a list.

Common Lisp has a related problem for arrays: there are some attributes of arrays which have no printed representation. One will read an array back, but it might lack some features - like not having a fill-pointer. But atleast ARRAYP will still return true.

This seq/list thing might not be a big deal in practice, but it's another design wart. The language has in several places names, which are fundamental in Lisp and which mean something totally different now. Like 'atom'. Since the concept of a Lisp atom no longer applies - remember we have seqs, not linked conses - the name was reused to mean something different. atom used to mean (not (consp thing)) now it is something else.

The way I usually read Clojure,

   (1 2 3)
isn't the printed representation of a list. It's just the printed representation of a sequence, which could be a list, a lazy seq, or others.

I'm not a Clojure expert, but when I use it, it looks like everything that responds to seq? prints in brackets. And so I tend to think of a seq as the fundamental, most important data structure in the language, and think of a list of just one kind of seq. And following from that, the seq? predicate is fundamental and returns true for everything that prints like a seq - which includes lists.

So maybe this seq primacy means it would be more accurate to call Clojure "Lisp like" or "a Lisp descendant" rather than "a Lisp"? I'm not sure.

I like Clojure, I like CL, and I tend to use and enjoy them both without worrying too much about taxonomy. Having said that, it's totally fair and important to ask the questions you asked!

For me, though, the answers to those questions don't make me like or dislike Clojure or CL more or less relative to each other. They're both fun and useful, and I'm glad they both exist. :)

Thanks! Super interesting.

Of course the meaning of (not (consp thing)) for atom is classical, but don't you think it's a bit weird? It always struck me that way. In a language where lists were the only composite data structure (i.e. not being a cons means being a number or a string or a symbol), it made sense, but that meaning degrades once you have vectors and hashtables. Those are no more deserving of the name 'atom' than lists are. Indeed if one indulges in the oxymoron of treating atomicity as a spectrum, vectors feel more atomic to me than lists while hashtables feel less atomic.

I think you will find that Clojure offers many of things that you like about Racket or CL, while also getting rid of a lot of the complexity of CL (CL is not really a functional language, and hardly can be considered an immutable one).

Clojurescript, which is nearly identical semantics to Clojure, also is quite a practical skill for front-end development.

> (CL is not really a functional language, and hardly can be considered an immutable one)

It's important to note here though that this is a feature, not a bug. CL is a multi-paradigm and extremely pragmatic language.

I usually quip that Common Lisp and Perl are basically the same language, bit with different syntax. Not quite correct, obviously, but both languages give me that same pragmatic feel where having several approaches to the same problem is considered something desirable, not a defect.
perl also grabbed a lot of things from CL, like moose(their MOP, at least so I hear).
> this is a feature, not a bug

1) I never said it was a bug. 2) Whether CL's multi-paradigm nature is an advantage or not is subjective.

That's all what I meant. I read your comment as implying this is a bug; seems I was wrong.
The FSet functional collections library [0] greatly improves CL's support for functional programming.

[0] https://github.com/slburson/fset

> positions where you use lisp where I live

Where do you live?