So I heard you like macros…
I got tired of writing lots of functions which would all end in putting nicely named variables into maps.
Typical example, assuming that a and b are descriptive names for something:
(let [a 1
b 2]
{:a a :b b}) ;; this last part is boring
So I got tired of rewriting, and wrote this little guy
As someone who has never done any JS at all (and hopefully never will), I find myself often needing to create these types of maps, for example when doing structured logging, or when providing error responses from an API. Many times I’ve thought of writing that same macro that Magnus wrote, but somehow I never got around to it
I wrote one too, vals->map. There is also an inverse function that is handy, with-map-vals. I use them all the time to save some typing. It is especially handy to quickly package up problem values for use in (throw (ex-info "some error msg" (vals->map x y z)).
Personally I think what I’d like is something more like:
(let [a 10]
{a, :b 20})
Where if you use a binding as a single, not a pair, it expands to a keyword of the binding as key and the value of the binding as the value.
But keep in mind, whole these tricks are a bit faster to type, they are riskier to accidentally refactor the bonding name and break the use of the map everywhere else, since the key changed.
Edit:
Or even something like:
(let [a 10]
{a a, :b 20})
Where a binding used as key just gets replaced by a keyword of the same name.
That’s {10 20} – and how would tell the difference between the intent of {a, b c} and {a b, c} since we’re already allowed to put expressions in hash maps and keys can be “anything”…?
Good point. This is where it could be nice for the comma to not just be whitespace, since it could disambiguate.
But to be fair, I didn’t think of it as a core feature, I was thinking within the context of some macro. So you could come up with whatever rule. Here I was assuming this macro doesn’t allow the value of the binding to be a key, instead this macro is used to make the var name itself a keyword key.
That’s what I was thinking reading this—how would the compiler ever comprehend which symbols are meant to be kv tuples, and not an unbalanced/shifted map—but now I’m curious to see someone write macros to respect commas and do exactly this! Some preposterous language rewriting like Rewriting the Technical Interview
What you are saying can’t be done using macros… it has to be done through the reader.
It’s just syntatic sugar. I personally like maps the way they are. It gets complicated really quickly if js notation gets imported wholesale. what about a spread operator? what about map defaults?
having said that… a spread operator might be useful for the var-to-map macro.