Live data from Hacker News

Six Years of Professional Clojure

engineering.nanit.com

51–60 of 254 posts

Re: Six Years of Professional Clojure

#51

> An incoming HTTP request? it is a plain Clojure dictionary. I learned to code in Python. Loved it. Dynamically typed dicts up the wazoo! Then I learned why I prefer actual types. Because then when I read code, I don't have to read the code that populates the dicts to understand what fields exist.

This is one of those self-inflicted Clojure problems. In Common Lisp you might use an alist or a plist for small things, but you'd definitely reach for CLOS classes for things that had relationships to other things and things that had greater complexity.

IIRC, the preference for complecting things via maps, and then beating back the hordes of problems with that via clojure.spec.alpha (alpha2?) is a Hickey preference. I don't recall exactly why.

Re: Six Years of Professional Clojure

#52
post #41

Earlier quoted context omitted.

I think there's two different issues: 1. picking a language/tool that a company doesn't have personnel with experience using it 2. picking a language/tool that is esoteric, which generally implies #1 as well. #1 on its own isn't great, but generally when sticking in the java/python/ruby/javascript/php/etc...mainstream languages, there's a lot more documentation, and there's a higher chance that _someone_ in the compa…

A higher chance, yes, but it doesn't matter much; what is tricky with most applications is the domain. Certainly, it's faster to go learn a language than to learn a new domain. To that end, you can get the whole team trained faster in a language than you can hire someone with experience and train them to the domain.

You're kind of reinforcing the point though -- now you've got a whole team distracted by picking up a new language....why? how is it a good use of anyone's time? And it'll be a perennial training issue in the case of an esoteric language, because those team members will eventually turn over as well, meaning that you don't get to avoid either hiring or training a new person on it.

If it's just one component, implemented by a single dev, it really can make more sense to understand what it does and rewrite it in a language that's common in the company.

Re: Six Years of Professional Clojure

#53
post #46

Earlier quoted context omitted.

Any statically-typed language with generics can express that by parameterising the request type with the body type. A bodiless request is then just Request[Nothing] (or Request[Unit] if your type system doesn't have a bottom type). Accessing the headers just requires an interface which all static languages should be able to express.

How about values restricted to identifiers currently in the database table? There's always something the type system can't do.

F# has a feature called type providers that make this sort of bookkeeping between the database and the code less tedious, but even if you mess it up, static typing still gives you more safety than dynamic. If your code blew up because it should have accepted an identifier it didn’t, you know that the code has not been written to handle that case and can fix it. Alternatively, you can just choose to ignore this, and do what a dynamic language does. There is nothing stopping you from being dynamic in a static language, passing everything around as a map, etc.

Re: Six Years of Professional Clojure

#54
post #31
post #15

Earlier quoted context omitted.

To be fair, an incoming request is, almost by definition, dynamic. It makes sense to have that as a map, since the main sensible thing to do on receipt is validation/inspection. Granted, you may have a framework do a fair bit of that. Depends how much you want between receipt of the request and code you directly control.

Usually the approach in a statically-typed language is to transform your dynamic request into something that you know through parsing instead of validation. Here's a great article about this: https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-va... .

This is the second time I've seen the link above. And while I agree with the premise, the author clearly does not understand how to properly use the `Maybe` monad (a term that does not make an appearance!).

There is little use in wrapping a call in `Maybe` to then immediately unwrap the result on the next line. Doing so isn't really using the construct... One would expect the lines following the creation of `Maybe` to bind calls through the monad.

In the end I see almost no meaningful difference between their "Paying it forward" example and simply utilizing an `if` to check the result and throw. In essence the author is using a parse and validate approach!

Re: Six Years of Professional Clojure

#55
post #52

Earlier quoted context omitted.

A higher chance, yes, but it doesn't matter much; what is tricky with most applications is the domain. Certainly, it's faster to go learn a language than to learn a new domain. To that end, you can get the whole team trained faster in a language than you can hire someone with experience and train them to the domain.

You're kind of reinforcing the point though -- now you've got a whole team distracted by picking up a new language....why? how is it a good use of anyone's time? And it'll be a perennial training issue in the case of an esoteric language, because those team members will eventually turn over as well, meaning that you don't get to avoid either hiring or training a new person on it. If it's just one component, implement…

I'm not advocating NOT rewriting it. I'm just saying, back to the great grandparent's point, that the issue is a dev went rogue, NOT the language the rogue dev chose. The difficulty is the same regardless of the language the rogue dev chose; it's not that they picked Clojure, it's that they picked a language there was no organizational adoption of.

Re: Six Years of Professional Clojure

#56
Another good report about what Clojure does well is this article by metabase: https://medium.com/@metabase/why-we-picked-clojure-448bf759d...

I have had the pleasure of contributing to their code since we used their product at a previous company I worked at, and I must say I am sold on Clojure. Definitely a great language to have in your toolbox.

Re: Six Years of Professional Clojure

#57
post #6

One thing I don't like about all articles on clojure is that basically all of them say: ah, it's just like lisp with lists `(an (example of) (a list))` with vectors `[1 2 3]` thrown in. So easy! But then you get to Clojure proper, and you run into additional syntax that either convention or functions/macros that look like additional syntax. Ok, granted, -> and ->> are easy to reason about (though they look like addit…

{:pre [(de/entity? entity)]} is "syntactic sugar" for (hash-map (keyword "pre") (vector (de/entity? entity))) while (.getAttribute mount "data") is calling the method `.getAttribute` on the `mount` object – since it's a Lisp, it's in prefix notation. It also highlights how methods are not special and just functions that receive the object as first argument. Finally, @*post is the same as (deref *post) and the `*` mea…

> Most of what you believe to be syntax are convenience "reader macros"

And yet, you need to know what all those ASCII symbols mean, where they are used, and they are indistinguishable from syntax.

Moreover, even Clojure documentation calls them syntax. A sibling comment provided a wonderful link: https://clojure.org/guides/weird_characters

Re: Six Years of Professional Clojure

#58
post #3

I found one of the perceived weaknesses of Clojure (in this article), it being dynamically typed, is a tradeoff rather than a pure negative. But it applies that tradeoff differently than dynamic languages I know otherwise and that difference is qualitative: It enables a truly interactive way of development that keeps your mind in the code, while it is running. This is why people get addicted to Lisp, Smalltalk and si…

Except, of course, that specs are only tested correct, not proven correct like types would be. Types (in a reasonable static type system, not, say, C) are never wrong. In addition, specs do not compose, do they ? If you call a function g in a function f, there is no automatic check that their specs align.

Re: Six Years of Professional Clojure

#59
post #3

I found one of the perceived weaknesses of Clojure (in this article), it being dynamically typed, is a tradeoff rather than a pure negative. But it applies that tradeoff differently than dynamic languages I know otherwise and that difference is qualitative: It enables a truly interactive way of development that keeps your mind in the code, while it is running. This is why people get addicted to Lisp, Smalltalk and si…

> ... such as arbitrary predicate validation, freely composable schemas, automated instrumentation and property testing ...

Why static typing makes those things impossible?

Re: Six Years of Professional Clojure

#60
I tried to use Clojure but what put me of was that simple mistakes like missing argument or wrongly closed bracket didn't alert me until I tried running the program and then gave me just some java stack spat out by jvm running Clojure compiler on my program.

It didn't feel like a first class experience.

Post reply on HN