2016-09-24 4 views
5

Nach dem changelog for Julia 0.5,Dispatching auf Funktionen in Julia v0.5 +

Jede Funktion und Schließung hat jetzt seine eigene Art.

Bedeutet dies, dass es jetzt möglich ist, detailliertere Informationen zu einer Funktion höherer Ordnung, z. foo(bar :: Function{Float64}) = ..., im Gegensatz zu vor-0,5, wo der Typ bar nicht spezifischer als Function sein könnte?

Wenn ja, was ist der richtige Weg? Wenn nicht, was ist der eigentliche Import dieser Änderung, außer dass der Compiler den generierten Code besser optimieren kann? TIA.

+0

Es gibt eine Teillösung für dieses Problem in Form von [typsichere Funktion Wrapper] (https://github.com/yuyichao/FunctionWrappers.jl). –

Antwort

6

Nicht wirklich nein. Ich sehe, was Sie bekommen, und ich mag es, aber es ist nicht möglich. (. Sicherlich nicht zur Zeit, vielleicht nicht immer OneDay Vielleicht Züge verwenden.)

Läßt ein Beispiel an: foo und bar

julia> foo(x::String) = println(x) 
foo (generic function with 1 method) 

julia> foo(x::Int64) = println(x+1) 
foo (generic function with 2 methods) 

julia> bar(x...) = println(x) 
bar (generic function with 1 method) 

Was für foo die Typhierarchie ist?

julia> typeof(foo) 
#foo 

julia> supertype(typeof(foo)) 
Function 

julia> supertype(supertype(typeof(foo))) 
Any 

So sehen wir, dass sie von der foo Funktion geben Sie eine #foo ist, die ein Subtyp von Function ist. Beachten Sie, dass # bedeutet, dass dies ein generierter Name ist, Sie können Hashs nicht in Namen setzen, wenn Sie nur Code schreiben, sondern den Julia-Compiler (der den Begriff lose verwendet).

Warum ist es nicht super-Supertype spezifischer, als nur funktionieren? Was wäre das? Function{Int64} oder Function{String}? Funktionen in Julia, haben keine Typ-Signaturen, Methoden tun. Eine Funktion ist nur ein Name für mehrere Versand, eine Methode ist eigentlich, was gesendet wird. Grob gesagt sagt der Funktionsname, in welcher Tabelle ich suchen soll, und die Typen der Argumente (dh die Typ-Signatur) sind der Schlüssel zum Nachschlagen in dieser Tabelle. Die Methode selbst wird mit diesem Schlüssel zurückgegeben.

So können mit unserem Beispiel weiter und sehen, was wir tun können:

julia> dothing(f::typeof(foo)) = f(rand([randstring(), rand(Int64)])) 
dothing (generic function with 1 method) 

julia> dothing(foo) 
3139374763834167054 

julia> dothing(foo) 
Ed2kNGrd 


julia> dothing(bar) 
ERROR: MethodError: no method matching dothing(::#bar) 
Closest candidates are: 
    dothing(::#foo) at REPL[11]:1 

So haben wir erfolgreich dothing beschränkt, nur eine #foo als arguement zu nehmen. Sehen Sie, es wirft einen Fehler, wenn Sie ihm eine #bar geben. Dies ist nicht wirklich nützlich, da die foo Funktion das einzige vom Typ #foo ist.

Wir könnten ein Union obwohl verwenden:

julia> dootherthing(f::Union{typeof(foo),typeof(bar)}) = f(rand([randstring(), rand(Int64)])) 
dootherthing (generic function with 1 method) 

julia> dootherthing(foo) 
9107791406050657562 

julia> dootherthing(foo) 
SmB2Xmw8 

julia> dootherthing(bar) 
("1IpZIMnx",) 

julia> dootherthing(bar) 
(-6356894350805213697,) 


julia> dootherthing(str) 
ERROR: UndefVarError: str not defined 

julia> dootherthing(string) 
ERROR: MethodError: no method matching dootherthing(::Base.#string) 
Closest candidates are: 
    dootherthing(::Union{#bar,#foo}) at REPL[19]:1 

dootherthing ein #foo oder ein #bar akzeptiert. Entweder Funktion funktioniert.

Dies hat begrenzte Anwendungen, wie eine Whitelist.

+0

Danke. Ich vermutete so viel, nachdem ich mit 'typeof' experimentiert hatte. –

Verwandte Themen