Depending on your performance needs, you could make a copy constructor with keyword arg overrides:
immutable Foo x y end Foo(foo::Foo; x=foo.x, y=foo.y) foo1 = Foo(1, 2) foo2 = Foo(foo1; y=5) Note: this constructor could easily be written as a macro: @copyconstruct immutable Foo x y end On Sunday, August 2, 2015, Cedric St-Jean <cedric.stj...@gmail.com> wrote: > In my (generally functional) code, I frequently find myself asking for "An > object like X but with Y different", eg. "that image but with the > background set to transparent" or "that dataframe but with all inactive > customers' profit set to 0". The usual idiom is: > > img2 = copy(img) > img2[img2.==black] = transparent > ... some_function(img2) > > I've written a macro that lets me write instead > > some_function(@assign(img[img.==black], transparent)) > > and it expands into the code above. This is very convenient, but it hits a > snag with immutable types, as the assignment fails. eg. @assign(obj.field, > 5) doesn't work. Thanks to Julia introspection, I can programmatically get > the fields, change the one that is @assigned to, and pass them to the > constructor, but that only works with the default constructor. This will > fail > > immutable Foo > a > b > Foo(x) = new(x,x) > end > > f = Foo(1) > @assign(f.b, 3) > > (arguably this @assign in particular violates Foo's invariant, but that's > not the point) > > Is there any way to do this differently? In particular, can I access the > "default constructor" for a type somehow? > > Cédric >