I think that default value syntax ambiguous so not allowed. You should do (;a, b) = (;a=1, b=2)
instead.
Can you show this in a function definition to get a + b
like in the example above from 3 years ago?
This syntax you are asking about always threw an error. @Lincoln_Hannah’s message above was merely a feature request that — as of now — never got implemented.
Just see
Thanks for the clarification. I was looking for a feature for adding defaults and stumbled on this old post. I thought (wrongly) it was implemented. This idea of
f((; A=1, B=2)) = A+B
X = (A=2)
f(X)
Julia> 4
is very appealing to me. Is there a different approach to accomplish something like this?
Keyword arguments may have defaults, and one can splat named tuples into keyword arguments:
julia> f(; a = 1, b = 2) = a + b
f (generic function with 1 method)
julia> g(n) = f(; n...)
g (generic function with 1 method)
julia> x = (; a = 2)
(a = 2,)
julia> g(x)
4
In case it’s not clear:
julia> (a = 2,) === (; a = 2,) === (; a = 2)
true
@nsajko Thanks for the concise overview
@nsajko How would the example look like in case of
f(c; a = 1, b = 2) = a + b + c
julia> f(c; a = 1, b = 2) = a + b + c
f (generic function with 1 method)
julia> x = (; a = 2)
(a = 2,)
julia> f(9; x...)
13
Not sure if that’s what you’re asking for.
A destructured argument can be annotated and given defaults like any other single argument:
julia> bar((;a, b) = (a=1, b=2)) = a+b
bar (generic function with 2 methods)
julia> bar()
3
which makes the unimplemented syntax redundant and deviate from expected rules. That is likely what tomaklutfu meant.
Edited for proper terminology. (;a, b)
is the argument assigned to the variables a
and b
.
@nasjko
julia> f(; a = 1, b = 2) = a + b
f (generic function with 1 method)
julia> g(n) = f(; n...)
g (generic function with 1 method)
julia> x = (; a = 2)
(a = 2,)
julia> g(x)
4
Maybe nice to add is the use of the empty tuple to get the complete default:
Julia> g(())
3
I was wondering about the g function def in case of f(c ; a = 1, b = 2) = a + b + c
, but the following worked:
f(c ; a = 1, b = 2) = a + b + c
g(c, n) = f(c; n...)
x = (; a = 2)
julia>g(3, x)
7
Julia>g(3())
6
@Benny Thanks for the annotation idea. Comes very close to the original request from 3 years ago. It is not clear to me, however, how to override a default, say a=2
. I tried bar((2,))
, bar((a=2,))
, bar(2,)
, bar(a=2)
, bar(;a=2)
but nothing works. What (probably obvious thing) am I missing?
Typo, should be
Julia>g(3,())
6
You can’t do it individually for a destructured argument. bar
only takes 1 argument, and it must have properties a
and b
to assign to those variables, e.g. bar((a=10, b=2))
. If you want to annotate, default, or otherwise handle a
and b
separately, then those should be separate arguments e.g. baz(a=1, b=2) = a-b
I have a different but related question about function arguments and destructuring, so I ask it here.
Since I’m an iteration newby, I’m wondering what would be a good generic iteration solution, in the scenario below, to make available in case 1 (the minimum case) the variables a, c, d
and in case 2 (the maximum case) the variables a, b1, b2, c, d, e1[2], e2[2]
.
julia> f(a, args...; c, d=4.1, kwargs...) = a, args, c, d, kwargs
f (generic function with 1 method)
# case 1 (minumum case)
julia> a, b, c, d, e = f(1, c=3)
(1, (), 3, 4.1, Base.Pairs{Symbol, Union{}, Tuple{}, @NamedTuple{}}())
julia> length(b)
0
julia> length(e)
0
julia> println("$a, $c, $d")
1, 3, 4.1
# case 2 (maximum case)
julia> a, b, c, d, e = f(1, 2.1, 2.2, c=3, d=4.2, e1=5.1, e2=5.2)
(1, (2.1, 2.2), 3, 4.2, Base.Pairs(:e1 => 5.1, :e2 => 5.2))
julia> length(b)
2
julia> b1, b2 = b
(2.1, 2.2)
julia> length(e)
2
julia> e1, e2 = e
pairs(::NamedTuple) with 2 entries:
:e1 => 5.1
:e2 => 5.2
julia> println("$a, $b1, $b2, $c, $d, $(e1[2]), $(e2[2])")
1, 2.1, 2.2, 3, 4.2, 5.1, 5.2