Perché la sintassi del linguaggio funzionale non è più vicina al linguaggio umano?


14

Sono interessato alla programmazione funzionale e ho deciso di confrontarmi con Haskell. Mi fa male la testa ... ma alla fine capirò ... Ho una curiosità però, perché la sintassi è così criptica (in mancanza di un'altra parola)?

C'è un motivo per cui non è più espressivo , più vicino al linguaggio umano?

Capisco che FP è bravo a modellare concetti matematici e ha preso in prestito alcuni dei suoi mezzi di espressione concisi, ma ancora non è matematica ... è un linguaggio.


4
@ratchet maniaco: :) quindi ce n'è uno disegnato da un ragazzo che odia la notazione polacca?
JohnDoDo,

10
@ratchetfreak In che modo la sintassi di Haskell assomiglia alla notazione polacca? Gli operatori di Haskell sono infissi, proprio come gli operatori della maggior parte delle altre lingue (e le chiamate di funzione sono il prefisso - come anche le chiamate di funzioni della maggior parte delle altre lingue).
sepp2k,

9
È un presupposto / salto piuttosto grande che stai facendo, che "più vicino al linguaggio umano" equivale a "più espressivo".
Matt Ball,

7
Hai mai sentito parlare di Cobol e Fortran?
ott--

7
Per lo stesso motivo per cui i matematici hanno sostituito lunghe frasi latine con espressioni algebriche. Con un po 'di pratica, una notazione più compatta è molto più produttiva.
Kevin Cline,

Risposte:


14

Linguaggi funzionali come Haskell e la sua antecedente Miranda sono nati dal concetto matematico di calcolo lambda . Dalla pagina di Wikipedia:

Il calcolo lambda (anche scritto come λ-calcolo o chiamato "calcolo lambda") è un sistema formale nella logica matematica per esprimere il calcolo mediante associazione e sostituzione variabili.

...

Il calcolo lambda ha svolto un ruolo importante nello sviluppo della teoria dei linguaggi di programmazione. Le controparti più importanti del calcolo lambda nell'informatica sono i linguaggi di programmazione funzionale, che essenzialmente implementano il calcolo (aumentato con alcune costanti e tipi di dati). Oltre ai linguaggi di programmazione, il calcolo lambda ha anche molte applicazioni nella teoria delle prove. Un esempio importante di ciò è la corrispondenza Curry-Howard, che fornisce una corrispondenza tra diversi sistemi di calcolo lambda tipizzato e sistemi di logica formale.

A causa di questa storia, le sintassi di questi linguaggi funzionali (ed elementi funzionali di linguaggi più imperativi) sono fortemente influenzati dalla notazione matematica usata dal calcolo lambda.

La precisione con cui sia le notazioni matematiche che i linguaggi informatici possono descrivere i requisiti e la precisione con cui i computer richiedono che le loro istruzioni siano scritte ben correlate tra loro. L'imprecisione del linguaggio naturale crea tuttavia un enorme ostacolo al suo utilizzo per la programmazione dei computer. Anche gli ambienti (probabilmente) di maggior successo del linguaggio naturale come Wolfram Alpha richiedono un'esperienza di dominio significativa per essere utilizzati in modo efficace.


29

La sintassi di Haskell è vicina al linguaggio umano. È specificamente progettato per assomigliare alla notazione matematica, che è un linguaggio progettato dagli umani (quindi un linguaggio umano ) per esprimere precisamente quei concetti su cui Haskell è costruito.

Puoi mostrare un pezzo di codice Haskell a qualsiasi matematico o logico, e sarà in grado di capirlo, anche se non ha mai sentito parlare di Haskell e non sa assolutamente nulla di programmazione, informatica o persino computer.

D'altra parte, puoi mostrare a qualsiasi matematico o logico un pezzo di codice come questo:

x = x + 1

e sarà completamente confuso, dicendo: "Questo non ha senso, non esiste xtale che sia xuguale a xpiù 1".

Se una notazione specifica sia o meno "criptica", è una questione di opinione e familiarità.


8
C'è solo un problema con questa risposta: non sono un matematico.
JohnDoDo,

6
@ sepp2k: non sarei d'accordo. Per la maggior parte delle persone senza precedente esposizione ai linguaggi di programmazione e alcune basi matematiche di base, la sintassi di Haskell sarà molto più semplice da comprendere rispetto al tipico codice procedurale con tutti i suoi effetti collaterali e le complicate istruzioni degli ambienti vengono eseguite. Sintassi come whereconsentono di condensare l'essenza di una funzione in una riga.
Benjamin Bannier,

17
-1: questa risposta sembra in gran parte pedante. Sono abbastanza certo che l'OP intendesse la lingua parlata.
Steven Evers,

6
In realtà, sono abbastanza sicuro che x = infinityrisolva davvero l'equazione.
DeadMG

6
Bene, anche i linguaggi di programmazione sono progettati dagli umani .... Quindi, per tua definizione, sono linguaggi umani.
marco-fiset,

13

Penso che una cosa che probabilmente stai incontrando è qualcosa che mi sono imbattuto anche durante l'apprendimento della programmazione funzionale, che è che con la programmazione funzionale puoi (e quasi devi) pensare / lavorare a un livello superiore rispetto a quello che fai con la programmazione imperativa.

Ciò che trovi meno espressivo, penso che in realtà sia più espressivo: non devi precisare ogni piccolo dettaglio e puoi fare di più con meno codice nella programmazione funzionale - c'è più potere in ciò che scrivi.

Ad esempio, potrei scrivere in modo imperativo:

for each (Person person in people)
    print(person.name)

che è totalmente leggibile come l'inglese.

Una versione di Haskell potrebbe essere (e questo non è valido Haskell, ma è solo per il confronto sintattico):

map (print . name) people

che richiede meno codice e meno conflitti di dettagli - Non devo scomporre le cose in un ciclo e le sue variabili () ( for each (...)), la mapfunzione si occupa di questo per me.

Lavorare a quel livello può richiedere un po 'di tempo per abituarsi. Se aiuta, Haskell è stato probabilmente il momento più difficile in cui ho imparato una nuova lingua da quando ho iniziato a programmare e conosco> 10 lingue (incluso Lisp). Ne è valsa la pena di imparare però.


8

Al momento mi sto occupando di Scala, quindi posso simpatizzare. Almeno con la Scala posso tornare a uno stile imperativo quando il gioco si fa troppo duro.

Penso che ci siano diverse forze in gioco qui:

  • I progettisti di linguaggi funzionali hanno necessariamente una solida preparazione matematica, quindi prendono in prestito la notazione matematica che è loro naturale.

  • Una maggiore espressività (cioè il potere delle dichiarazioni, piuttosto che la vicinanza all'inglese) di qualsiasi lingua ha (IMO) un prezzo corrispondente nella pendenza della curva di apprendimento. Terseness è una qualità molto apprezzata in Scala, con molte cose facoltative.

  • I linguaggi funzionali fanno le cose in modo molto diverso, quindi le operazioni di base non si associano a costrutti imperativi.


3
Vorrei anche aggiungere che spesso i linguaggi funzionali possono esprimere concetti di ordine superiore, essendo questi più astratti, è più difficile nominare in modo significativo
jk.

1
@jk, sì, d'accordo! Allo stesso tempo, è il motivo per cui hanno una ripida curva di apprendimento per programmatori con un background imperativo e poca matematica (come me) e perché valgono la pena.
Richard Close,

3

Se ho compreso correttamente il tuo ultimo commento, la tua domanda è perché Haskell utilizza spesso operatori simbolici in luoghi in cui potrebbe anche utilizzare parole chiave alfanumeriche (o nomi di funzioni)?

Per quanto riguarda le parole chiave, una risposta sarebbe che le parole chiave ti impediscono di utilizzare determinate parole come nomi di variabili. Ad esempio, sono sempre seccato quando voglio chiamare le mie variabili frome toin una lingua in cui una di queste è una parola chiave, come in Python.

Un altro motivo per gli operatori simbolici in generale è la concisione. Ciò non si applica ai tuoi esempi specifici di comprensione dell'elenco ( <-non è più breve di in), ma in molti casi lo fa.

Ancora un altro motivo è la leggibilità. Ciò potrebbe sembrare controintuitivo perché gli operatori simbolici sono spesso più difficili da imparare poiché i loro "nomi" non ti dicono davvero nulla di ciò che fanno (mentre il nome di una funzione di solito lo farà), ma una volta che sai cosa fa un determinato operatore, le espressioni con operatori simbolici infissi sono spesso più facili da analizzare per un essere umano rispetto a uno con molte chiamate al prefisso alfanumerico poiché gli operatori in questo modo si distinguono visivamente più facilmente dagli operandi. Ad esempio, la maggior parte delle persone concorderebbe sul fatto che 2 * 3 + 4è più facilmente leggibile di add (mult 2 3) 4o add(mult(2, 3), 4).


@PeterTaylor No, solo che sono stupido ;-) Risolto ora.
sepp2k,

3

I linguaggi informatici imperativi per lo più non sono più vicini ai linguaggi naturali di quanto lo sia Haskell.

Tuttavia, alcuni sono progettati per assomigliare maggiormente all'inglese: Cobol e Hypercard, per esempio. Le lezioni che prenderei da questi esempi sono:

  • la somiglianza con le lingue naturali non sembra produrre miglioramenti diretti nell'usabilità
  • emulare direttamente i linguaggi naturali può produrre linguaggi informatici che sono verbosi e oscuri

Secondo quanto riferito, il linguaggio informatico Perl è stato progettato tenendo conto di alcuni aspetti più sottili del linguaggio naturale . Giudicherei che Perl fa meglio di Cobol o Hypercard sull'usabilità generale, ma le persone hanno opinioni diverse su Perl.


3

Penso che Haskell diventi il ​​più simile al linguaggio umano possibile senza introdurre una sintassi folle. Si spinge davvero molto, ad esempio con la whereclausola di posticipare una definizione e con la sintassi di comprensione dell'elenco che è esattamente ciò che scriverei su una lavagna. Evita anche caratteri estranei come parentesi graffe e ha un uso liberale della rientranza. L'esempio tipico è quicksort:

qsort [] = []
qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater
               where lesser = [x | x <- xs, x <= p] 
                     greater = [x | x <- xs, x > p]

Ammesso, è un semplice esempio, ma non conosco nessun'altra lingua che lo renda leggibile come questo.

Fare cose più complicate può diventare difficile da leggere in Haskell, ma ciò ha a che fare con il sistema dei tipi, l'IO vincolato e non con la sintassi.

Semmai direi che Haskell ha sacrificato la semplicità sintattica per accogliere una sintassi più simile al linguaggio umano. Uno schema simile a un linguaggio ha una sintassi che è molto lontana da ciò che un umano scriverebbe, ma è davvero semplice spiegare le sue regole.


3
Difficilmente lo definirei leggibile dall'uomo. Io so quicksort. Conosco bene come configurarlo in più lingue diverse, so cosa dovrebbe fare e ancora non riesco a ricavare testa o croce dalla metà inferiore di quel frammento di codice.
Mason Wheeler,

Immagino che dipenda davvero dal tuo background. Questo è chiaro per me ...
Andrea,

2
In ogni caso, dovrebbe assomigliare a questa notazione: purplemath.com/modules/setnotn.htm
Andrea

4
Sei sicuro che non dovrebbe essere ++ [p] ++?
Peter Taylor,

1
@Mason: Mi sembra abbastanza chiaro, e non ho mai scritto una riga di Haskell
kevin cline,

2

Penso che la differenza abbia a che fare con il modo in cui la programmazione funzionale / dichiarativa fa affermazioni su un problema come se fosse un problema di matematica, dove la programmazione imperativa descrive un processo . Nel mondo degli affari, i programmi per computer avvolgono o sostituiscono i processi fisici, quindi potresti trovare un linguaggio che riflette questo per essere più intuitivo.

Si scopre che lo stile funzionale si presta a fare un uso sicuro di più processori (perché riduce al minimo la mutabilità e gli effetti collaterali) - qualcosa di cui vedremo di più in futuro. Inoltre, i linguaggi funzionali più moderni dispongono di raccolte con iteratori a cui è possibile passare funzioni. Questi metodi possono dividere il carico di lavoro su più processori in modo molto efficiente senza che tu lo sappia.


Penso che questa sia la risposta migliore, l'unica che chiarisca la distinzione tra processo e dichiarazioni.
Milind R
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.