2009-06-03 8 views
68

Una frase che ho notato di recente è il concetto di "point gratuito" stile ...Che cos'è lo stile point free in Functional Programming?

In primo luogo, non vi era this domanda, e also this one.

Poi, ho scoperto here menzionano "Un altro argomento che potrebbe valere la pena di discutere è l'antipatia degli autori per lo stile senza punti".

Che cos'è lo stile "point free"? Qualcuno può dare una spiegazione concisa? Ha qualcosa a che fare con il curriculum "automatico"?

Per avere un'idea del mio livello - Ho insegnato io stesso schema, e ho scritto un semplice interprete Scheme ... capisco cosa accattivarsi "implicito" è, ma io non conosco nessun Haskell o ML.

+2

Solo una nota: per capire perché si chiama _pointfree_ visita [Pointfree/But pointfree ha più punti!] (Http://www.haskell.org/haskellwiki/Pointfree#But_pointfree_has_more_points.21) su HaskellWiki. –

risposta

52

Basta guardare la Wikipedia article per ottenere la sua definizione:

Tacit programmazione (-point gratuito di programmazione) è un paradigma di programmazione in cui una definizione di funzione non includono le informazioni riguardanti i suoi argomenti, utilizzando combinatori e la composizione funzione [...] invece di variabili.

Haskell esempio:

convenzionale (si specificano gli argomenti esplicitamente):

sum (x:xs) = x + (sum xs) 
sum [] = 0 

-Point gratuito (sum non ha argomenti espliciti - è solo una piega con + a cominciare 0):

sum = foldr (+) 0 

O ancora più semplice: invece di g(x) = f(x) , potresti semplicemente scrivere g = f.

Quindi sì: è strettamente correlato al currying (o operazioni come la composizione delle funzioni).

+8

Ahh ci vedo! Quindi costruisci nuove funzioni sempre solo combinando altre funzioni piuttosto che dichiarando argomenti ... Molto elegante! –

+14

Non mi piace dover inventare nuovi nomi per variabili/argomenti quando sto programmando. Questa è una grande ragione per cui amo lo stile senza punti! – Martijn

+1

In che modo è correlato a Currying? – kaleidic

24

Stile senza punti significa che gli argomenti della funzione che si sta definendo non sono esplicitamente menzionati, che la funzione è definita attraverso la composizione di funzione.

Se si dispone di due funzioni, come

square :: a -> a 
square x = x*x 

inc :: a -> a 
inc x = x+1 

e se si desidera combinare queste due funzioni a uno che calcola x*x+1, è possibile definirla "point-full" come questo:

f :: a -> a 
f x = inc (square x) 

l'alternativa senza punto sarebbe non parlare l'argomento x:

f :: a -> a 
f = inc . square 
+14

Stupidamente, in Haskell, il modo "senza punti" è solitamente quello che appare più lucido (più periodi). Questo fastidio rende un eccellente mnemonico. (Il libro commentato da World World Haskell su questo.) – Dan

+2

Per quanto riguarda il commento di @ Dan, [Pointfree] (http://www.haskell.org/haskellwiki/Pointfree#But_pointfree_has_more_points.21) La pagina HaskellWiki offre una spiegazione del perché si chiama _pointfree_. –

+2

@Dan: Non penso che sia stupido, dato che il punto Haskell è pensato per essere "quell'operatore del cerchio" (dovrebbe apparire più come ° però). Ma confuso, lo è, specialmente quando si è nuovi ai linguaggi di programmazione funzionale; ogni libro introduttivo su haskell dovrebbe spiegare lo stile point-free. –

4

Stile libero punto significa che il codice non menziona esplicitamente gli argomenti, anche se esistono e vengono utilizzati.

Questo funziona in Haskell a causa del modo in cui funzionano le funzioni.

Per esempio:

myTake = take 

restituisce una funzione che prende un argomento, quindi, non v'è alcun motivo di tipo esplicito l'argomento meno che non vogliate semplicemente troppo. campione

+1

A volte, non funziona in Haskell 98, come in 'myShow = show'. C'è di più su [Haskell wiki] (http://www.haskell.org/haskellwiki/Monomorphism_restriction) –

4

Un JavaScript:

//not pointfree cause we receive args 
var initials = function(name) { 
    return name.split(' ').map(compose(toUpperCase, head)).join('. '); 
}; 

//pointfree 
var initials = compose(join('. '), map(compose(toUpperCase, head)), split(' ')); 

initials("hunter stockton thompson"); 
// 'H. S. T' 

Reference

0

Ecco un esempio a macchina, senza alcuna altra libreria:

interface Transaction { 
    amount: number; 
} 

class Test { 
    public getPositiveNumbers(transactions: Transaction[]) { 
    return transactions.filter(this.isPositive); 

    //return transactions.filter((transaction: {amount: number} => transaction.amount > 0)); 
    } 

    public getBigNumbers(transactions: Transaction[]) { 
    // point-free 
    return transactions.filter(this.moreThan(10)); 

    // not point-free 
    // return transactions.filter((transaction: any) => transaction.amount > 10); 
    } 

    private isPositive(transaction: Transaction) { 
    return transactions.amount > 0; 
    } 

    private moreThan(amount: number) { 
    return (transaction: Transaction) => { 
     return transactions.amount > amount; 
    } 
    } 
} 

Si può vedere stile libero-point è più "fluida" e più facile da leggere.