Interessante oder einzigartige Typen in Programmiersprachen? [geschlossen]


20

Wir haben alle Integer, Floating Point, String und den gelegentlichen Dezimaltyp gesehen. Was sind einige der merkwürdigsten oder einzigartigsten oder nützlichsten Typen, die Ihnen begegnet sind, nützlich oder nicht?


Hallo user10008, willkommen bei Programmers.SE! Haben Sie unsere FAQs gelesen ? Welche der sechs subjektiven Richtlinien erfüllt Ihrer Meinung nach Ihre Frage?

4
Möchte jemand den Eintrag für Lisp schreiben?
Mark C

Ich dachte, es wäre ein Betrug gewesen, aber nur, weil meine Antwort ein Betrug gewesen wäre, also poste ich einen Link und vielleicht findest du einige gute Antworten: programmers.stackexchange.com/questions/724/…
Peter Turner

@Mark: Ich habe es versucht, aber Typen sind wahrscheinlich eines der am wenigsten interessanten Dinge an Lisp.
Larry Coleman

@ LarryC Ich dachte, dies wäre die perfekte Frage für Lisp, da die Listen allgegenwärtig sind ! Die Listen bilden den Syntaxbaum und dies ermöglicht es Ihnen, Funktionen zu schreiben, die erstaunliche Dinge an Ihrem Code bewirken, wie ich erfahre. Ich lerne jetzt Racket (früher PLT-Schema ). Lisp ist die einzige Programmiersprache, die mich wirklich motiviert und interessiert hat zu lernen.
Mark C

Antworten:


18

Ich werde kurz sein:

Maybe a

in Haskell.

Mit diesem einfachen Konstrukt löst die Sprache das Problem der Abstürze oder NullPointerExceptionumgeht den "One Million Mistake" von Tony Hoare :)

Ehrlich gesagt, eine optionale Präsenz zur Kompilierungszeit überprüft? Es ist traumhaft ...


1
Oder Option, wie es in vielen anderen Programmiersprachen heißt.
Jonas

@Jonas: Ich muss zugeben, dass mir der OptionName nicht gefällt . Warum nicht Optional! Es kann sein, dass ich kein Muttersprachler bin Option, mir aber nicht die "optionale" Bedeutung vermittelt.
Matthieu M.

Der MaybeName ist süß: "Was hast du?" "Vielleicht ein Int". Das wirklich nette daran ist jedoch, dass es sowohl ein Funktor als auch eine Monade ist, was im Klartext bedeutet, dass Sie die Null-Propagierung kostenlos erhalten. Sie müssen niemals Null-Checks in Funktionen oder in die Mitte Ihres Codes setzen. Sie müssen es, wenn überhaupt, immer nur ganz am Ende Ihres Codes überprüfen.
Tikhon Jelvis


15

Ich bin immer gern void *. Es ist wahrscheinlich ein Symptom für etwas, das tief in mir steckt.


2
Ja. Ich fürchte, genau das ist es. :) Oh, +1 für "interessant" anstatt "einzigartig". Objective-C hat offensichtlich void *und Pascal / Delphi haben Pointer.
Frank Shearar

haha eher ein non-Typ, aber man kann nicht behaupten, dass es nicht mächtig ist
user10008 25.01.11

15
Ich liebe den Pessimismus, der darin zum Ausdruck kommt: "Kannst du das Ding dort drüben sehen?" "Ja, was ist das?", "Keine Ahnung."
biziclop

Ich fand es immer lustig, dass man keine Leere deklarieren kann, aber man kann die Adresse davon nehmen. Scheint mir das mit struct s {int A; nichtig B; int C; } dass die Adresse von B die Adresse des Risses zwischen A und C sein soll. Aber nein, nicht erlaubt.
Andy Canfield

Deshalb wird in Pascal "Zeiger" verwendet, um einen generischen Zeiger zu bezeichnen und nicht mit "Prozedur" zu verwechseln.
Umlcat

14

Lua hat einen eingebauten Tisch , der am eindrucksvollsten ist. Es verfügt über eine eingebaute Hashtabelle und einen Vektor und kann bei Verwendung von Metatabellen die grundlegende Basis für die objektorientierte Programmierung in einer prozeduralen Sprache sein.

Jeder Index einer Tabelle kann eine der grundlegenden Sprachstrukturen erhalten (Zahl, Boolescher Wert, Zeichenfolge, Funktion - Ja, Funktionen sind Typen in lua - und Tabellen).


Beachten Sie, dass Javascript auf sehr ähnliche Weise aufgebaut ist und Python auf derselben Grundlage aufgebaut ist, wie wahrscheinlich Ruby.
9000

Ich denke, das ist auch in Perl und PHP möglich, ja?
FrustratedWithFormsDesigner

Es gibt einen Unterschied zwischen den Tabellen in lua und den Hash-Containern in anderen Sprachen. Es gibt einen subtilen Implementierungsunterschied in der Art und Weise, wie lua Hash-Werte verteilt, wodurch die Tabellen auf eine Art und Weise funktionieren, die beinahe magisch ist. Ich programmiere hauptsächlich in Python und stelle gelegentlich fest, dass ich Annahmen verwende, die nicht zutreffen, basierend auf meinen Erwartungen an die Funktionsweise von Tabellen in lua. Ein spezielles Beispiel für diese Magie ist, dass Ganzzahlen sich selbst + 1 haschen. Dies bedeutet, dass Ganzzahlschlüssel dicht gepackt sind und dass +0,0 und -0,0 denselben Hash haben (sie sind gleich)
SingleNegationElimination


8

Lisp hat zwei interessante Typen: tund nil. Das Interessante an ihnen ist, dass alles a tund nichts a ist nil.


Sind Sie im Ernst? Ich wusste das nicht.
Mark C

Ist nilein t?
Jon Harrop


6

Fortran hat gemeinsame Blöcke; Dies ist einer der am seltensten vorkommenden Datentypen in modernen Sprachen oder eher eine ungewöhnliche Art, Daten effizient auszutauschen.

Fortran 95 verfügt über Intervalltypen und integrierte Intervallarithmetik.

Ohne die in Haskell vorkommenden monadischen Typen wäre die Liste nicht vollständig . Um sie zu verstehen, muss man sich ein wenig anstrengen.


Ah, UniData / UniVerse-DBs haben auch gemeinsame Blöcke in ihrer internen Sprache (UniBasic).
Dan McGrath

Ist ein gemeinsamer Block ein Codeblock, der von verschiedenen Programmteilen verwendet wird?
Mark C

1
@MarkC IIRC enthält im Grunde genommen globale Daten, aber jede Funktion, auf die zugegriffen wird, muss explizit angeben, dass sie ganz oben steht
jk.

5

Delphi hat Mengen ( siehe auch ), von denen ich glaube, dass sie in anderen Sprachen nicht auf die gleiche Weise implementiert sind.

Dadurch wird das Speichern von Attributen mit mehreren Variablen in Datenbanken zum Kinderspiel: D



3

Mit PL / SQL können Sie Variablen vom Typ deklarieren my_table.some_column%type... Das finde ich verdammt nützlich.

Mit C # können Sie Objekte als nullbar oder nicht deklarieren, obwohl ich nicht sicher bin, ob dies als Typ gilt.


4
Aber es cursor%rowtypeist noch lustiger: Es handelt sich um einen dynamisch geformten Datensatztyp, der angibt, welche Spalten die Cursorabfrage zurückgibt.
9000

.NET "Nullable" ist eigentlich ein (generischer) Typ für sich.
Konamiman

3

Als ich jünger war, hatte ich ein Faible für Euphorias Datentypen

Es ist wie folgt aufgebaut:

Object
-> Atom
-> Sequence
  • Atom = Ein einzelner numerischer Wert
  • Sequenz = Eine Sequenz von Objekten

    -- 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
    

    Siehe: Das Referenzhandbuch

Hinweis: "jon" ist eigentlich eine Kurzform zum Schreiben der Folge von ASCII-Werten. Zum Beispiel "ABCDEFG"ist das gleiche wie{65, 66, 67, 68, 69, 70, 71}


7
Dies fühlt sich an wie LISP ...
FrustratedWithFormsDesigner

Die tatsächlichen Datentypen sind das einzige Bit.
Dan McGrath

1
@FrustratedWithForms Dasselbe, dachte ich, "Hey, er sagte, 'Atom'! Das sieht aus wie (a) Lisp, aber mit unnötigen Teilern.: P
Mark C

3

Felix hat anonyme Summentypen. Der Typ ist wie folgt geschrieben:

typedef il = int + long;

wie es theoretisch sein würde. Die Werte sind hässlich:

case 0 of il (1)
case 1 of il (2L)

außer vielleicht für eine Einheitssumme wie 3 = 1 + 1 + 1

case 0 of 3
case 1 of 3 

die unglücklicherweise die Nullursprungszählung für "C-Kompatibilität" verwendet. Anonyme Summen sind für strukturell typisierte algebraische Typen erforderlich, zum Beispiel:

(1 + T * li) as li

ist eine (einfach verknüpfte) Liste von T. Alle anderen Sprachen, die ich kenne, benötigen nominell typisierte Summen, wobei sowohl der Typ selbst als auch die Konstruktoren benannt werden müssen.

Die oben verwendete Kurzschrift 3 ist niedlich, die folgende befindet sich in der Bibliothek:

typedef void = 0;
typedef unit = 1;
typedef bool = 2;

und diese Notation:

 T ^ 3

ist ein Array der statischen Länge 3. Die 3 ist keine ganze Zahl, sondern eine Summe von 3 Einheiten. Wie schade + ist nicht assoziativ :)


2

In q / kdb + sind Tabellen integriert. Da es sich um eine Programmiersprache und eine spaltenorientierte Datenbank handelt, sind weder LINQ noch ORMs erforderlich.

Zum Beispiel kann eine Tabelle wie diese erstellt werden (die Zuweisung unterscheidet sich :eher =von der in den meisten Sprachen):

people:([]name:`Joe`Amy`Sarah; age:17 15 18; GPA:3.5 3.8 3.33)

Jetzt kann ich auf meinen Tisch schauen:

q)show people
name  age GPA 
--------------
Joe   17  3.5 
Amy   15  3.8 
Sarah 18  3.33

Und ich kann es abfragen:

q)select from people where GPA>3.4
name age GPA
------------
Joe  17  3.5
Amy  15  3.8

2

Ich fand Gewerkschaften in C ++ 'schrullig', als ich zum ersten Mal von ihnen hörte. Ich habe noch kein Szenario getroffen, in dem sie die naheliegende Wahl für die Implementierung sind.


3
Gewerkschaften kamen von C. Ein gutes Beispiel ist die zval-Struktur in PHP.
Martin Wickman

2
Ich habe sie in einem Z80-Emulator verwendet, um einfach auf die 16-Bit-Register als ganze Register (HL, BC) und als 8-Bit-Register (H, L, B und C) zuzugreifen. Dies spiegelt wider, wie sie in Z80 asm verwendet werden. Auch in "variant", einer Klasse, die einen Wert verschiedener Typen enthalten kann (zum Beispiel int / float) - nicht sicher, warum ich keine Unterklassen verwendet habe, aber es hat zu der Zeit Sinn gemacht :)
ggambett 25.01.11

@ggambett: Ich habe genau dasselbe für meine Z80-Programme gemacht! Nur, dass ich auch ein Bitfeld hinzugefügt habe, um auf einzelne Flags im F-Register zuzugreifen.
Konamiman

2

Ich versuche immer noch, mir Gedanken darüber zu machen, was aus einer Multiparameter-Funktion in F # und anderen funktionalen Sprachen wird. Grundsätzlich int f (Foo, Bar) wird func f (Foo)

Dies ist die Zwei-Parameter-Funktion, die ein Foo und einen Takt und ein int zurückgibt. Dies ist eine Ein-Parameter-Funktion, die ein Foo und eine Ein-Parameter-Funktion zurückgibt, die einen Takt und ein int zurückgibt. Aber irgendwie kann man es mit zwei Parametern aufrufen, wenn man will. Ich habe hier einen Beitrag darüber geschrieben


8
Vielmehr ist eine Funktion f(Foo, Bar)dieselbe wie eine Funktion f(Foo), die eine andere Funktion f'(Bar)zurückgibt, die den Wert zurückgibt, der zurückgegeben werden f(Foo, Bar)würde. Das heißt, wenn Sie das Argument 'Foo' korrigieren, aber nicht 'Bar', haben Sie eine Funktion, die nicht von 'Foo' abhängt, aber immer noch vom Argument 'Bar' abhängt. Dies ist typisch für funktionale Sprachen. es heißt "currying".
9000

2

Reguläre Ausdrücke:

Sie sind extrem leistungsfähige und dennoch kompakte Objekte.
Sprachen, in denen sie eingebaut sind, können Text sehr gut manipulieren (lassen Sie uns das Wort nicht hören, wenn sie nicht so gut sind).


2
Es ist durchaus möglich, viele einfache Grammatiken mit regulären Ausdrücken zu analysieren. Zum Beispiel ist es relativ trivial, eine INI-Datei mit einem Minimum an Logik über einer Menge von Regexen zu analysieren. Der Fehler, den viele Leute machen, besteht darin, sehr komplexe Grammatiken damit zu analysieren (z. B. XML / HTML).
Matthew Scharley


@ Mark C: Die beste Antwort ist (mit einem Rekord von 4320 Stimmen). Sie können nicht
Martin York

Ja, das war für Humor. Es kam mir in den Sinn, als ich Matthews Kommentar las.
Mark C

2

Eine Handvoll Sprachen in der funktionalen Familie haben eine Klasse von Typen, die als Einheit bekannt sind. Das Unterscheidungsmerkmal von Unity-Typen besteht darin, dass sie keine Informationen enthalten und Null-Bit-Typen sind. Ein Einheitstyp (in einigen Variationen) ist auch sein einziger Wert oder (in den meisten anderen) hat nur einen Wert (der selbst kein Typ ist).

Diese sind jedoch nützlich, da es sich um unterschiedliche Typen handelt. Da Sie nicht implizit von einem Einheitstyp in einen anderen konvertieren können, können Sie die statische Typprüfung sehr effizient und aussagekräftig einsetzen.

Einheit ist auch die Art und Weise, wie solche Sprachen Enums beschreiben, indem sie einem neuen Typ erlauben, eine definierte Menge anderer Typen zu sein, oder vielleicht Typen zu beschreiben , Werte, die entweder ein Wert eines typischen Typs sein können (z. B. eine Ganzzahl). oder einen Wert haben, der keinen Wert darstellt.

Einige Sprachen, die nicht den Reichtum an benutzerdefinierten Einheitstypen verwenden, enthalten in der einen oder anderen Form immer noch eine Einheit. Zum Beispiel Python hat mindestens drei Einheitstypen NoneType, NotImplementedTypeund EllipsisType. Es ist interessant, dass die ersten beiden Werte so etwas wie "Kein Wert" bedeuten, aber der dritte Wert wird in komplexen Werten (insbesondere in Slice-Ausdrücken) verwendet, um interessante Sonderfälle darzustellen.

Weitere interessante Beispiele für Unity sind NULLSQL und undefinedJavascript, jedoch nicht voidC oder C ++. voidscheitert. Obwohl es einen Wert ohne Information beschreibt, kann kein tatsächlicher Wert vom Typ sein void.


Ich denke du meinst "Einheitentyp".
Jason Baker

2

Rubys symbolTyp ist etwas ungewöhnlich. Es ist im Wesentlichen eine Zeichenfolge, die das Singleton-Muster implementiert. Oder so. Bisher habe ich festgestellt, dass Symbole am besten in Verfolgungszuständen und beim Übergeben von Funktionsnamen verwendet werden.


Auch als Schlüssel zu einer Karte für den O (1) -Tastenvergleich.
Jeremy Heiler

Nun, das ist nicht wirklich ungewöhnlich. Ruby hat es von Smalltalk geerbt, das es von Lisp geerbt hat. Scala hat es auch, denke ich. Tatsächlich hat fast jede Sprachimplementierung (Compiler oder Interpreter) eine Symboltabelle, die Lisp, Smalltalk und Ruby nur dem Programmierer zur Verfügung stellen.
Jörg W Mittag

1

COBOL. Im Wesentlichen nur zwei grundlegende Datentypen, Zeichenfolgen und Zahlen, aber Sie müssen genau angeben , wie sie im Speicher angeordnet sind, z PIC S9(5)V99 COMP-3.


Das kann ich schlagen. BCPL hat einen Datentyp - Wort; siehe en.wikipedia.org/wiki/BCPL
Stephen C

Es gibt verschiedene Arten von Zahlen (COMP, COMP-1, COMP-2, COMP-3).
David Thornley

Das klingt schrecklich. Können Sie näher erläutern, was diese Details bedeuten?
Mark C

S= Vorzeichen , 9(5)= 5 Ziffern, V= impliziter Dezimalpunkt, 99= 2 weitere Ziffern, COMP-3= BCD + Vorzeichen-Nybble.
Dan04

1

Clipper hatte 'Codeblöcke', die anonymen Methoden ähnelten. Sie können bei Bedarf weitergegeben und ausgewertet werden, normalerweise als Rückruf. Sie werden häufig verwendet, um beispielsweise Berechnungen während der Präsentation von Datentabellen durchzuführen.


0

VHDL hat physikalische Typen. Ein solches Literal enthält sowohl einen Wert als auch eine Einheit. Sie können auch Untereinheiten definieren. Ein vordefinierter physikalischer Typ ist beispielsweise 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;

Zusammen mit der Überladung von Operatoren können Sie sehr interessante Dinge definieren.


0

Clojure ist interessant, weil es ein Meta-Konzept von "Abstraktionen" hat, die die Sprache durchziehen. Beispiele:

  • Sammlungen
  • Sequenzen (faul und nicht faul)
  • Funktionen höherer Ordnung
  • Multimethoden
  • Protokolle
  • Verwaltete Referenzen
  • Makros
  • verschiedene andere .....

In gewisser Weise heben die Abstraktionen das Prinzip der " Einzelverantwortung " auf das Äußerste. Es liegt an Ihnen, sie zusammenzustellen, um die gewünschte Funktionalität zu erhalten, aber Sie können äußerst flexibel sein, wie Sie sie zusammenkleben.

Wenn Sie beispielsweise ein klassenbasiertes OOP-System mit Vererbung möchten, können Sie relativ schnell eine dieser Kernabstraktionen erstellen.

In der Praxis sind die Abstraktionen selbst so konzipiert, dass mehrere Implementierungen möglich sind, z. B. über bestimmte Schnittstellen wie clojure.lang.ISeq für Sequenzen oder clojure.lang.IFn für Funktionen höherer Ordnung.

Zu diesem Thema gibt es ein interessantes Video: Die Kunst der Abstraktion


0

Wenn Sie eine Sprache mit einem eindeutigen Typ wünschen, gehen Sie zu BCPL . Diese Sprache hat nur einen Datentyp, das Wort, eine feste Anzahl von Bits für die Sprachimplementierung.


0

Googles Go hat einen "Channel" -Typ, der ziemlich einzigartig ist.


1
Kanäle sind nicht eindeutig. Viele Sprachen haben sie. Felix hatte sie 10 Jahre vor Google :) Ocaml hatte sie 10 Jahre vor Felix.
Yttrill

Und es gab mindestens eine andere Sprache, die Kanäle hatte, bevor es Ocaml gab. Immer noch einer der am wenigsten verfügbaren Typen in Programmiersprachen.
Brainlag
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.