-
Notifications
You must be signed in to change notification settings - Fork 31
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
Make use of ConstructionBase #105
base: master
Are you sure you want to change the base?
Conversation
@mauro3 Just as a fair warning, |
@mauro3 what do you think about this PR? |
@@ -4,6 +4,7 @@ author = ["Mauro Werder <[email protected]>"] | |||
version = "0.12.0" | |||
|
|||
[deps] | |||
ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" | |||
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" | |||
|
|||
[compat] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about adding ConstructionBase = "0.1, 1.0"
? (I think CompatHelper can figure out 1.0 but I'm not sure if it adds 0.1)
Aright, sorry for the long radio-silence. I answer, just as I'm about to go on holidays again... I'm a bit hesitant to take on the dependency of ConstructionBase.jl. Is my understanding right, that if someone wants good performance, then there is nothing in the way of them just using
|
I guess that is correct. Are you open to have some tests that test that setproperties actually works on types created by your macro? |
Yes, I have no reservations to have ConstructionBase as a test-dependency. |
I think of this PR more as for package composition rather than performance. For example, I think we need this PR to make this scenario work:
|
True, but note that
My hunch is that this is fairly rare (but I might be wrong) and has an easy fix, and thus imposing the extra dependency is not worth it. |
I should've set up the scenario more accurately. What I meant to say was that function_b(x) = reconstruct(x, alpha = x.alpha + 1) package |
Ok, I don't quite understand ConstructionBase. How do properties even feature in ConstructionBase? |
Here is a concrete toy example: module A
using ConstructionBase
struct TypeA{x,y,z} end
TypeA(x, y, z) = TypeA{x,y,z}()
Base.getproperty(::TypeA{x,y,z}, name::Symbol) where {x,y,z} =
if name === :x
x
elseif name === :y
y
elseif name === :z
z
else
throw(ArgumentError("Unknown property $name"))
end
Base.propertynames(::TypeA) = (:x, :y, :z)
function ConstructionBase.setproperties(::TypeA{x0,y0,z0}, nt::NamedTuple) where {x0,y0,z0}
props = merge((x = x0, y = y0, z = z0), nt)
if keys(props) !== (:x, :y, :z)
throw(ArgumentError("Unknown properties in: $nt"))
end
return TypeA(props.x, props.y, props.z)
end
end # module A
# I'm pretending that package `B` uses `Parameters.reconstruct`:
module B
# using Parameters
using ConstructionBase
const reconstruct = setproperties
function_b(obj) = reconstruct(obj, x = obj.x + 1)
end # module B
# Package `C` uses packages `A` and `B` without knowing they are using
# `ConstructionBase`/`Parameters`.
module C
using ..A: TypeA
using ..B: function_b
demo() = @assert function_b(TypeA(0, 2, 3)) === TypeA(1, 2, 3)
end # module C
C.demo() |
Thanks for the detailed example! (Maybe something like this could go into your docs, as they are a bit on the theoretical side so far.) But in the example, package B could change from it using I guess, I kinda see OT: what is |
I see, I think that makes sense. Indeed, package
Thanks for the suggestion. That's a good idea.
Yeah, I think throwing an error makes sense. |
Another possibility would be to remove Or, we go down the route of defining custom methods for |
Yeah, you can overload
But Parameters.jl still needs to depend on ConstructionBase.jl if you want to overload |
Yes, I wasn't clear: the last option would require the dependency on ConstructionBase. Which is ok, but it's also ok to strive for few dependencies. |
Various packages implement variants of
Parameters.reconstruct
. ConstructionBase.jl is an effort to unify these. Benefits are:ConstructionBase.setproperties
is very fastgetproperty
to interact well with bothSetfield.jl
andParameters.jl
, she only needs to overload one function.See also JuliaObjects/ConstructionBase.jl#6
ConstructionBase is not yet released, so CI will fail and this PR should not yet be merged.