Fork me on GitHub
#clojure
<
2022-07-01
>
potetm00:07:42

(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}

potetm00:07:12

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

hiredman01:07:33

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

potetm01:07:11

yeah I'm finding the same

potetm01:07:26

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

potetm01:07:47

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

potetm01:07:55

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
jcf09:07:53

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?

jcf09:07:56

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.

jcf09:07:24

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). https://clojure.org/news/2021/03/18/apis-serving-people-and-programs

jcf09:07:38

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.

jcf09:07:33

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

jcf09:07:57

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

dergutemoritz15:07:28

Heya, not sure if this is the right channel: I was trying out https://clojure.org/guides/dev_startup_time in a project and encountered a problem I couldn't overcome myself. I was able to produce a minimal repro which has further details: https://github.com/bevuta/clojure-improved-dev-startup-time-repro - hope it makes sense 🙏

hiredman16:07:01

basically this comes down to using user.clj being terrible

hiredman16:07:41

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

hiredman16:07:58

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

hiredman16:07:04

so the FooMap stuff is loaded

dergutemoritz16:07:29

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

hiredman16:07:30

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

hiredman16:07:50

yeah, but the guide doesn't reckon with potemkin

dergutemoritz16:07:16

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

hiredman16:07:24

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

dergutemoritz16:07:36

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

hiredman16:07:49

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

hiredman16:07:55

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

dergutemoritz16:07:35

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

dergutemoritz16:07:10

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

hiredman16:07:06

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)