On Tuesday, September 1, 2015 at 1:08:38 PM UTC, Jeffrey Sarnoff wrote:
>
> import Base:(+),(*),(-)
>
> julia> 2+3+4
> 9
> julia> (+){T<:Integer}(a::T,b::T,c::T) = ((a+b)+c)+1
> julia> 2+3+4
> 10
>
> julia> 2-3-4
> -5
> julia> (+){T<:Integer}(a::T,b::T,c::T) = ((a-b)-c)-1
> julia> 2-3-4
> -5
>
> Are (+),(*) the only ops that can be n-ary specialized?
>

No, it seems not.
 

> What gives them that ability? Why only those?
>

This here:

(a, b, c, xs...)

the ... part allows for 4-ary and higher. I'm not sure why that is helpful 
(maybe just for generality, to make 3-ary work), but I can guess way 3-ary 
is useful.

I was curiuos by the question, so I looked up. I like how easy Julia is to 
check out stuff like this (and change..) so I did:

edit(+, (Float64, Float64, Float64))

and found:

for (op,F) in ((:+,:(AddFun())), (:*,:(MulFun())), (:&,:(AndFun())), 
(:|,:(OrFun())),
               (:$,:(XorFun())), (:min,:(ElementwiseMinFun())), 
(:max,:(ElementwiseMaxFun())), (:kron,:kron))
    @eval begin
        # note: these definitions must not cause a dispatch loop when 
+(a,b) is
        # not defined, and must only try to call 2-argument definitions, so
        # that defining +(a,b) is sufficient for full functionality.
        ($op)(a, b, c, xs...) = afoldl($F, ($op)(($op)(a,b),c), xs...)
        # a further concern is that it's easy for a type like (Int,Int...)
        # to match many definitions, so we need to keep the number of
        # definitions down to avoid losing type information.
    end
end

[For one op this would be simpler.. but cool how for redundant stuff, this 
makes shorter..]

My guess (probably wrong?), without looking further is that this is to help 
use 3-ary floating point instruction MultiplyAdd (a=b*c+a) that is faster 
than two instructions and more accurate for floating point. At least I know 
Julia has support somehow..

for (op,F) in ((:+,:(AddFun())), (:*,:(MulFun())), (:&,:(AndFun())), 
(:|,:(OrFun())),
               (:$,:(XorFun())), (:min,:(ElementwiseMinFun())), 
(:max,:(ElementwiseMaxFun())), (:kron,:kron))
    @eval begin
        # note: these definitions must not cause a dispatch loop when 
+(a,b) is
        # not defined, and must only try to call 2-argument definitions, so
        # that defining +(a,b) is sufficient for full functionality.
        ($op)(a, b, c, xs...) = afoldl($F, ($op)(($op)(a,b),c), xs...)
        # a further concern is that it's easy for a type like (Int,Int...)
        # to match many definitions, so we need to keep the number of
        # definitions down to avoid losing type information.
    end
end


julia> edit(-, (Float64, Float64, Float64))
ERROR: no method found for the specified argument types
 in which at ./reflection.jl:293
 in edit at interactiveutil.jl:58

-- 
Palli.

Reply via email to