Function arguments

I think that default value syntax ambiguous so not allowed. You should do (;a, b) = (;a=1, b=2) instead.

1 Like

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

1 Like

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
1 Like

@nsajko Thanks for the concise overview

1 Like

@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