style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

Feliz día de Ryz!!!

El año pasado anuncié que estaba trabajando en un lenguaje de programación llamado Ryz ( /reies/ ) y poco tiempo más tarde hice una pequeña presentación del mismo en el #HackerRoom para un "selectísimo" grupo de personas. Este post es una revisión del estado del lenguaje y siguientes pasos.

Historia

  • octubre 2010 El primer Hola Mundo de Ryz.
  • enero 2011 Anunció en Java México y creación del repositorio en http://code.google.com/p/ryz/
  • mayo del 2011 Presentación del lenguaje y una aplicación muy sencilla para sacar screenshots.
  • mayo del 2011 Se creó el repositorio en https://github.com/OscarRyz/Ryz/
  • octubre 2011 Se planeaba terminar la funcionalidad básica que le permitiera entrar en fase alpha, pero por motivos de trabajo ( en agosto del 2011 inicié un proyecto que me consumió hasta los fines de semana ) y ya no pude avanzar como quería
  • Se tenía planeado el beta para el día de hoy ( 6 enero 2012 ) pero esta muy lejos aún.

Estatus

Aunque el avance no fue como lo quería, veo con mucho agrado que la mayoría de la funcionalidad necesaria para pasar a alpha está lista.

Esto incluye las siguientes características implementadas:

  • Definición de clases
    main.Persona {
    }
  • Definición de métodos, atributos de clase y de instancia con modificadores de acceso ( publico, protegido, paquete y privado ), ej.
    main.Persona {
         -  nombre : String
        + __ main( args : String* ) {
            persona = Persona()
            persona.nombre=("Ryz")
            persona.saluda()
        }

        + saluda() {
            "Hola, yo me llamo %s".%( self.nombre() ).println()
        }
        - nombre=( n : String ) {
            nombre = n
        }
        - nombre() : String {
            nombre
        }  
    }

  • Definición de bloques de código
    block.Demo {
       main() {
          unBloque = () {
              "Yeap".println()
          }
          unBloque()
        }
    }
  • Métodos de extensión:
    import( java.util.* )
    extension.Demo {
        // sin modificador de acceso
        // el atributo es privado por omisión
        mapa : Map = HashMap()
       
        // metodo main de instancia
        // sin modificador de acceso es publico
        // por omisión
        main() {
            "nombre" .:( "Oscar" )
            "apellido" .:( "Reyes" )
            mapa.toString().println()
        }
       
        // metodo de extension para string llamado ":"
        // que asocia un valor con la llave en el mapa
        :( key: String, value: String ) {
            mapa.put( key, value )
        }
    }
           
    Salida:
    $ java -jar ryzc-20120106.jar Mapa.ryz
    $ java -cp .:ryzc-20120106.jar extension.Demo
    {apellido=Reyes, nombre=Oscar}

     

  • Annotations
    import ( lombok.* )
    import( some.TestClass )
    @Data @AllArgsConstructor
    demo.lombok.Persona {
       name     : String
       lastName : String
       age      : Integer
    }

    Ver http://projectlombok.org/features/Data.html para más info sobre esta anotación

  • Herencia
    // Un empleado es una subclase de persona
    demo.Empleado : Persona {
    }
  • Implementación de interfaces
    demo.Tarea : Runnable {
        run() {
             "Ruun... ruuuun".println()
        }
    }
  • Inferencia de tipo "obvia"
    demo.Persona {
        unString = "Un string"
        unInt     = 1
        unaPersona = Persona()
    }
  • Eliminación de checked excepcions
    methods.UseCheckedException {

        import( java.io.File )

        test() {
            file = File("sample")
            file.createNewFile()        
        }
    }

  • varargs
    methods.parameters.VarArgsParameterSpec {

       main() {
        self.varArgs("uno")
        self.varArgs("uno","dos")
        self.varArgs("uno", "dos", "tres")
        self.otherVarArs("a", "b", "c").toString().println()
       }

       import( java.util.* )

       varArgs( many : String* ) {
        Arrays.toString(many).println()
       }

       otherVarArs( many: String* ) : List {
          Arrays.asList( many )
       }

    }

  • Multiline strings
    demo.Multilinea {
      multiline = "    This
        is a
        multiline
        string in "
    Ryz"
      "

    }

( Todos estos ejemplos ya compilan y corren actualmente )

Y así varios otros "mini features" más, que por ejemplo sin ser parte del lenguaje mismo, permite construir "cosas" utilizando las características anteriores.

Por ejemplo, a la clase Boolean se le puede agregar un método de extensión que se llame isTrue? que reciba como parámetro un bloque de código y tenemos entonces, control de flujo.

    mensaje : String = recibirMensajeDeAlgunLado()
    mensaje.==("EXIT").isTrue?((){
        System.exit(0)
     }

O si utilizamos un método de extensión each para las colecciones se puede escribir un código que itere una lista ejemplo

   __ main( args : String* ) {
       nombres : List = Arrays.asList( args )
       nombres.each( ( nombre : String ) {
            "Hola %s".%( nombre ).println()
        })
    }

La única característica importante que no está incluída y que evita que el lenguaje entre en alpha es el acceso a las variables locales desde un bloque. Ya sé como resolverlo y he hecho varias pruebas pero aún no he tenido tiempo de implementarlo en el compilador:

    accessVariableInBlock() {
        variable  = "Hola"
        bloque  = (s : String ) {
            variable.println() // <-- no compila aún :-(
        }
    }

Hay muchas otras características que no están implementadas aún y que irán en la fase alpha, ninguna sin embargo muy compleja y son más bien cosméticas así que incluyo podrían no ir.

Ejemplo

  • Paréntesis opcionales para invocaciones con un solo argumento≤
    saluda( mensaje : String ) {
         mensaje.println()
    }
    // más adelante..
    ...
    someObject.saluda "Hola a todos"

    Lo cual serviría para hacer getters más interesantes:

    nombre=( aName: String ) {
       self.name = aName
    }
    ...
    someObject.nombre= "Juan"

    Que podría hacer el código un poco más legible sin caer en la magia extrema de otros lenguajes de programación.

  •  

Funcionalidad lejana por incluir.

Existen muchísmas características más por incluir, pero no creo que sea buena hablar de ellas sobre todo cuando están tan lejos aún. También es importante para mí no cargar de características al lenguaje desde el inicio. La idea detrás de Ryz es que sea un lenguaje simple y sencillo, aunque la simplicidad y la sencillez sean casi por definición atributos subjetivos.

Aún así lo que tengo muchísima interés en implementar es:

  • Tipeo estructurado
  • Parámetros nombrados ( must have )
  • Más inferencia de tipo
  • Generics simplistas

Pero eso quedará supongo no para una primera versión sino para mucho más adelante ( excepto los parámetros nombrados que deben de ir lo más pronto posible )

Siguientes pasos

Pues bien, lo siguiente es terminar la parte de acceso a variables dentro de bloques para poder pasar a alpha y de ahí... chan chan chan chaaaan, hacer el compilado de forma "autocontenida" es decir, escribir el compilador en Ryz mismo ahora sí de una manera "correcta", es decir utilizando la sequencia scanner -> analizer ->AST -> IR -> target.

Actualmente el compilador esta hecho mmhh digamos que de manera "intuitiva" utilizando TDD, así que si está como está es por que fui a fondo con aquello de ... y los patrones emergerán aunque me ha faltado disciplina para aplicar la otra parte de: y entonces refactorizar sin misericordia...

Cuando esta parte este construída entonces Ryz entrará en fase beta y cuando todo aquello funcione muy bien, será el primer release.

Ese es el roadmap y quizá no resulte obvio, pero las fechas para todo aquello están más que en el aire, sin embargo no tengo prisa, la verdad es que voy haciendo esto en mi tiempo libre y a veces es muy pero muy poco el tiempo libre que tengo.

Lecciones aprendidas

Todo esto ha sido maravillosamente educativo. Confirme algunas creencias que tenía y vi de primera mano algunas cosas que no creí que pasarían.

Por ejemplo, vi que es cierto que se puede utilizar TDD para construir cosas como estas, también que se necesita un buen nivel de experiencia para aplicarlo para que se vaya dirigiendo la prueba correcta, de otra forma el TDD te puede llevar a /dev/null :P

También confirmé que escribir un compilador de forma no tradicional ( sin el pipeline descrito arriba , lexer -> parser -> ast -> etc ) es posible y aunque ya sabía que hacerlo de otra forma crea problemas de crecimiento no lo había atestiguado en realidad, así que eso también lo confirmé y es por ello que la fase alfa será hacer el lenguaje autocontenido ( y por eso ahora todo se llame pre-pre-pre-alpha )

Cosas que no me esperaba ( aunque ya las tenía en consideración ) es que la falta de palabras reservadas creara un vacío tal que confundiera, por ejemplo en los métodos, lenguajes como Java anteponen el tipo de retorno ( o void si no tiene )

void nada() {
}

Lo cual permite ver a simple vista donde empieza un método y otro. Otros lenguajes de programación de tipeo dinámico o con inferencia de tipo utilizan alguna palabra reservada como def, fn, func, function ( la que más me gustá es fun, hace la programación divertida de nuevo ¬¬ ) y así por el estilo. Mi idea es que aquello no era necesario ( de hecho NO es necesario , al menos no todo el tiempo, en algún punto el compilador desecha esa y todas las palabras reservadas ) sin embargo, aprendí de primera mano que ese tipo de cosas sirven al humano, al programador pues, para que visualmente pueda identificar en un pedazo de código grande los métodos. Al no tener nada, se confunde un poco donde empeiza un método y donde esta un bloque de código y/o la invocación a otro.

Ejemplo

   mouseReleased( e : MouseEvent  ) {
        isDragging = false
        result.isNull?({
            out.println( "Result is null!")
        })
        result.notNull?({
            dialog.setVisible( true )
            finished = true
        })
    }
    mouseMoved(e : MouseEvent ) {
        finished.isTrue?({
            helper.exit()
        })
    }
    insideOrOutSide() {
       hardToTell = () {
       }
    }
    unless = () {
    }

Conclusión

En fin, me ha dado mucho gusto poder crear esto desde cero. No es el objetivo competir contra otros lenguajes, ni tratar de ser mejor o peor que otros, he encontrado que con que me guste a mí en este momento es razón más que suficiente para existir, y no es egoísmo extremo, simplemente que hay cosas así en la vida, que uno quiere hacer y si las puede hacer las hace y ya.

También me dio mucho gusto encontrar que al menos en diseño Ryz se anticipó, pareció o coincidió con otros lenguajes que tienen la misma dirección, crear un lenguaje de programación compatible con Java que sea más sencillo de usar, después de ello se dieron a conocer esfuerzos como Dart, Extend, Kotlin y Ceylon de los cuales ya hemos dado cuenta acá en Java Mexico. Claro, no es comparación ni nada, es obvio para mí desde el inició que aquellos son lenguajes mucho más mmmhh "formales" y soportados por organizaciones grandes. Aún así, eso no me desmotiva.

Pues esto es todo. Feliz día de Ryz!! :)

TL;DR
Ryz sigue vivo, va lento pero ya tiene muchos features implementados y en el 2012 será autocontenido y seguirá creciendo.

El primer release = undefined

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.
Imagen de Jose Manuel

Que nice.

Pues como yo de estas cosas no se, solo me queda decir: Si se puede!, echale ganas!, que te diviertas!, cuando este listo el primer release me hago un programa en el. =)
Y feliz día de Ryz!!

Rosca de Ryz ...

Hola Oscar, cuenta conmigo si es que necesitas un soldado para extender este lenguaje, fue hace ya algunos ayeres cuando tome mis clases de compiladores jeje, pero siempre es bueno retomarlo :D.

Cosas locas ...

Siempre he tenido la idea de hacer un lenguaje de programación cuya gramática este basada en el Latín o bien desarrollar
un nuevo paradigma de programación basado en la forma en la que un autista describe el mundo. Tuve por ahí algunas platicas con algunos cuates del CIC IPN, pero nunca concretamos nada, había que buscar la papa , jajaja.

Imagen de Sr. Negativo

Feliz día de Ryz

Felicidades !!!

Verás que tu esfuerzo algún día dara buenos resultados :D !!

Por cierto es bastante completa tu explicación.

Imagen de chonflys

Feliz dia de Ryz

Bien..... el desarrollar un lenguaje no es cosa facil, en la universidad me pidieron los automatas de un lenguaje propipo y de verdad se me hace muy complejo.....ojala todo salga bien y esperemos que Ryz vea un dia la luz como lo hizo java en sus inicios

:D :D Muchas gracias. No

:D :D Muchas gracias.

No creo que llegue a tanto, no lo estoy planeando así, pero .. ya veremos , ya veremos :D

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">