2010-01-25 11 views
16

Las siguientes afirmaciones representan mi comprensión de los sistemas de tipo (que adolece de muy poca experiencia práctica fuera del mundo de Java); por favor corrija cualquier error.¿Es correcto mi entendimiento de los sistemas tipo?

La distinción estático/dinámico parece bastante clara:

  • tipos estáticos langauges asignan cada variable, el campo y parámetro de un tipo y el compilador impide asignaciones entre tipos incompatibles. Ejemplos: C, Java, Pascal.
  • Los idiomas de con dinamización dinámica tratan las variables como contenedores genéricos que pueden contener lo que desee; los tipos se comprueban (si es que lo hacen) solo en tiempo de ejecución cuando realiza operaciones en los valores, no cuando los asigna. Ejemplos: Smalltalk, Python, JavaScript.
  • La inferencia tipo le permite a los lenguajes tipados estáticos (y tiene algunas de las ventajas de) escribirlos dinámicamente, deduciendo tipos del contexto para no tener que declararlos la mayoría de las veces, pero a diferencia en lenguajes dinámicos, no se puede, por ejemplo use una variable para mantener una cadena inicialmente y luego asigne un entero a ella. Ejemplos: Haskell, Scala

yo soy mucho menos seguro acerca de la distinción fuerte/débil, y sospecho que no está muy bien definido:

  • fuertemente tipado idiomas asignan a cada valor de tiempo de ejecución de un tipo y solo permite que se realicen operaciones definidas para ese tipo; de lo contrario, existe un error de tipo explícito.
  • Los idiomas débilmente tipados no tienen comprobaciones del tipo de tiempo de ejecución: si intenta realizar una operación con un valor que no admite, los resultados son impredecibles. En realidad, puede hacer algo útil, pero es más probable que obtenga datos corruptos, un bloqueo o algún error secundario indescifrable.
  • Parece que hay al menos dos tipos diferentes de idiomas tipos débiles (o tal vez una serie continua):
    • En C y ensamblador, los valores son básicamente cubos de bits, así que cualquier cosa es posible y si se obtiene el compilador para desreferenciar los primeros 4 bytes de una cadena terminada en nulo, es mejor que conduzca a un sitio que no contenga código de máquina legal.
    • PHP y JavaScript generalmente también se consideran de tipo débil, pero no consideran que los valores sean cubos de bits opacos; Sin embargo, realizarán conversiones de tipo implícitas.
  • Pero estas conversiones implícitas parecen aplicarse principalmente a las variables de cadena/entero/float: ¿eso realmente garantiza que la clasificación sea débilmente tipada? ¿O hay otros problemas donde el sistema de tipos de estos idiomas puede ofuscar errores?
+4

Buena suerte. Nunca he encontrado una respuesta "buena" para las personas fuertes/débiles, solo una respuesta "lo suficientemente buena para salir adelante" de personas muy informadas. – wheaties

Respuesta

17

Estoy mucho menos seguro acerca de la distinción fuerte/débil, y sospecho que no está muy claramente definido.

Tienes razón: no lo es.

Esto es lo que Benjamin C. Pierce, autor de Tipos y lenguajes de programación y tipos avanzados y Lenguajes de Programación tiene que decir:

yo pasamos unos días ... tratando de ordenar la terminología de "fuertemente mecanografiada," "estáticamente mecanografió," caja fuerte, "etc., y me pareció increíblemente difícil ... El uso de estos términos es tan vario que los hace casi inútiles.

Luca Cardelli, en su artículo con tipo de programación, la define como la ausencia de errores sin control de tipo en tiempo de ejecución. Tony Hoare llama a eso exactamente la misma propiedad de "". Otros documentos lo llaman "seguridad tipo" o simplemente "seguridad".

Mark-Jason Dominus wrote a classic rant about this hace un par de años en el grupo de noticias comp.lang.perl.moderated, en una discusión sobre si Perl estaba o no fuertemente tipado. En esta diatriba, afirma que en unas pocas horas de investigación, pudo encontrar 8 definiciones diferentes, a veces contradictorias, en su mayoría de fuentes respetadas como libros de texto universitarios o artículos revisados ​​por pares. En particular, esos textos contenían ejemplos que estaban destinados a ayudar a los estudiantes a distinguir entre lenguajes fuertemente y débilmente tipados, y de acuerdo con esos ejemplos, C está fuertemente tipado, C es débilmente tipado, C++ fuertemente tipado, C++ débilmente tipado, Lisp es fuertemente tipado, Lisp está débilmente tipado, Perl está fuertemente tipado, Perl está débilmente tipado. (? ¿Eso aclarar cualquier confusión)

La única definición que he visto aplicado de forma coherente es:

  • establecimiento inflexible: mi lenguaje de programación
  • tipos débiles: su programación idioma
+1

Eso suena como Benjamin. No estoy de acuerdo en un solo aspecto: eliminar el "casi" :-) +1 –

+0

La 'única definición' es hilarante. : D –

+2

En realidad no es mío, pero no puedo recordar dónde lo vi primero, e incluso si pudiera, no era la fuente original de todos modos. Vamos a atribuirlo al folclore. –

0

Hmm, tampoco sé mucho más, pero quería mencionar C++ y sus conversiones implícitas (constructores implícitos). Esto también podría ser un ejemplo de tipeo débil.

+0

Eso es porque fue construido sobre la base (débilmente tipada) de C. –

1

Tal vez this Book puede ayudar. Sin embargo, prepárate para algunas matemáticas. Si mal no recuerdo, una declaración "no matemática" fue: "Muy tipado: un idioma con el que me siento seguro para programar".

+0

"¿Prepárate para algo de matemática? ¿Eufemismo de la semana? ¿Y es solo el lunes? Si bien es un gran libro, no estoy seguro de que sea exactamente lo que el solicitante está buscando B-) OTOH, su segunda respuesta se ve bien B-) –

1

Parece que hay al menos dos tipos diferentes de idiomas tipos débiles (o tal vez una serie continua):

  • En C y ensamblador, los valores son básicamente cubos de bits, así que cualquier cosa es posible y si obtienes que el compilador desreferencia los primeros 4 bytes de una cadena terminada en nulo, es mejor que conduzca a un sitio que no contenga código de máquina legal.

estoy de acuerdo con esta afirmación, al menos en C. Se puede manipular el sistema de tipos en C de tal manera que se puede tratar cualquier posición de memoria dada como un cubo de bits, sino una variable definitivamente tiene un tipo y ese tipo tiene propiedades específicas. El hecho de que no haya comprobaciones de tiempo de ejecución (a menos que considere que las excepciones de coma flotante o las fallas de segmentación sean comprobaciones de tiempo de ejecución) no es realmente relevante. C puede considerarse "débilmente tipado" en el sentido de que el compilador realizará alguna conversión de tipo implícita para usted, pero no va muy lejos con eso.

+0

El hecho de que no haya controles de tiempo de ejecución es muy relevante, ya que el camino Lo entiendo, las comprobaciones en tiempo de compilación solo son relevantes para la distinción estática/dinámica, mientras que "no verificaciones de tiempo de ejecución" es la forma más extrema de tipeo débil. –

+0

Solo en muy pequeña medida. Por ejemplo, en C (o al menos "C clásico" que estoy acostumbrado) no hay forma de definir un tipo de entero especial que no se pueda asignar libremente a "int". Un verdadero lenguaje fuertemente tipado te brinda eso. –

+0

Supongo que es una cuestión de perspectiva. Si estamos hablando de * valores *, entonces supongo que C es tan débil como puede ser, ya que los valores son solo un montón de bits que pueden ser reinterpretados como cualquier cosa. Pero en términos de * variables *, la razón por la que no hay verificaciones en tiempo de ejecución es porque * all * la comprobación se realiza en tiempo de compilación, y hay muy poca conversión implícita entre todo menos los tipos de datos incorporados más básicos. –

2

Este es un reflejo bastante preciso de mi propia comprensión del tema de la discusión de tipeo estático/dinámico, fuerte/débil. Además, puede considerar esos otros idiomas:

En idiomas como TCL y Bourne Shell, el tipo de valor "principal" es la cadena. Existen operadores numéricos que implícitamente fuerzan los valores de entrada de la representación de cadenas y los valores de resultados a la representación de cadenas. Se pueden considerar ejemplos de lenguajes dinámicos y de tipo débil.

Adelante puede ser un ejemplo de un lenguaje estático, débilmente tipado. El lenguaje no realiza ningún tipo de comprobación, y la pila principal puede contener indistintamente punteros, enteros, cadenas (representadas convencionalmente como dos celdas, inicio y longitud). El uso inconsistente de los operadores puede conducir a un comportamiento interesante o no especificado. Las implementaciones típicas de Forth proporcionan una pila separada para números de coma flotante.

+0

Forth es realmente un lenguaje de programación sin tipo. – mipadi

+0

Forth no es más sin tipo que ensamblaje. Los bytes, enteros y flotantes son diferentes por estructura, los enteros y punteros son diferentes por destino (generalmente no por estructura en hardware moderno), y aunque puede INTENTAR realizar cualquier operación en cualquier grupo de bits, debe respetar ALGUN sistema de tipo para obtener un comportamiento útil. – ddaa

+0

Eso me recuerda la vieja broma de Martin Richards de que BCPL es un lenguaje fuertemente tipado con un tipo. –

0

Estoy de acuerdo con los otros que dicen "aquí no parece haber una definición difícil y rápida". Mi respuesta tiende a basarse en la cantidad de cuerda que el lenguaje le da a los tipos de WRT. Si puedes casi simular cualquier cosa que desees, entonces es débil. Si realmente no te permite meterse en problemas, incluso si lo deseas, es fuerte.

realmente no he visto a muchos idiomas que bordean esta frontera, así que no puedo decir que nunca he necesitado una definición mejor que eso ...

1

considero fuerte/débil para ser el concepto de conversión implícita y un buen ejemplo es la adición de una cadena y un número. En un lenguaje fuertemente tipado, la conversión no ocurrirá (al menos en todos los idiomas en los que pueda pensar) y obtendrá un error. Los lenguajes débilmente tipados como VB (con Option Explicit Off) y Javascript intentarán lanzar uno de los operandos al otro tipo.

en VB.Net con Option Strict Off:

Dim A As String = "5" 
    Dim B As Integer = 5 
    Trace.WriteLine(A + B) 'returns 10 

Con Option Strict On (VB convertir en un lenguaje fuertemente tipado) obtendrá un error de compilación.

en javascript:

var A = '5'; 
    var B = 5; 
    alert(A + B);//returns 55 

Algunas personas dicen que los resultados no son predecibles, pero que en realidad hacen seguir un conjunto de reglas.

+0

Java generalmente se considera fuertemente tipado, pero tiene un operador + sobrecargado que felizmente agregará un número a una cadena (pero no al revés). –

+0

@Michael: Este es un buen ejemplo de por qué la distinción simple fuerte <-> débil no es útil. Hay demasiadas variantes en diferentes idiomas. – sleske

+0

@Michael Borgwardt y @sleske, los operadores sobrecargados son en realidad un gran ejemplo de un lenguaje fuertemente tipado que intenta trabajar con código débilmente tipado. Si Java sobrecarga su operador, entonces hay un método fuertemente tipado detrás de escena que se explica por esto. En VB y Javascript (AFAIK) simplemente intentan lanzar implícitamente lo que se les ha otorgado, que es lo que los debilita. –

4

Referente a tipeo estático y dinámico estás muerto en el dinero. La tipificación estática significa que los programas se verifican antes de ejecutarse, y un programa puede ser rechazado antes de que comience. El tipado dinámico significa que los tipos de valores se verifican durante la ejecución, y una operación mal tipada puede hacer que el programa se detenga o de lo contrario señalice un error en el tiempo de ejecución. Una razón principal para el tipado estático es descartar programas que puedan tener tales "errores de tipo dinámico".

Bob Harper ha argumentado que un lenguaje de tipado dinámico puede (y debe) ser considerado como un lenguaje estáticamente tipado con un solo tipo, que Bob llama "valor". Esta visión es justa, pero solo es útil en contextos limitados, como tratar de ser preciso sobre la teoría de tipos de los lenguajes.

Aunque creo que entienden el concepto, sus viñetas no dejan en claro que la inferencia de tipo es simplemente un caso especial de tipado estático. En la mayoría de los idiomas con inferencia de tipo, las anotaciones de tipo son opcionales, pero no necesariamente en todos los contextos. (Ejemplo: firmas en ML.) Los sistemas de tipo estático avanzado a menudo le dan una compensación entre anotaciones e inferencia; por ejemplo, en Haskell puedes escribir funciones polimórficas de mayor rango (por delante a la izquierda de una flecha) pero solo con anotaciones. Entonces, si está dispuesto a agregar una anotación, puede hacer que el compilador acepte un programa que sería rechazado sin la anotación. Creo que esta es la ola del futuro en tipo de inferencia.

Las ideas de mecanografía "fuerte" y "débil" que caracterizaría como no es útil, porque no tienen un significado técnico aceptado universalmente. La tipificación fuerte generalmente significa que no hay lagunas en el sistema de tipos, mientras que la tipificación débil significa que el sistema de tipos puede ser subvertido (invalidando cualquier garantía). Los términos a menudo se usan incorrectamente para indicar tipeo estático y dinámico. Para ver la diferencia, piense en C: el lenguaje está verificado en tiempo de compilación (tipado estático), pero hay muchas lagunas; puede lanzar un valor de cualquier tipo a otro tipo del mismo tamaño —, en particular, puede convertir tipos de puntero libremente. Pascal era un lenguaje que estaba destinado a ser fuertemente tipado, pero que tenía un vacío imprevisto: un registro variante sin etiqueta.

Las implementaciones de lenguajes fuertemente tipados a menudo adquieren escapatorias a lo largo del tiempo, normalmente para que parte del sistema de tiempo de ejecución se pueda implementar en el lenguaje de alto nivel. Por ejemplo, Objective Caml tiene una función llamada Obj.magic que tiene el efecto de tiempo de ejecución de simplemente devolver su argumento, pero en tiempo de compilación convierte un valor de cualquier tipo a uno de cualquier otro tipo. Mi ejemplo favorito es Modula-3, cuyos diseñadores llamaron a su construcción de fundición de tipo LOOPHOLE.

Lo invito a evitar los términos "fuerte" y "débil" con respecto a los sistemas tipo, y en cambio decir exactamente lo que quiere decir, por ejemplo, "el sistema tipo garantiza que la siguiente clase de errores no puede ocurrir en tiempo de ejecución "(fuerte)," el sistema de tipo estático no protege contra ciertos errores de tiempo de ejecución "(débil), o" el sistema de tipo tiene una laguna "(débil). Simplemente llamar a un sistema de tipos "fuerte" o "débil" por sí solo no se comunica mucho.

Cuestiones relacionadas