Accessors.jl icon indicating copy to clipboard operation
Accessors.jl copied to clipboard

Cannot parse optic `_ && true`

Open jariji opened this issue 1 year ago • 5 comments

julia> @o (_ && true)
ERROR: LoadError: ArgumentError: Cannot parse optic _ && true. Lens expressions must start with _, got $(Expr(:escape, :(_ && true))) instead.

What's happening here?

jariji avatar Jul 27 '24 06:07 jariji

Note that it works with &:


julia> using Accessors

julia> @o _ & true
(::Base.Fix2{typeof(&), Bool}) (generic function with 1 method)

On the other hand && is not a function, but has special short-circuit semantics.

julia> dump(:(_ && true))
Expr
  head: Symbol &&
  args: Array{Any}((2,))
    1: Symbol _
    2: Bool true

julia> dump(:(_ & true))
Expr
  head: Symbol call
  args: Array{Any}((3,))
    1: Symbol &
    2: Symbol _
    3: Bool true

I think we could in improve the error message, but I don't think we should produce an optic from this.

jw3126 avatar Jul 27 '24 07:07 jw3126

Btw, this kind of stuff works with AccessorsExtra – not with constants like true but with actual functions on each side:

julia> using AccessorsExtra

julia> @o _.a && _.b
(@o _.a) ⩓ (@o _.b)

aplavin avatar Jul 29 '24 12:07 aplavin

That means that AccessorsExtra is pirating Accessors functions, right? I don't think that's absolutely wrong, but IMO it would deserve a warning in the README.

cstjean avatar Mar 31 '25 02:03 cstjean

Currently: yes, it pirates some internal function that does actual @o parsing. But piracy isn't required to achieve the same end result: AccessorsExtra can in principle define and export its own @o and other macros.

Now, AccessorExtra also runs Accessors tests to ensure than extended parsing doesn't break anything that worked before. This would be more difficult to test if it defined a separate set of macros. Ideally, this piracy should be avoided, and it's possible – just difficult to setup everything around properly.

aplavin avatar Mar 31 '25 02:03 aplavin

Right, I get why you do it, and I might do the same in that context. Just that "Why does set(obj, @o ...) work when I import QuaternionDance, but not without?" can be a terribly painful problem to bisect and understand (answer: because QuaternionDance uses AccessorsExtra, which is pirating Accessors).

Personally I would be happy to use AccessorsExtra in a end-user-package even with the (understandable) piracy. But in an open-source library, it has the above downside, which one should be aware of.

cstjean avatar Mar 31 '25 02:03 cstjean