Translate

miércoles, 12 de agosto de 2020

Scala 3, indentación en vez de llaves ???


Una característica experimental, Scala 3 impone algunas reglas sobre sangría y permite que algunas apariciones de llaves {...} sean opcionales. Se puede desactivar con el indicador del compilador -noindent.

  • Primero, algunos programas mal sangrados van a estar marcados con un error de tipo advertencias.
  • En segundo lugar, algunas apariciones de llaves {...} se hacen opcionales. Generalmente, la regla es que agregar un par de llaves opcionales no cambiará el significado de un programa bien sangrado.
Esta característica seguro los hace pensar en python, pero les recuerdo que en haskell tambien la identación es importante. Y scala, tiene más influencia de haskell que de python.

El compilador impone dos reglas para programas bien sangrados, marcando las violaciones como advertencias.

1.En una región delimitada por llaves, no se permite que ninguna instrucción comience a la izquierda de la primera instrucción después de la llave de apertura que comienza una nueva línea.

Esta regla es útil para encontrar llaves de cierre faltantes. Previene errores como:


if (x < 0) {
  println(1)
  println(2)

println("done")  // error: indented too far to the left

2.Si la sangría significativa está desactivada (es decir, en el modo Scala-2 o en -noindent) y estamos al comienzo de una subparte con sangría de una expresión, y la parte con sangría termina en una nueva línea, la siguiente instrucción debe comenzar en una ancho de sangría menor que la subparte. Esto evita errores en los que se olvidó una llave de apertura, como:

if (x < 0)
  println(1)
  println(2)   // error: missing `{

Estas reglas aún dejan un gran margen de maniobra sobre cómo se deben sangrar los programas. Por ejemplo, no imponen ninguna restricción sobre la sangría dentro de las expresiones, ni requieren que todas las declaraciones de un bloque de sangría se alineen exactamente.

Las reglas generalmente son útiles para identificar la causa raíz de los errores relacionados con la falta de llaves de apertura o cierre. Estos errores suelen ser bastante difíciles de diagnosticar, en particular en programas grandes.

Además, el compilador insertará tokens <indent> o <outdent> en ciertos saltos de línea. Gramaticalmente, los pares de tokens <indent> y <outdent> tienen el mismo efecto que los pares de llaves {y}.

Con estas nuevas reglas, las siguientes construcciones son todas válidas:

trait A:
  def f: Int

class C(x: Int) extends A:
  def f = x

object O:
  def f = 3

enum Color:
  case Red, Green, Blue

type T = A:
  def f: Int

given [T](using Ord[T]) as Ord[List[T]]:
  def compare(x: List[T], y: List[T]) = ???

extension (xs: List[Int])
  def second: Int = xs.tail.head

new A:
  def f = 3

package p:
  def a = 1
package q:
  def b = 2

Ojo que agregá los : 

En fin, me parece un gran cambio y va a generar 2 formas de escribir y no sé si es la mejor idea, ya que un junior no va saber cuando escribir de que forma.