tutorial started software getting example scala

started - ¿Qué tipos son especiales para el compilador de Scala?



scala vs java (1)

Hay una cantidad increíble de tipos que son "conocidos" del compilador, y son especiales en diversos grados. Puede encontrar una lista completa en Definitions.scala de scalac.

Probablemente podamos clasificarlos de acuerdo con el grado de especialidad que tengan.

Descargo de responsabilidad: probablemente he olvidado algunos más.

Especial para el sistema de tipo

Los siguientes tipos son cruciales para el sistema de tipos de Scala. Tienen una influencia sobre cómo se realiza la comprobación de tipos. Todos estos tipos se mencionan en la especificación (o al menos, definitivamente deberían serlo).

  • Any , AnyRef , AnyVal , Null , Nothing : los cinco tipos que se encuentran en la parte superior e inferior del sistema de tipos de Scala.
  • scala.FunctionN , el tipo (canónico) dado de funciones anónimas (incluida la expansión eta). Incluso en 2.12, que tiene el tratamiento SAM de las funciones anónimas, FunctionN sigue siendo especial en algunos casos (especialmente en la resolución de sobrecarga).
  • scala.PartialFunction (tiene un impacto en cómo funciona la inferencia de tipos)
  • Unit
  • Todos los tipos con notación literal: Int , Long , Float , Double , Char , Boolean , String , Symbol , java.lang.Class
  • Todos los tipos primitivos numéricos y Char , para la conformidad débil (en conjunto, estas dos viñetas cubren todos los tipos primitivos)
  • Option y tuplas (para coincidencia de patrones y auto-tupling)
  • java.lang.Throwable
  • scala.Dynamic
  • scala.Singleton
  • La mayoría de scala.reflect.* , En particular ClassTag , TypeTag , etc.
  • scala.annotation.{,ClassFile,Static}Annotation
  • Casi todas las anotaciones en scala.annotation.* ( scala.annotation.* )
  • scala.language.*
  • scala.math.ScalaNumber (por razones desconocidas)

Conocido por el compilador como el desgrase de algunas características del lenguaje

Los siguientes tipos no son cruciales para el sistema de tipos. No tienen influencia en la verificación de tipos. Sin embargo, el lenguaje Scala presenta una serie de construcciones que descienden a expresiones de esos tipos.

Estos tipos también se mencionarían en la especificación.

  • scala.collection.Seq , Nil y WrappedArray , que se utilizan para los parámetros varargs.
  • Tipos de TupleN
  • Product y Serializable (para clases de casos)
  • MatchError , generado por construcciones de coincidencia de patrones
  • scala.xml.*
  • scala.DelayedInit
  • List (el compilador realiza algunas optimizaciones triviales, como la reescritura de List() como Nil )

Conocido por la implementación del lenguaje

Esta es probablemente la lista que más te importa, dado que dijiste que estabas interesado en saber qué podría pasar de manera diferente en diferentes back-ends. Las categorías anteriores son manejadas por fases tempranas (front-end) del compilador, y por lo tanto son compartidas por Scala / JVM, Scala.js y Scala Native. Esta categoría es típicamente conocida del back-end del compilador, y potencialmente tiene diferentes tratamientos. Tenga en cuenta que tanto Scala.js como Scala Native intentan imitar la semántica de Scala / JVM en un grado razonable.

Esos tipos pueden no mencionarse en la especificación del lenguaje per se, al menos no todos.

Aquí están aquellos en los que los back-ends están de acuerdo (según Scala Native, a mi leal saber y entender):

  • Todos los tipos primitivos: Boolean , Char , Byte , Short , Int , Long , Float , Double , Unit .
  • scala.Array .
  • Cloneable (actualmente no es compatible con Scala Native, consulte el n #334 )
  • String y StringBuilder (principalmente para la concatenación de cadenas)
  • Object , para prácticamente todos sus métodos

Y aquí están aquellos en los que no están de acuerdo:

  • Versiones en caja de tipos primitivos (como java.lang.Integer )
  • Serializable
  • java.rmi.Remote y java.rmi.RemoteException
  • Algunas anotaciones en scala.annotation.* (Ej., strictfp )
  • Algunas cosas en java.lang.reflect.* , Utilizadas por Scala / JVM para implementar tipos estructurales

Además, aunque no son tipos per se, una larga lista de métodos primitivos también se manejan específicamente en los back-ends.

Tipos específicos de plataforma

Además de los tipos mencionados anteriormente, que están disponibles en todas las plataformas, las plataformas que no son de JVM agregan sus propios tipos especiales para fines de interoperabilidad.

Tipos específicos de Scala.js

Ver JSDefinitions.scala

  • js.Any : conceptualmente un tercer subtipo de Any , además de AnyVal y AnyRef . Tienen semántica de JavaScript en lugar de la semántica de Scala.
  • String y versiones en caja de todos los tipos primitivos (muy reescrito, denominado "secuestrado" por el compilador)
  • js.ThisFunctionN : sus métodos de apply comportan de manera diferente a la de otros tipos de JavaScript (el primer argumento real se convierte en el argumento thisArgument de la función llamada)
  • js.UndefOr y js.| (se comportan como tipos JS aunque no se extienden js.Any )
  • js.Object ( new js.Object() es especial-cased como un objeto JS literal vacío {} )
  • js.JavaScriptException (se comporta muy especialmente en throw y catch )
  • js.WrappedArray (utilizado por desugaring de varargs)
  • js.ConstructorTag (similar a ClassTag )
  • La anotación js.native y todas las anotaciones en js.annotation.*

Además, una docena de métodos más primitivos .

Tipos específicos de nativos de Scala

Ver NirDefinitions.scala

  • Enteros sin UByte : UByte , UShort , UInt y ULong
  • Ptr , el tipo de puntero
  • FunctionPtrN , los tipos de punteros de función
  • Las anotaciones en native.*
  • Una cantidad de métodos primitivos adicionales en scala.scalanative.runtime

Scala hace una gran oferta sobre cómo las características de lenguaje que parecen ser implementadas como características de la biblioteca.

¿Hay una lista de tipos que son tratados especialmente por el idioma?

¿Ya sea en la especificación o como un detalle de implementación?

Eso incluiría, por ejemplo, la optimización de partidos ausentes en tuplas.

¿Qué hay de las convenciones especiales relacionadas con la coincidencia de patrones, para las comprensiones, los bloques de prueba y otros constructos de lenguaje?

¿Es String algo especial para el compilador? Veo que la mejora String es solo una conversión implícita de la biblioteca, y que la concatenación de cadenas es soportada por Predef , pero ¿es eso de alguna manera el lenguaje especial?

Del mismo modo, veo preguntas sobre <:< y classOf y asInstanceOf , y no está claro qué es un elemento mágico intrínseco. ¿Hay alguna manera de ver la diferencia, ya sea con una opción de compilación o mirando el código de bytes?

Me gustaría entender si una función es compatible de manera uniforme por implementaciones como Scala.JS y Scala-native, o si una característica podría demostrar ser dependiente de la implementación, dependiendo de la implementación de la biblioteca.