Skip to content
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

keyword argument constructor for immutables #5333

Closed
Keno opened this issue Jan 9, 2014 · 15 comments
Closed

keyword argument constructor for immutables #5333

Keno opened this issue Jan 9, 2014 · 15 comments
Labels
keyword arguments f(x; keyword=arguments) needs decision A decision on this change is needed
Milestone

Comments

@Keno
Copy link
Member

Keno commented Jan 9, 2014

@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

@johnmyleswhite
Copy link
Member

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.

@JeffBezanson
Copy link
Sponsor Member

Even better:

foo(x::foo; bar=x.bar, baz=x.baz) = new(bar, baz)

@StefanKarpinski
Copy link
Sponsor Member

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.

@Keno
Copy link
Member Author

Keno commented Aug 21, 2014

Relatedly it might make sense to have nice to have syntax sugar for modifying the field of an immutable when placed in an array.

@JeffBezanson JeffBezanson added this to the 0.4 milestone Aug 21, 2014
@rfourquet
Copy link
Member

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?

@JeffBezanson
Copy link
Sponsor Member

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.

nolta added a commit that referenced this issue Sep 21, 2014
nolta added a commit that referenced this issue Sep 21, 2014
nolta added a commit that referenced this issue Dec 9, 2014
For example, the type

    immutable X
        a::Int
        b::Int
    end

now comes with the extra constructor:

    X(x::X; a=x.a, b=x.b) = new(a,b)

Closes #5333.
@SimonDanisch
Copy link
Contributor

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.

@Keno
Copy link
Member Author

Keno commented May 3, 2015

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.

@johnmyleswhite
Copy link
Member

Bump

nolta added a commit that referenced this issue Jun 28, 2015
For example, the type

    immutable X
        a::Int
        b::Int
    end

now comes with the extra constructor:

    X(x::X; a=x.a, b=x.b) = new(a,b)

Closes #5333.
nolta added a commit that referenced this issue Jun 29, 2015
For example, the type

    immutable X
        a::Int
        b::Int
    end

now comes with the extra constructor:

    X(x::X; a=x.a, b=x.b) = new(a,b)

Closes #5333.
@damiendr
Copy link
Contributor

It seems the above commit (9233943) is not in the current master. Will it eventually get there, or did this get reverted?

@ihnorton
Copy link
Member

See #6122

@StefanKarpinski
Copy link
Sponsor Member

I think we still want this – at least I periodically do and then wonder why we don't have it yet.

@JeffBezanson JeffBezanson modified the milestones: 2.0+, 1.0 Jul 1, 2017
@JeffBezanson JeffBezanson added the keyword arguments f(x; keyword=arguments) label Jul 20, 2017
@StefanKarpinski
Copy link
Sponsor Member

I don't believe this would be breaking, would it?

@tkf
Copy link
Member

tkf commented Jan 22, 2019

Wouldn't it break Adjoint?

@vtjnash
Copy link
Sponsor Member

vtjnash commented Jan 31, 2024

Base now has @kwdef, which I guess pretty much replaces this, since we haven't had this for many releases now anyways

@vtjnash vtjnash closed this as not planned Won't fix, can't repro, duplicate, stale Jan 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
keyword arguments f(x; keyword=arguments) needs decision A decision on this change is needed
Projects
None yet
Development

No branches or pull requests

10 participants