-
Notifications
You must be signed in to change notification settings - Fork 372
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
into a function instead of a special form
#1346
Conversation
I noticed some awkward But why was |
+1 to this. Using a plain function will likely be a performance killer. |
9145ebd
to
4e68963
Compare
What exactly do you mean? Can you give an example? Good catch regarding
I don't know. Possibly by mistake, possibly because
I would generally advocate changing special forms to macros or functions when this is possible, so let me know if you find any others. Do we really need the micro-optimization of |
Look what Python can do. >>> spam = [0]*5
>>> spam
[0, 0, 0, 0, 0]
>>> spam[::2] = [1]*3
>>> spam
[1, 0, 1, 0, 1]
>>> spam[1::2] = [-1, -2]
>>> spam
[1, -1, 1, -2, 1] Actually, I think this will work fine even in the function version with explicit
The advantage is more obvious when setting multiple things at once. (setv (get foo :a) 1
(get foo :b) 2
(get foo :c) 3) See that repetition of (assoc foo
:a 1
:b 2
:c 3) Much more concise, but it compiles exactly the same way.
Pretty much all of our operators are both special forms and functions in shadow. Why not eliminate all the operator special forms and just use the functions? Performance. Shadowed forms give us the best of both worlds, and it's the same with
I would be in favor of redefining compiler special forms as macros in terms of more basic special forms, as is the case with |
Sounds good to me.
While I agree with the performance consideration in the case of math operators, I think that being able to produce real
I see what you mean, but then how do we decide which core functions are a variation on an operator and which aren't? Is |
4e68963
to
f68f875
Compare
I also want this to be possible, at least for the most current version of Python.
Everything with a direct analogue in I don't think those three examples qualify by that standard, but making, say, |
Yeah, if we want to go down that route, it seems that we should be generating the code rather than maintaining two versions (shadow and macro) of every function. One can imagine a macro or special form |
A basic |
So, an (defmacro! assoc [o!coll &rest kvs]
"doc here"
(assert (even? (len kvs))) ; or equivalant macro-error
`(setv
~@(chain.from-iterable
(genexpr [`(get ~g!coll ~k) v]
[[k v]
(partition kvs)])))) |
Can we leave the macro version and shadowing and so on for a later PR for |
Or let it be just a macro for now. One or the other. |
Making it a macro for now is the more conservative change. I'd approve that alone, but I'd approve both that and shadowing it with a function too. |
Okay, I'll check on my first, macro version and PR that instead. |
Fixes #1068.
I was putting the finishing touches on a PR making
assoc
into a macro and only then realized it could be a plain old function. Derp!