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

add default keyword constructor for immutables #6122

Closed
wants to merge 1 commit into from
Closed

Conversation

nolta
Copy link
Member

@nolta nolta commented Mar 12, 2014

Implements #5333.

@JeffBezanson
Copy link
Sponsor Member

Well, that was easy. :)

@stevengj
Copy link
Member

No documentation?

@StefanKarpinski
Copy link
Sponsor Member

This functionality is really, really nice. Works for me like a charm. I'm sure it's clear that there is also a default "copy" constructor as a side-effect, which seems harmless (copying an immutable is a noop, so it's pretty pointless). Any reason this shouldn't be extended to mutable types?

@nolta
Copy link
Member Author

nolta commented Mar 12, 2014

I tried to extend this to mutable types, but it segfaults building sysimg.

(let* ((arg-names (safe-field-names field-names field-types))
(ctors (list `(function (call ,name ,@arg-names)
(block (call new ,@arg-names))))))
(if (and (or (not mutabl) (eq? mutabl 'false))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit odd: mutabl is either #f or 'false depending on if the type is defined in the repl or in a script.

Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be fixed in 86e03d8

@aviks
Copy link
Member

aviks commented Mar 12, 2014

Some packages explicitly define constructors like this. Will that fail once this lands?

@mbauman
Copy link
Sponsor Member

mbauman commented Mar 15, 2014

I really like this, and would love to have it for mutables, too. But undefined references might make the implementation for them a major pain.

@StefanKarpinski
Copy link
Sponsor Member

It's certainly not impossible to handle that – an undef field would remain undef in the new object unless assigned via keyword. It's not super easy to implement in the parser, however.

@StefanKarpinski
Copy link
Sponsor Member

Hmm. I thought we'd merged this. Any reason not to? I guess we should wait for @JeffBezanson's ok.

@StefanKarpinski
Copy link
Sponsor Member

Bump.

@carlobaldassi
Copy link
Member

Also looking forward to this. Just wondering though, will the keyword arg parsing destroy performance when using immutables?
Also, needs documentation.

@StefanKarpinski
Copy link
Sponsor Member

Are we going to do this or what? I periodically think we've already changed this and I want to use the feature, but then I remember that we haven't.

@JeffBezanson
Copy link
Sponsor Member

I'd like to, but I think if we do then we should really implement the compile-time keyword sorting optimization.

@StefanKarpinski
Copy link
Sponsor Member

Ok, good to get a definitive reason for this being on hold. Sounds like a 0.4 thing then.

@JeffBezanson
Copy link
Sponsor Member

Would also be good to try again for mutable types and see if the segfault is fixed, or can be fixed.

@JeffBezanson
Copy link
Sponsor Member

Bump. Needs a rebase. Does extending this to mutable still segfault?

@nolta
Copy link
Member Author

nolta commented Dec 9, 2014

Rebased. Mutables still segfault.

@pluskid
Copy link
Member

pluskid commented Dec 10, 2014

This feature would be really nice! And it might be even nicer if default values are supported for the fields of at least immutable types.

@mauro3
Copy link
Contributor

mauro3 commented Feb 7, 2015

Allowing default values, at least with the obvious syntax, would be a breaking change:

julia> immutable A
       a=5
       b::Int
       end

julia> names(A)
1-element Array{Symbol,1}:
 :b

julia> immutable B
       a=5
       b::Int
       B() = new(a)
       end

julia> B()
B(5)

Although, presumably this feature is not used a lot. So, I'm all for defaults as well.

Edit: this feature is discussed in #5790 & #9443

@tkelman
Copy link
Contributor

tkelman commented Feb 8, 2015

Multiple times I have thought default values would work, gotten briefly confused, then frustrated that they don't. Constructors for big types with lots of fields are pretty messy to keep track of at the moment.

@tkelman
Copy link
Contributor

tkelman commented Apr 19, 2015

We haven't seen much of @nolta lately. Someone who wants this should try adopting the PR, rebasing and submitting anew.

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
Copy link
Member Author

nolta commented Jun 29, 2015

Rebased.

@JeffBezanson JeffBezanson modified the milestones: 0.5, 0.4.0 Jul 10, 2015
@damiendr
Copy link
Contributor

I'd really like to use this feature, but it does not seem to be in the current master. I'm not quite sure what the status is after reading the above; is there a stable-ish branch in which it works? Would you recommend using it at all?

@mauro3
Copy link
Contributor

mauro3 commented Sep 28, 2015

Until this gets merged have a look at https:/mauro3/Parameters.jl. It should do all of this and more (except high performance, say you try and use it in a hot inner loop). Please file an issue with Parameters.jl if something is missing.

@damiendr
Copy link
Contributor

@mauro3 Thanks, that looks interesting. My use case is in a hot inner loop though.

@mauro3
Copy link
Contributor

mauro3 commented Sep 28, 2015

Keyword functions are currently not very performant (edit: see #9551). I suspect that this PR suffers from that as well. So you probably have to use the non-keyword constructors for a little longer. Also, depending you your use-case this may help: https:/StephenVavasis/Modifyfield.jl

@StefanKarpinski StefanKarpinski added the speculative Whether the change will be implemented is speculative label Mar 30, 2016
@JeffBezanson JeffBezanson modified the milestones: 0.6.0, 0.5.0 Mar 30, 2016
@StefanKarpinski
Copy link
Sponsor Member

@JeffBezanson's objection to this is that this generates a huge number of methods, which is a lot of overhead for a feature that is only wanted sometimes. My objection was why this only applies to immutables rather than mutables as well. A number of ad hoc implementations of this exist in the package ecosystem, however, so some standard solution seems warranted.

@StefanKarpinski
Copy link
Sponsor Member

Also, would be obviated by the feature of putting an immutable in a Ref and "mutating" it.

@tkelman
Copy link
Contributor

tkelman commented Nov 10, 2016

Perhaps we promote one of the package implementations of this to an installed-by-default stdlib? This functionality could cut down a lot of boilerplate in large types for some of the library bindings we have in Base, but most of those should be moved to stdlib modules anyway so adding other stdlib dependencies to them would be okay.

@mauro3
Copy link
Contributor

mauro3 commented Nov 10, 2016

One of them: https:/mauro3/Parameters.jl.

@JeffBezanson JeffBezanson modified the milestones: 1.0, 0.6.0 Dec 28, 2016
@JeffBezanson JeffBezanson modified the milestones: 2.0+, 1.0 Jul 1, 2017
@StefanKarpinski
Copy link
Sponsor Member

Is this really necessarily 2.0 or can this be added in a non-breaking way in a 1.x release?

@gbaraldi
Copy link
Member

gbaraldi commented Aug 7, 2023

Do we want this in base, this seems very much what https:/JuliaObjects/Accessors.jl seems to do.

@vtjnash
Copy link
Sponsor Member

vtjnash commented Jan 31, 2024

Base now has @kwdef, which I guess pretty much replaces this

@vtjnash vtjnash closed this Jan 31, 2024
@vtjnash vtjnash deleted the mn/5333 branch January 31, 2024 19:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
speculative Whether the change will be implemented is speculative
Projects
None yet
Development

Successfully merging this pull request may close these issues.