# Syntax for outer constructor and thow-away input argument

Hello there,

A simple semantic question, and a way to call an inner constructor
Assuming I have a simple structure defined as follows

``````struct Test
b::Int;
m::Int;
n::Int;
end
``````

But such that we have b = m+n+1. One can built an inner constructor to check that the construction is fine

``````struct Test
b::Int;
m::Int;
n::Int;
Test(b::Int,m::Int,n::Int) = begin
@assert b == m+n+1 "b should be m+n+1"
return new(b,m,n)
end
end
``````

And the structure can be called by

``````Test(8,0,7)
``````

And raises an error with Test(8,0,4).

In some cases, I would like to be able to partially defined the structure, i.e call a Test(8,0,) that returns a Test(8,0,7) or Test(8,,7) that returns a Test(8,0,7). Kind of throw-away input argument.
However, I cannot figure out how to call such a function. I was thinking to define function as

``````Q(b::Int,m::Int,_) = Q(b,m,b-m-1);
Q(b::Int,_,n::Int) = Q(b,b-n-1,n);
``````

But if definition is possible, I can’t instanciate them with

``````Test(8,0,_)
ERROR: syntax: all-underscore identifier used as rvalue
``````

I understand the error, and

• I know that I can handle the construction using keyword
• Can also define Test(8,0,nothing) that can be handled by multiple dispatch, but I was wondering if such an easy syntax as Q(8,0,) or Q(8,,7) can be used ?

Thanks

`_` is not a value you can use (rvalue), it is syntax for ignoring values. This is what the error message says.

I would suggest that you have a `Test(; b, m, n)` outer constructor that just fills in the value not provided. `range` is a example you can follow for the implementation.

An alternative is to define a singleton struct, eg

``````struct FillIn end

Q(b::Int, m::Int, ::FillIn) = Q(b,m,b-m-1)

# call as Q(b, m, FillIn())
``````

(incidentally, lines do not need to be terminated with `;` in Julia)

Maybe you could use a colon (`:`) as placeholder for a missing value?

``````Q(b, m, n) = (b=b, m=m, n=n)
Q(b::Int, m::Int, ::Colon) = Q(b, m, b-m-1);
Q(b::Int, ::Colon, n::Int) = Q(b, b-n-1, n);
``````
``````julia> Q(8, 0, :)
(b = 8, m = 0, n = 7)

julia> Q(8, :, 7)
(b = 8, m = 0, n = 7)
``````

Such a syntax is consistent with what is done for example in `reshape` when one does not want to specify all arguments.

1 Like

@Tamas_Papp Thanks for the answer. Outer is indeed a good solution there, even if I prefer the second approach with the specific type handler. For the ;, I am affraid that it is some PTSD from former langages !

@ffevotte Many thanks, this is exaclty what I was looking for !