Live data from Hacker News

Why Clojure?

gaiwan.co

271–280 of 302 posts

Re: Why Clojure?

#271

Earlier quoted context omitted.

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 poin…

That has nothing to do with types. You are now talking about when a compiler is run. Clojure gives you the option to run the compiler at runtime, so that's what people normally do. However, you can also run the compiler at compile time. Right? For people who want type checking, they can opt to write Clojure in this defprotocol everywhere style, and turn on AOT. Then they basically get the same thing as what Java give…

The whole premise of static typing is that type errors can be caught at compile time. Java type system allows for kinds of errors to be caught at compile time that will not be caught by using protocols in Clojure. Yes, you can run the compiler at run time, but that's entirely besides the point here.

These libraries aren't using protocols for type safety though, they're using them as a performance optimization. That's certainly a perfectly fine reason to use protocols, and I agree that it's a completely legitimate use case. It's the whole right tool for the job thing. If you're writing something where performance is the top concern, then that's what protocols are for.

I very much agree with you that that there are people who focus on low level code, and those who focus on application level code. The style of coding will be different depending on the type of problem you're solving. You're right that I failed to qualify my original statement regarding protocols being an anti-pattern.

You're absolutely correct that we should take a pragmatic approach towards using language features. Hence why the context of whether protocols are the right tool to each for lies in the type of code you're writing. And of course, some people find it easier to have more structure to help with their reasoning. Although, I'd argue tools like Malli work better there.

To sum up, I'm not arguing against protocols being useful or that there's no place for them. We started this discussion talking about whether protocols provide equivalent guarantees to Java's type system. I disagree regarding that. However, I also don't think that this is a real problem. Otherwise, use of something like core.typed would've become prevalent by now.

Re: Why Clojure?

#272

Earlier quoted context omitted.

deftype IS a Java class, it's not compiled into something else. What is a Clojure function? A Clojure function is a Java class. Clojure is a compiled language, so it does check types, just like Java check types. So if you use defprotocol and deftype for every domain objects in your code, your code won't compile if there's a type error. Try it. BTW, that's the way many Clojure libraries are implemented. These librarie…

Of course Clojure has to ultimately be compiled into a native format for the host platform, bytecode in the case of the JVM implementation, but that doesn't require type checking in the same way Java does. Clojure functions are compiled into implementations of clojure.lang.IFn - you can see from https://clojure.github.io/clojure/javadoc/clojure/lang/IFn.h... that this interface simply has a number of overloads of an…

But if you add type hint in the signature, it does check the type. Basically, if you specify the type, it will check type. Just like any language that is not automatically inferring types, e.g. Java. So it is the same as Java.

You guys make it out like Clojure is doing something extra to hide Java types, but it doesn’t. What Clojure does is really minimal on top of Java. It barely hides anything.

If you give it type, it will check type. If you don’t give a type, it falls back to a default type, Object, which IS a TYPE. The fact that Clojure compiler cannot deal with GraalVM SVM Pointer type tells you that it’s checking type, because Pointer is not an Object! I found this out the hard way: https://yyhh.org/blog/2021/02/writing-c-code-in-javaclojure-...

“One limitation that one needs to be aware of when writing native image related Clojure code, is that most things in the GraalVM SDK inherit from org.graalvm.word.WordBase, not from java.lang.Object, which breaks the hidden assumption of a lot of Clojure constructs.”

Re: Why Clojure?

#273

Earlier quoted context omitted.

That has nothing to do with types. You are now talking about when a compiler is run. Clojure gives you the option to run the compiler at runtime, so that's what people normally do. However, you can also run the compiler at compile time. Right? For people who want type checking, they can opt to write Clojure in this defprotocol everywhere style, and turn on AOT. Then they basically get the same thing as what Java give…

The whole premise of static typing is that type errors can be caught at compile time. Java type system allows for kinds of errors to be caught at compile time that will not be caught by using protocols in Clojure. Yes, you can run the compiler at run time, but that's entirely besides the point here. These libraries aren't using protocols for type safety though, they're using them as a performance optimization. That's…

I wrote my library this way for both performance AND type checking reasons. You cannot tell me the reasons why I wrote my code my way. That is just absurd.

In any case, it is possible to write Clojure in a way that is type checked at compile time. And it is an acceptable way to write Clojure. I just want to clear the air.

Re: Why Clojure?

#274

Earlier quoted context omitted.

Coming from a love of strong typing (scala) clojure dynamic typing was a real adjustment. One thing I grew to really love is how small my changes were when I’m just adjusting a decidedly brownfield chain of functions that operate on data. With go in place at work, I added a couple fields to a core data type in my business and I ended up with thousands of lines of changes to pipe them everywhere. Doing the correspondi…

The Haskell type `[x] -> [x]` (the equivalent of `List[A] -> List[A]`) tells you an incredible amount about the function. It tells you that the function must calculate a subset of a permutation of the input list. The function cannot be anything else (or else it will crash or hang). In a language with stricter requirements you can omit even the crash/hang caveat. Don't underestimate the amount of information even simp…

Rich’s point is the type signature actually tells you little about what the function does. You need the name, docs, tribal knowledge, your own understanding of the math… etc. to actually understand what it does. Type signature alone is a very incomplete understanding. But come on, do you think I learned how to write Haskell and don’t understand what a type signature’s value is? Give me a little credit.

Here is Rich’s work on the subject: https://youtu.be/YR5WdGrpoug?si=7C8EjQ7TVo2Ua8w7

I’m biased, but I think he’s got a point.

Re: Why Clojure?

#275
post #251

Earlier quoted context omitted.

The Haskell type `[x] -> [x]` (the equivalent of `List[A] -> List[A]`) tells you an incredible amount about the function. It tells you that the function must calculate a subset of a permutation of the input list. The function cannot be anything else (or else it will crash or hang). In a language with stricter requirements you can omit even the crash/hang caveat. Don't underestimate the amount of information even simp…

Yeah, Hickey was just wrong about this. For me, watching his talks goes like this: Hickey: I value X, Y, Z Me: Yeah man! Hickey: We get great consequences A, B, C Me: Ah yeah, I love programming like that. That's why I love Haskell! Hickey: That's why Haskell is bad. Me: err, what!? > It tells you that the function must calculate a subset of a permutation of the input list As tromp pointed out, "permutation" is techn…

I think what he’s saying is the type signature alone isn’t enough, but in some languages like Haskell, people do imagine if the program type checks, it’s good. But that isn’t necessarily true, you need a ton of other context to actually have a proper functioning program, and the reverse function is an example of this.

I didn’t say Haskell was bad though. I love Haskell in a different way from clojure.

Re: Why Clojure?

#276
post #64

As a data point: I've been running my solo-founder SaaS business for 10 years now using Clojure. It changed my life. It would not have been possible without Clojure and ClojureScript, building and maintaining an app of this complexity would have exceeded my limits. The article is excellent and I agree with everything in it. The stability of the language is unbelievably useful. I look around and it seems it isn't valu…

You will find that "whatever language you are most familiar with" is the only one that you will perceive makes it possible for you to build whatever you are working on.

That is a shallow take and I disagree — at least in my case, I make a conscious effort to avoid being a Blub programmer and regularly try different languages and look at different ecosystems. The choice of Clojure and ClojureScript for this application was not accidental, and it wasn't the thing I was most familiar with at the time.

There are good reasons why I said it was only possible with Clojure and ClojureScript. Conciseness, expressiveness, long-term stability, the ability to share business logic code between the client and server, same language used for data serialization (e.g. no JSON), good async code support (core.async), transducers for code reuse and performance, and more.

Re: Why Clojure?

#277
post #164

Earlier quoted context omitted.

The dynamic typing and "everything is a map" can be a PITA. At the moment I'm working on a codebase that has I/O to JSON APIs, Avro schemas and postgres databases. That means that a field called "date" can be either a string, integer days since the epoch or a Java Date, and (because this codebase isn't great) there's no way of knowing without tracing the call stack. With the right discipline (specs, obsessively norma…

>That means that a field called "date" can be either a string, integer days since the epoch or a Java Date, and (because this codebase isn't great) there's no way of knowing without tracing the call stack. But this is because JSON is an untyped data structure. (And btw, a flawed one...) You would have this problem in any programming language.

In other languages you would know which date you were dealing with based on the type regardless of the function you were in. In Clojure, you have to either name the variable date-string or find which API it came from, which means tracing the call stack

Re: Why Clojure?

#279

Earlier quoted context omitted.

The whole premise of static typing is that type errors can be caught at compile time. Java type system allows for kinds of errors to be caught at compile time that will not be caught by using protocols in Clojure. Yes, you can run the compiler at run time, but that's entirely besides the point here. These libraries aren't using protocols for type safety though, they're using them as a performance optimization. That's…

I wrote my library this way for both performance AND type checking reasons. You cannot tell me the reasons why I wrote my code my way. That is just absurd. In any case, it is possible to write Clojure in a way that is type checked at compile time. And it is an acceptable way to write Clojure. I just want to clear the air.

I'm not telling you the reasons why you write code the way you do. I'm just telling you about my experience of using the language, which clearly differs from yours. I never found protocols to be useful as a type checking tool, and I find they're not necessary for optimizations most of the time. I spent a lot of time profiling and optimizing Selmer, this is the only protocol that turned out to be necessary for performance https://github.com/yogthos/Selmer/blob/master/src/selmer/nod...

If you find protocols are a helpful tool to structure code that's great, keep using them. Nobody is telling you not to. However, try to accept that different people use the language in different ways. Try to follow your own advice and not to be dogmatic about it.

Re: Why Clojure?

#280

Earlier quoted context omitted.

Did you or any of your fellow devs have ADD or ADHD? How did they adapt to dynamic types? I have ADD and I once heard that devs with ADD/ADHD have an incredibly small heap size for context but compensate for their weakness by being great at solving logical problems in that small heap. Types have been essential for me when functioning in code bases. I really struggle with pure JS and untyped Python. Clojure was simila…

Types and other techniques as an accessibility tool for the ADHD brain - Michael Newton talk https://www.youtube.com/watch?v=vd1-rAIYV6I

That was an interesting talk, thanks for sharing.
Post reply on HN