Tipi interessanti o unici nei linguaggi di programmazione? [chiuso]


20

Abbiamo visto tutti numeri interi, virgola mobile, stringa e il tipo decimale occasionale. Quali sono alcuni dei tipi più strani o unici o utili che hai incontrato, utili o no?


Ciao user10008, benvenuto in Programmers.SE! Hai controllato le nostre FAQ ? Quale delle sei linee guida soggettive ritieni che la tua domanda soddisfi?

4
Qualcuno vorrebbe scrivere la voce per Lisp?
Segna C

Ho pensato che potesse essere un duplicato, ma solo perché la mia risposta sarebbe stata un ingannevole, quindi posterò un link e forse troverai delle buone risposte: programmers.stackexchange.com/questions/724/…
Peter Turner,

@Mark: ci ho provato, ma i tipi sono probabilmente una delle cose meno interessanti di Lisp.
Larry Coleman,

@LarryC Ho pensato che questa fosse la domanda perfetta per Lisp a causa dell'uso onnicomprensivo delle liste ! Le liste formano l'albero della sintassi e questo ti permette di scrivere funzioni che fanno cose sorprendenti nel tuo codice, mi pare. Sto imparando Racket (precedentemente PLT Scheme ) ora. Lisp è l'unico linguaggio di programmazione che sono stato veramente motivato e interessato a imparare.
Mark C

Risposte:


18

Sarò basso:

Maybe a

a Haskell.

Con questo semplice costrutto, il linguaggio risolve il problema degli arresti anomali o NullPointerException, elude ordinatamente il "One Million Mistake" di Tony Hoare :)

Francamente, una presenza opzionale controllata al momento della compilazione? È da sogno ...


1
O Opzione come viene chiamata in molti altri linguaggi di programmazione.
Jonas,

@Jonas: devo ammettere che non mi piace il Optionnome. Perché no Optional! Forse perché non sono madrelingua, ma Optionnon mi trasmette il significato "facoltativo".
Matthieu M.,

Il Maybenome è carino: "Che cosa hai?" "Forse un Int". Tuttavia, il bit davvero pulito è che è sia un funzione che una monade che, in parole povere, significa che si ottiene gratuitamente la propagazione nulla. Non è mai necessario inserire controlli nulli all'interno delle funzioni o nel mezzo del codice; devi solo verificarlo alla fine del tuo codice, se non del tutto.
Tikhon Jelvis,


15

Sono perennemente affezionato void *. Probabilmente è un sintomo di qualcosa di profondamente imperfetto in me.


2
Sì. Temo che sia esattamente quello che è. :) Oh, +1 per "interessante" piuttosto che "unico". Ovviamente Objective-C ha void *e Pascal / Delphi hanno Pointer.
Frank Shearar, il

haha più di un non tipo, ma non si può sostenere che non sia potente
user10008

15
Adoro il pessimismo intrinseco che esprime: "Riesci a vedere quella cosa laggiù?" "Sì, che cos'è?", "Nessuna idea."
biziclop,

Ho sempre pensato che fosse divertente non poter dichiarare un vuoto, ma puoi prenderne l'indirizzo. Mi sembra che con struct s {int A; vuoto B; int C; } che l'indirizzo di B dovrebbe essere l'indirizzo del crack tra A e C. Ma no, non è permesso.
Andy Canfield,

Ecco perché in Pascal il "puntatore" viene utilizzato per indicare un puntatore generico e non confondere con la "procedura".
umlcat,

14

Lua ha un tavolo integrato che è davvero impressionante. Ha un hashtable incorporato e un vettore, e con l'uso di metatable può essere la base fondamentale per la programmazione orientata agli oggetti in un linguaggio procedurale.

Ogni indice di una tabella può ricevere una qualsiasi delle strutture linguistiche di base (numero, valore booleano, stringa, funzione-sì, funzioni sono tipi su lua - e tabelle).


Nota come Javascript è costruito in un modo molto simile e Python è costruito sulla stessa base, come probabilmente è Ruby.
9000

Penso che questo sia possibile anche in Perl e PHP, sì?
FrustratedWithFormsDesigner

C'è una differenza tra le tabelle in lua e i contenitori di hash in altre lingue. C'è una sottile differenza di implementazione nel modo in cui lua distribuisce i valori di hash che fa funzionare le sue tabelle in modi quasi magici. Principalmente programma in Python e, a volte, trovo che sto usando ipotesi che non valgono, in base alle mie aspettative sul modo in cui le tabelle funzionano in Lua. Un esempio specifico di questa magia è che gli hash degli interi a se stessi + 1. Ciò significa che le chiavi degli interi sono impacchettate densamente e che +0.0 e -0.0 hanno lo stesso hash (sono uguali)
SingleNegationElimination

9

Sono sorpreso che nessuno abbia ancora menzionato Monade o Tipi di dati algebrici.


Potrebbero mostrarci degli esempi :)
nawfal,


6

SNOBOL: modello (essenzialmente un albero parser LL (1), se lo ricordo correttamente).


6

Fortran ha blocchi comuni; è uno dei tipi di dati meno comuni nei linguaggi moderni o, piuttosto, un modo insolito per condividere i dati in modo efficiente.

Fortran 95 ha tipi di intervallo e aritmetica di intervallo incorporata.

L'elenco non sarebbe completo senza i tipi monadici trovati in Haskell. Per capirli hai bisogno di un po 'di sforzo.


Ah, anche i DB UniData / UniVerse hanno blocchi comuni nel loro linguaggio interno (UniBasic).
Dan McGrath il

Un blocco comune è un blocco di codice utilizzato da diverse parti del programma?
Mark C

1
@MarkC IIRC sono i suoi dati sostanzialmente globali, ma ogni funzione a cui accede deve dire esplicitamente che andrà in cima
jk.

5

Delphi ha set ( vedi anche ), che non credo siano implementati allo stesso modo in altre lingue.

Questo rende un gioco da ragazzi la memorizzazione di attributi multi-variabile nei database: D


4

Suppongo che sia davvero strano venire dalla programmazione su un'architettura classica, ma certamente uno dei tipi più difficili per me da cui mi sono girato la testa all'inizio era il registro quantico , che compare in QCL .


3

PL / SQL ti permette di dichiarare variabili di tipo my_table.some_column%type... Trovo che sia dannatamente utile.

E C # ti consente di dichiarare gli oggetti come nullable o no, anche se non sono sicuro che conti come un tipo.


4
Ma cursor%rowtypeè ancora più divertente: è un tipo di record formato dinamicamente che riflette quali colonne restituisce la query del cursore.
9000

.NET "Nullable" è in realtà un tipo (generico) in sé.
Konamiman,

3

Avevo un debole nel mio cuore per i tipi di dati di Euphoria quando ero più giovane

È strutturato in questo modo:

Object
-> Atom
-> Sequence
  • Atom = Un singolo valore numerico
  • 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: Il manuale di riferimento

Nota: "jon" è in realtà un modo breve di scrivere la sequenza di valori ASCII. Ad esempio "ABCDEFG"è lo stesso di{65, 66, 67, 68, 69, 70, 71}


7
Sembra LISP ...
FrustratedWithFormsDesigner

I tipi di dati effettivi sono l'unico bit.
Dan McGrath,

1
@FrustratedWithForms Lo stesso, ho pensato, "Ehi, ha detto, 'Atom'! Questo sembra (a) Lisp ma con divisori inutili.: P
Mark C

3

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 sfortunatamente usa il conteggio delle origini zero per la "compatibilità C". Somme anonime sono necessarie per tipi algebrici strutturalmente tipizzati, ad esempio:

(1 + T * li) as li

è un elenco (singolarmente collegato) di T. Tutte le altre lingue che conosco delle somme richieste tipicamente nominate, in cui sia il tipo stesso che i costruttori devono avere nomi.

La scorciatoia 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 :)


2

q / kdb + ha tabelle integrate. Poiché è un linguaggio di programmazione e un database orientato alle colonne in uno, non è necessario LINQ o ORM.

Ad esempio, è possibile creare una tabella come questa (l'assegnazione viene ignorata :anziché =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

2

Ho scoperto che il sindacato in C ++ era "eccentrico" quando ne ho sentito parlare per la prima volta. Non ho ancora colpito uno scenario in cui sono la scelta ovvia da implementare.


3
I sindacati provengono da C. Un buon esempio è la struttura zval in php.
Martin Wickman,

2
Li ho usati in un emulatore Z80, per accedere facilmente ai registri a 16 bit come registri interi (HL, BC) e come registri a 8 bit (H, L, B e C). Ciò riflette il modo in cui vengono utilizzati in Z80 asm. Anche in "varianti", una classe che può contenere un valore di diversi tipi (ad esempio int / float) - non so perché non ho usato le sottoclassi, ma in quel momento aveva senso :)
ggambett

@ggambett: ho fatto esattamente lo stesso per i miei programmi Z80! Solo che ho anche aggiunto un bitfield per accedere ai singoli flag nel registro F.
Konamiman,

2

Sto ancora cercando di capire cosa diventa 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 accetta un Foo e una barra e restituisce un int è in realtà una funzione a un parametro che accetta un Foo e restituisce una funzione a 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 al riguardo qui


8
Piuttosto, una funzione f(Foo, Bar)è uguale alla funzione f(Foo)che restituisce un'altra funzione f'(Bar)che restituisce il valore che f(Foo, Bar)sarebbe restituito. Cioè, se si corregge l'argomento "Foo", ma non "Bar", si ha una funzione che non dipende da "Foo" ma dipende comunque dall'argomento "Bar". Questo è tipico per i linguaggi funzionali; si chiama "curry".
9000

2

Espressioni regolari:

Sono oggetti estremamente potenti ma compatti.
Le lingue che li hanno integrati hanno una grande capacità di manipolare il testo (non sentiamo la parola analizzare che non sono così buone).


2
È del tutto possibile analizzare molte semplici grammatiche con regex. Ad esempio, è relativamente banale analizzare un file ini con un minimo di logica sopra una serie di regex. L'errore che molte persone fanno è cercare di analizzare grammatiche molto complesse (ad es. XML / HTML).
Matthew Scharley,


@Mark C: la risposta migliore è (con un record di 4320 voti in più). Non puoi
Martin York il

Sì, quello era per l'umorismo. Mi è venuto in mente quando ho letto il commento di Matthew.
Mark C

2

Una manciata di lingue nella famiglia funzionale ha una classe di tipi noti come Unity. La caratteristica distintiva dei tipi di 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 è esso stesso un tipo).

Questi sono utili, tuttavia, perché sono tipi distinti. Dal momento che non è possibile convertire implicitamente da un tipo di unità a un altro, è possibile eseguire il controllo del tipo statico in modo molto efficiente ed espressivo.

L'unità è anche il modo in cui la maggior parte di tali linguaggi descrive Enum, consentendo a un nuovo tipo di appartenere a un insieme definito di altri tipi o di descrivere forse tipi, valori che possono essere sia un valore di un tipo tipico (diciamo, un numero intero) o hanno un valore che rappresenta nessun valore.

Alcune lingue che non impiegano la ricchezza di tipi di unità definiti dall'utente hanno ancora unità in loro, in un modo o nell'altro. Per esempio, Python ha almeno tre tipi di unità, NoneType, NotImplementedType, e EllipsisType. È interessante notare che i primi due significano entrambi qualcosa come "Nessun valore", ma il terzo viene utilizzato in valori complessi (in particolare, espressioni di sezione) per rappresentare casi speciali interessanti.

Altri esempi interessanti di unità includono NULLin sql e undefinedin javascript, ma non voidin C o C ++. voidnon riesce. Anche se descrive un valore senza informazioni, ma nessun valore effettivo può essere di tipo void.


Penso che intendi "tipo di unità".
Jason Baker,

2

Il symboltipo di Ruby è un po 'insolito. È essenzialmente una stringa che implementa il modello singleton. O qualcosa. Finora, ho scoperto che gli usi migliori per i simboli sono negli stati di tracciamento e nel passaggio dei nomi delle funzioni.


Anche come chiavi di una mappa per il confronto delle chiavi O (1).
Jeremy Heiler,

Beh, non è poi così insolito. Ruby lo ereditò da Smalltalk, che lo ereditò da Lisp. Anche Scala ha, credo. In effetti, quasi tutte le implementazioni linguistiche (compilatore o interprete) hanno internamente una tabella dei simboli, Lisp, Smalltalk e Ruby la espongono al programmatore.
Jörg W Mittag,

1

COBOL. Essenzialmente solo due tipi di dati, stringhe e numeri di base, ma devi specificare esattamente come sono disposti in memoria, ad es PIC S9(5)V99 COMP-3.


Posso batterlo. BCPL ha un tipo di dati: word; vedi en.wikipedia.org/wiki/BCPL
Stephen C

Esistono diversi tipi di numeri (COMP, COMP-1, COMP-2, COMP-3).
David Thornley,

È terribile. Puoi approfondire cosa significano quei dettagli?
Marco C,

S= firmato, 9(5)= 5 cifre, V= punto decimale implicito, 99= 2 cifre in più, COMP-3= BCD + segno nybble.
dan04,

1

Clipper aveva "Code Blocks", che erano simili ai metodi anonimi. Potrebbero essere passati in giro e valutati secondo necessità, di solito come una forma di callback. Li useresti spesso per cose come eseguire calcoli al volo quando presenti tabelle di dati.


0

VHDL ha tipi fisici. Un letterale di questo tipo include sia un valore che un'unità. Puoi anche definire subunità. 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 al sovraccarico dell'operatore, è possibile definire cose molto interessanti.


0

Clojure è interessante perché ha un meta-concetto di "astrazioni" che pervadono il linguaggio. Esempi:

  • collezioni
  • Sequenze (pigro e non pigro)
  • Funzioni di ordine superiore
  • multimethods
  • protocolli
  • Riferimenti gestiti
  • Macro
  • vari altri .....

In una certa misura, le astrazioni portano il " principio della responsabilità singola " all'estremo. Sta 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 da queste astrazioni di base in modo relativamente rapido.

In pratica, le astrazioni stesse sono progettate in modo tale che siano possibili molteplici implementazioni, ad esempio 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


0

Se vuoi una lingua con un tipo univoco, vai a BCPL . Questo linguaggio ha solo un tipo di dati, la parola, essendo un numero fisso di bit per l'implementazione del linguaggio.


0

Googles Go ha un tipo di "canale" che è piuttosto unico.


1
I canali non sono unici. Molte lingue li hanno. Felix li aveva 10 anni prima dell'esistenza di Google :) Ocaml li aveva 10 anni prima dell'esistenza di Felix.
Yttrill

E c'era almeno un'altra lingua che aveva canali prima che esistesse Ocaml. È ancora uno dei tipi meno disponibili nei linguaggi di programmazione.
Brainlag,
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.