Actually, looking at it again with fresh eyes - I can define a few new 
classes inhering from Ordering, and then define my own lt(o, x, [j-1]) for 
each. It looks like these predefined orderings and lt methods in the 
sorting api - ForwardOrdering, ReverseOrdering and so on are fast as their 
lt() methods are defined as:

lt(o::ForwardOrdering,       a, b) = isless(a,b)lt(o::ReverseOrdering,     
  a, b) = lt(o.fwd,b,a)

Whereas with feeding in custom functions it builds a Lt Operdering type 
that contains a reference for the custom Lt function - which I believe is 
the slow version.

On Wednesday, June 17, 2015 at 11:20:47 PM UTC+1, Ben Ward wrote:
>
> I guess for Base sort! passing a functior overriding call() as lt is 
> possible, if it accepts the three arguments passed to lt in lt(o, x, v[j-1
> ])
>
> On Wednesday, June 17, 2015 at 9:11:22 PM UTC+1, Kristoffer Carlsson wrote:
>>
>> You could also use something called functors which basically are types 
>> that overload the call function. When you pass these as argument the 
>> compiler can specialize the function on the type of the functor and thus 
>> inline the call. See here for example for them being used effectively for 
>> performance increase: https://github.com/JuliaLang/julia/pull/11685
>>
>> As an example I took the code for insertionsort and made it instead 
>> accept an argument f which will be the functor. I then create some functors 
>> to sort on the different type fields and show an example how sort is called.
>>
>>
>> function sort!(v::AbstractVector, f, lo::Int=1, hi::Int=length(v))
>>     @inbounds for i = lo+1:hi
>>         j = i
>>         x = v[i]
>>         while j > lo
>>             if f(x, v[j-1])
>>                 v[j] = v[j-1]
>>                 j -= 1
>>                 continue
>>             end
>>             break
>>         end
>>         v[j] = x
>>     end
>>     return v
>> end
>>
>> # Some type
>> immutable CompType
>>     a::Int
>>     b::Int
>>     c::Int
>> end
>>
>>
>> b = [CompType(1,2,3), CompType(3,2,1), CompType(2,1,3)]
>>
>> # Functors 
>> immutable AFunc end
>> call(::AFunc, x, y) = x.a < y.a
>> immutable BFunc end
>> call(::BFunc, x, y) = x.b < y.b
>> immutable CFunc end
>> call(::CFunc, x, y) = x.c < y.c
>>
>> # Can now sort with good performance
>> sort!(b, AFunc())
>> println(b)
>> sort!(b, BFunc())
>> println(b)
>> sort!(b, CFunc())
>> println(b)
>>
>>
>> Now, this is of course not optimal to rip code out of base. It would be 
>> better if we could pass a functor straight to Base.sort!. 
>>
>>
>> On Wednesday, June 17, 2015 at 8:13:41 PM UTC+2, Ben Ward wrote:
>>>
>>> Hi, I want to create a macro with which I can create a function with a 
>>> custom bit of code:
>>>
>>> In the repl I can do a toy example:
>>>
>>>
>>> *name = :hi*
>>>
>>>
>>> *vectype = Vector{Int}*
>>>
>>>
>>> *quote**  function ($name)(v::$vectype)*
>>>
>>>     *println("hi")*
>>>
>>>   *end*
>>>
>>> *end*
>>>
>>> However if I try to put this in a macro and use it I get an error:
>>>
>>> *macro customFun(vectype::DataType, name::Symbol)*
>>>
>>>
>>> *  quote**   function ($name)(v::$vectype)*
>>>
>>> *      println("hi World!")*
>>>
>>> *    end*
>>>
>>> *  end*
>>>
>>>
>>>
>>> *end*
>>>
>>> *@customFun(Vector{Int}, :hi)*
>>>
>>> What am I doing wrong? I'd like to use macro arguments to provide a 
>>> function's name, and the datatype of the argument. I haven't used macros to 
>>> define functions more complex than simple one liners.
>>>
>>> Thanks,
>>> Ben.
>>>
>>

Reply via email to