@JeffBezanson and I were discussing adding a second default constructor with the semantics
immutable foo
bar::Int
baz::Int
# this is the usual default constructor
foo(bar,baz) = new(bar,baz)
# I am proposing this in addition
foo(x::foo;bar=nothing,baz=nothing) =
foo(bar === nothing ? x.bar : bar, baz === nothing ? x.baz : baz)
end
This would cover the case where you want to obtain a new value with one field changed e.g. in the example above
julia> foo(1,2)
foo(1,2)
julia> foo(ans,baz=3)
foo(1,3)
This is especially useful when the immutable has a lot of field. One example that comes to mind and where I already define a constructor like the above is URIParser.jl
I like this. If we're going to do something like this, could we also consider having both mutable and immutables types allow default values, which would allow the use of keyword arguments for construction from scratch (rather than based on a small variant of an existing immutable)? When writing my Vega wrapper I wound up writing up some hacky code to allow type fields to have default values and would love to have something more official.
Even better:
foo(x::foo; bar=x.bar, baz=x.baz) = new(bar, baz)
I really like that last version. The business with nothing
as a default feels icky. Any particular reason this only applies to immutables? I guess it's more useful with immutables since you can just copy and mutate a mutable object.
Relatedly it might make sense to have nice to have syntax sugar for modifying the field of an immutable when placed in an array.
It would also be nice to not have to write down the type. In haskell it would be x=foo(1,2); y=x{baz=3}
In elm (haskell-like pure language): y={x | baz <- 3}
(see elm records). Is it too confusing to have x.baz = 3
translate to x = foo(x, baz=3)
for immutables?
Yes, we dislike that idea since it means x.baz = 3
may or may not be a mutating operation depending on the type of x
. That code will silently do subtly different things for different types of x
.
Relatedly it might make sense to have nice to have syntax sugar for modifying the field of an immutable when placed in an array.
@Keno, is there any work done in this direction?
I actually wrote some code to do this, basically offering one more dimension for setindex, for arrays of immutables (well in my case fixed size arrays)...
This is especially nice for editing color channels of images, when the color is an immutable.
I think we need to start thinking about syntax for modifying immutables in place in arrays (and potentially in other mutables) now that that tuples can be used as fixed size arrays. Right now using them that way is quite painful.
Bump
It seems the above commit (92339436a97753b950e63f8a095148b3ea8a755e) is not in the current master
. Will it eventually get there, or did this get reverted?
See #6122
I think we still want this – at least I periodically do and then wonder why we don't have it yet.
I don't believe this would be breaking, would it?
Wouldn't it break Adjoint
?
Most helpful comment
I think we still want this – at least I periodically do and then wonder why we don't have it yet.