-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
?= "get or set" operator #2108
Comments
This is kind of awesome. But I worry that we'll end up with Perl syntax soon since what I would really want is |
That's too much and better done via #1529 by having a |
Interesting idea, could be nice. More or less acting as dedicated syntax @johnmyleswhite: By analogy, would |
Having |
Stefan, you just beat me to the point. But I don't think we totally agree. As Stefan says, I would want Now it is tempting to make In this case, I agree that DefaultDict's are what we really need. And I am starting to think that Pandas series type is pretty awesome. I still don't know whether it is related to Avi's idea, equivalent to Avi's idea or whether it subsumes it. |
I've been planning to write a little I guess I'd vote for methods rather than special syntax here, for readability, although the conciseness is appealing... |
Why use |
Methods like |
Really? To me this is much more readable:
I suppose my preference really stems from the fact that all of the operators I already know work exactly the same way for this new type if I assume that |
@HarlanH: the original proposal of |
Makes sense! Thanks, Stefan. On Tue, Jan 22, 2013 at 5:14 PM, Stefan Karpinski
|
Ruby's handy and popular ||= idiom is a bit like this, but there are subtleties: http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html |
Yep, that's the inspiration. That particular syntax (which Ruby in turn got from Perl) doesn't quite work for Julia, where the |
[Parts of] this proposal also seems extremely similar to Python's How would you feel about these methods (or alternatively, macros), for avoiding multiple lookups?
I believe the first two can be written purely as special cases of the third. |
After banging out some other attempts at a solution for this (all of which involved creating multiple reference types), I may have stumbled on something a bit more elegant. This idea assumes that the major motivation for all of these combined test/get/set operations is that we want to avoid re-computing a (possibly expensive) hash function for the key type. To do this, we create a special key type which is "pre-hashed", as follows: immutable PreHashed{K}
key::K
hashval::Int
end
prehash(key) = PreHashed{typeof(key)}(key, hash(key))
Base.hash(ph::PreHashed) = ph.hashval
Base.convert{K}(::Type{K}, ph::PreHashed{K}) = ph.key The idea now is that, using this type, we can perform test/get/set without re-computing the key's hash, like so: # define the pre-hashed key...
key = prehash("MySomewhatLongishStringKey")
# and now...
haskey(d, key) ? d[key] : (d[key] = generate_default_value()) In the above code, Of course for this solution to work as-is, you would need to define the key type of your dictionary to be This certainly doesn't get rid of all the overhead in repeated calls to (As an aside, keeping the hash value for each key with a dictionary can be a nice optimization in general. When the dictionary is resized, the hash function does not need to be re-evaluated for the existing keys. Python uses this trick. However, there may need to be an explicit |
This of course is assuming that hashing is what you are using to implement these data structures. |
Yes, I'd seen #12157, and liked the proposal! |
To be clear there is currently no way to do it yet right? If I want to achieve this I'd have to first check whether the entry exists, and if not create it before returning it? |
|
Thanks |
Related to #1764, I'd like to propose a
?=
operator to do get-or-set operations. This is primarily useful for associative collections like Dicts. Example:which translates to
except that it avoids hashing the key three separate times.
This is more properly called the
[]?=
operator, since the indexing operation is part of the entire syntax. However, the?=
operator could be used for conditionally assigning to undefined variables:in which the
x ? = 0
is likeisdefined(:x) ? x : (x=0)
but works in local or global scopes. This is of much more dubious utility thand[k] ?= f()
but seems like a natural analogue.The text was updated successfully, but these errors were encountered: