Sök…


Syntax

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

Anmärkningar

0.4.0

I äldre versioner av Julia hade nedläggningar och anonyma funktioner en körbordsprestanda. Denna straff har eliminerats i 0,5.

Funktionskomposition

Vi kan definiera en funktion för att utföra funktionskomposition med anonym syntax :

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

Observera att denna definition motsvarar var och en av följande definitioner:

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

eller

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

minns att i Julia är f ∘ g bara syntaxsocker för ∘(f, g) .

Vi kan se att den här funktionen komponerar korrekt:

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

I version v0.5 är denna definition mycket performant. Vi kan undersöka den genererade LLVM-koden:

julia> @code_llvm sextuple(1)

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

Det är uppenbart att de två multiplikationerna har vikts till en enda multiplikation och att denna funktion är så effektiv som möjligt.

Hur fungerar denna högre ordningsfunktion? Det skapar en så kallad stängning , som inte bara består av dess kod, utan också håller reda på vissa variabler från dess omfattning. Alla funktioner i Julia som inte skapas på toppnivå är stängningar.

0.5.0

Man kan undersöka variablerna stängda genom fälten för stängningen. Vi ser till exempel att:

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

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

Implementering Currying

En tillämpning av stängningar är att delvis tillämpa en funktion; det vill säga ge några argument nu och skapa en funktion som tar de återstående argumenten. Currying är en specifik form av partiell applikation.

Låt oss börja med den enkla funktionens curry(f, x) som ger det första argumentet till en funktion och förväntar oss ytterligare argument senare. Definitionen är ganska enkel:

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

Återigen använder vi anonym funktionssyntax , den här gången i kombination med variadisk argumentsyntax.

Vi kan implementera några grundläggande funktioner i tyst (eller punktfri) stil med hjälp av denna curry funktion.

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?

Funktioner upprätthåller den förväntade generismen:

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

Introduktion till stängningar

Funktioner är en viktig del av Julia-programmeringen. De kan definieras direkt inom moduler, i vilket fall funktionerna kallas toppnivå . Men funktioner kan också definieras inom andra funktioner. Sådana funktioner kallas " stängningar ".

Stängningar fångar variablerna i sin yttre funktion. En toppnivåfunktion kan bara använda globala variabler från deras modul, funktionsparametrar eller lokala variabler:

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

En stängning, å andra sidan, kan använda alla de förutom variabler från yttre funktioner som den fångar:

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

Om vi kör c = toplevel(10) ser vi att resultatet är

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)

Observera att svansuttrycket för denna funktion är en funktion i sig; det vill säga en stängning. Vi kan kalla stängningen c som om det var någon annan funktion:

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)

Observera att c fortfarande har tillgång till variablerna y och z från toplevel - även om toplevel redan har återvänt! Varje stängning, även de som returneras av samma funktion, stängs över olika variabler. Vi kan kalla toplevel igen

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)

Observera att trots att d och c har samma kod och har skickats med samma argument, är deras output annorlunda. Det är distinkta stängningar.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow