Todos hemos visto enteros, coma flotante, cadenas y el tipo decimal ocasional. ¿Cuáles son algunos de los tipos más extraños, únicos o útiles que ha encontrado, útiles o no?
Todos hemos visto enteros, coma flotante, cadenas y el tipo decimal ocasional. ¿Cuáles son algunos de los tipos más extraños, únicos o útiles que ha encontrado, útiles o no?
Respuestas:
Seré corto:
Maybe a
en Haskell
Con esta construcción simple, el lenguaje resuelve el problema de los choques o NullPointerException
evita el "One Million Mistake" de Tony Hoare :)
Francamente, ¿se verifica una presencia opcional en tiempo de compilación? Es como un sueño ...
Option
nombre. Por qué no Optional
! Puede ser porque no soy un hablante nativo, pero Option
no me transmite el significado "opcional".
Maybe
nombre es lindo: "¿Qué tienes?" "Quizás un int". Sin embargo, lo más interesante es que es a la vez un functor y una mónada, lo que, en pocas palabras, significa que obtienes propagación nula de forma gratuita. Nunca necesita poner controles nulos dentro de las funciones o en el medio de su código; solo necesita verificarlo al final de su código, si es que lo hace.
Maybe
mónada para Ruby: lostechies.com/derickbailey/2010/10/10/the-maybe-monad-in-ruby
Soy perennemente aficionado void *
. Probablemente sea un síntoma de algo profundamente defectuoso en mí.
void *
y Pascal / Delphi tienen Pointer
.
Lua tiene una mesa integrada que es de lo más impresionante. Tiene una tabla hash incorporada y un vector, y con el uso de metatablas puede ser la base fundamental para la programación orientada a objetos en un lenguaje de procedimiento.
Cada índice de una tabla puede recibir cualquiera de las estructuras básicas del lenguaje (número, booleano, cadena, función-sí, las funciones son tipos en lua - y tablas).
Me sorprende que nadie haya mencionado las mónadas o los tipos de datos algebraicos todavía.
Lisp tiene dos tipos interesantes: t
y nil
. Lo interesante de ellos es que todo es un t
y nada es un nil
.
nil
un t
?
SNOBOL: patrón (esencialmente un árbol analizador LL (1), si no recuerdo mal).
Fortran tiene bloques comunes; Es uno de los tipos de datos menos comunes en los idiomas modernos o, más bien, una forma inusual de compartir datos de manera eficiente.
Fortran 95 tiene tipos de intervalos y aritmética de intervalos incorporada.
La lista no estaría completa sin los tipos monádicos encontrados en Haskell. Para entenderlos necesitas un poco de esfuerzo.
Delphi tiene conjuntos ( ver también ), que no creo que se implementen de la misma manera en otros idiomas.
Esto hace que almacenar atributos de variables múltiples en bases de datos sea muy sencillo: D
Supongo que es realmente extraño venir de la programación en una arquitectura clásica, pero ciertamente uno de los tipos más difíciles para mí al principio fue el registro cuántico , que aparece en QCL .
PL / SQL te permite declarar variables de tipo my_table.some_column%type
... Me parece muy útil.
Y C # le permite declarar objetos como anulables o no, aunque no estoy seguro de que cuente como un tipo.
cursor%rowtype
es aún más divertido: es un tipo de registro formado dinámicamente que refleja qué columnas devuelve la consulta del cursor.
Tuve un punto débil en mi corazón por los tipos de datos de Euphoria cuando era más joven
Está estructurado así:
Object
-> Atom
-> Sequence
Secuencia = Una secuencia de objetos
-- 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
Nota: "jon" es en realidad una forma abreviada de escribir la secuencia de valores ASCII. Por ejemplo "ABCDEFG"
es lo mismo que{65, 66, 67, 68, 69, 70, 71}
Felix tiene tipos de suma anónimos. El tipo se escribe como:
typedef il = int + long;
como sería en teoría. Los valores son feos:
case 0 of il (1)
case 1 of il (2L)
excepto quizás por una suma unitaria como 3 = 1 + 1 + 1
case 0 of 3
case 1 of 3
que desafortunadamente usa el conteo de origen cero para "compatibilidad C". Las sumas anónimas son necesarias para los tipos algebraicos estructuralmente tipificados, por ejemplo:
(1 + T * li) as li
es una lista (individualmente vinculada) de T. Todos los otros idiomas que conozco requieren sumas nominalmente escritas, donde se debe dar nombres tanto al tipo como a los constructores.
La taquigrafía 3 utilizada anteriormente es linda, la siguiente está en la biblioteca:
typedef void = 0;
typedef unit = 1;
typedef bool = 2;
y esta notación:
T ^ 3
es una matriz de longitud estática 3 .. el 3 no es un entero sino una suma de 3 unidades. Qué lástima + no es asociativo :)
q / kdb + tiene tablas integradas. Dado que es un lenguaje de programación y una base de datos orientada a columnas en uno, no hay necesidad de LINQ u ORM.
Por ejemplo, puede crear una tabla como esta (la asignación se distingue por :
más que =
en la mayoría de los idiomas):
people:([]name:`Joe`Amy`Sarah; age:17 15 18; GPA:3.5 3.8 3.33)
Ahora puedo mirar mi mesa:
q)show people
name age GPA
--------------
Joe 17 3.5
Amy 15 3.8
Sarah 18 3.33
Y puedo consultarlo:
q)select from people where GPA>3.4
name age GPA
------------
Joe 17 3.5
Amy 15 3.8
Encontré que las uniones en C ++ son 'extravagantes' cuando escuché por primera vez sobre ellas. Todavía no he llegado a un escenario en el que sean la opción obvia de implementar.
Todavía estoy tratando de entender en qué se convierte una función de parámetros múltiples en F # y otros lenguajes funcionales. Básicamente int f (Foo, Bar) se convierte en func f (Foo)
Esa es la función de dos parámetros que toma un Foo, y una barra y devuelve un int es realmente una función de un parámetro que toma un Foo y devuelve una función de un parámetro que toma una barra y devuelve un int. Pero de alguna manera puede llamarlo con dos parámetros si lo desea. Escribí una publicación al respecto aquí
f(Foo, Bar)
es lo mismo que una función f(Foo)
que devuelve otra función f'(Bar)
que devuelve el valor que f(Foo, Bar)
devolvería. Es decir, si arregla el argumento 'Foo', pero no 'Bar', tiene una función que no depende de 'Foo' pero que aún depende del argumento 'Bar'. Esto es típico para lenguajes funcionales; se llama 'curry'.
Son objetos extremadamente potentes pero compactos.
Los idiomas que los tienen incorporados tienen una gran capacidad para manipular texto (no escuchemos la palabra analizar, no son tan buenos).
Un puñado de idiomas en la familia funcional tiene una clase de tipos conocidos como Unity. La característica distintiva de los tipos de Unity es que no contienen información, son tipos de cero bits. Un tipo de unidad (en algunas variaciones) también es su único valor, o (en la mayoría de los otros) tiene solo un valor (que no es en sí mismo un tipo).
Sin embargo, son útiles porque son tipos distinguidos. Como no puede convertir implícitamente de un tipo de unidad a otro, puede hacer que la verificación de tipo estático funcione de una manera muy eficiente y expresiva.
La unidad también es la forma en que la mayoría de estos lenguajes describen Enums, al permitir que un nuevo tipo sea cualquiera de un conjunto definido de otros tipos, o para describir quizás tipos, valores que pueden ser un valor de un tipo típico (digamos, un entero) , o tiene un valor que representa sin valor.
Algunos lenguajes que no emplean la riqueza de los tipos de unidad definidos por el usuario todavía tienen unidad en ellos, de una forma u otra. Por ejemplo, Python tiene al menos tres tipos de unidad, NoneType
, NotImplementedType
, y EllipsisType
. Es interesante que los dos primeros significan algo así como "Sin valor", pero el tercero se usa en valores complejos (específicamente, expresiones de corte) para representar casos especiales interesantes.
Otros ejemplos interesantes de la unidad incluyen NULL
en SQL y undefined
JavaScript, pero no void
en C o C ++. void
falla Aunque describe un valor sin información, ningún valor real puede ser de tipo void
.
El symbol
tipo de Ruby es un poco inusual. Es esencialmente una cadena que implementa el patrón singleton. O algo. Hasta ahora, he encontrado que los mejores usos para los símbolos están en estados de seguimiento y nombres de funciones de paso.
COBOL Esencialmente, solo hay dos tipos de datos básicos, cadenas y números, pero debe especificar exactamente cómo se presentan en la memoria, por ejemplo PIC S9(5)V99 COMP-3
.
S
= con signo, 9(5)
= 5 dígitos, V
= punto decimal implícito, 99
= 2 dígitos más, COMP-3
= BCD + signo nybble.
Clipper tenía 'Bloques de código', que eran similares a los métodos anónimos. Podrían pasarse y evaluarse según sea necesario, generalmente como una forma de devolución de llamada. A menudo los usaba para cosas como realizar cálculos sobre la marcha al presentar tablas de datos.
VHDL tiene tipos físicos. Un literal de ese tipo incluye tanto un valor como una unidad. También puede definir subunidades. Por ejemplo, un tipo físico predefinido es 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;
Junto con la sobrecarga del operador, puede definir cosas muy interesantes.
Clojure es interesante porque tiene un metaconcepto de "abstracciones" que impregna el lenguaje. Ejemplos:
Hasta cierto punto, las abstracciones llevan al extremo el " principio de responsabilidad única ". Depende de usted componerlos para obtener la funcionalidad que desea, pero puede ser extremadamente flexible sobre cómo los une.
Por ejemplo, si desea un sistema OOP basado en clases con herencia, podría construir uno de estas abstracciones centrales con relativa rapidez.
En la práctica, las abstracciones en sí mismas están diseñadas de manera que son posibles implementaciones múltiples, por ejemplo, a través de interfaces específicas como clojure.lang.ISeq para secuencias o clojure.lang.IFn para funciones de orden superior.
Hay un video interesante sobre este tema: El arte de la abstracción
Googles Go tiene un tipo de "Canal" que es bastante único.