Live data from Hacker News

Clojure 1.13 adds support for checked keys

clojure.org

41–50 of 50 posts

Re: Clojure 1.13 adds support for checked keys

#41
post #36

Slowly but surely dynamic programming proponents discover the value of statically verifiable correctness. Who'd have thought?

Snarkiness aside, this is hardly a static type check. This appears to be a runtime argument check, somewhat akin to the following python:

  def foo(*, a, b): return a+b
which errors out at runtime if `a` or `b` are omitted, despite being keyword arguments which are usually optional.

Re: Clojure 1.13 adds support for checked keys

#42
post #2

This is a case I never really thought about - if the key is missing today you'll get nil as the value and since Clojure is a nil punning language it usually does sensible behaviour in your program I know this sounds unreliable but in practise I like a language that defaults to pragmatic code paths so I don't have to stay up at night imagining a million code paths This adds a throwing codepath which is quite drastic s…

> if the key is missing today you'll get nil as the value

You can add a third parameter to override the nil if detecting the missing key matters.

(You almost surely know this, but not all HN commenters will.)

  user> (:bar {:foo 1})
  nil
  user> (:bar {:foo 1} :missing)
  :missing

Re: Clojure 1.13 adds support for checked keys

#44
post #2

This is a case I never really thought about - if the key is missing today you'll get nil as the value and since Clojure is a nil punning language it usually does sensible behaviour in your program I know this sounds unreliable but in practise I like a language that defaults to pragmatic code paths so I don't have to stay up at night imagining a million code paths This adds a throwing codepath which is quite drastic s…

The problem in my experience is that while nil is a perfectly reasonable default 9/10 times that 1/10 happens often enough and causes major problems that it is worth taking the extra few seconds to write it explicitly in the code to acknowledge that case and that you have checked that it is fine in the 9/10 cases or handle it in the 1/10 case. I have seen multiple major production outages in Golang code because peopl…

I suspect there should be some data model guideline that says if keys can be missing then values can’t be nil, or if values can be nil then keys must be present. In the famous saying there are two hard things: naming, cache invalidation, off by one errors, I think one more to add is handling missing data.

Re: Clojure 1.13 adds support for checked keys

#45
post #2

This is a case I never really thought about - if the key is missing today you'll get nil as the value and since Clojure is a nil punning language it usually does sensible behaviour in your program I know this sounds unreliable but in practise I like a language that defaults to pragmatic code paths so I don't have to stay up at night imagining a million code paths This adds a throwing codepath which is quite drastic s…

Yeah I'm with you, this feels like a case for assertions & not a new core feature. Perhaps I'm missing something because it was promoted by Michael Fogus and has been ratified by those who would know (Alex I'm assuming). To me it doesn't pass the test of necessity as something needed at the core but at least it feels somewhat ideomatic.

Re: Clojure 1.13 adds support for checked keys

#46
One thing to note that's maybe less obvious is that you can destructure some keys with the check and others without. This makes the function interface a bit self-documenting. At a glance you see that the username is required and other parts are maybe not.

    (defn my-function
      [{:keys! [username]
        :keys  [firstname
               lastname]}]
      (do-stuff username
                firstname
                lastname))
A minor downside is that now it seems `nil` is even more overloaded b/c you can explicitly pass in a nil and give it a special meaning. This generally cascades in to messyness (better to have a special key like `:missing-username`).

Feels like throwing an error on nil would have been better/simpler? But I'm sure there's an angle I've not considered

Re: Clojure 1.13 adds support for checked keys

#47

I love the idea of clojure and perfect immutability, but holy crap I cannot grok the syntax. My C-trained brain explodes.

Lisp is tricky. Pretty much every programmer for whom it's not their very first PL hates it initially, but then there's a time, a threshold after which no other language feels more readable than Lisp. Using structural editing idioms and the REPL, usually makes the process less vexing.

I think for some people it's an aesthetic knee-jerk reaction and the fact that it's "unusual" for a programming language. It's not like their brains "can't grok" -- it's just syntax after all. People don't tend to have that reaction to xml for some reason. It's data, so it gets a pass. But then this is code-as-data and they have to break that barrier conceptually and then get past the aesthetic knee-jerk reaction.

Re: Clojure 1.13 adds support for checked keys

#48
post #2

This is a case I never really thought about - if the key is missing today you'll get nil as the value and since Clojure is a nil punning language it usually does sensible behaviour in your program I know this sounds unreliable but in practise I like a language that defaults to pragmatic code paths so I don't have to stay up at night imagining a million code paths This adds a throwing codepath which is quite drastic s…

Yeah I'm with you, this feels like a case for assertions & not a new core feature. Perhaps I'm missing something because it was promoted by Michael Fogus and has been ratified by those who would know (Alex I'm assuming). To me it doesn't pass the test of necessity as something needed at the core but at least it feels somewhat ideomatic.

For me it solves a real issue, a lot of the code that I work on looks like this:

  (defn foo [{:keys [a b c] :or {a 1}]
    {:pre [(some? b) (some? c]}
     .....

having `:keys!` will automatically remove the need for `:pre`

Re: Clojure 1.13 adds support for checked keys

#49
post #3

Is it only me or this sounds a bit counter to clojure philosophy?

I agree it feels a bit counter to the philosophy of Clojure. It's adding new syntax to the language for map destructuring only (that will need to be implemented in cljs and other runtimes for consistency) and it's a purely runtime check as we don't know the map's keys at compile time. I don't see what new kind of safety it adds that's not achievable with existing solutions such as :pre or doing an assert inline.

I feel there are better solutions to this problem that already exist, such as using spec/malli and validating the value properly rather than just checking for presence.

Re: Clojure 1.13 adds support for checked keys

#50
post #49
post #3

Is it only me or this sounds a bit counter to clojure philosophy?

I agree it feels a bit counter to the philosophy of Clojure. It's adding new syntax to the language for map destructuring only (that will need to be implemented in cljs and other runtimes for consistency) and it's a purely runtime check as we don't know the map's keys at compile time. I don't see what new kind of safety it adds that's not achievable with existing solutions such as :pre or doing an assert inline. I fe…

One philosophy of Clojure is to facilitate building practical and robust systems. In practice, people do runtime checking of maps using punning, some kind of `nil` check, or a more ponderous `(get m k sentinel)` checking pattern. The new feature obviates the latter as destructuring syntax in the vast majority of cases where the absence of the key throws. It's opt-in, so if Malli/Spec work then you don't need to use this. I will say that we have some other things brewing that compose well with `:keys!` and friends and the 1.13 release is going to DRY a lot of existing and future Clojure code.
Post reply on HN