Tipi in Lisp e Scheme

8

Ora vedo che Racket ha tipi. A prima vista sembra quasi identico alla tipizzazione di Haskell. Ma il CLOS di Lisp copre alcuni dei tipi di cover di Haskell dello spazio? Creare un tipo Haskell molto rigido e un oggetto in qualsiasi linguaggio OO sembra vagamente simile. È solo che ho bevuto un po 'del kool-aiuto Haskell e sono totalmente paranoico che se scendo lungo la strada Lisp, sarò fregato a causa della digitazione dinamica.

    
posta user2054900 17.02.2013 - 01:56
fonte

2 risposte

3

Il sistema di tipo CL è più espressivo di quello di Haskell, ad es. puoi avere un tipo (or (integer 1 10) (integer 20 30)) per un valore 1,2,...9,10,20,21,...,30 .

Tuttavia, i compilatori Lisp non impongono la loro comprensione del tipo sicurezza in gola, quindi puoi ignorare le loro "note" - a tuo rischio e pericolo .

Ciò significa che puoi scrivere Haskell in Lisp (per così dire) dichiarando tutti i tipi di valore e assicurandoti attentamente che tutti i tipi necessari siano dedotti, ma in primo luogo è più semplice usare Haskell.

In sostanza, se vuoi una strong digitazione statica, usa Haskell o OCaml, se vuoi una strong digitazione dinamica, usa Lisp. Se si desidera una digitazione statica debole, utilizzare C, se si desidera una digitazione dinamica debole, utilizzare Perl / Python. Ogni percorso ha i suoi vantaggi (e zeloti) e svantaggi (e detrattori), quindi trarrai beneficio dall'apprendimento di tutti loro.

    
risposta data 17.02.2013 - 04:59
fonte
3

Racket tipizzato è molto diverso da Haskell. Digitare i sistemi in Lisp e Scheme, e in effetti digitare i sistemi in ecosistemi linguistici tradizionalmente non tipizzati, hanno un obiettivo fondamentale che altri sistemi di tipi non - interoperano con il codice non tipizzato esistente . Ad esempio, Racket tipizzato ha introdotto nuove regole di digitazione per adattarsi a vari idiomi di Racket. Considera questa funzione:

(define (first some-list)
  (if (empty? some-list)
      #f
      (car some-list)))

Per gli elenchi non vuoti, restituisce il primo elemento. Per gli elenchi vuoti, questo restituisce false. Questo è comune nelle lingue non tipizzate; un linguaggio tipizzato usa un tipo di wrapper come Maybe o genera un errore nel caso vuoto. Se volessimo aggiungere un tipo a questa funzione, quale tipo dovrebbe essere usato? Non è [a] -> a (nella notazione Haskell), perché può restituire false. Non è anche [a] -> Either a Boolean , perché (1) restituisce sempre false nel caso vuoto, non un arbitrario booleano e (2) un tipo Entrambi avvolgere elementi in Left e falso in Right e richiede di "scartare il o "per arrivare all'elemento reale. Invece, il valore restituisce un vero unione - non esiste alcun costruttore di wrapping, restituisce semplicemente un tipo in alcuni casi e un altro tipo in altri casi. In Racket tipizzato, questo è rappresentato con il costruttore del tipo di unione:

(: first (All (A) (-> (Listof A) (U A #f))))
(define (first some-list)
  (if (empty? some-list)
      #f
      (car some-list)))

Il tipo (U A #f) afferma che la funzione potrebbe restituire un elemento della lista o falso senza alcuna istanza di wrapping Either . Il type checker può inferire che some-list è di tipo (Pair A (Listof A)) o la lista vuota, e inoltre deduce che nei due rami dell'istruzione if è noto quale di questi è il caso . Il controllo del tipo sa che nell'espressione (car some-list) , l'elenco deve avere il tipo (Pair A (Listof A)) perché la condizione if lo garantisce. Questo è chiamato typing occorrenza ed è progettato per facilitare la transizione dal codice non tipizzato al codice digitato.

Il problema è la migrazione. C'è un sacco di codice Racket non incluso, e Typed Racket non può semplicemente costringerti ad abbandonare tutte le tue librerie non tipizzate preferite e passare un mese ad aggiungere tipi al tuo codebase se vuoi usarlo. Questo problema si applica ogni volta che il tuo tipo di aggiunta gradualmente a una base di codice esistente, vedi TypeScript e il suo Qualsiasi tipo per un'applicazione javascript di queste idee.

Un sistema di tipo graduale deve fornire strumenti per trattare gli idiomi comuni non tipizzati e interagire con il codice non ancora esistente. Usarlo sarà alquanto doloroso, vedi "Perché non usiamo più Core. digitato " per un esempio di Clojure.

    
risposta data 26.05.2016 - 21:32
fonte

Leggi altre domande sui tag