Repository navigation
default field values #10146
Description
Activity
- addedspeculativeWhether the change will be implemented is speculativeWhether the change will be implemented is speculative
on Feb 10, 2015 +1000
I've often written macros to automatically give me both a type definition and an all-keywords constructor function with sane default values.
This certainly is a useful feature to have.
same thought recently #6122 (comment)
If breaking the current semantics of how
=inside a type definition works would somehow be a major problem, then maybe we could use different syntax for this - I think=>inside a type definition would currently be invalid?StefanKarpinski commented
on Feb 10, 2015 SponsorMemberAuthorMore actionsNo, I think we should just bite the bullet and change it. Very little code would get broken. This is used once or twice in base and probably very few other places.
I agree we should just change it.
Doesn't this complicate the semantics of inner constructors even more? The distinction between inner and outer constructors is a tricky concept to explain to people unfamiliar with the language.
How does this interact with evaluating arbitrary expressions for type fields?
type Foo foo::Int=rand(1:10) baz::String=randstring() endI feel allowing side-effects here is a bit weird.
I assume this would only work for default constructors.
Reacted by Yan Ren and Azamat BerdyshevSo the following would retain the behavior we have now (expressions would be ignored)?
type Foo foo::Int=rand(1:10) baz::String=randstring() Foo() = new() Foo(f) = new(f) endGiven that the inner/outer constructor business is one of the most complicated parts of the (otherwise reasonably simple) language, I wonder if this is worth the increased complexity?
Wouldn't documenting the pattern of creating a no-arg inner constructor suffice?
Wouldn't documenting the pattern of creating a no-arg inner constructor suffice?
I'd argue that the no-arg constructor (which shouldn't be the inner constructor, but only one outer constructor) is an anti-pattern.
StefanKarpinski commented
on Feb 10, 2015 SponsorMemberAuthorMore actionsWhy not use defaults in
newfor all arguments that aren't provided? This would work very well withnewwith keywords since you can provide whatever subset of values you want to and get defaults for the rest. Keep in mind that if you're going to add a language feature, you might as well make it powerful.I'm assuming that the use of keywords in
newwill slow down construction of types even when you don't use keyword arguments, which seems like a large risk.55 remaining items
it feels like GaussianVariogram{Float64}() should work, which is not something Parameters.jl can do IIRC.
It does:
julia> using Parameters julia> @with_kw struct Blag{T} x::T=one(T) y::T=one(T) end Blag julia> Blag{Float64}() Blag{Float64} x: Float64 1.0 y: Float64 1.0
Wow cool, never knew that. Though it does have the lack of inferrability:
julia> @with_kw struct Blag{T} x::T=one(T) y::T=one(T) end Blag julia> @code_warntype Blag{Float64}() Variables: #self#::Type{Blag{Float64}} Body: begin return ((Core.getfield)($(QuoteNode(Core.Box(#call#1))), :contents)::Any)((Base.sitofp)(Float64, 1)::Float64, (Base.sitofp)(Float64, 1)::Float64, #self#::Type{Blag{Float64}})::Any end::Any
It doesn't for me:
using Parameters @with_kw immutable Foo{T<:Real} a::T = one(T) end Foo()
EDIT:
Got it, you have to be explicit about the type in order for it to work.@StefanKarpinski: I assumed that this issue would be solved by automatically generating a keyword constructor rather than modifying
new. But your approach maybe easier.For below type this would mean
struct A a b=5 end
What would
new's signatures be? You suggest, I think:new(a, b) = ... new(a; b=5) = ... new(;a=undef, b=5) = ...
with the automatically defined inner constructors:
A(a,b) = new(a,b) A(;kws...) = new(;kws...)
- modified the milestones: This milestone has been deleted, This milestone has been deleted
on Jul 7, 2017 StefanKarpinski commented
on Jul 7, 2017 SponsorMemberAuthorMore actionsI'm changing the milestone to 1.x since this seems like a feature that we can add post 1.0 as long as we've made the appropriate things errors in advance.
Reacted by Christopher Rackauckasas long as we've made the appropriate things errors in advance.
Is it clear if the appropriate things error in the current state of master, or if something needs to be prepared for this to be simple to do post v1.0?
StefanKarpinski commented
on Mar 5, 2018 SponsorMemberAuthorMore actionsIt's a syntax error now, so we're all good:
julia> struct Foo a::Int = 0 end ERROR: syntax: "a::Int = 0" inside type definition is reserved
Reacted by Azamat Berdyshev, Mohammed Sabbah, Tamas Gal and YuriCould default field values be part of Julia v1.3? I wonder if we can also have the
@unpackfunctionality from Parameters.jl as well.StefanKarpinski commented
on Aug 15, 2019 SponsorMemberAuthorMore actionsSince the feature freeze is today, no. But if someone implements it in the next four months, it could be in the 1.4 release.
Reacted by Azamat Berdyshev, Júlio Hoffimann, Dan Beall, Timothy Gaede, Scott Staniewicz, Rana Ian, Spiros Baxevanakis, Pablo Winant, Lasse Peters and Raul DurandFor v1.6?
Reacted by Jonas Schulze, Matěj Račinský, Alice Cecile, Sai Vemprala, Tomasz Kalinowski, Fabien Baron and Jonas EschleReacted by Raul DurandI believe this issue shouldn't have been closed? Since a non-macro solution is possible in the future.
This comes up periodically since people seem to expect it to work:
type Foo bar::Int=0 baz::String="" endCurrently, this doesn't do what people expect it to do at all, but I suspect we should change that. This would be a useful feature and the fact that so many people expect it seems like a pretty strong argument in its favor.