Qual è il punto della notazione delle funzioni di Swift?

0

Perché Swift usa questa notazione di funzione:

func greet(person: String, day: String) -> String {
    return "Hello \(person), today is \(day)."
}

Ad esempio, non capisco perché utilizza la notazione a freccia piccola -> per specificare il tipo di ritorno. func identifier() -> Type invece di qualcosa di più sensibile, come Type identifier() .

Ho visto una notazione simile in Haskell, ma in Haskell ha senso per me perché Haskell usa funzioni al curry, quindi la freccia rappresenta la funzione in corso. In un attimo sembra solo prolisso e superfluo.

Qual è stato il ragionamento alla base di questa scelta progettuale?

    
posta theonlygusti 15.12.2016 - 01:35
fonte

2 risposte

5

tl; dr: notazione matematica.

In Matematica, una funzione è una mappa che prende le cose da uno "Spazio" (un set) a un altro (un altro set). cioè f potrebbe essere una funzione che prende elementi dai numeri naturali alle lettere dell'alfabeto. Il tipo di questo sarebbe f:Real numbers -> Letters un altro esempio potrebbe essere g(x) = x + 1 . il tipo di questa funzione potrebbe essere g:R -> R . (dove R sono i numeri reali.)

Ma c'è una ragione per cui i matematici la scrivono così: è intuitiva. Le frecce indicano come cambiano i valori. Stai passando da elementi in un primo set a elementi in un secondo. quindi per il tuo esempio, potresti dire nella tua testa: greet è una funzione che prende la tupla di due Strings in un'altra String .

ora, perché i tipi dovrebbero venire dopo i nomi delle variabili? La mia ipotesi è per lo stesso motivo:

Nelle prove matematiche spesso dici cose come "sia un intero" che somiglia stranamente a let m:Int .

Questo tende a sembrare migliore e più formale dell'alternativo "An Integer m ha qualche valore": int m;

    
risposta data 15.12.2016 - 01:55
fonte
4

Like, I don't get why it uses the small arrow -> notation to specify return type. func identifier() -> Type instead of something more sensible, like Type identifier().

Questo commento mi suggerisce che questa domanda è in realtà solo per battere Swift per non essere C / C ++ / Java. È abbastanza probabile che niente a cui qualcuno possa rispondere ti soddisferà.

In Swift, a differenza di C, C ++ e Java, è molto comune (e anzi, effettivamente possibile) restituire funzioni (chiusure) dalle funzioni.

Considera questo esempio:

func incrementerMaker(startAt start: Int) -> () -> Int {
    var count = start
    return { count += 1; return count }
}

let incrementer = incrementerMaker(startAt: 0)

print(incrementer()) // 1
print(incrementer()) // 2
print(incrementer()) // 3

Per uno, prendi nota che questa è una funzione al curry. Non è così comune in Swift come in Haskell, ma è certamente una possibilità.

Tutti i metodi di istanza sono funzioni al curry. Questo è molto utile, perché significa che puoi passarli in giro senza ancora legarli per agire su un'istanza specifica. Considera la funzione String.uppercased() :

print(type(of: String.uppercased)) //prints: (String) -> () -> String

Il tipo (String) -> () -> String rende molto chiaro quale serie di passaggi deve essere sottoposta alla funzione fino a quando non produce il risultato finale. In primo luogo, si aspetta di essere invocato con un singolo argomento String . Ciò associa l'istanza self e restituisce un metodo di istanza di tipo () -> String . Questo ti dice che si aspetta di essere invocato senza argomenti, producendo un risultato String .

Come sarebbe la firma del tipo per quella funzione, data la sintassi "sensibile" Type identifier() ? La funzione che viene restituita è anonima, quindi non esiste un identificatore e, a differenza di C o C ++, non è un puntatore a funzione, quindi non c'è nemmeno il simbolo * da utilizzare.

    
risposta data 30.04.2017 - 07:05
fonte