Tutti abbiamo visto interi, virgola mobile, stringa e il tipo decimale occasionale. Quali sono alcuni dei tipi più strani, unici o utili che hai incontrato, utili o meno?
Sarò breve:
Maybe a
in Haskell.
Con questo semplice costrutto, il linguaggio risolve il problema degli arresti anomali o NullPointerException
, che elude in modo netto il "One Million Mistake" di Tony Hoare:)
Francamente, una presenza opzionale è stata verificata in fase di compilazione? È onirico ...
Sono perennemente appassionato di void *
. È probabilmente un sintomo di qualcosa di profondamente imperfetto in me.
Lua ha una tabella che è davvero impressionante. Ha un hashtable e un vettore incorporati, e con l'uso di metatables può essere la base fondamentale per l'oggetto programmazione orientata in un linguaggio procedurale.
Ogni indice di una tabella può ricevere una qualsiasi delle strutture linguistiche di base (numero, booleano, stringa, funzione -sì, le funzioni sono tipi su lua - e tabelle).
Sono sorpreso che nessuno abbia ancora menzionato Monads o Algebraic Datatypes.
Lisp ha due tipi interessanti: t
e nil
. La cosa interessante è che tutto è un t
e niente è un nil
.
SNOBOL: pattern (essenzialmente un albero parser LL (1), se lo ricordo correttamente).
Fortran ha blocchi comuni; è uno dei meno comuni tipi di dati nelle lingue moderne o, piuttosto, un modo insolito per condividere in modo efficiente i dati.
Fortran 95 ha tipi di intervallo e aritmetica dell'intervallo incorporato.
L'elenco non sarebbe completo senza tipi monadici trovati in Haskell. Per capirli hai bisogno di un po 'di sforzo.
Delphi ha set ( vedi anche ), che non credo siano implementati allo stesso modo in altre lingue.
Questo semplifica la memorizzazione di attributi multi-variabili nei database: D
Suppongo che sia davvero strano venire dalla programmazione su un'architettura classica, ma certamente uno dei tipi più difficili per me da parte mia è stato il registro quantistico , che compare in QCL .
PL / SQL ti consente di dichiarare le variabili di tipo my_table.some_column%type
... Trovo che sia dannatamente utile.
E C # ti consente di dichiarare oggetti come annullabili o meno, anche se non sono sicuro che conti come tipo.
Ho avuto un debole nel mio cuore per i tipi di dati Euphoria quando ero più giovane
È strutturato così:
Object
-> Atom
-> Sequence
Sequenza = Una sequenza di oggetti
-- examples of atoms:
0
98.6
-1e6
-- examples of sequences:
{2, 3, 5, 7, 11, 13, 17, 19}
{1, 2, {3, 3, 3}, 4, {5, {6}}}
{{"jon", "smith"}, 52389, 97.25}
{} -- the 0-element sequence
Vedi: Manuale di riferimento
Nota: "jon" è in realtà un modo breve per scrivere la sequenza di valori ASCII. Ad esempio "ABCDEFG"
è uguale a {65, 66, 67, 68, 69, 70, 71}
Felix ha tipi di somma anonimi. Il tipo è scritto come:
typedef il = int + long;
come sarebbe in teoria. I valori sono brutti:
case 0 of il (1)
case 1 of il (2L)
tranne forse per una somma unitaria come 3 = 1 + 1 + 1
case 0 of 3
case 1 of 3
che purtroppo utilizza il conteggio delle origini pari a "Compatibilità C". Le somme anonime sono necessarie per tipi algebrici tipizzati strutturalmente, ad esempio:
(1 + T * li) as li
è una lista (con collegamenti singoli) di T. Tutte le altre lingue che conosco richieste somme nominalmente digitate, in cui sia il tipo stesso che i costruttori devono essere nominati.
La stenografia 3 usata sopra è carina, la seguente è nella libreria:
typedef void = 0;
typedef unit = 1;
typedef bool = 2;
e questa notazione:
T ^ 3
è un array di lunghezza statica 3 .. il 3 non è un numero intero ma una somma di 3 unità. Che peccato + non è associativo:)
q / kdb + ha tabelle incorporate. Poiché si tratta di un linguaggio di programmazione e di un database orientato alle colonne in uno, non è necessario LINQ o ORM.
Ad esempio, puoi creare una tabella come questa (l'assegnazione è distinta da :
piuttosto che =
come nella maggior parte delle lingue):
people:([]name:'Joe'Amy'Sarah; age:17 15 18; GPA:3.5 3.8 3.33)
Ora posso guardare il mio tavolo:
q)show people
name age GPA
--------------
Joe 17 3.5
Amy 15 3.8
Sarah 18 3.33
E posso interrogarlo:
q)select from people where GPA>3.4
name age GPA
------------
Joe 17 3.5
Amy 15 3.8
Ho trovato che il sindacato in C ++ era "bizzarro" quando ne ho sentito parlare per la prima volta. Non ho ancora raggiunto uno scenario in cui sono la scelta più ovvia da implementare.
Sto ancora cercando di capire come funziona una funzione multiparametrica in F # e in altri linguaggi funzionali. Fondamentalmente int f (Foo, Bar) diventa func f (Foo)
Questa è la funzione a due parametri che prende un Foo, e una Barra e restituisce un int è in realtà una funzione a parametro unico che prende un Foo e restituisce una funzione di un parametro che prende una barra e restituisce un int. Ma in qualche modo puoi chiamarlo con due parametri se vuoi. Ho scritto un post su di esso qui
Sono oggetti estremamente potenti ma compatti.
Le lingue che le hanno incorporate hanno una grande capacità di manipolare il testo (non sentiamo che la parola parse non siano così buone).
Una manciata di lingue nella famiglia funzionale hanno una classe di tipi noti come Unity. La caratteristica distintiva dei tipi Unity è che non contengono informazioni, sono tipi a zero bit. Un tipo di unità (in alcune varianti) è anche il suo unico valore o (nella maggior parte degli altri) ha un solo valore (che non è di per sé un tipo).
Sono utili, tuttavia, perché sono tipi distinti. Poiché non è possibile convertire implicitamente da un tipo di unità a un altro, è possibile utilizzare il controllo statico dei tipi per funzionare in modo molto efficiente ed espressivo.
Unity è anche il modo in cui la maggior parte di questi linguaggi descrive Enum, consentendo a un nuovo tipo di essere un insieme definito di altri tipi, o per descrivere tipi forse , valori che possono essere sia un valore di un tipo tipico (ad esempio un numero intero) o un valore che rappresenta un valore no.
Alcune lingue che non impiegano la ricchezza dei tipi di unità definite dall'utente hanno ancora unità in esse, in una forma o nell'altra. Ad esempio, Python ha almeno tre tipi di unità, NoneType
, NotImplementedType
e EllipsisType
. È interessante notare che i primi due significano qualcosa del tipo "Nessun valore", ma il terzo viene utilizzato in valori complessi (in particolare, le espressioni di sezione) per rappresentare casi speciali interessanti.
Altri esempi interessanti di unità includono NULL
in sql e undefined
in javascript, ma non void
in C o C ++. void
fallisce. Anche se descrive un valore senza informazioni, ma nessun valore effettivo può essere di tipo void
.
Il tipo symbol
di Ruby è un po 'insolito. È essenzialmente una stringa che implementa il modello singleton. O qualcosa. Finora, ho trovato che i migliori usi per i simboli sono negli stati di tracciamento e nel passaggio dei nomi di funzioni.
COBOL. Essenzialmente solo due tipi di dati di base, stringhe e numeri, ma devi specificare esattamente come sono disposti in memoria, ad es. PIC S9(5)V99 COMP-3
.
Clipper aveva 'Code Blocks', che erano simili ai metodi anonimi. Potrebbero essere passati in rassegna e valutati secondo necessità, solitamente come una forma di callback. Li useresti spesso per cose come eseguire calcoli in tempo reale durante la presentazione di tabelle di dati.
VHDL ha tipi fisici. Un letterale di questo tipo include sia un valore che un'unità. È possibile definire anche le sottounità. Ad esempio, un tipo fisico predefinito è time
:
type time is range <machine dependant> to <machine dependant>
units
fs;
ps = 1000 fs;
ns = 1000 ps;
us = 1000 ns;
Ms = 1000 us;
sec = 1000 ms;
min = 60 sec;
hr = 60 min;
end units;
Insieme all'overloading dell'operatore, puoi definire cose molto interessanti.
Clojure è interessante perché ha un meta-concetto di "astrazioni" che pervade la lingua. Esempi:
In una certa misura, le astrazioni prendono all'estremo il " principio di responsabilità singola ". Spetta a te comporli per ottenere la funzionalità che desideri, ma puoi essere estremamente flessibile su come incollarli insieme.
Ad esempio, se si desidera un sistema OOP basato su classi con ereditarietà, è possibile crearne uno in modo relativamente rapido.
In pratica, le astrazioni stesse sono progettate in modo tale che siano possibili più implementazioni, ad es. attraverso interfacce specifiche come clojure.lang.ISeq per sequenze o clojure.lang.IFn per funzioni di ordine superiore.
C'è un video interessante su questo argomento: The Art of Abstraction
Leggi altre domande sui tag programming-languages data-types type-systems language-features