Something along these lines is being implemented/discussed in
https://github.com/JuliaLang/julia/pull/6122
https://github.com/JuliaLang/julia/issues/5333

Meanwhile, below function should work.  Note that I did not write
copyandmodify! as it makes a new instance and does not modify it in
place.  Which isn't really possible for an immutable.

function copyandmodify{T}(pp::T, di)
    di = !isa(di, Associative) ? Dict(di) : di
    ns = names(pp)
    args = Array(Any, length(ns))
    for (i,n) in enumerate(ns)
        args[i] = get(di, n, getfield(pp, n))
    end
    T(args...)
end
copyandmodify{T}(pp::T; kws...) = copyandmodify(pp, kws)

# examples
immutable A{I}
    a::I
    b::I
    c::Float64
end
a1 = A(5, 6, 5.)
a2 = copyandmodify(a1, b=7)
a3 = copyandmodify(a1, ((:a,7),)) # not using keywords is probably faster

immutable B{I}
    a::I
    b::I
    c::Vector{I}
end
b1 = B(5, 6, [5,5])
b2 = copyandmodify(deepcopy(b1), b=7) # use deepcopy to not share array c


On Sun, 2015-02-08 at 21:35, vava...@uwaterloo.ca wrote:
> I would like to request the following language feature: a function or macro 
> to modify a field of an immutable inside a container.  Consider:
>
> immutable T
>   fielda::Int
>   fieldb::Int
>   fieldc::Int
> end
>
> function modify_fieldc!(x::Array{T,1}, sub::Int, newc::Int)
>    x[sub] = T(x[sub].fielda, x[sub].fieldb, newc)
> end
>
> This function modifies one field of an immutable object that sits inside a 
> container.  The above construct, namely:
>    x[sub] = T(x[sub].field1, x[sub].field2, ... , newval, ... x[sub].fieldn)
> occurs rather frequently in my code.  It is not very readable and is also 
> fragile in the case that I modify my code and put more fields in T later. 
> It would be much nicer if there were a universal function like this:
>    modifyField!(x, sub, fieldc, newc)
>
> Note that I declared T to be 'immutable' rather than 'type' for performance 
> reasons-- I prefer the data in the array x to be packed in memory rather 
> than accessed with pointers.  If T were a 'type' then obviously the problem 
> would go away.
>
> Maybe it is already possible to write a function or macro for this purpose 
> in the existing language?
>
> Thanks,
> Steve Vavasis

Reply via email to