29 Stimmen

Über erstklassigen, zweitklassigen und drittklassigen Wert

Erstklassiger Wert kann sein

  1. als Argument übergeben werden
  2. aufgerufen von einer Unterfunktion zurückgegeben werden
  3. in eine Variable zugewiesen werden.

Zweitklassiger Wert kann nur als Argument übergeben werden.

Drittklassiger Wert kann nicht einmal als Argument übergeben werden.

Warum sollten diese Dinge so definiert sein? So wie ich es verstehe, bedeutet "als Argument übergeben werden", dass es in den Laufzeitspeicher geschoben werden kann; "in eine Variable zugewiesen werden" bedeutet, dass es an einen anderen Speicherort verschoben werden kann; "von einer Unterfunktion zurückgegeben werden" hat fast die gleiche Bedeutung wie "in eine Variable zugewiesen werden", da der zurückgegebene Wert immer an eine bekannte Adresse gelegt wird. Erstklassiger Wert ist also völlig "beweglich" oder "dynamisch", zweitklassiger Wert ist halb "beweglich" und drittklassiger Wert ist einfach "statisch", wie beispielsweise Labels in C/C++, die nur durch goto-Anweisungen angesprochen werden können, und mit dieser Adresse kann man nichts weiter machen außer "goto". Ergibt mein Verständnis irgendwie Sinn? Oder was bedeuten diese drei Arten von Werten genau?

54voto

Norman Ramsey Punkte 193087

Oh nein, ich muss vielleicht wieder Wikipedia bearbeiten.

Es gibt wirklich nur zwei Unterscheidungen, die es wert sind: erstklassig und nicht erstklassig. Wenn Michael Scott über eine dritte-Klasse irgendetwas spricht, werde ich sehr deprimiert sein.

Also, was bedeutet "erstklassig" überhaupt? Nun, es ist ein Begriff, der kaum eine technische Bedeutung hat. Die Bedeutung, wenn vorhanden, ist normalerweise vergleichend, und er bezieht sich auf eine Sache in einer Sprache (ich bin hier bewusst vage), die mehr Privilegien hat als eine vergleichbare Sache. Das ist alles, was die Leute damit meinen.

Lassen Sie uns einige Beispiele ansehen:

  • Funktionszeiger in C sind Werte erster Klasse, weil sie an Funktionen übergeben, von Funktionen zurückgegeben und in heap-allokierten Datenstrukturen gespeichert werden können wie jeder andere Wert. Funktionen in Pascal und Ada sind keine Werte erster Klasse, weil sie zwar als Argumente übergeben werden können, aber nicht als Ergebnisse zurückgegeben oder in heap-allokierten Datenstrukturen gespeichert werden können.

  • Struct-Typen sind Typen zweiter Klasse in C, weil es keine Literalausdrücke des Strukturtyps gibt. (Seit C99 gibt es Literalliteratoren mit benannten Feldern, aber dies ist immer noch nicht so allgemein wie ein Literal überall dort, wo Sie einen Ausdruck verwenden können.)

  • Polymorphe Werte sind Werte zweiter Klasse in ML, weil sie zwar an Namen gebunden werden können, aber nicht lambda-gebunden werden können. Daher können sie nicht als Argumente übergeben werden. Aber in Haskell, weil Haskell Polymorphie höherer Ordnung unterstützt, sind polymorphe Werte erstklassig. (Sie können sogar in Datenstrukturen gespeichert werden!)

  • In Java ist der Typ int zweiter Klasse, weil Sie nicht davon erben können. Der Typ Integer ist erstklassig.

  • In C sind Labels zweiter Klasse, weil sie keine Werte haben und Sie nicht mit ihnen rechnen können. In FORTRAN haben Zeilennummern Werte und sind daher erstklassig. Es gibt eine GNU-Erweiterung für C, die es ermöglicht, erstklassige Labels zu definieren, und sie ist sehr nützlich. Was bedeutet erstklassig in diesem Fall? Es bedeutet, dass die Labels Werte haben, in Datenstrukturen gespeichert werden können und in goto verwendet werden können. Aber diese Werte sind in einem anderen Sinne zweiter Klasse, weil ein Label aus einem Verfahren nicht sinnvoll in einem goto verwendet werden kann, das zu einem anderen Verfahren gehört.

Bekommen wir eine Vorstellung davon, wie nutzlos diese Terminologie ist?

Ich hoffe, diese Beispiele überzeugen Sie davon, dass die Idee von "erstklassig" keine sehr nützliche Idee ist, um darüber nachzudenken, wie Programmiersprachen insgesamt funktionieren. Wenn Sie über ein bestimmtes Merkmal einer bestimmten Sprache oder Sprachfamilie sprechen, kann es ein nützliches Schlagwort sein ("eine Sprache ist nicht funktional, es sei denn, sie hat erstklassige, verschachtelte Funktionen"), aber im Allgemeinen ist es besser, einfach zu sagen, was Sie meinen, anstatt über "erstklassige" oder "nicht erstklassige" Dinge zu sprechen.

Was "drittklassig" betrifft, sagen Sie einfach nein.

4voto

ewernli Punkte 37122

Etwas ist erstklassig, wenn es im Code explizit manipulierbar ist. Mit anderen Worten, etwas ist erstklassig, wenn es zur Laufzeit programmgesteuert manipuliert werden kann.

Dies steht in enger Beziehung zur Metaprogrammierung, in dem Sinne, dass das, was Sie im Code beschreiben (zur Entwicklungszeit), eine Metaebene ist, und was zur Laufzeit existiert, eine andere Metaebene ist. Aber die Barriere zwischen diesen beiden Metaebenen kann verschwimmen, zum Beispiel mit Reflexion. Wenn etwas zur Laufzeit verkörpert wird, wird es explizit manipulierbar.

  • Wir sprechen von einem erstklassigen Objekt, weil Objekte programmgesteuert zur Laufzeit manipuliert werden können (das ist der eigentliche Zweck).

  • In Java haben Sie Klassen, aber sie sind nicht erstklassig, weil der Code normalerweise keine Klasse manipulieren kann, es sei denn, Sie verwenden Reflexion. Aber in Smalltalk sind Klassen erstklassig: Der Code kann eine Klasse wie ein reguläres Objekt manipulieren.

  • In Java haben Sie Pakete (Module), aber sie sind nicht erstklassig, weil der Code Pakete nicht zur Laufzeit manipuliert. Aber in NewSpeak sind Pakete (Module) erstklassig, Sie können ein Modul instanziieren und es einem anderen Modul übergeben, um die Modularität zur Laufzeit festzulegen.

  • In C# haben Sie Closures, die erstklassige Funktionen sind. Sie existieren und können programmgesteuert zur Laufzeit manipuliert werden. Solche Dinge existieren (noch) nicht in Java.

Für mich ist die Grenze zwischen erstklassig/nicht erstklassig nicht genau festgelegt. Es ist manchmal schwer zu sagen für bestimmte Sprachkonstrukte, z.B. Java-Primitivtypen. Wir könnten sagen, es ist nicht erstklassig, weil es kein Objekt ist und nicht durch eine referenz manipulierbar ist, die übergeben werden kann, aber der primitive Wert existiert immer noch und kann zur Laufzeit manipuliert werden.

PS: Ich stimme Norman Ramsey zu und 2-Klasse und 3-Klasse Wert machen für mich keinen Sinn.

3voto

Leonardo Marques Punkte 3491
  1. Erstklassig: Ein erstklassiges Konstrukt ist ein intrinsischer Bestandteil einer Sprache. Die folgenden Eigenschaften müssen zutreffen.
    • Es muss Teil der lexikalischen Syntax der Sprache sein
    • Es dürfen Operatoren darauf angewendet werden
    • Es muss referenzierbar sein (zum Beispiel in einer Variablen gespeichert)
  2. Zweitklassig: Ein zweitklassiges Konstrukt ist ein intrinsischer Bestandteil der Sprache mit den folgenden Eigenschaften.
    • Es muss Teil der lexikalischen Syntax der Sprache sein
    • Es dürfen Operatoren darauf angewendet werden
  3. Drittklassig: Ein drittklassiges Konstrukt ist ein Bestandteil der Syntax einer Sprache.

in Roger Keays und Andry Rakotonirainy. Kontextorientierte Programmierung. In den Proceedings des 3. ACM International Workshop on Data Engineering for Wireless and Mobile Access, MobiDe '03, Seiten 9-16, New York, NY, USA, 2003. ACM.

1voto

jv110 Punkte 348

Diese Begriffe sind sehr weit gefasst und nicht wirklich global wohldefiniert, aber hier sind die logischsten Definitionen für sie:

Erstklassige Werte sind diejenigen, die tatsächliche, greifbare Werte haben und somit als Variablen, Argumente, Rückgabewerte oder Ähnliches verwendet werden können.

Dies benötigt wirklich kein ausführliches Beispiel, oder? In C ist ein int erstklassig.

Zweitklassige Werte sind eingeschränkter. Sie haben Werte, können jedoch nicht direkt verwendet werden, sodass der Compiler bewusst einschränkt, was Sie damit tun können. Sie können auf sie verweisen, sodass Sie weiterhin einen erstklassigen Wert haben, der sie repräsentiert.

Zum Beispiel ist in C eine Funktion ein zweitklassiger Wert. Sie kann nicht verändert werden, kann jedoch aufgerufen und referenziert werden.

Drittklassige Werte sind noch weiter eingeschränkt. Sie haben nicht nur keine Werte, sondern die Interaktion ist vollständig abwesend und besteht oft nur darin, als Kompilierzeitattribute verwendet zu werden.

Zum Beispiel ist in Rust eine Lebensdauer ein drittklassiger Wert. Sie können die Lebensdauer überhaupt nicht verwenden. Sie können sie nur als Vorlagenparameter erhalten, Sie können sie nur als Vorlagenparameter verwenden (nur beim Erstellen einer neuen Variable), und das ist alles, was Sie damit tun können.

Ein weiteres Beispiel: In C++ sind eine Struktur oder eine Klasse ein drittklassiger Wert. Das bedarf keiner ausführlichen Erklärung.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X