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
>

Reply via email to