Hacker News new | ask | show | jobs
by lispm 750 days ago
and then you get this in Clojure:

  user=> (list? (cons 1 '(2 3)))
  false
  user=> (cons 1 '(2 3))
  (1 2 3)
That's "strange", isn't it? It prints as (1 2 3), but it is not a list? So there are things which print as lists, but aren't lists? What? Which also means that when we print it and read it back, it will be of a different type and list? will be true?!

  ELISP> (listp (cons 1 '(2 3)))
  t
Puh, Emacs Lisp got it right.
2 comments

I just tried your first example on tryclojure.org and it returned "true":

    user=> (list? (cons 1 '(2 3)))
    true
Your example looks like Clojurescript? It is also inconsistent between variants?

  Clojure 1.11.3
  user=> (list? (cons 1 '(2 3)))
  false
Interesting! The tryclojure.org website says it's Clojure, not ClojureScript.

If it's inconsistent between variants then I'm absolutely not going to code in it...

It's not "inconsistent" between the variants. Clojure is a hosted language, it depends on the underlying platform.

In Clojurescript, the implementation details and type checks differ slightly from Clojure due to the different runtime environments (Javascript vs. JVM). As a result, certain predicates like `list?` might behave differently.

In Clojure, it's generally better to use (seq?) instead of (list?) when you need to check if a value is a sequence, as (seq?) is more encompassing and works for all sequence types, not just lists.

You almost never use (list?) in Clojure unless you explicitly need to check for a list created via (list ...), and most of the time we use (seq?) instead.

Maybe Clojure doesn't work for you because you haven't even bothered checking the documentation? At least you could've asked Google or ChatGPT, before crying how "broken it is". The language after all wasn't created last weekend, it's been around for 17 years

Yes, I'm tired of Clojure fanboys recommending their language as a Lisp. It's not.
You can probably make many like minded friends in r/haskell. Just post something about Clojure and pedants most likely crawl out, saying how it is not an FP-language. :)
Not about FP; it' just that Clojure tries to be a Lisp and it fails on the simplest basic list cons'ing.

Like declaring some mini-C 'ANSI C compatible' and you can't even provide a complete but basic stdio.h header.

It's not "failing" on the simplest basic list cons'ing, it did what's expected, it consed the list. You're trying language features without even bothering to ask if the function you're using does what you think it does.

Have you read the docstring for (list?)? It says "Returns true if x implements IPersistentList". (cons 1 '(2 3)) results in a clojure.lang.Cons not the instance of clojure.lang.PersistentList. A clojure dev would be using (seq? (cons 1 '(2 3))) instead of what you tried.

Maybe before hating something so fervently try to learn it a bit more first?

> A clojure dev would be using (seq? (cons 1 '(2 3))) instead of what [the Lisp dev] tried.

Well, no kidding.

> (cons 1 '(2 3)) results in a <Java thing> not the instance of <another Java thing>.

:)

Clojure is a hosted language. It embraces the idioms, strengths, and ecosystems of the platforms it runs on (JVM, Javascript, .NET, Dart, etc.) without trying to "change the platform" or impose an absolute uniform behavior across different environments.

Clojure encourages using idiomatic patterns that align with the host platform’s best practices. For instance, when running on the JVM, it leverages JVM's threading model and garbage collection; in Clojurescript, it adopts patterns suitable for JS's event-driven model.

Clojure does not try to provide a uniform abstraction layer that masks platform differences. Instead, it exposes platform-specific capabilities, making developers aware of and able to exploit the unique features and strengths of each platform.

Clojure compiles down to the native code of the host platform. For the JVM, it compiles to JVM bytecode; for JS, it compiles to JS code. This means the compiled code runs as if it were natively written in the host language.

Clojure operates within the host runtime, using the host platform’s execution model, memory management, and runtime services.

Being a hosted language means that Clojure does not attempt to hide or abstract away the platform it runs on. Instead, it integrates deeply with the host platform, leveraging its native capabilities and interoperation features. This allows Clojure code to be idiomatic to the host environment and benefit fully from its strengths.