¿Tipos interesantes o únicos en lenguajes de programación? [cerrado]


20

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?


Hola user10008, bienvenido a Programmers.SE! ¿Has revisado nuestras preguntas frecuentes ? ¿Cuál de las seis pautas subjetivas crees que cumple tu pregunta?

44
¿Alguien quiere escribir la entrada para Lisp?
Mark C

Pensé que podría haber sido un engaño, pero solo porque mi respuesta hubiera sido un engaño, así que publicaré un enlace y tal vez encuentres algunas buenas respuestas: programmers.stackexchange.com/questions/724/…
Peter Turner

@ Mark: Lo intenté, pero los tipos son probablemente una de las cosas menos interesantes de Lisp.
Larry Coleman el

@LarryC ¡Pensé que esta era la pregunta perfecta para Lisp debido al uso generalizado de las listas ! Las listas forman el árbol de sintaxis y esto le permite escribir funciones que hacen cosas asombrosas a su código, supongo. Estoy aprendiendo Racket (anteriormente PLT Scheme ) ahora. Lisp es el único lenguaje de programación que realmente me ha motivado e interesado en aprender.
Mark C

Respuestas:


18

Seré corto:

Maybe a

en Haskell

Con esta construcción simple, el lenguaje resuelve el problema de los choques o NullPointerExceptionevita el "One Million Mistake" de Tony Hoare :)

Francamente, ¿se verifica una presencia opcional en tiempo de compilación? Es como un sueño ...


1
O Opción como se llama en muchos otros lenguajes de programación.
Jonas

@Jonas: Debo admitir que no me gusta el Optionnombre. Por qué no Optional! Puede ser porque no soy un hablante nativo, pero Optionno me transmite el significado "opcional".
Matthieu M.

El Maybenombre 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.
Tikhon Jelvis


15

Soy perennemente aficionado void *. Probablemente sea un síntoma de algo profundamente defectuoso en mí.


2
Si. Me temo que eso es exactamente lo que es. :) Oh, +1 para "interesante" en lugar de "único". Objective-C obviamente tiene void *y Pascal / Delphi tienen Pointer.
Frank Shearar

jaja más de un tipo que no, pero no se puede argumentar que no es de gran alcance
user10008

15
Me encanta el pesimismo inherente que expresa: "¿Puedes ver esa cosa allí?" 'Sí, ¿qué es?', 'No tengo idea'.
biziclop

Siempre pensé que era gracioso que no pudieras declarar un vacío, pero puedes tomar la dirección. Me parece que con struct s {int A; nulo B; int C; } que la dirección de B debe ser la dirección de la grieta entre A y C. Pero no, no está permitido.
Andy Canfield

Es por eso que en pascal "puntero" se usa para denotar un puntero genérico, y no confundirlo con "procedimiento".
umlcat

14

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


Tenga en cuenta cómo Javascript se construye de una manera muy similar, y Python se construye sobre la misma base, como probablemente sea Ruby.
9000

Creo que esto también es posible en Perl y PHP, ¿sí?
FrustratedWithFormsDesigner

Hay una diferencia entre las tablas en lua y los contenedores hash en otros idiomas. Existe una sutil diferencia de implementación en la forma en que lua distribuye los valores hash que hacen que sus tablas funcionen de manera casi mágica. Principalmente programo en python, y en ocasiones encuentro que estoy usando suposiciones que no son válidas, según mis expectativas sobre la forma en que funcionan las tablas en lua. Un ejemplo específico de esta magia es que los enteros hash para los propios + 1. Esto significa que las teclas de números enteros son envasados densamente, y que 0,0 y -0,0 tienen el mismo hash (son iguales)
SingleNegationElimination

9

Me sorprende que nadie haya mencionado las mónadas o los tipos de datos algebraicos todavía.


Puede mostrarnos ejemplos :)
nawfal



6

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.


Ah, las bases de datos UniData / UniVerse también tienen bloques comunes en su idioma interno (UniBasic).
Dan McGrath el

¿Es un bloque común un bloque de código que es utilizado por diferentes partes del programa?
Mark C

1
@MarkC IIRC son datos básicamente globales, pero cada función que accede tiene que decir explícitamente que va a estar en la parte superior
jk.

5

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


4

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 .


3

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.


44
Pero cursor%rowtypees aún más divertido: es un tipo de registro formado dinámicamente que refleja qué columnas devuelve la consulta del cursor.
9000

.NET "Nullable" es en realidad un tipo (genérico) en sí mismo.
Konamiman

3

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
  • Atom = Un solo valor numérico
  • 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
    

    Ver: El manual de referencia

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}


77
Esto se siente como LISP ...
FrustratedWithFormsDesigner

Los tipos de datos reales son el único bit.
Dan McGrath el

1
@FrustratedWithForms Igual, pensé: "¡Oye, dijo, 'Atom'! Esto se parece a (a) Lisp pero con divisores innecesarios.: P
Mark C

3

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


2

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

2

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.


3
Las uniones vinieron de C. Un buen ejemplo es la estructura zval en php.
Martin Wickman el

2
Los he usado en un emulador Z80, para acceder fácilmente a los registros de 16 bits como registros completos (HL, BC) y como registros de 8 bits (H, L, B y C). Esto refleja cómo se usan en Z80 asm. También en "variantes", una clase que puede contener un valor de diferentes tipos (por ejemplo, int / float) - no estoy seguro de por qué no
usé

@ggambett: ¡He hecho exactamente lo mismo para mis programas Z80! Solo que también he agregado un campo de bits para acceder a banderas individuales en el registro F.
Konamiman

2

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í


8
Más bien, una función 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'.
9000

2

Expresiones regulares:

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


2
Es completamente posible analizar muchas gramáticas simples con expresiones regulares. Por ejemplo, es relativamente trivial analizar un archivo ini con un mínimo de lógica sobre un conjunto de expresiones regulares. El error que mucha gente comete es tratar de analizar gramáticas muy complejas (es decir, XML / HTML).
Matthew Scharley el


@ Mark C: La respuesta principal es (con un récord de 4320 votos). No puedes
Martin York

Sí, eso fue por humor. Me vino a la mente cuando leí el comentario de Matthew.
Mark C

2

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 NULLen SQL y undefinedJavaScript, pero no voiden C o C ++. voidfalla Aunque describe un valor sin información, ningún valor real puede ser de tipo void.


Creo que te refieres a "tipo de unidad".
Jason Baker

2

El symboltipo 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.


También como claves para un mapa para la comparación de teclas O (1).
Jeremy Heiler el

Bueno, en realidad no es tan inusual. Ruby lo heredó de Smalltalk, que lo heredó de Lisp. Scala también lo tiene, creo. De hecho, casi todas las implementaciones de lenguaje (compilador o intérprete) tienen una tabla de símbolos internamente, Lisp, Smalltalk y Ruby simplemente la exponen al programador.
Jörg W Mittag el

1

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.


Puedo vencer eso. BCPL tiene un tipo de datos: palabra; ver en.wikipedia.org/wiki/BCPL
Stephen C

Existen diferentes tipos de números (COMP, COMP-1, COMP-2, COMP-3).
David Thornley el

Eso suena mal. ¿Puedes explicar qué significan esos detalles?
Mark C

S= con signo, 9(5)= 5 dígitos, V= punto decimal implícito, 99= 2 dígitos más, COMP-3= BCD + signo nybble.
dan04

1

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.


0

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.


0

Clojure es interesante porque tiene un metaconcepto de "abstracciones" que impregna el lenguaje. Ejemplos:

  • Colecciones
  • Secuencias (perezosas y no perezosas)
  • Funciones de orden superior
  • Multimetodos
  • Protocolos
  • Referencias gestionadas
  • Macros
  • varios otros .....

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


0

Si desea un idioma con un tipo único, diríjase a BCPL . Este idioma solo tiene un tipo de datos, la palabra, que es un número fijo de bits para la implementación del lenguaje.


0

Googles Go tiene un tipo de "Canal" que es bastante único.


1
Los canales no son únicos. Muchos idiomas los tienen. Félix los tuvo 10 años antes de que Google existiera :) Ocaml los tuvo 10 años antes de que Félix existiera.
Yttrill

Y había al menos otro idioma que tenía canales antes de que existiera Ocaml. Sigue siendo uno de los tipos menos disponibles en lenguajes de programación.
Brainlag el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.