Live data from Hacker News

Six Years of Professional Clojure

engineering.nanit.com

111–120 of 254 posts

Re: Six Years of Professional Clojure

#111

Earlier quoted context omitted.

I agree. This doesn't seem much different to saying they're all objects. You still need to know what to expect inside the dictionary.

The difference being that objects have a class where you can look to see what fields it specifies.

Sure, depending on the language. What I mean is having dictionaries doesn't mean you don't have to learn schemas.

Re: Six Years of Professional Clojure

#112
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.

> Certainly, it's faster to go learn a language than to learn a new domain.

It's not only the language but the framework. For example I know javascript well enough but I now am quite a noob with Ember in my new role. I would say the framework is just as important as the language, at least when doing web development.

Re: Six Years of Professional Clojure

#113
post #10
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…

Single engineers will pick clojure at companies , build a project in it, later that engineer will move on, now nobody can maintain this code so it’s rewritten in some normal language. I’ve seen that happen a few times. That code is hard to read and understand. This is why clojure will remain niche.

> Single engineers will pick clojure at companies , build a project in it, later that engineer will move on, now nobody can maintain this code so it’s rewritten in some normal language

"Normal language"?

You mean, whatever language is most popular at the company. What's "normal" at one would be completely alien at another. Even things like Java. If you don't have anything in the Java ecosystem, the oddball Java app will be alien and will likely get rewritten into something else.

The reason Clojure remains niche is that some people somehow think it's not a "normal" language, for whatever reason.

Re: Six Years of Professional Clojure

#114
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…

I feel like there's a missing axis in the static/dynamic debate: the language's information model.

In an OOP language, types are hugely important, because the types let you know the object's ad-hoc API. OOP types are incredibly complicated.

In lisps, and Clojure in particular, your information model is scalars, lists, and maps. These are fully generic structures whose API is the standard Clojure lib. This means that its both far easier to keep the flow of data through your program in your head.

This gives you a 2x2 matrix to sort languages into, static vs dynamic, and OOP vs value based.

* OOP x static works thanks to awesome IDE tooling enabled by static typing

* value x static works due to powerful type systems

* value x dynamic works due to powerful generic APIs

* OOP x dynamic is a dumpster fire of trying to figure out what object you're dealing with at any given time (looking right at you Python and Ruby)

Re: Six Years of Professional Clojure

#115
post #19

> ... and the question regarding choosing Clojure as our main programming language rose over and over again If I find myself having to repeat myself justifying a certain decision time and time again, it's an indicator that the decision needs to be revised to be something which is a more intuitive fit for the organization.

I donno why you're being downvoted, it's a questionable decision and probably the company would have been better off with Python/PHP/Node. Hiring and onboarding are extremely important for a startup. You know what else? Finding answers to common questions on Google/Stackoverflow; I am now working with Ember and can tell you guys you take a 50% productivity hit by using a tool that's obscure on Google. Sure once you become super familiar with a tool that matters less, but that takes time. Much more time. React/Angular may be an inferior tool to Ember but the fact that you can get answers to almost any question is priceless. The community size is super important. The frameworks are super important (is there a Closure equivalent to Rails/Django/Laravel in community size, in battle testedness? I really doubt it).

That being said, I salute these brave companies for sticking to these obscure languages. Do we want to live in a world where there's only 3 languages to do everything? Even 10 sounds boring. Hell, even a fantastic tool like Ruby is considered Niche in certain parts of the world. I don't want a world without Ruby so I don't want a world without Closure.

Re: Six Years of Professional Clojure

#116
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…

In 2021, I find it hard to justify using a dynamically typed language for any project that exceeds a few hundreds of lines. It's not a trade off, it's a net loss. The current crop of statically typed languages (from the oldest ones, e.g. C#, to the more recent ones, e.g. Kotlin and Rust) is basically doing everything that dynamically typed languages used to have a monopoly on, but on top of that, they offer performan…

[deleted]

Re: Six Years of Professional Clojure

#117

Earlier quoted context omitted.

I think you're referring to this part of the `getConfigurationDirectories` action, which has type `IO (NonEmpty FilePath)`: case nonEmpty configDirsList of Just nonEmptyConfigDirsList -> pure nonEmptyConfigDirsList Nothing -> throwIO $ userError "CONFIG_DIRS cannot be empty" The "meaningful difference" you're looking for is the type of `getConfigurationDirectories`. The previous version had type `IO [FilePath] `, whi…

My point is that if you are not chaining `Maybe` then the utility of employing the construct is unobserved. The entire purpose of using `Maybe` is to relieve the client from the need to make checks at every call for a value that may (or may not) exist. If you intend to immediately "break out" of the monad and (even more specifically) throw an error, you might as well just use an `if`. I'm sure `main` could be written…

The purpose of Maybe is to explicitly represent the possible non-existence of a value which in Haskell is the only option since there's no null value which inhabits every type. The existence of the monad instance is convenient but it's not fundamental. The type of getConfigurationDirectories could be changed to MaybeT IO (NonEmpty FilePath) to avoid the match but I don't think it would make such a small example clearer.

Re: Six Years of Professional Clojure

#118
post #19

> ... and the question regarding choosing Clojure as our main programming language rose over and over again If I find myself having to repeat myself justifying a certain decision time and time again, it's an indicator that the decision needs to be revised to be something which is a more intuitive fit for the organization.

That's not a good indication that the decision was or was not correct. Only that it currently runs against whatever the established practice is. Sometimes "the way things have always been done" is just wrong.

This is unlikely to be the case in the choice of programming languages. Some may be a bad fit, some may have ecosystems that are unpleasant to use, but it's generally not the biggest problem an organization will have.

Re: Six Years of Professional Clojure

#119
post #39

I started working professionally with Clojure earlier this year and this article rings true. I think the article leaves out a fourth downside to running on the JVM: cryptic stack traces. Clojure will often throw Java errors when you do something wrong in Clojure. It's a bit of a pain to reason about what part of your Clojure code this Java error relates to, especially when just starting out.

How did you make the switch? Were you already working for the same company? Did you already know Clojure, from open source, or side projects?

Re: Six Years of Professional Clojure

#120

Earlier quoted context omitted.

It's your opinion though, there's nothing scientific about what you're saying. Take mocking for example, in Ruby/Rails it's a breeze. In Java you need to invent a dependency injection framework (Spring) to do it.

I think you are mistaken. Mocking and DI frameworks are two unrelated concepts. There is nothing in Java that forces you to use a DI framework, e.g., Spring if you want to use mocks during testing.

Let's say I have a class called User and in it a method that says the current time. So User#say_current_time which simply accesses the Date class (it takes no arguments).

Can you show me how you would mock the current time of that method in Java?

It's one line of Ruby/Javascript code to do that.

Post reply on HN