#Ryz_language

El pasado viernes 27 se @OscarRyz ha presentado su engendro #Ryz que es un lenguaje alternativo para la JVM y es Orientado a Objetos con tipeo pseudoestatico o pseudodinamico (yo lo definiría así) porque permite definir ambos casos lo cual es un punto a favor porque hay para los que nos gustan los tipos estrictos y hay a quienes les gusta el tipeo libre

la forma de declarar una propiedad:

   + cosaA : String
   - cosaB : Object
   cosaC : Integer // ahorita en este momento tengo la duda si se podria "cosaC : int" o forzosamente debe ser objeto

Pero que es eso del +, - ?? pues resulta que el lenguaje se ha basado en UML para indicar los limitadores de acceso

Por cierto hablando un poco de la declaración de propiedades puedo mencionarles que una desventaja que presenta es que no es posible declarar varias propiedades de un jalón… si así sucediera estaría chido hacer algo así

   -{
   a, b, c, d, e
   } : String

La forma de declarar una clase junto con el paquete se me hace algo muy cómodo ademas de muy razonable ademas que siento que así deberia ser una buena forma de declarar los paquetes junto con las clases... Adiós a package a.b.c.d;

este.es.mi.paquete.Clase { ... }

Lo que no me gusto es cuando vas declarando paquete por paquete en una sintaxis que mencionaron similar a JSON, para mi resulta incomodo estar empujando el código hacia la derecha y eso como que le puedo llamar indentacion absurda:

este {
        es{
                mi{
                        paquete{
                                ClaseA {
                                ...
                                }

                                ClaseB {
                                ...
                                }
                        }
                }
        }
}

Cual es el truco para no confundirse? pues resulta que #Ryz se basa en las "buenas practicas" donde los excelentes programadores SABEMOS que paquete con minusculas y clases con mayusculas en su primera letra... asi es como #Ryz sabe lo que queres decir con tu codigo... buenas practicas, seria genial que todos lo practicaran

Los nombres de los métodos pueden ser expresivos (literalmente hablando)

isValid?()
scream!()

esto ultimo no lo he aceptado completamente (por ahora). Aunque es verdad que #Ryz no tiene operadores (en su lugar tiene métodos que implementan la funcionalidad de ellos) creo que una buena practica seria que nuestros métodos no tengan caracteres que habitualmente no se utilizan porque esto me suena peligroso con la comprension de codigo a posteriori... aunque como dice Oscar "cochinadas las puedes hacer y en cualquier lenguaje (Oscar++ por esa puntada). Este tema lo justifica con la libertad para que puedas nombrar como quieras no como mas se acerque al nombre que verdaderamente quieres (aunque si hay algunas pocas reglas para evitar la confusión del compilador)

Las estructuras de control muestran una peculiaridad… veamos el IF que tiene un cuerpo de esta forma if(<condicion>,<bloque> [, bloque]) (tomado de código real de un programa hecho en #Ryz por el propio autor)

1            ifTrue( x .- x0 .< 1, {
2               ^ 1
3            }, else= {    //;else is a named parameter
4               ^ x .- x0  //; ^ means return from block
5            })

Linea 1: Existe directamente la evaluación verdadera de una condición según lo definido en la primer parte del cuerpo del if (x - x0 < 1) recuerden que los operadores son métodos y es por eso que tiene un punto antes del - y del <… por cierto una peculiaridad que tiene #Ryz es que objeto.metodo() es exactamente los mismo que escribir objeto.metodo esto quiere decir que para invocar a los métodos sin parámetros puede omitirse el paréntesis (esto para mi solo es útil para los operadores porque para la vida real es recomendable escribirlos) y solo será obligatorio cuando se genere ambigüedad con una propiedad (en este caso) llamada método.
Después de la condición inicia el bloque de código que se ejecuta si se cumple la condición… por cierto, iftrue se me hace que no es tan necesario (también existe el ifFalse el cual si se me hace conveniente) porque una condición if sencilla es exactamente lo mismo que el ifTrue

Linea 2: El carácter ^ significa return por lo que esta linea dice que retorna 1

Linea 3: Interesante esta linea, aquí se define el fin del bloque de lo que se ejecuta si la condición de la linea 1 es correcta pero también viene otro bloque llamado else, ahí se nota claramente que un bloque es asignado a else… no sé si se puede cambiar el nombre y en vez de else escribir ySiNo={}

Linea 4: (el cuerpo del else nos retorna x - x0

Linea 5: pues se cierra el bloque del else y cerramos al if

(no recuerdo exactamente los bucles pero igual es condición bloque, espero podamos complementar este post)

En conclusión : conociendo al lenguaje se me hizo muy practica la idea, el autor nos comentó en la presentación que #Ryz se crea por emplear un lenguaje que pueda esribirse a modo de pseudocodigo pero que funcione de verdad aunque nos recalco que es mas "por el gusto" de crearlo. La idea esta bien, el código está abierto así como la invitación a participar en el proyecto http://code.google.com/p/ryz/

El código lo vimos funcionar con una aplicación que hace screenshoots sacada de una área definida por el famoso drag&drop con el mouse. Les complemento diciendo que no hubo errores, la salida fue la esperada y el código también lo tiene en linea para los que gusten probar el lenguaje http://code.google.com/r/oscarryz-ryz/source/browse

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.

Antes que nada muchas gracias

Antes que nada muchas gracias por asistir y por aguantar las casi 3 hrs. de presentación. Quizá si hubieramos platicado menos hubiera sido más rápido pero también estuvo muy entretenido así no crees?

Acá ven algunos comentarios/correcciones sobre lo que dices, respetando claro siempre tu punto de vista:

1.- El tipeo es siempre estático, pero con la inferencia de tipo se puede hacer esto:

a = 1

Con lo cual se define una variable a de tipo entero. Pero como el tipeo es estático lo siguiente mandaría un error:

a = 1
a = ""

A la variable a no se le puede asignar ya un tipo String ( lo cual si se puede en un lenguaje de tipeo dinámico )

2.- Declaración multiple

No me parece muy conveniente esa sintaxis porque colisiona muy feo con los bloques, pero que tal?:

a,b,c,d : String

Mhhh la verdad no lo tengo considerado pero, porque no abres RED ( Ryz Enhancement Description ) je je je .. ( me lo acabo de inventar ) y si viene acompañado de código mucho mejor. Creeme que en este momento es mucho más fácil de lo que parece. La clase a la que hay que moverle es esta: AttributeTransformer.java ( también estaría chido hacer un taller, pero ahora sobre la implementación :-P ) ehem, ehem, ya aterrizando, regresemos.

3.- Paquetes

El default es usar el nombre completo

java.mexico.Post {
}

Pero usar paquetes anidados puede ser util para algunas casos:

java {
   mexico {
        Post {
        }
        Blog {
        }
    }
}

4.- Nombres raros

Simpre quise escribir algo como

a.isNull?({
   "Aguas con el null!!".println()
})

Es decir con un signo de interrogación, ahora puedo. Pero si, hay que tener cuidado con escribir un método como:

    // look ma, no meaning
    +-*%() {
         // Define un método llamado: "+-*%"
         // uh?!
    }

Sobre las reglas que hay que seguir, básicamete lo que no se puede usar es , ( ) { } [ ] y el "." solo puede ir al inicio.

Para ser sincero y como Enrique pudo darse cuenta muy fácilmente estas reglas si están saliendo un poco al vuelo. :) :)

5.- objeto.metodo() no es lo mismo que objeto.metodo exceeeepto! para métodos con un solo argumento:

uno( ) {
}
otro( o : Object ) {
}
yOtro( a: String, b : String ) {
}
...
a = ...
a.uno() //;Si
a.uno   //; No

a.otro( x ) //;Si
a.otro  x    //; SI

a.yOtro( "foo", "bar" ) //; SI
a.yOtro  "foo", "bar"  //;NO

Y es correctísimo!!! la razón es hacernos la vida más fácil al usar métodos como operadores:

a : Integer
//; Correcto pero feo
a = 1 .+( 2 ) .*( 3 ) ./( 4)
// Usando la regla de un paréntesis
a = 1 .+ 2 .* 3 ./ 4  //;un poco más "natural"

( Por cierto, así es entonces como se restan tres números )

b : Integer = 2011 .- 03 .- 27

Más aún, como los bloques se pueden pasar como argumentos se puede escribir:

a.isNull? {
   //;toing...
}

Pero como ya vimos, solo cuando se reciba un solo argumento.

Sobre el "ySiNo=" no no se puede porque el "else=" es un parametro nombrado, se podría no poner, pero al hacerlo se le da claridad.
Otra alternativa es:

   ifTrue( x .- x0 .< 1 , {
      ^ 1
   }).else({
       ^ x .-  10
   })

Pero este es usando "auto encadenamiento" :)

6.- Bucles:

While

//; Quita todo los elementos de la lista e imprime el valor devuelto
list = ArrayList( Arrays.asList("a","b","c"))
whileTrue({ list.size() .> 0 },  {
    out.println( list.remove( 0 ))
})

For

list = ArrayList( Arrays.asList("a","b","c"))
list.each((e:String){
    //;....
})

Hay varias cosas que se nos quedaron el el tintero, pero ya tendremos tiempo de irlas mencionando.

Sobre la aplicación de ejemplo ahí les va un screenshot

Aquí un video de 12 segundos

Aquí un video de 12 segundos demostrando la aplicación:

Todo escrito 100% en Ryz y utilizando claro está las bibliotecas base de Java ( java.awt , javax.swing etc. )

Este es el código ( puesto en Gist para que le resalte la sintaxis y ligeramente modificado de la versión que esta en HG ) : https://gist.github.com/999815

Mareo cool!

Primero que nada, felicidades Oscar.

Lo que estoy viendo de RyzLang es que se parece mucho a muchos lenguajes, por ejemplo el "-" y "+" tipo cómo en Objective-C, las convenciones nomenclatura estilo Java, el uso de "isNull?" muy Rubyista, el init() de Python, algunas cosas tomadas de C# y pues seguro de otros lenguajes que no he tenido la oportunidad de usar o conocer.

Esto lo veo cómo un arma de dos filos, primero porqué pues está chido que hayas sacado cosas que caracterizan y gustan de cada lenguaje en el que te has basado. Lo único malo (desde mi punto de vista) es el paradigma o más bien la mentalidad; leyendo el código de la aplicación tenía que "cambiar de cassette" cada rato y hubo momentos en los que me perdí.

Ahora, respecto a la declaración de variables "de jalón", cómo menciona @java.daba.doo, ya se propuso el "-{a,b,c} : String", y pues tú (@OscarRyz) propusiste "a,b,c : String", pero con respecto a lo de darle visibilidad o no, ¿quedaría así "- a, b, c : String"?

Y pues se ve interesante, raro, pero interesante; esperemos y sea un "éTSito".

Gracias. Jajaj si. Los

Gracias.

Jajaj si.

Los modificadores de acceso son los de UML, pues en Objective-C + y - sirven para indicar si es de clase o de instancia respectivamente.

Lo del isNull? seee Ruby definitivamente, el init() no es de Python, en realidad si se usan constructores ( Python no tiene ) más bien es una convención que usó el que hizo el demo ese de ventanas translucidas y yo de ahí lo traduje.

Sobre cambiar el cassette, precisamente de esto hablabamos el viernes respecto a aprender Scala y Haskell, con uno te hace ruido lo que ya sabes de Java y con otro como empiezas desde cero no hay nada que te estorbe. Por otro lado tener una sintaxis similar, te hace al menos no espantarte cuando ves algo totalmente diferente.

Es cierto, habrá que ser cuidadosos y crear un estilo propio. Ahora mismo me parece un tanto natural que se vea así, medio mezclado; pienso que este estilo se va a consolidar con el tiempo.

Sobre los modificadores de acceso, Ryz provee un default "aducuado" dependiendo de la cosa. Si es atributo el default es privado, si es método, constructor o clase, el default es publico, si es variable, no aplica ejemplo:

demo.Persona {
   nombre : String
   nombre(): String {
        x = 0
       self.nombre
   }
}

Sería en Java:

package demo;
public class Persona {
   private /*final*/ String nombre;
   public /*final*/  String nombre() {
      int x = 0;
      return this.nombre;
   }
}

Pero se puede especificar por supuesto:

+ demo.Persona {
   - nombre : String
   + nombre(): String {
        x = 0
       self.nombre
   }
}

Por lo que se usaría

- a,b,c,d,e : String

cuando se quiere ser explicito en el modificador de acceso o

a,b,c,d,e : String

Cuando se usa el default ( que es privado de todas formas )

Laaaa cuestión viene en como inicializarlos:

a,b,c,d : String = "1","2","3","4"

y con inferencia:

a,b,c,d  = "1","2","3","4"

Puede ser, hay muchísimas!! muchísimas cosas por construir.

Re: Gracias. Jajaja si. Los

Ah, muy bien todo aclarado sólo hay una cosa en la que no estoy de acuerdo:

el init() no es de Python, en realidad si se usan constructores (Python no tiene )

Según yo recuerdo que Python si tiene constructores:

class Persona(object):
        def __init__(self, nombre): #Este es el constructor
                self.nombre = nombre
       
        def printNombre(self):
                print("Hola tu nombre es: %s") % (self.nombre) 
               
persona = Persona(raw_input("Cual es tu nombre?"))
persona.printNombre()

De ahí saqué la idea de qué init lo has sacado de Python. Buena idea, entonces al parecer seguiré con scala.

Me refiero a que no tiene

Me refiero a que no tiene constructores ... mmmhh como Java, C#, C++, Scala ( y claro Ryz ). En realidad Python tiene un método especial llamado __init__ que es invocado cuando se construye el objeto. De forma similar, Ruby tambien y Objective-C tienen un método especial llamado init.

Re: Me refiero a que no tiene

Así ser, funciona igual que un constructor. Porqué un constructor es invocado cuando se construye el objeto (de ahí llamado constructor), ¿o no?, ¿o te refieres a múltiples constructores, que son llamados cómo el nombre de la clase, pero que aceptan cosas cómo polimorfismo sin la necesidad de que el programador evalúe y sea el compilador el encargado?

No me refiero a la cosa que

No me refiero a la cosa que parece método pero que no es método y que se llama igual que la clase :) :) A ese me refiero. jejeje

Saludos

Entendido;)

Entendido;)