Fork me on GitHub

(defn foo [{b :bar}]
  {:baz b})
=> #'user/foo
(foo {:bar 1})
=> {:baz 1}
(foo [{:bar 1}])
=> {:baz nil}
(foo '({:bar 1})) ;; WAT
=> {:baz 1}
(foo '({:bar 1} {:bar 2}))
=> {:baz nil}


I figure someone's run across that before^. Anyone know if there's a ticket for it?


I kind of recall this being a consequence of the recent keyword args/map args changes


yeah I'm finding the same


just looking to see if it's intended before I say more


If you pass in a ISeq of 1 element, it falls through to that bottom if and the (first ~gmapseq) is used.


I can't decide if this case was intended or not. It doesn't appear to be documented in the commit or in any link the commit adds.

Alex Miller (Clojure team)01:07:59

Like many other things, the trailing arg is added “as if by conj”, which includes many things people are not very aware of

👍 1

I’m curious what other things you've noticed people are unaware of, @U064X3EF3? As someone who teaches Clojure, this is an asymmetry I’ll have to be sure to explain. Are there others you'd suggest adding to a curriculum?


Also understanding the motivation would be helpful. I've been recommending use of plain old maps over keyword arguments for sometime. While keyword arguments might make an API feel more fluent, it makes modification more painful by taking away associative ops, and typically requires some validation of arguments that the compiler would catch with a regular hash map literal. Maybe this simplifies areas of clojure.core or codebases other people have worked on, and I've yet to realise the benefits? I'll take a look at the JIRA ticket again.


For anyone interested in better understanding like me… this is in the original announcement post: > To date, Clojure’s support for keyword arguments forces programmers to choose between creating APIs that better support people (accepting keyword args) or APIs that better support programs (by taking a map of those args).


I think this is the motivation: > If a programmer wishes to write a function that takes key/value pairs, or a map, or key/value pairs followed by a map then they must write code to perform checks in the function on its varargs and perhaps wrap that into a custom macro. Hmm.


Maybe I'm only seeing the problems and the people who are experiencing the value aren't popping up in Slack.


I'll think some more about how I can use this feature to improve my code.


Heya, not sure if this is the right channel: I was trying out in a project and encountered a problem I couldn't overcome myself. I was able to produce a minimal repro which has further details: - hope it makes sense 🙏


basically this comes down to using user.clj being terrible


because there is a user.clj it is loaded right away before anything else the clojure runtime does


and it requires the foo namespace, so that is also loaded right away before anything else


so the FooMap stuff is loaded


Right but the guide goes out of its way to have a section about just this issue


then eval is called on the code to aot compile while force reloading from user


yeah, but the guide doesn't reckon with potemkin


I think I also tried with bare deftype and that worked fine, as well


potemkin's deftype stuff tries to be clever then the built in deftype


Must be due to the codewalking during macro expansion in potemkin or so


and that cleverness results in the type not being properly aot compiled if it was already loaded


because as the docstring there says "won't evaluate if an equivalent ... already exists" you can't force it to aot by reloading


Cool, at least it's documented and in fact kind of a feature 😄


I guess I'll look into getting rid of user.clj then 🙂


if your user.clj is in a directory like dev/ you can just leave it out of the paths when aot compiling (depending on your aliases)