-
Notifications
You must be signed in to change notification settings - Fork 371
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
Make assoc
a macro instead of a special form
#1378
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see you're not using defmacro!
That must be to avoid the gensym in the case of only one pair.
hy/core/macros.hy
Outdated
(macro-error (last other-kvs) "`assoc` takes an odd number of arguments")) | ||
(setv c (if other-kvs (gensym "c") coll)) | ||
`(setv | ||
~@(if other-kvs [c coll] []) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since #1349, splice works on any False value. This could be ~@(if other-kvs [c coll])
(or when
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
~@(and other-kvs [c coll])
would also work.
hy/core/macros.hy
Outdated
(list-comp [`(get ~c ~k) v] [[k v] (zip | ||
(+ (, k1) (cut other-kvs 0 None 2)) | ||
(+ (, v1) (cut other-kvs 1 None 2)))]) | ||
[]))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sum
and zip
are not indented. And is there a reason you're avoiding partition
? That would be simpler.
~@(sum (list-comp [`(get ~c ~k) v] [[k v] (partition other-kvs)])
[`(get ~c ~k1) v1])
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
~@(sum (list-comp [`(get ~c ~k) v] [[k v] (cons [k1 v1] (partition other-kvs))])
should also work. I should be testing these at the repl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, nope. A cons onto a generic iterable doesn't work like that for some reason. It would have to be (chain [[k1 v1]] (partition other-kvs))
, or spliced like
~@(sum (list-comp [`(get ~c ~k) v] [[k v] `(~[k1 v1] ~@(partition other-kvs))])
(I'd have used #*
instead of the splice, but that doesn't work in older versions of Python.)
21a3f32
to
d461932
Compare
How's that? |
Not what I meant. Sorry I got it wrong the first try, you probably didn't see the edit. How about like this. (defmacro assoc [coll k1 v1 &rest other-kvs]
(if (odd? (len other-kvs))
(macro-error (last other-kvs) "`assoc` takes an odd number of arguments"))
(setv c (if other-kvs (gensym "g-assoc") coll))
`(setv
~@(and other-kvs [c coll])
~@(sum (list-comp [`(get ~c ~k) v] [[k v] (partition other-kvs)])
[`(get ~c ~k1) v1]))) |
I see the motivation for using |
Hmm, yes. I don't like it there either. I think it's clearer to put all the assignments in the order they'd appear in the expansion. (defmacro assoc [coll k1 v1 &rest other-kvs]
(if (odd? (len other-kvs))
(macro-error (last other-kvs)
"`assoc` takes an odd number of arguments"))
(setv c (if other-kvs
(gensym "assoc-coll")
coll))
`(setv
~@(and other-kvs [c coll])
(get ~c ~k1) ~v1
~@(+ [] #* (list-comp [`(get ~c ~k) v]
[[k v] (partition other-kvs)])))) This looks more like a template for the expansion. I like it there better. We shouldn't ever be using
[Edit: the We do have the shadow |
f929ab1
to
394e619
Compare
That's true about |
hy/core/macros.hy
Outdated
(setv c (if other-kvs (gensym "c") coll)) | ||
`(setv ~@(+ (if other-kvs [c coll] []) #* (genexpr | ||
[`(get ~c ~k) v] | ||
[[k v] (partition (+ (, k1 v1) other-kvs))])))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not indented properly, which makes it hard to read. Emacs can do this for you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's indented with two spaces, same as everything else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it is not indented 2 spaces. After bracket counting, I can see that arguments to genexpr
are indented as if they were arguments to setv
. It will take 42 more spaces to get it indented two spaces past the start of their list. To avoid excessively wide lines, instead of just inserting 42 spaces at the start of those two lines, add some newlines.
One must never put list elements on a column before (or equal to) the bracket opening the list, in any Lisp. Elements must always appear on a column following the opening bracket of the list they belong to. And when I say "list", this applies to all Hy models inheriting from HyList.
e9b428e
to
ca0e5de
Compare
Okay. |
hy/core/macros.hy
Outdated
(macro-error (last other-kvs) "`assoc` takes an odd number of arguments")) | ||
(setv c (if other-kvs (gensym "c") coll)) | ||
`(setv ~@(+ (if other-kvs [c coll] []) #* | ||
(genexpr [`(get ~c ~k) v] [[k v] (partition (+ (, k1 v1) other-kvs))])))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
genexpr
is now indented at -7 from the opening bracket of its list. Line it up with the (if
, or add a newline and line up both the (if
and (genexpr
at +2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would also look better if #*
were on the same line as the thing it's unpacking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not legible, Kodi.
I cannot approve obfuscated code.
You don't seem to understand how to format Lisp, or why it is important to. Please read up on it, or let Emacs do it for you.
I amended a commit for formatting and I fixed the conflict with NEWS using the web editor, which added a merge commit. @Kodiologist is this commit structure OK? |
The new macro evaluates its lvalue only once.
e8f29ff
to
2bbf886
Compare
I don't like to keep merge commits inside a PR (as opposed to the merge commit that brings the PR into master), so I rebased it away. |
Thanks! |
See the discussion in #1346.