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 particularClassTag
,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
yWrappedArray
, que se utilizan para los parámetros varargs. - Tipos de
TupleN
-
Product
ySerializable
(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 deList()
comoNil
)
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
yStringBuilder
(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
yjava.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
-
js.Any
: conceptualmente un tercer subtipo deAny
, además deAnyVal
yAnyRef
. 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 deapply
comportan de manera diferente a la de otros tipos de JavaScript (el primer argumento real se convierte en el argumentothisArgument
de la función llamada) -
js.UndefOr
yjs.|
(se comportan como tipos JS aunque no se extiendenjs.Any
) -
js.Object
(new js.Object()
es especial-cased como un objeto JS literal vacío{}
) -
js.JavaScriptException
(se comporta muy especialmente enthrow
ycatch
) -
js.WrappedArray
(utilizado por desugaring de varargs) -
js.ConstructorTag
(similar aClassTag
) - La anotación
js.native
y todas las anotaciones enjs.annotation.*
Además, una docena de métodos más primitivos .
Tipos específicos de nativos de Scala
- Enteros sin
UByte
:UByte
,UShort
,UInt
yULong
-
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.