El otro día hubo lanzamiento de las llamadas "versiones de primavera" de todos los sistemas y la incorporación de algunas funciones interesantes como el soporte de ratón y trackpad en iPadOS.
Pero junto a las versiones de sistemas, también llegaron las renovaciones en el campo del desarrollo: Xcode 11.4 con sustanciales mejoras y arreglos que la convierten en la versión estable de Xcode 11 que llevamos esperando desde septiembre, así como la llegada de la última versión del lenguaje Swift: la versión 5.2.
Vamos a repasar brevemente todas las novedades que nos ofrece.
Las principales mejoras en el lenguaje no están en cambios en el mismo, ya que Swift tiene una API estable desde su versión 3 y prácticamente el 99% del código que se creara en esa versión seguirá funcionando en esta última. Lo que Apple ha hecho es mejorar sustancialmente "las tripas" del lenguaje mejorando e incorporando nuevas funciones que permiten un mejor análisis y detección de errores mientras escribimos nuestro código.
Arquitectura de diagnóstico
Lo primero que se ha hecho es cambiar la arquitectura de diagnóstico del lenguaje a una nueva y mejorada. Esta arquitectura es lo que permite analizar el código mientras lo escribimos y detectar errores en el mismo incluso antes de compilar nuestro programa.
Si has trabajado con Swift, es de sobra conocido que en ocasiones su "exactitud" en señalar un problema en el código, no era la mejor. Y ese problema se agravó enormemente al llegar SwiftUI cuya estructura DSL (lenguaje específico para dominio) cambió la forma general de representación del mismo para con el uso de dicha librería.
Apple, consciente del problema, lleva muchos meses trabajando en incorporar un nuevo motor de arquitectura de diagnóstico que nos dirá de forma más precisa dónde está el error, y no solo eso, también nos sugerirá más "fixes" (soluciones rápidas) para que el código se arregle y se muestre como debería.
Usando un ejemplo de la propia Apple, en la versión anterior del lenguaje, si creábamos el siguiente código:
enum E
{ case one, two }
func check(e: E) {
if e != .three {
print("okay")
}
}
En este código hemos creado una enumeración que tiene dos posibles valores: one
y two
. Nada más. Pero en la función check
preguntamos por un hipotético valor three
que obviamente no existe. Hasta ahora, el error que nos daba tenía que ver con el operador de comparación de no igualdad (el !=
) donde nos decía que ambos tipos de datos no podían ser comparados pues los detectaba como diferentes. Un error inexacto.
Con la nueva versión del motor, nos dirá exactamente que el valor three
no existe en la enumeración E
, con lo que podemos entender de una forma más exacta el problema.
Este es solamente un pequeño ejemplo para hacernos una idea de este profundo cambio que nos ayudará a que el análisis del código sea más preciso indicándonos de forma eficiente (y rápida, ya que se ha mejorado el propio algoritmo subyacente) dónde están los errores en el código.
Como complemento a este cambio, también se ha mejorado sustancial el motor de completado de código, que nos sugiere qué código escribir mientras lo escribimos (y así no tener que recordar siempre el nombre exacto de cientos o miles de métodos, variables o elementos que tengamos en nuestro programa, así como los de las librerías que usemos). Este motor ha mejorado su eficacia entre un 1.2 y un 1.6x eliminando comprobaciones redundantes.
Gran parte del responsable de este cambio es la arquitectura LSP (Language Server Protocol) de Microsoft que Apple ha incorporado al etiquetado, proceso y completado de código. Al usar Apple esta tecnología, en breve, cualquier editor o programa de terceros (como Sublime Text, Visual Studio Code o incluso IDEs como Visual Studio) podrá autocompletar, analizar y gestionar el código en Swift de la misma forma y con el mismo motor que usa Xcode, lo que dará una experiencia más sostenible incluso entre diferentes sistemas operativos.
Mejoras en el compilador
Compilar un programa y su velocidad es tarea esencial. Es lo que traduce nuestro código en algo que un sistema operativo pueda entender. Aquí Apple también se ha puesto las pilas y ha mejorado sustancialmente la velocidad de los procesos de compilación final (release) y para depuración (debug).
Para ello ha optimizado los dos modos más usados: el incremental (que detecta y compila solo los cambios reales en el código entre compilación y compilación, y así mejora el tiempo en las pruebas de nuestro programa) y el de la optimización del módulo completo (o WMO) que es usado cuando queremos crear la versión final de nuestro programa y que pone todo el código en un solo fichero, trabajándolo de forma completa para un enlace más eficiente.
A este cambio se han incorporado también importantes mejoras en el depurador que nos permite ejecutar nuestro programa línea a línea, ver su comportamiento mientras se ejecuta y extraer datos que nos ayuden a detectar errores en tiempo de ejecución.
Incorporaciones en el código
Con este lanzamiento, Apple ha incorporado dos nuevas funciones interesantes al lenguaje. Una de ellas es la posibilidad de usar una función llamada callAsFunction
dentro de cualquier clase o estructura. Su uso, muy enfocado a la futura interoperabilidad de Swift con Python en la que trabaja Google para su motor TensorFlow de aprendizaje automático, permite que llamemos a la constante o variable donde se guarde la instancia de la clase o estructura, como si fuera una función.
struct Dado {
var caras:Int
func callAsFunction() -> Int {
Int.random(in: 1...caras)
}
}
let dado1 = Dado(caras: 8)
let resultado = dado1()
Como podemos ver, creamos la instancia del struct
Dado
, y podemos ejecutarlo como una función llamando a dado1()
a pesar de no indicar de forma explícita el nombre de la función ya que callAsFunction
hace las veces de función asociada a la propia instancia.
También, en programación funcional podemos usar una nueva forma de referenciar a los elementos dentro de las funciones de orden más alto de la programación funcional, así como cualquier otra función implícita que reciba como parámetro la instancia de un dato.
Antes había que usar el parámetro abreviado $0
seguido del nombre de la propiedad (como $0.name
) y ahora podemos usar la referencia a través de un key path con la barra invertida: \.name
, dando por hecho que \.
corresponde a la raíz de la instancia recibida por parámetro. Una pequeña mejora semántica que hace más claras las referencias.
Pequeñas mejoras
Sin duda, Swift es uno de los proyectos más prometedores de Apple en todos los sentidos y donde más esfuerzo y trabajo están poniendo. No solo por la propia compañía y todas las empresas que colaboran en el proyecto como lenguaje de código abierto, también por una increíble comunidad que propone activa mejoras, arreglos, incorporaciones...
Desde aquí, nuestro agradecimiento a todos ellos por el excelente trabajo que están realizando.
Ver 3 comentarios