Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass functions as arguments to other functions in Julia without sacrificing performance?

EDIT to try to address @user2864740's edit and comment: I am wondering if there is any information particularly relevant to 0.4rc1/rc2 or in particular a strategy or suggestion from one of the Julia developers more recent than those cited below (particularly @StefanKarpinski's Jan 2014 answer in #6 below). Thx

Please see e.g.

  1. https://groups.google.com/forum/#!topic/julia-users/pCuDx6jNJzU
  2. https://groups.google.com/forum/#!topic/julia-users/2kLNdQTGZcA
  3. https://groups.google.com/forum/#!msg/julia-dev/JEiH96ofclY/_amm9Cah6YAJ
  4. https://github.com/JuliaLang/julia/pull/10269
  5. https://github.com/JuliaLang/julia/issues/1090
  6. Can I add type information to arguments that are functions in Julia?
  7. Performance penalty using anonymous function in Julia

(As a fairly inexperienced Julia user) my best synthesis of this information, some of which seems to be dated, is that the best practice is either "avoid doing this" or "use FastAnonymous.jl."

I'm wondering what the bleeding edge latest and greatest way to handle this is.

[Longer version:]

In particular, suppose I have a big hierarchy of functions. I would like to be able to do something like

function transform(function_one::Function{from A to B},
                   function_two::Function{from B to C},
                   function_three::Function{from A to D})
    function::Function{from Set{A} to Dict{C,D}}(set_of_As::Set{A})
        Dict{C,D}([function_two(function_one(a)) => function_three(a)
                   for a in set_of_As])
    end
end

Please don't take the code too literally. This is a narrow example of a more general form of transformation I'd like to be able to do regardless of the actual specifics of the transformation, BUT I'd like to do it in such a way that I don't have to worry (too much) about checking the performance (that is, beyond the normal worries I'd apply in any non-function-with-function-as-parameter case) each time I write a function that behaves this way.

For example, in my ideal world, the correct answer would be "so long as you annotate each input function with @anon before you call this function with those functions as arguments, then you're going to do as well as you can without tuning to the specific case of the concrete arguments you're passing."

If that's true, great--I'm just wondering if that's the right interpretation, or if not, if there is some resource I could read on this topic that is closer to a "logically" presented synthesis than the collection of links here (which are more a stream of collective consciousness or history of thought on this issue).

like image 331
Philip Avatar asked Sep 22 '15 20:09

Philip


1 Answers

The answer is still "use FastAnonymous.jl," or create "functor types" manually (see NumericFuns.jl).

If you're using julia 0.4, FastAnonymous.jl works essentially the same way that official "fast closures" will eventually work in base julia. See https://github.com/JuliaLang/julia/issues/11452#issuecomment-125854499. (FastAnonymous is implemented in a very different way on julia 0.3, and has many more weaknesses.)

like image 178
tholy Avatar answered Oct 01 '22 19:10

tholy