I was running the roames notebook exercises, in an attempt to fix this:
Create a more generic reduce2 function that works recursively over a tuple
For the operations + and *, being associative, simulate the operation in this direction 1*(2*(3*(4))) or on the contrary (((1)*2)*3)*4, the result is the same.
However, wanting to extend the result also to the operations (-) and (/) I tried to create the second structure, i.e. ((((1/2)/3)/4)/5) which is the one adopted by the library reduce function.
In the absence of slurping in a not final position, I had to use this somewhat convoluted method.
I’ve tried using non-trailing slurping, which I thought was possible in version 1.9 of julia, also as function arguments as well as for assigning values to multiple variables.
Why was this possibility not extended to function arguments?
Thank you!
On the main question (that of slurping) I have to think about it calmly.
For the secondary question: why don’t the same parsing rules hold for the case of a tuple with two elements?
julia> g((x,y))=x+y
g (generic function with 1 method)
julia> g(x,y)=x+y
g (generic function with 2 methods)
So the two expressions (two methods!??!, why only one method then?)) are equivalent only for input of a single element?
julia> g((x,))=x.^2
g (generic function with 1 method)
julia>
julia> g(((2,3),))
(4, 9)
julia> g(3)
9
julia> g(2,3)
ERROR: MethodError: no method matching g(::Int64, ::Int64)
julia> g(x)=x.^2
g (generic function with 1 method)
I don’t want to abuse your availability, but I also try to ask the reason for the following results:
julia> t,h...=1
1
julia> t
1
julia> h
Base.Iterators.Rest{Int64, Nothing}(1, nothing)
julia> t...,h=1
1
julia> t
Int64[]
julia> h
1
julia> k,t...,h = 1
ERROR: ArgumentError: The iterator only contains 0 elements, but at least 1 were requested.
This assigns the first element to t, and the rest to h. In this case, h is empty, as there is only one element on the right-hand side.
In this case, the last element is assigned to h, and the elements before that are assigned to t. Since there is only one element on the right, t is empty.
In this case, the first element is assigned to k, the last to h, and the ones in between to t. However, as there is only one element on the right-hand side, the operation leads to an error. This assignment expects at least two values on the right.
julia> k, t..., h = 1,2
(1, 2)
julia> t
()
julia> k
1
julia> h
2
Okay. I understand. Although I’m still curious as to why t... is Int[] in one case, Base.Iterators.Rest{Int64, Nothing}(1, nothing) in another, and yet another ().
In the meantime I have found, by trial and error, a way to simulate slurping even in non-final position
julia> reduce4(f, t::Tuple)= _r(f,t...)
reduce4 (generic function with 1 method)
julia> _r(f,x)=x
_r (generic function with 1 method)
julia> _r(f,(t...,h)...)=f(reduce4(f,t),h)
_r (generic function with 2 methods)
julia> reduce4(*, (1,2,3,4,5))
120
julia> reduce4(+, (1,2,3,4,5))
15
julia> reduce4(-, (1,2,3,4,5))
-13
julia> reduce4(/, (1,2,3,4,5))
0.008333333333333333