-
-
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
allow overloading of a.b field access syntax #1974
Comments
The ability to use dots as syntactic sugar for mutator/accessor methods would be nice for lots of things. I've always appreciated this in languages that provide it, so that you can turn structure fields into more complicated abstractions without breaking the API. |
+1 |
I have an absolutely awesome way to implement this. |
Interested in talking about it? I know that Tom Short is really interested in having this for DataFrames, although I've come to be increasingly skeptical about the wisdom of using this feature. |
This would make calling Python code (via PyCall) significantly nicer, since currently I'm forced to do |
@JeffBezanson, any chance of having this for 0.3? Would be great for inter-language interop, both for PyCall and for JavaCall (cc @aviks). |
@JeffBezanson if not, is there any chance you could give some direction on how you want this implemented? ( |
In my experience, there is no faster nor surer way to get Jeff to implement something than to implement a version of it that he doesn't like ;-) |
The basic idea is that you implement
so that you can overload it per-field. That allows access to "real" fields to keep working transparently. With suitable fallbacks The biggest issue is that modules have special behavior with respect to |
@JeffBezanson Do you also refer to I would find that to be very useful in combination with #5395. Then one be able to intercept a call to a undefined function or method |
Let me, a simple Julia newbie, present a little concern: I think the possibility to overload the dot operator might imply that field access "purity" is somehow lost. The user would generally lose the knowledge if doing a.b is just an access to a reference/value or if there can be a huge function machinery being called behind. I'm not sure how that could be bad though, it is just a feeling... On the other hand, I see that indeed this is a big wish for syntax sugar for many cases (PyCall, Dataframes...), which is perfectly understandable. |
I support doing this. But the purity does have something to say for it, even if one can use The purity argument is closely related to the main practical concern I have, which is how one handles name conflicts when the fields of the type interfere with names you might hope to use. In DataFrames, I think we'd resolve this by banning the use of |
I guess (Meanwhile, I stumbled upon this about C++.) |
It's not a major problem. We can provide something like |
Ok, maybe I'm sold. But then defining a shortcut to |
I'm not worried about the purity aspect - until we have this, the only code |
It had already been pointed out in #4935, but let's pull it to here: dot overloading can overlap a little with classical Julian multiple dispatch if not properly used, since we can start doing getfield(x::MyType, ::Field{:size}) = ......... instead of size(x::MyType) = .......... While the dot would be great to access items in collections (Dataframes, Dicts, PyObjects), it can somehow change the way object properties (not fields) are accessed. |
I think one thing to consider is that if you can overload accessing field, you should also be able to overload setting a field. Else this will be inconsistent and frustrating. Are you OK to go that far? |
@nalimilan, one absolutely needs a |
Agree with @stevengj: DataFrames will definitely be implementing |
I support this. Experience with other languages (e.g. C# and Python) does show that the dot syntax does have a lot of practical value. The way that it is implemented through specialized methods largely addresses the concern of performance regression. It is, however, important to ensure that the inlineability of a method won't be seriously affected by this change. For example, something like If we decide to make this happen, it is useful to also provide macros to make the definition of property easier, which might look like: # let A be a type, and foo a property name
@property (a::A).foo = begin
# compute the return the property value
end
# for simpler cases, this can be simplified to
@property (a::A).foo2 = (2 * a.foo)
# set property
@setproperty (a::A).foo v::V begin
# codes for setting value v to a property a.foo
end Behind the scene, all these can be translated to the method definitions. |
New functions `Base.getproperty` and `Base.setproperty!` can be overloaded to change the behavior of `x.p` and `x.p = v`, respectively. This forces inference constant propagation through get/setproperty, since it is very likely this method will yield better information after specializing on the field name (even if `convert` is too big to make us want to inline the generic version and trigger the heuristic normally). closes #16195 (and thus also closes #16226) fix #1974
Pls change milestone to 1.0! :) |
@Liso77 What do you mean? This is already implemented on git master, as noted in the status when closing. |
@nalimilan sorry if I understand it wrong! But I thought that as 1.x are labeled postponed things which are going to be solved after 1.0. And this is solved now... |
Open source is a decentralized community. The milestone sets what should be complete by 1.0, but contributors and work on whatever they want. In this case someone wanted this in 1.0, so they contributed the code to get it there. |
@Liso77 As I understand it, this will not be in v1.0. The Julia v1.0 feature freeze date was set to Dec 15th, but this issue was closed on Dec 17th so I think we can expect it in a 1.x release. Core devs can correct me if my interpretation is incorrect. |
No, it is merged into master and will be in the next release. |
:) Well! I just thought that it is good to label 1.0 what is going out in 1.0. If it is not wanted then sorry for disturbing! :) |
I think the NEWS file is a better way to see what is going into 1.0. |
The milestone was added to mean "can be implemented without breaking compatibility in the 1.x release series", but then since the code was ready it's been merged anyway before the 1.0 feature freeze. I've removed the milestone for clarity, but at this point everything which is merged in master will be in 1.0. |
Thanks for the clarification! This is exciting! The NEWS file was also particularly enlightening. |
Thanks for remove! I am also very glad it will come in 1.0! :) |
I wonder if there's a way to support these new "dynamically-defined fields" in auto-complete, e.g. by allowing to overload I guess at the moment the REPL (tab-expansion), IJulia, etc. look at the type definition, not the instance? But maybe that could be changed, for interactive use. It's probably impossible to support in an IDE like Juno, though, as instances are not available during coding. |
@oschulz, you can already overload julia> struct Foo; foo; end
julia> fieldnames(Foo)
1-element Array{Symbol,1}:
:foo
julia> Base.fieldnames(::Type{Foo}) = [:bar, :baz]
julia> fieldnames(Foo)
2-element Array{Symbol,1}:
:bar
:baz And it looks like julia> x = Foo(3)
Foo(3)
julia> x.ba<tab>
bar baz |
@yurivish right - but is it "safe" to do so, currently? I'm not sure what else relies on |
If not safe, it should be possible to define a |
Yes, this is why I was bringing this up - in case something needs to be changed/added in Base, so that REPL and friends can take advantage of it later. In view of the 0.7 feature freeze ... |
This is why I'm glad we called the function |
We might need a corresponding |
I had a feeling that this may require a bit of deeper analysis and input from the experts (thanks!) - should we open a new issue for this? |
New functions `Base.getproperty` and `Base.setproperty!` can be overloaded to change the behavior of `x.p` and `x.p = v`, respectively. This forces inference constant propagation through get/setproperty, since it is very likely this method will yield better information after specializing on the field name (even if `convert` is too big to make us want to inline the generic version and trigger the heuristic normally). closes #16195 (and thus also closes #16226) fix #1974
Brought up here: #1263.
The text was updated successfully, but these errors were encountered: