Live data from Hacker News

Why Clojure?

gaiwan.co

241–250 of 302 posts

Re: Why Clojure?

#241

Earlier quoted context omitted.

Neither defprotocol nor deftype introduce static typing into Clojure. Errors in their usage are not checked statically and are only discovered at runtime.

No, defprotocol and deftype have the same properties as Java interface and Java classes, and the types are checked at compile time. This is static typing. Period. Clojure is a compiled language, it does check typing during compilation.

Protocols do not work like Java interfaces or classes. Their methods are compiled into regular functions which lookup the implementation to use at runtime based on the runtime type of the receiver. Compilation will check for the named function but doesn't do any further checking. Given the following protocol and implementation:

  (defprotocol P
    (method [this ^Integer i]))

  (extend-protocol P
    String
    (method [s i] (.substring s i)))
both (method "test" "call") and (method 1 2) will be accepted by the compilation phase but will fail at runtime.

Of course there's no requirement for Clojure code to be AOT compiled anyway so in that case any name errors will still only be caught at runtime when the compilation happens.

Type hinted bindings are only converted into a cast and are not checked at compilation time either e.g.

  (defn hinted [^String s] (.length s))
  (hinted 3)
will be accepted but fail at runtime.

deftype is only used for Java interop an is also not a form of type checking. The methods will be compiled into Java classes and interfaces, but the implementations defer to regular Clojure functions which are not type checked. You can only make use of the type information by referencing the compiled class files in Java or another statically typed language, using them from Clojure will not perform type checking.

Re: Why Clojure?

#242

Earlier quoted context omitted.

Well, also, sadly, the first thing I would want to be right now happens to be... a GUI, which seems to be the archnmesis of Java in general, and clojure in particular ;)

Ain't nothing wrong with Swing or JavaFX :).

Ehhhh they work, but at what cost? If you know them already go ahead, but the other popular desktop ui's are probably easier and more maintainable. I really do wish desktop and mobile in Java was more popular. I'd really like to have one language and ecosystem.

Re: Why Clojure?

#243

Earlier quoted context omitted.

That's not quite true though. Java tracks types in the signatures of the functions, defprotocol does not. If I make a protocol and then pass a wrong type as a parameter to it then I'll get a runtime error. It's not going to tell me that I passed in a wrong type at compile time. I find using defprotocol in Clojure tends to be an antipattern because it just makes code harder to read by introducing indirection. The libr…

Then you are not writing in defprotocol everywhere style. The keyword is everywhere. All the domain objects are deftype or defrecord. Try that. It is the same as Java, basically. It is not an anti pattern, it is the way most low level libraries and clojure itself are written. Clojure is a tool, not a cult. This core team worship is turning people away. The core team made plenty of mistakes, and got called out, rightf…

Even if you did, that wouldn't solve the problem because many checks are still done at runtime. Also, if you started doing that then you might as well just write Java at that point. I've worked on code bases structured in this way and it's absolutely terrible to work with. For one, protocols completely break any sort of REPL driven development.

Most libraries are absolutely not written in this way either. Please point me to a single library that's actually written in the style you describe. The use of protocols in actual popular libraries like Ring tends to be minimal.

The reality is that dynamic typing has never been a real problem in Clojure. I've worked with the language almost exclusively for over a decade now, and I maintain a number of popular libraries, like Selmer, with millions of users.

Re: Why Clojure?

#244
post #224

Earlier quoted context omitted.

It's just a native function named eval(), so I wouldn't expect to find projects built up around it.

That's not enough, there ought to be IDE/editor integration and so on. Here's one such project: https://github.com/swank-js/swank-js

Quokka.js would probably be the nearest JS equivalent.

Re: Why Clojure?

#245

I love writing Clojure. Whenever I say that publicly, there are inevitably some voices challenging my stance with skepticism, criticism, and attempts to discredit whatever I say provides practical value for me. Then I have to explain to them, "no, it's not the only language I know," "yes, I've used dozens of other languages before," "yes, including languages with robust static type systems as well." And you know what…

Through the last decade, I have found that programmers' judgment of technologies, tools, and languages are incredibly noisy. It is hard to make correct decisions based on opinions alone, and design by committee is a real thing. Common Lisp was the most mind-blowing language I ever touched, and it seems the creator of Clojure really filled the gap between the brilliant simplicity of Lisp as a language and the access t…

If you already like Common Lisp, what Clojure brings are:

1) runs on the JVM, access to any Java or Python library within Clojure without wrappers

2) an immutable-by-default language with a standard library that takes advantage of it

3) the best out-of-the-box concurrency story of any language I know of

4) a very well-developed ecosystem for developer tooling and general project stuff

Common Lisp is very fun, but the stress level is definitely higher with it due to the mutability and the generally less well-designed APIs. Only lists are actually functional, concurrency is YOLO-tier, etc.

Re: Why Clojure?

#246

Earlier quoted context omitted.

> There is no way to know what's being passed around without reading the source of the whole chain. But that's not what a Clojure dev would do. 1) We use Malli [0] (or similar) to check specs and coerce types if needed at every point. Checks can be left on in production (I do), or disable–up to you. 2) If the coercion is difficult, use something like Meander. [1] 3) If even that isn't straightforward and you need act…

That's a lot of different tools for something that could simply be a statically defined type with compile-time checking.

No it can't, but hey, there's a talk about that!

The Value of Values: https://www.youtube.com/watch?v=-I-VpPMzG7c

Using types to model data is a terrible idea.

Re: Why Clojure?

#247
post #71

It’s great, and I learned a ton from Rich Hickey, despite not fully grokking Clojure or FP in general. I briefly worked at a small Clojure shop with an extremely talented crew. People were excited about FP and writing real business logic with it. My stack was different there. The problem started when the honeymoon phase ended, and the codebase grew as the business gained traction. Dynamic typing became a burden, and…

I’ve been having a lot of fun messing with clojure, but the dynamic typing really grates on me. At your clojure job, we’re y’all using spec? I haven’t looked into it yet, and I’m wondering how much it mitigates the annoyances of dynamic types

The tooling around static types is worlds better than any tooling around spec - it's not like working with a static typing system, unfortunately.

Re: Why Clojure?

#248
post #162

Earlier quoted context omitted.

How does the REPL approach scale in very large codebases? I.e. code that talks to multiple services, complex configurations, etc..

I use Integrant to make systems out of components that are tied together at runtime. I have the option of running real versions or mock versions in tests or the REPL, with config drawn from the environment or config files or parameters. I can boot or reboot any combination of components at will. It’s fairly easy to divide and conquer this way.

I like integrant, but I feel like a lot of the examples I see use it for each web endpoint, which seems like a massive amount of overkill to me. I tend to use it just for the router, but it sometimes feels like I'm not using the library to its full potential with that.

Re: Why Clojure?

#249

Earlier quoted context omitted.

I think the Java 8+ functional APIs/streaming/etc. kind of stole Scala's thunder. Java has all of the necessary tools to replicate the functional style of Scala now, and it's a lot easier to hire for, so :/

Ah, got it. So it’s not to much that Scala went away, as that Java became Scala?

In my opinion, the people who went to use Scala were in two categories: people who wanted functional programming on the JVM and people who just wanted a better Java. As Java progressed and Kotlin launched the people that wanted a better Java either stuck with Java or moved to Kotlin.

Personally, I think Scala is a fantastic language, but it's had breaking changes, a functional only ecosystem, Java -> Scala interoperability is HARD, and the language is complex. Now there is Scala 3 and there are more breaking changes and the tooling landscape hasn't caught up.

Re: Why Clojure?

#250
post #226
post #177

Earlier quoted context omitted.

Reducing cognitive load is the key. Several approaches I usually take are: 1. Make strict rules for code convention, especially naming things, and stick to that. 2. Use intermediate variables (let binding) often 3. Turn meaningful code block to a function often 4. Write Clojure specs and turn them to docstrings In addition to that, a real REPL programming really helps to do small tests and understand the code quickly…

Do you have any resources showing what this type of coding works in the real world? I keep running into this same types issue when I use languages without types specified everywhere, where the cognitive load gets too much for non-trivial projects. I would be pretty unhappy writing python without type hints and tools that check these for correctness built into my workflow for example.

This was from my experience that I thought may work for others too. Types may help in some sense, but is not enough and sometimes even add extra load especially on heterogenous data structures. Before using any tools beside basic IDE features, I think there are fundamental things you can do to reduce cognitive load, such as focusing more on code design, convention, structures, naming, testing, documentation, which can be applied whatever language you use.
Post reply on HN