>
> 'Traditional' Julia: you can pass a function f as an argument to another
> function g.
>
> Rafael's functors: instead you create new type F whose constructor is f,
> and then you make g a parametric function with a parameter F instead of an
> argument f.
>

A typo here, the constructor of type F is F, and that's the point: F is
both a type and a "callable".


> And the point of this technique is that you can potentially boost
> performance because the compiler can in-line the implicit call to f
> inherent in g{F}(...), whereas the call to f in g(f,...) cannot be inlined.
>

Yes (but I think it is planned to make the compiler be able to inline
normal functions... maybe by being desugared to functors ;-) ).
The declaration of g must be like g{F}(::Type{F}, ...) to enable inlining,
and simply g(F, ...) or g(F::DataType, ...) otherwise (AFAIU, g would then
have only one specialization for all F::DataType, as typeof(F)==DataType).

Have I got it?  Are there other advantages to Rafael's functors (simplified
> code, better error-checking...) compared to 'traditional' Julia?
>

One application is using the inheritance machinery (type constraints...),
eg to take Stefan's example from
https://github.com/JuliaLang/julia/issues/1470:

abstract BinaryOperator
function call{op<:BinaryOperator}(::Type{op}, v::Vector, w::Vector)
    # implement generic vectorized operation in terms of functor op
end
function call{op<:BinaryOperator}(::Type{op}, v::Vector, x)
    # implement generic op(vector, scalar)
end

type plus <: BinaryOperator end
plus(a::Number, b::Number) = a+b
plus(args...) = call(plus, args...) # delegate everything else to super
types

This is less ideal than what is proposed in issue 1470, as one has to write
the delegating code (last line above) for each new sub-type of
BinaryOperator, however only one generic such line is necessary (and can be
macroized :) ).

Reply via email to