Los niveles de "expertisidad" en Scala

En http://www.scala-lang.org/node/8610, Martin Odersky escribe sobre los niveles de Scala para el principiante y el experto. Me parece interesante "copiar" aquí una parte referente a lo que debe conocerse y usarse según el nivel y el tipo de cosas que desarrollamos. Esto creo que puede orientar a los que están en "amoríos"con este lenguaje.

Level A1: Beginning application programmer
Java-like statements and expressions: standard operators, method calls, conditionals, loops, try/catch
class, object, def, val, var, import, package
Infix notation for method calls
Simple closures
Collections with map, filter, etc
for-expressions

Level A2: Intermediate application programmer
Pattern matching
Trait composition
Recursion, in particular tail recursion
XML literals

Level A3: Expert application programmer
Folds, i.e. methods such as foldLeft, foldRight
Streams and other lazy data structures
Actors
Combinator parsers

Level L1: Junior library designer
Type parameters
Traits
Lazy vals
Control abstraction, currying
By-name parameters

Level L2: Senior library designer
Variance annotations
Existential types (e.g., to interface with Java wildcards)
Self type annotations and the cake pattern for dependency injection
Structural types (aka static duck typing)
Defining map/flatmap/withFilter for new kinds of for-expressions
Extractors

Level L3: Expert library designer
Early initializers
Abstract types
Implicit definitions
Higher-kinded types

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

He visto código que usa

He visto código que usa foldLeft y foldRight y sus equivalentes impronunciables ( que ya no recuerdo cuales son ) y cosas como :>|:> y así por el estilo.

La verdad es que ese nivel de estilo funcional me impresiona, pero no me motiva mucho. Prefiero dejarlo en es estatus de "misticismo" :)

Cuando aprendo algo nuevo pues inevitablemente se le quita el chiste.

Un ejemplo no relacionado a Scala pero sí de un código que por más que lo veía no entendía muy bien que pasaba era algo como esto:

| aString vowels |
aString := 'This is a string'.
vowels := aString select: [:aCharacter | aCharacter isVowel].

Y lo veía y lo veía y nada. Ahora lo veo y es para mí totalmente natural.

Así que quiero seguir viendo esto con misticismo, al menos por un rato:

    val m1 = head[Int] >>= ((b:Option[Int]) => head[Int] map (b2 => (b <|*|> b2)))

Que hace? Quién sabe ( y eso que no está tan difícil... claro falta contexto pero la idea era mirar: >>= y <|*|> :)

Imagen de beto.bateria

¿En Mexico ya existen

¿En Mexico ya existen empresas que trabajen con Scala?

Respecto a expertisidad, siento extraña la palabra.

jajaj El Dr. @bferro lo hizo

jajaj El Dr. @bferro lo hizo a propósito. Viene del inglés: expertise

Si ya hay...

@beto.bateria actualmente hay un par de empresas que ya lo implementan y usan de manera formal te recomiendo le heches un ojo a http://vivecodigo.org/2011/05/18/podcast-2-de-la-temporada-0/ para que escuches a alguien que ya lo viene usando e incluso es parte fundamental de su trabajo...

Imagen de Nopalin

A la máquina....Sé que Scala

A la máquina....(la expresión es por los ejemplos que puso oscar)

Sé que Scala implementa nuevos conceptos que ayudaran a la hora de hacer sistemas complejos, pero por que su sintaxis tiene que ser tan... tan, no se como describirla para que los fans no se me vengan encima, tan confusa?

Yo sé que muchos odian a java por su verbosidad, pero por contrario de ellos a mi por eso me gusta.

Jaja bueno pues ya cada quien.

sobres

Imagen de ezamudio

expertitud

El término correcto es expertitud. No, es expertancia. No, expertición. No, es... otra de esas palabras que no tienen traducción al español. Podríamos decir experiencia, la bronca es que aquí "experiencia" se lee como "el tiempo que llevo usando algo, no necesariamente aprendiéndolo". Yo tengo 20 años manejando, sin embargo seguramente hay mucha gente que lleva un año manejando y lo hace mucho mejor que yo... su expertise es mayor.

En fin. En cuanto a lo de la sintaxis de Scala, pues sí, la cosa es que metieron una idea que viene de C++ (o tal vez de FORTRAN, no sé, no importa mucho ahorita) de la sobrecarga de operadores, que no es otra cosa que ampliar los caracteres que puedes usar para ponerle nombre a un método. Creo que Ryz también lo va a hacer o lo hace ya.

Tomemos como ejemplo semi-hipotético, una lista en Scala, que puede tener el método append, y se usa igual que en Java: listaInmutable.append(elemento), esto no va a modificar la listaInmutable sino que te va a devolver una nueva lista (probablemente también inmutable) que trae todos los elementos de la original, más el nuevo elemento hasta el final. Scala tiene una sintaxis alterna para invocar métodos que tienen un solo argumento, que en vez del punto, puedes usar espacios y no usar los paréntesis, de modo que en vez de listaInmutable.append(elemento) puedes poner listaInmutable append elemento. Y puedes tener métodos con nombres que en Java no podrías, por ejemplo puedes tener un método llamado simplemente + y que acepte un solo parámetro que sea un objeto (Any en Scala). Entonces ahora puedes invocar listaInmutable.+(elemento) aunque queda más legible si simplemente usas listaInmutable+elemento, y sabes que eso internamente simplemente va a invocar append, pero pues ya te queda más breve el código donde usas ese método.

Ahora, puedes decir "ah pero para mi es más claro decir append que decir +" y puede que tengas razón, pero luego estás escribiendo código y te pones a pensar... para agregar un elemento a la lista, es append o es add? y entonces tienes que recurrir a la documntación. Pues lo mismo pasa con los métodos de nombres mafufos, puedes ir a la documentación y ahí están listados con su descripción y todo.

Scala tiene además una cosa especial con los :, que si los usas al principio o al final de un método, tienen cierto efecto. Esto todavía no lo he visto muy a fondo, lo único que sé es que los métodos que terminan con : los invocas poniéndolos ANTES del receptor. Por ejemplo las listas tienen un método :: podría llamarse prepend porque lo que hace es crear una nueva lista que empieza con el elemento indicado y luego trae todos los elementos de la lista original. Pero la cosa es que lo llamas poniendo primero el nuevo elemento y luego el objeto. Y eso tiene sentido cuando lo lees:

1::2::3::Nil

Nil es un objeto especial, es una lista vacía. A esa lista le estamos pidiendo que haga una nueva lista que empiece con 3. Y luego al resultado de eso le pedimos una nueva lista que empiece con 2. Y a eso le pedimos una nueva lista que empiece con 1. El resultado final es una lista que tiene los elementos 1,2,3. El operador :: se llama cons (y parece que viene definido como un tipo más que como un método, no sé bien los detalles de la implementación pero así es como se usa, apenas estoy aprendiendo esto).

Imagen de bferro

Los operadores que terminan con dos puntos (:)

Los operadores (métodos) en Scala que terminan con dos puntos (:) son asociativos a al derecha

Imagen de bferro

El operador :: no es un tipo; es un método

Las listas en Scala definen el operador :: como un método en el trait List

def :: (x:A): List [A]

Es un operador "asociativo a la derecha". El método se aplica sobre el objeto (lista) que está a la derecha del operador.

Creo que Ryz también lo va a

Creo que Ryz también lo va a hacer o lo hace ya

Algo así, pero en realidad Ryz no tiene sobrecarga de operadores porque el único operador que tiene hasta el momento es el operador de asignación ( = ). Pero el efecto es el mismo pues hay que recordar que el slogan es: "No se trata de escribir menos código sino de que exprese mejor tus intenciones" Aunque este "exprese mejor" varia de persona en persona.

Eso más los métodos de extensión, nos permiten escribir cosas como:

saluda (  mensaje : String,  aquien : String ) {
   "%s, %s!".%( mensaje, aquien ).prinltn()  //Llamar al método % de String
}

Y luego:

saluda("Hello", "world")
//Hello, world!
saluda("Hola",  "Ryz")
//Hola, Ryz!

Donde el método "raro" de extensión se escribe tan simple como:

%( receptor: String,  args: String* ) : String  {
     String.format( receptor, args )
}

Pero bueno, volviendo a Scala, ahí se pueden escribir los métodos con y sin puntos indistintamente, dejando eso a discreción de las buenas prácticas, de la misma manera usar paréntesis o no. Hay una guía "no oficial" de estilo que habla sobre esto, les dejo el link:

http://www.codecommit.com/scala-style-guide.pdf

La desventaja como es posible observar, es que quién no conoce el lenguaje ( técnicamente TODOS, al principio ) pues no pueden saber de que se trata el método ni siquiera buscarlo por Google. Yo sigo sin saber como pronunciar >>= y le digo la función Haskell :P

Imagen de bferro

Sintaxis de los lenguajes funcionales

Es bueno recordar que la sintaxis de los lenguajes funcionales tiene que responder a la forma en que la programación funcional concibe cualquier computación y esa forma es la aplicación de una función sobre el resultado de aplicar otra función y así sucesivamente.
Scala tiene entonces que ofrecer la posibilidad de escribir con una sintaxis orientada a objetos donde la cualquier computación se basa en aplicar un método sobre un objeto y de escribir con una sintaxis de programación funcional.
Creo que esos niveles de expertitud (usando la palabra que dice Enrique) tienen que ver con eso también.
Si vienes de un ambiente orientado a objetos comienza entonces a usar Scala con ese estilo de escribir y poco a poco te irás metiendo en las profundidades oscuras de la programación funcional.

Tomando como ejemplo el operador ::

Con un estilo orientado a objetos:

scala> Nil.::(3).::(2).::(1)
res3: List[Int] = List(1, 2, 3)
scala>

Con un estilo funcional:

scala> 1 :: 2 :: 3 :: Nil
res4: List[Int] = List(1, 2, 3)

scala>

Imagen de ezamudio

Euler

Esta semana me ha servido muchísimo para aprender Scala el estar resolviendo problemas de Project Euler. Muchos se resuelven con manejos de listas y rangos y filtros y cosas así, para lo que Scala se presta muy bien. Algunos problemas los he podido resolver menos de 5 líneas de código.

El poder escribir código que solamente tengo que ejecutar una vez (bueno puede ser varias veces si es que no resuelve el problema correctamente), me libera de pensar en cosas como performance, uso de memoria, etc. Hay problemas donde se tiene que pensar en un algoritmo que no sea pura fuerza bruta para encontrar la respuesta porque toma demasiado tiempo o requiere demasiada memoria, pero en muchos casos no importa si en vez de medio segundo se tarda 30 segundos, si al final se obtiene la respuesta correcta.

En varios casos ya he encontrado dos o tres maneras de lograr el mismo resultado. Y he guardado el código que hice para resolver varios problemas, y ahora que lo veo cronológicamente es curioso que empecé haciendo código muy al estilo Java o cuando mucho estilo Groovy pero ya los últimos conforme he ido conociendo mejor algunas clases, la sintaxis y maneras de resolver algunas cosas, el código se ve más estilo Scala. Sé que todavía me falta mucho, pero seguro que mi nivel de expertancia ya subió un poquito.