-
Notifications
You must be signed in to change notification settings - Fork 370
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
Assoc returning the dict #238
Comments
+1 |
This is a bit tricky implementation-wise, though, as |
Yes, if it was easy I probably would have attached a patch :-) |
Wouldn't it be possible to override it in the core lib? name the compilers assoc too |
@Foxboron: since we can express it in AST, we should avoid making a function for it :) |
...but can we fix it? I keep getting bit by this when context-switching from another LISP :) |
I'd prefer to see a |
+1 |
Maybe I am missing something but
http://stackoverflow.com/a/1453013/2131094 Hm, I should PR shouldn't I. |
@chr15m Wouldn't that be slower, though? You're copying the entire dictionary to update one key. Hy has the ability to implement this the correct way, similarly to |
Just tested - yes it is nearly 1000 times slower on my machine. |
So, assoc is useful in a lisp using linked lists because it usually works with alists, which, while not the most efficient structures in the world, are (assuming nobody does any nasty stuff and mutate the cons cells), mostly immutable mapping structures. Of course, sometimes people want more efficient variants... in Guile there are vlists, and there's a whole set of purely functional data structures and fectors available. Which is great. Often these reuse the name "assoc" in some way, but are purely functional! So my suggestion is, instead of abusing assoc to try to fake immutability through having nice new structures returned on totally mutable structures by copying the dicts (yikes!), Hy should add nice sugar around existing immutable datastructures for Python... maybe pyrsistent? |
FWIW, I think bolting in immutable data structures is another matter altogether. I would be very happy if assoc "just worked" and returned _something_ besides None/nil even if it mutated the dict. I know I'm using a Python data structure...
|
If I introduced an |
@chr15m I'd be in favor of such a function, but I can imagine the name |
Good point. The immediate situation is that the current tl;dr: rename existing |
How about compiling # current assoc
spam[i] = y
# proposed assoc
(spam.__setitem__(i, y) or spam)
# or even like this?
(spam.__setitem__(i, y), spam)[1] Which of the two we use depends on if we want to allow custom If we want the old behavior, for performance reasons, we can rename the current |
A possible issue with my approach: >>> spam = [1,2,3]
[1, 2, 3]
>>> def getspam():
... print("side effect!")
... return spam
...
>>> getspam().__setitem__(0,"zero") or getspam()
side effect!
side effect!
['zero', 2, 3] I'm still not familiar enough with Hy's AST manipulation approach to know if this is easily avoidable. # (assoc (getspam) 0 "zero")) ; compiles to:
(lambda x: x.__setitem__(0, "zero") or x)(getspam()) But this doesn't appear to work automatically, since then the # (def x "something important")
# (assoc (getspam) 1 x) ; compiles to:
x = "something important"
(lambda x: x.__setitem__(0, x) or x)(getspam()) # probably not what you meant. I would also like to point out that Python already has an |
On second thought this should work: x = "important"
(lambda x,i,y:x.__setitem__(i, y) or x)(getspam(), 0, x) I noticed
So there's a possible performance reason to duplicate the |
I think I have a really simple solution. Basically, this: (print (assoc d 1 2)) turns into: d[1] = 2
print(d) and this: (print (assoc (f) 1 2)) turns into: _hy_anon_var_x = f()
_hy_anon_var_x[1] = 2
print(_hy_anon_var_x) |
Would it be possible to have assoc return the modified dict instead of nil?
It would make dealing with dictionaries in Hy a bit easier, IMHO
The text was updated successfully, but these errors were encountered: