programming languages - Acerca del valor de primera, segunda y tercera clase
programming-languages terminology (4)
El valor de primera clase puede ser
- pasado como un argumento
- regresado de una subrutina
- asignado a una variable.
El valor de segunda clase solo se puede pasar como un argumento.
El valor de tercera clase ni siquiera se puede pasar como un argumento.
¿Por qué deberían definirse así estas cosas? Según tengo entendido, "se puede pasar como un argumento" significa que se puede enviar a la pila de tiempo de ejecución; "se puede asignar a una variable" significa que se puede mover a una ubicación diferente de la memoria; "se puede devolver desde una subrutina" casi tiene el mismo significado de "se puede asignar a una variable" ya que el valor devuelto siempre se coloca en una dirección conocida, por lo que el valor de primera clase es totalmente "móvil" o "dinámico", segunda clase el valor es la mitad "móvil", y el valor de tercera clase es simplemente "estático", como las etiquetas en C / C ++, que solo pueden abordarse mediante la instrucción goto, y no puede hacer nada con esa dirección excepto "goto". ¿Comprender tiene sentido? ¿O qué significan exactamente estos tres tipos de valores?
- Primera clase: una construcción de primera clase es aquella que es un elemento intrínseco de un lenguaje. Las siguientes propiedades deben ser válidas.
- Debe formar parte de la sintaxis léxica del lenguaje.
- Puede tener operadores aplicados
- Debe ser referenciable (por ejemplo, almacenado en una variable)
- Segunda clase: una construcción de segunda clase es una que es un elemento intrínseco del lenguaje con las siguientes propiedades.
- Debe formar parte de la sintaxis léxica del lenguaje.
- Puede tener operadores aplicados
- Tercera clase: un constructo de tercera clase es uno que forma parte de la sintaxis de un lenguaje.
en Roger Keays y Andry Rakotonirainy. Programación orientada al contexto. En Procesos del 3er Taller Internacional ACM sobre Ingeniería de Datos para Acceso Inalámbrico y Móvil, MobiDe ''03, páginas 9–16, Nueva York, NY, EE. UU., 2003. ACM.
Algo es de primera clase si es explícitamente manipulable en el código. En otras palabras, algo es de primera clase si se puede manipular mediante programación en tiempo de ejecución.
Esto se relaciona estrechamente con la meta-programación en el sentido de que lo que describe en el código (en el momento del desarrollo) es un meta-nivel, y lo que existe en el tiempo de ejecución es otro meta-nivel. Pero la barrera entre estos dos niveles meta se puede difuminar, por ejemplo, con la reflexión. Cuando algo se reifica en tiempo de ejecución, se vuelve explícitamente manipulable.
Hablamos de objetos de primera clase, porque los objetos se pueden manipular mediante programación en tiempo de ejecución (ese es el propósito).
En java, tienes clases , pero no son de primera clase, porque el código normalmente no puede manipular una clase a menos que uses la reflexión. Pero en Smalltalk, las clases son de primera clase: el código puede manipular una clase como un objeto regular.
En java, tienes paquetes (módulos) , pero no son de primera clase, porque el código no manipula el paquete en tiempo de ejecución. Pero en NewSpeak, los paquetes (módulos) son de primera clase, puede crear una instancia de un módulo y pasarlo a otro módulo para especificar la modularidad en tiempo de ejecución.
En C #, tiene cierres que son funciones de primera clase. Existen y se pueden manipular en tiempo de ejecución mediante programación. Tales cosas no existen (todavía) en java.
Para mí, el límite de primera clase / no de primera clase no es exactamente estricto. A veces es difícil pronunciar algunas construcciones de lenguaje, por ejemplo, los tipos primitivos de Java. Podríamos decir que no es de primera clase porque no es un objeto y no se puede manipular a través de una referencia que se puede transmitir, pero el valor primitivo todavía existe y se puede manipular en tiempo de ejecución.
PD: Estoy de acuerdo con Norman Ramsey y el valor de 2da clase y 3ra clase no tiene sentido para mí.
Esos términos son muy amplios y no están bien definidos globalmente, pero aquí están las definiciones más lógicas para ellos:
Los valores de primera clase son aquellos que tienen valores reales y tangibles, por lo que pueden operarse y circular, como variables, argumentos, valores de retorno o lo que sea.
Esto realmente no necesita un ejemplo completo, ¿verdad? En C, un int es de primera clase.
Los valores de segunda clase son más limitados. Tienen valores, pero no pueden usarse directamente, por lo que el compilador limita deliberadamente lo que puede hacer con ellos. Puede hacer referencia a ellos, por lo que aún puede tener un valor de primera clase que los represente.
Por ejemplo, en C, una función es un valor de segunda clase. No puede ser alterado, pero puede ser llamado y referenciado.
Los valores de tercera clase son aún más limitados. No solo no tienen valores, sino que la interacción está completamente ausente y, a menudo, solo existe para ser utilizada como atributos de tiempo de compilación.
Por ejemplo, en Rust, una vida útil es un valor de tercera clase. No puedes usar la vida en absoluto. Solo puede recibirlo como un parámetro de plantilla, solo puede usarlo como un parámetro de plantilla ( solo al crear una nueva variable), y eso es todo lo que puede hacer con él.
Otro ejemplo, en C ++, una estructura o una clase es un valor de tercera clase. Esto no necesita mucha explicación.
Oh no, puede que tenga que ir a editar Wikipedia otra vez.
En realidad, solo hay dos distinciones que vale la pena hacer: de primera clase y no de primera clase. Si Michael Scott habla de una tercera clase, estaré muy deprimido.
Ok, entonces, ¿qué es "de primera clase"? Bueno, es un término que apenas tiene un significado técnico . El significado, cuando está presente, suele ser comparativo y se aplica a una cosa en un lenguaje (estoy siendo deliberadamente vago aquí) que tiene más privilegios que una cosa comparable. Eso es todo lo que la gente quiere decir con eso.
Veamos algunos ejemplos:
Los punteros de función en C son valores de primera clase porque pueden pasarse a funciones, devolverse desde funciones y almacenarse en estructuras de datos asignadas en heap como cualquier otro valor. Las funciones en Pascal y Ada no son valores de primera clase porque, aunque pueden pasarse como argumentos, no pueden devolverse como resultados o almacenarse en estructuras de datos asignadas en el montón.
Los tipos Struct son tipos de segunda clase en C, porque no hay expresiones literales de tipo struct. (Desde C99 hay inicializadores literales con campos con nombre, pero esto no es tan general como tener un literal en cualquier lugar donde se puede usar una expresión).
Los valores polimórficos son valores de segunda clase en ML porque aunque pueden estar vinculados a nombres, no pueden estar vinculados a lambda. Por lo tanto, no pueden ser pasados como argumentos. Pero en Haskell, debido a que Haskell admite el polimorfismo de rango superior, los valores polimórficos son de primera clase. (¡Incluso se pueden almacenar en estructuras de datos!)
En Java, el tipo
int
es de segunda clase porque no se puede heredar de él. TipoInteger
es de primera clase.En C, las etiquetas son de segunda clase, porque no tienen valores y no se puede calcular con ellas. En FORTRAN, los números de línea tienen valores y también lo son la primera clase. Hay una extensión de GNU a C que le permite definir etiquetas de primera clase, y es muy útil. ¿Qué significa primera clase en este caso? Significa que las etiquetas tienen valores, se pueden almacenar en estructuras de datos y se pueden usar en
goto
. Pero esos valores son de segunda clase en otro sentido, porque una etiqueta de un procedimiento no puede usarse de manera significativa en ungoto
que pertenece a otro procedimiento.
¿Nos estamos dando una idea de lo inútil que es esta terminología?
Espero que estos ejemplos los convencan de que la idea de "primera clase" no es una idea muy útil para pensar en los lenguajes de programación en general. Cuando se habla de una característica particular de un idioma o una familia de idiomas en particular, puede ser una abreviatura útil ("un lenguaje no es funcional a menos que tenga funciones anidadas de primera clase") pero en general es mejor Deje de decir exactamente lo que quiere decir en lugar de hablar de cosas de "primera clase" o "no de primera clase".
En cuanto a la "tercera clase", solo di que no.