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…
Minor point of order about the atoms: they're not defined with @ nor derefd with . If you're referring to earmuffs* that's convention not syntax (specifically for dynamically scoped variables, which could be atoms or anything else), and @ is indeed deref. (More specifically @x is a reader macro ish that expands to literally `(deref x)`.)
Six Years of Professional Clojure
91–100 of 254 posts
Re: Six Years of Professional Clojure
#92I 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…
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 performance, automatic refactorings (pretty much impossible to achieve on dynamically typed languages without human supervision), fantastic IDE's and debuggability, stellar package management (still a nightmare in dynamic land), etc...
Re: Six Years of Professional Clojure
#93Earlier quoted context omitted.
> ... such as arbitrary predicate validation, freely composable schemas, automated instrumentation and property testing ... Why static typing makes those things impossible?
They don't make these impossible, they typically just don't let you express these within the type system and they typically don't let you not specify your types. I should have made clear that I'm emphasizing the advantages of being dynamic to describe and check the shape of your data to the degree of your choosing. Static typing is very powerful and useful, but writing dynamic code interactively is not just "woopdied…
Re: Six Years of Professional Clojure
#94Earlier quoted context omitted.
Interesting. How exactly that looks? Do you have files opened in your editor, change them then go into previously opened repl, and just call the functions and the new version of those function runs?
Thanks to the dynamic nature of Clojure programs, experienced Clojure developers use the REPL-driven development workflow as demonstrated in this video [1]. [1] https://youtu.be/gIoadGfm5T8
So what you get, after running the file afterwards from clean state might be different than the result of your selective separate manual evaluations.
This looks like exactly the opposite of the F5 workflow in the browser where you can run your program from clean state with single keypress.
I haven't watched the video till the end though maybe there's a single key that restarts the repl and runs the files from clean state here too.
At first glance you could have the same workflow with JS, but there's not much need for it because JS VMs restart very quickly and also you'd need to code in JS in very particular style, avoiding passing function and class "pointers" around and avoid keeping them in variables. I guess clojure just doesn't do that very often and just refers to functions through their global identifiers, and if that's not enough, even through symbols (like passing the #'app in this video instead of just app).
Re: Six Years of Professional Clojure
#95I 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…
Re: Six Years of Professional Clojure
#96Earlier quoted context omitted.
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` t…
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…
I'm sure `main` could be written to "bind"/"map" `getConfigurationDirectories` with `nonEmpty`, `head`, and `initializeCache` in a way that puts the `throw` at the top-level (of course the above implementations may need to change as well). Unfortunately I'm not familiar enough with Haskell to illustrate it myself.
Re: Six Years of Professional Clojure
#97I 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…
Re: Six Years of Professional Clojure
#98I 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…
Re: Six Years of Professional Clojure
#99Re: Six Years of Professional Clojure
#100Earlier quoted context omitted.
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` t…
Lexi absolutely understands how to properly use the Maybe monad. What you're saying to do here is the exact opposite of what this post is advocating for. You're talking about pushing the handling of the Maybe till later and the post is all about the advantages of handling it upfront and not having to worry about it anymore. You might want to read it one more time.
Sure you can unwrap it right away, but that isn't necessary because you could also just "bind" the next function call to the monad (which is more idiomatic to the construct). You never have to worry about that value in this case because... well... that's the benefit of using `Maybe`.
I'm not super familiar with Haskell, but my sense is that the author is trying more to please the compiler (at a specific point in the program!) than simplify the logic. That is, they want a concrete value (`configDirs`) to exist in the body of `main` more than they want the cleanest representation of the problem in code.