Zoeken…


Syntaxis

  • x -> [body]
  • (x, y) -> [body]
  • (xs ...) -> [body]

Opmerkingen

0.4.0

In oudere versies van Julia hadden sluitingen en anonieme functies een uitvoeringsduurstraf. Deze boete is geëlimineerd in 0,5.

Functie samenstelling

We kunnen definiëren van een functie uit te voeren functie samenstelling met behulp van anonieme syntaxis van de functie :

f ∘ g = x -> f(g(x))

Merk op dat deze definitie equivalent is aan elk van de volgende definities:

∘(f, g) = x -> f(g(x))

of

function ∘(f, g)
    x -> f(g(x))
end

herinnerend aan het feit dat f ∘ g in Julia gewoon syntaxisuiker is voor ∘(f, g) .

We kunnen zien dat deze functie correct is samengesteld:

julia> double(x) = 2x
double (generic function with 1 method)

julia> triple(x) = 3x
triple (generic function with 1 method)

julia> const sextuple = double ∘ triple
(::#17) (generic function with 1 method)

julia> sextuple(1.5)
9.0
0.5.0

In versie v0.5 is deze definitie zeer performant. We kunnen de gegenereerde LLVM-code bekijken:

julia> @code_llvm sextuple(1)

define i64 @"julia_#17_71238"(i64) #0 {
top:
  %1 = mul i64 %0, 6
  ret i64 %1
}

Het is duidelijk dat de twee vermenigvuldigingen zijn samengevouwen tot een enkele vermenigvuldiging en dat deze functie zo efficiënt mogelijk is.

Hoe werkt deze hogere orde functie? Het creëert een zogenaamde afsluiting , die niet alleen uit de code bestaat, maar ook bepaalde variabelen uit het bereik houdt. Alle functies in Julia die niet op het hoogste niveau zijn gemaakt, zijn sluitingen.

0.5.0

Men kan de gesloten variabelen door de velden van de sluiting inspecteren. We zien bijvoorbeeld dat:

julia> (sin ∘ cos).f
sin (generic function with 10 methods)

julia> (sin ∘ cos).g
cos (generic function with 10 methods)

Curry implementeren

Een toepassing van sluitingen is om een functie gedeeltelijk toe te passen; dat wil zeggen, geef nu enkele argumenten en maak een functie die de resterende argumenten overneemt. Currying is een specifieke vorm van gedeeltelijke toepassing.

Laten we beginnen met de eenvoudige functie curry(f, x) die het eerste argument voor een functie levert en later aanvullende argumenten verwachten. De definitie is vrij eenvoudig:

curry(f, x) = (xs...) -> f(x, xs...)

We gebruiken opnieuw de syntaxis van de anonieme functie , dit keer in combinatie met de syntaxis van variadische argumenten.

We kunnen enkele basisfuncties in stilzwijgende (of puntloze) stijl implementeren met behulp van deze curry .

julia> const double = curry(*, 2)
(::#19) (generic function with 1 method)

julia> double(10)
20

julia> const simon_says = curry(println, "Simon: ")
(::#19) (generic function with 1 method)

julia> simon_says("How are you?")
Simon: How are you?

Functies handhaven het verwachte generisme:

julia> simon_says("I have ", 3, " arguments.")
Simon: I have 3 arguments.

julia> double([1, 2, 3])
3-element Array{Int64,1}:
 2
 4
 6

Inleiding tot sluitingen

Functies zijn een belangrijk onderdeel van de programmering van Julia. Ze kunnen direct binnen modules worden gedefinieerd, in welk geval de functies topniveau worden genoemd . Maar functies kunnen ook worden gedefinieerd binnen andere functies. Dergelijke functies worden " sluitingen " genoemd.

Bij sluitingen worden de variabelen in hun uiterlijke functie vastgelegd. Een functie op het hoogste niveau kan alleen globale variabelen uit hun module, functieparameters of lokale variabelen gebruiken:

x = 0  # global
function toplevel(y)
    println("x = ", x, " is a global variable")
    println("y = ", y, " is a parameter")
    z = 2
    println("z = ", z, " is a local variable")
end

Een sluiting, aan de andere kant, kan al deze gebruiken naast variabelen van externe functies die het vastlegt:

x = 0  # global
function toplevel(y)
    println("x = ", x, " is a global variable")
    println("y = ", y, " is a parameter")
    z = 2
    println("z = ", z, " is a local variable")

    function closure(v)
        println("v = ", v, " is a parameter")
        w = 3
        println("w = ", w, " is a local variable")
        println("x = ", x, " is a global variable")
        println("y = ", y, " is a closed variable (a parameter of the outer function)")
        println("z = ", z, " is a closed variable (a local of the outer function)")
    end
end

Als we c = toplevel(10) , zien we dat het resultaat is

julia> c = toplevel(10)
x = 0 is a global variable
y = 10 is a parameter
z = 2 is a local variable
(::closure) (generic function with 1 method)

Merk op dat de staartuitdrukking van deze functie een functie op zichzelf is; dat wil zeggen een sluiting. We kunnen de sluiting c noemen alsof het een andere functie was:

julia> c(11)
v = 11 is a parameter
w = 3 is a local variable
x = 0 is a global variable
y = 10 is a closed variable (a parameter of the outer function)
z = 2 is a closed variable (a local of the outer function)

Merk op dat c nog steeds toegang heeft tot de variabelen y en z vanuit de toplevel aanroep - ook al is toplevel al terug! Elke sluiting, zelfs die teruggegeven door dezelfde functie, sluit over verschillende variabelen. We kunnen weer toplevel bellen

julia> d = toplevel(20)
x = 0 is a global variable
y = 20 is a parameter
z = 2 is a local variable
(::closure) (generic function with 1 method)

julia> d(22)
v = 22 is a parameter
w = 3 is a local variable
x = 0 is a global variable
y = 20 is a closed variable (a parameter of the outer function)
z = 2 is a closed variable (a local of the outer function)

julia> c(22)
v = 22 is a parameter
w = 3 is a local variable
x = 0 is a global variable
y = 10 is a closed variable (a parameter of the outer function)
z = 2 is a closed variable (a local of the outer function)

Merk op dat, ondanks dat d en c dezelfde code hebben en dezelfde argumenten krijgen, hun uitvoer anders is. Het zijn verschillende sluitingen.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow