Skip to content
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

support a.$b in quoted expressions #4004

Closed
stevengj opened this issue Aug 10, 2013 · 11 comments
Closed

support a.$b in quoted expressions #4004

stevengj opened this issue Aug 10, 2013 · 11 comments

Comments

@stevengj
Copy link
Member

If b is a Symbol and a is a composite type Foo, it would be nice if quote a.$b end turned into access for the field $b of a. However, evaling this gives an error type Foo has no field $ because it parses as :(*(a.$,b)).

a.($(Expr(:quote, b))) works, but is rather counter-intuitive.

@kmsquire
Copy link
Member

If you know that a.(b) already allows you access to the fields of a programmatically, a.(:($b)) isn't too much of a leap. But it probably should be documented.

julia> type Foo
          c::Int
          d::Int
       end

julia> a = Foo(1,2)
Foo(1,2)

julia> b = :c
:c

julia> a.(b)
1

julia> a.(:($b))
1

julia> :(a.(:($b)))
:(a.(b))

julia> eval(:(a.(:($b))))
1

@stevengj
Copy link
Member Author

Unfortunately, it's not as simple as that, because the $b is executed at the wrong time in your expression, hence the need for Expr(:quote, ...). For example, try:

type Foo
    c::Int
    d::Int
end
let b = :c
    @eval foo(a::Foo) = a.(:($b))
end
foo(Foo(1,2))

This throws an exception b not defined.

It seems to be unfortunately rather tricky to insert a Symbol into an expression as a quoted symbol, rather than as a variable to be evaluated.

@kmsquire
Copy link
Member

Yup, that's true. I have a vague recollection of a similar discussion, but I can't seem to find it. @toivoh, do you have any thoughts?

@toivoh
Copy link
Contributor

toivoh commented Aug 11, 2013

@kmsquire, I think that the previous discussion that you are referring to is #1540 (comment).

Two thoughts:

  • If @JeffBezanson deems it reasonable to let the parser handle a.$b, I don't see any reason not to do it.
  • I think that a number of things would be simplified if we could the remove the matlabism that a.(name) corresponds to getfield(a, name). (In this case, it would allow to use a.($b) for a.$b. See also the discussion in Allow adding methods via Foo.bar(x) #1540.) Since I'm quite sure that this is not an idiom that we want to encourage (there must be substantial overhead for it, right?), I think that it would be better to force people to use getfield/setfield explicitly instead. I would also guess that the a.(name) syntax is not much used currently.

@StefanKarpinski
Copy link
Sponsor Member

I'm not a fan of the Matlabism – it's unintuitive to me that wrapping something in parens should change its meaning.

@kmsquire
Copy link
Member

@toivoh, yes, that was the conversation, thanks! And thanks for your input--seems reasonable to me. I believe it's undocumented behavior (I can't find it), and it probably isn't used much.

@JeffBezanson
Copy link
Sponsor Member

Ok I'm going to remove the a.(b) syntax.

@johnmyleswhite
Copy link
Member

Ok. That change is going to need a lot of packages to change in response. I think JSON uses this. Distributions definitely does.

@JeffBezanson
Copy link
Sponsor Member

Yes, I just started looking through packages and as a result I'm having second thoughts. It is used more than we thought.

@StefanKarpinski
Copy link
Sponsor Member

Can we deprecate it instead?

@JeffBezanson
Copy link
Sponsor Member

Maybe, but it's tricky. And the abstract syntax built by Expr(symbol("."), :a, :b) cannot really be deprecated, since we don't know from that which meaning is intended.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants