New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rely less on undocumented features #1406
Conversation
We simply guard against nil leaking into `merge` or `select-keys`. This does not change semantics. I caught this with a linter I'm building.
Rely less on undocumented features
I suspect there's lots of other code out there that uses The current |
Hi Colin, This is my opinionated linter that points out code I would rather not find in production. Personally I wouldn't trust It's a subtle issue, the docstring claims it "conj's" on the map argument, but clearly it does not call (conj nil ...) if you pass nil as the first argument. That's too arbitrary for me. I have a whole list of pet peeves, my biases are clearing showing! This was just a pull request after all, perhaps the devs would like to explain why they accepted it? I would assume it's to beat the cleverness/brittleness out of the code. The disjunctive conditional makes it interesting that it works at all. |
I am not fond of the fact that Clojure is sloppy about its nil handling, but that's how it is. It's idiomatic in most lisps to conflate nil and empty collections, and going against that is just going to be a constant battle; I don't think it's worth cluttering the codebase for it. I'm certain this is not the only place that exhibits this aspect. |
I don't mind the correctness, and have no issues with this patch. That being said, I'm not sure that using undocumented features in general is necessarily the problem -- It may be an upstream problem instead (i.e. lack of proper This is a bit unrelated to the PR, but I think it would be very interesting to see which undocumented features are most frequently used. Perhaps it even can be used as an argument for elaborating undocumented features in |
Allowing nils as |
These corner cases are enough to make me avoid passing nil to (merge nil)
;=> nil
(merge nil nil nil)
;=> nil |
In the context of the meta-merge function here (and many other places in Clojure), there is no ill effect from propagating nil through to I think it would be great if Clojure became more discerning around its use of nil, but that is something that would have to happen from the top-down. Trying to effect that kind of change in codebases like this one doesn't make sense. |
Yes, bullying Clojure core into making changes just because of downstream usage is silly. I think the sloppiness/convenience has its place in Clojure core, especially during dev. I'm building tools to avoid "buying in" to the sloppiness in important code. It's also troubling to think of someone modifying meta-merge and misinterpreting the invariants at play (there are many implicit ones). So it's also defensive (proposed) change. |
One succinct option in cases where it matters that the result of a merge not be nil is to add an empty map to the end of the arg list:
|
Just to clarify, this PR wasn't trying to remove non-nil results from a merge, but rather the fact that the nil values passed to |
We simply guard against nil leaking into
merge
orselect-keys
. This does not change semantics.I caught this with a linter I'm building.