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

¡¡Feliz día de Reyes!!

¡¡Feliz día de Reyes!!

Desde que estaba en la universidad, siempre quise crear mi propio lenguaje de programación, pero siempre lo consideré algo mucho muy complejo y propio para Doctores en computación ( y no es que no lo sea, sigue siendo complejísimo, solo que ahora no lo considero como una tarea casi imposible ), y pues nunca le entré.

Recientemente ( 3 - 4 años ) con el florecimiento de tantísimos lenguajes de programación me la pasaba siempre pensando: "Por que no tiene esto?, por que no tiene aquello? y por que no tiene lo otro? y por que no? y por que no?" y de tantos por que noes, me dije a mi mismo: "Mi mismo, ¡¿por que no te dejas de quejar y lo haces tu mismo?!". ¿El resultado? Me di cuenta que no solo es difícil escribir un nuevo lenguaje de programación sino que ¡diseñarlo! es ya es de por sí una tarea muy compleja y cuesta mucho trabajo crear algo que sea a la vez original y "usable".

Aún así insistí.

El resultado es este lenguaje de programación que por no encontrar mejor nombre le puse Ryz - pronunciado Reyes :-" )

hola.Mundo {
  main( ) {
    out.println("Hola mundo Ryz!")
  }
}

¿Y por que diablos crear ¡otro lenguaje de programación más en el mundo! habiendo tantos y tan buenos? Pues por que como diría el comercial: ¡Por el puro inche gusto, caray! ( bueno eso no dice, pero yo por eso lo creé ). Me podría inventar muchísimas razones, como que quería algo más sencillo, que quería algo para mis scripts rápidos, que para no lidiar con X,Y o Z, pero la mera verdad, es que lo hice por que tenía ganas.

El estatus al día de hoy ( 6 de enero del 2011 ) es que, al menos el código anterior ya funciona. Existe un micro "compilador" ( que descaro el mío en llamarlo así ) que genera archivos .class que claro, son 100% compatibles con Java y en general lleva un 20% de avance.

Este lenguaje es diferente a muchos otros, al menos en su razón de ser para con Java, en tanto que, en vez de "patear el pesebre" como algunos otros, diciendo "Java es malo y necesita cambiarse" Ryz admite que de inicio Java es genial, y solo pretende ayudar en la tarea.

Otro ejemplo un poco más complejo ( y que aún no funciona :P ) sería:

hola.SaludaRyz {
  main( args: String*  ) {

    // Ordena el arreglo en forma descendente    
    args.sort!( ( a : String, b : String ) {
       b .<=> a
    })

    // Itera el arreglo e imprime un saludo
    // al argumento pasado
    args.each( ( value : String ) {
      out.print "Hola %s" .% value
    })
  }
}

Mi objetivo es que, el pre-alpha, esto esté listo para abril de este año ( esto de tener que trabajar para vivir, deja muy poco tiempo a los hobbies )

Es lenguaje es open source y el "compilador" está escrito en Java. La estrategia es usar TDD con TestNG sobre IntellJ IDEA, pero el código está tan libre de dependencias hoy en día, que no sería difícil compilarlo incluso desde la linea de comandos.

Como no tenía ningún ánimo de meterme con generadores léxicos y parsers, lo hice a manita, ya sé esto me traerá problemas, pero mi objetivo no es hacer algo robusto, al menos no en esta etapa, sino que todos las ideas que tenía en mi cuaderno cobren vida y esto me ha permitido poder avanzar poco a poco y obtener resultados dedicándole al menos algunos minutos, algunas noches en la semana. Cuando todo funcione, podré considerar usar un generador léxico/parser etc. pero por lo pronto no.

Sin más que agregar les deseo un feliz día de reyes!

Les dejo el link del proyecto:

http://bit.ly/Ryz-language

por si alguien quiere echarle un ojo ( aunque como les dije, casi no hay nada )

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 AlexSnake

Interesante

Se ve bastante bien lo que estas haciendo. Pero si tienes considerado crear un nuevo lenguaje por que no hacer las palabras reservadas en español, así muchos que no entiendan el inglés pues tal vez lo entiendan en español, ó tal vez no tengo ni la menor idea de que tan complejo sea cambiar las palabras, en este caso las que estas ocupando main, args, print, out, each, pero seria algo bueno.

Ojala que pronto puedas echar andar el segundo ejemplo.
Bueno pues mucho éxito, Saludos.

Imagen de bina_best

Muy buen proyecto, mucho éxito!

Muy buen proyecto, mucho éxito! ¡Qué padre que en México haya emprendedores como en su caso y es que en realidad lo que falta es iniciativa y luchar por lo que realmente queremos... que capacidad hay mucha!

Imagen de tejonbiker

Se ve ya con buenos pasos

Se ve ya con buenos pasos avanzados, yo también estoy en vías de hacer un interprete de ecuaciones sencillo, es para un programa de vectores ;).

Buen proyecto @OscarRyz

Siempre es bueno encontrar gente con iniciativa.

0_o

Muchísimas gracias por los

Muchísimas gracias por los comentarios de aliento.

@AlexSnake, Yeap, es algo que también pensé en algún momento, pero es un tanto inevitable. De hecho, ¿mencioné que Ryz no tiene palabras reservadas ( excepto self ) ? Creo que no; bueno pues no tiene.

Algo como esto es posible:

otro.ejemplo.ClasePrincipal {
  validacionEjemplo( nombre = "", apellido = "" ) {
           
    resultado = "Correcto"

    ( nombre .== apellido ) .esVerdad?({
      resultado = "Incorrecto. El nombre debe ser diferente al apellido"        
    })  
  }
}

Pero por regla general, el inglés es el idioma de facto de la industria, por lo que las bibliotecas base y todo el código, está en inglés.

Otra cosa interesante que he aprendido es que con el tiempo, no hablas ni inglés ni español, ni nada cuando programas, por que a la máquina le importa poco. Con el tiempo lo que terminas haciendo es hablar en el lenguaje de programación mismo y documentando ( de ser posible con código ) en algún lenguaje natural.

@Bina_best, gracias. Lo que hace falta , a veces es tiempo :P jejej , Gracias.

@Tejonbiker ahi posteas el link.
@Carraro, gracias!

Saludos a todos y espero, más adelante, poder mostrar algo más y obtener sus críticas y de ser posible sus sugerencias.

Imagen de rodrigo salado anaya

Muchas porras !!!

jejejeje si se necesitaba algo que le diera mucha pila a este proyecto (sin mencionar el tiempo) era esto.

Vientos Oscar : ).

Imagen de CesarAlducin

BUENA IDEA

QUE BUENO QUE EXISTA GENTE CON MUCHA CREATIVIDAD Y QUE DESPUES DE MUCHO BATALLAR
LOGRE COSAS IMPORTANTES

:) !!!!!

Me gusta. A mi parecer es

Me gusta. A mi parecer es cómo un Ruby, Python (el uso de self, valor de parámetros por defecto). Me preguntaba, ¿es posible conseguir el código de Ryz?. Todo con fines educativos claro =), y de ser posible hacer algunas contribuciones o propuestas. Creo una vez lo vi en google code, pero no tuve tiempo de revisarlo bien.

Y pues mucho exito.

Imagen de ezamudio

self

Yo creo que Oscar tomó el self de ObjC, no de Python.

Xaaaacto Ruby, Python,

Xaaaacto Java, Ruby, Python, Smalltalk, Scala, Javascript, C#, Objective-C, hasta UML!. Resulta difícil después de un tiempo hacer algo que alguien no haya hecho antes. Muchas veces dizque se me ocurría algo, solo para encontrar que alguno de esos lenguajes ya lo tiene ( y mucho mejor hecho ).

Por ejemplo, Smalltalk no tiene palabras reservadas ( o creo que si, como 3 o 4 incluidas self ), de Objective-C el self ( como dice ezamudio ) Ruby están muy influenciado por Smalltalk y de ambos ( Ruby y Smalltalk ) está la noción de bloques de código ( aka closures ), Pyhon parametros nombrados, Scala inmutabilidad, C# extension methods, de Objective-C y UML la declaración como con los diagramas de clase ( aunque en Objective-C - es instancia y + es de clase )

- atributoPrivado : String
+ atributoPublico : Bool
- metodoPrivado() : Date
# metodoProtegido()  : Int

Lo malo es que en UML las cosas de clase van subrayadas, pero sería impractico:

- atributoDeClasePrivado
--------------------------

Así que opté por un doble underscore

- __ classPrivateAttribute : Bool

Etc. etc.

Las ideas más radicales y originales, fueron descartadas desde el inicio por impracticas ( aunque algunas lograron sobrevivir )

ej. Inicialmente quería las declaraciones de métodos asi:

someMethod:ReturnType(  arg1: Type, arg2:Type
     methodBody
     moreBody
     yetMoreBody
)

O sea con un solo paréntesis, poner parametros y cuerpo del método. :) :) lo cual es super original, pero yo mismo lo odié en muy poco tiempo, así que murió.

En fin. Por otro lado, por supuesto que las contribuciones son muy bienvenidas. El fin para eso es open source, aunque recalco, solo el 20% de la funcionalidad planeada está completa, mucho de lo que dije acá aún no está implementado :P , pero ya tiene una buena base. Algunas cosas quizá cambien, algunas cosas quizá resulte que no puedo hacerlas. etc.

El link está al final de la página pero ahi va de nuevo:

http://bit.ly/Ryz-language

Imagen de LWSH

wow buen proyecto y muy

wow buen proyecto y muy interesante te deseo mucha suerte compa eso es lo que mexico necesita emprendedores como tu

Imagen de Nopalin

Razones

Que bueno que te animes a hacer algo tan complejo como crear un compilador, pero, al inicio pusiste que siempre decias: por que no tienen esto o aquello, mi pregunta es: a que exactamente te referias con eso? es decir los lenguages nacen para atacar algo específico y por ningun lado lei cuales eran los tuyos. ¿Podrías describirnos cual es el propósito del mismo?, ¿pretendes economizar codigo?, o ¿forzar una escritura ordenada?

Sobres

Excelente pregunta.

@Nopalin, excelente pregunta!

Como decía, este lenguaje toma como principio que Java es excelente y dice "vamos a ayudarlo". Hay muchas cosas son solamente "syntactic sugar" de Java ( en términos estrictos, todo es syntactic sugar de otra cosa, hasta llegar a los impulsos eléctricos, pero eso es otro tema ).

Yo no diría que estas son "las" razones de existir el lenguaje, pero en su conjunto forman un diferenciador.

Una vez más, yo no quiero dar a entender que Java esta mal por lo que sigue, sino, que Java esta bien, tan bien que lo quiero ayudar con:

  • El método main.
  • A veces quiero escribir un programa rápido, y aunque mis dedos ya teclean en automágico:

    public static void main( String ... args ) {
    }

    a veces me gustaría simplemente escribir:

    main() {
    }

    Puede parecer absurdo, pero a veces así es.

  • Inferencia de tipo básica
  •  i = 0
     b = true
     s = "hola"

    // updated
     d = 2011-01-06
     r = /^.*java$/

    "i" es un integer que vale 0, b es un bool que vale true, s es un string, d una fecha, r una expresion regular, etc., digo básica, por que tampoco se trata de hacer adivinanzas. Por ejemplo, los métodos no deberían tenerla:

       canYouTell?() {
           0
       }
       value = canYouTell?()

    Aquí podría ser obvio que el método canYouTell? devuelve Int, pero para ello hay que leer la implementación cuando debería de bastar con que veamos la firma del método.

    Cuando un método no tiene tipo de dato de retorno su tipo de retorno se puede decir que es "void"

    Todo esto, conservando el "tipeo estático", por que varios lenguajes lo hacen con "tipeo dinámico" y solo te das cuenta hasta el tiempo de ejecución.

  • Palabras reservadas
  • Este puede ser un tanto controversial, pero, aunque las palabras reservadas indican clarmente y sin ambiguedad que es lo que hace el programa, a veces siento que podrías prescindir de ellas y al mismo tiempo conservar la claridad. Cuando sale un nuevo lenguaje, se introducen nuevas palabras reservadas. Acá la idea es disminuirlas.

    ejemplos.Principal {
      nombre = "Programa principal"
      version  = 1
       
      main() {
           out.println( "Nombre %s.  v%d".%(nombre, version) )
      }      
    }

    "Principal" es una clase, por que parece una clase; empieza con mayúsculas, tiene el nombre del paquete antecediendole.
    "nombre" y "versión" son attributos de esta clase, parecen atributos, empiezan con minúsculas, tienen un valor etc.
    "main" es un método, parece un método ( espero que no solo para mi ) , empieza con minúscula, tiene unos parentesis, tiene una llave.

    Y así por el estilo. Lo mejor de todo es que al ser un lenguaje de programación de tipeo estático, esta información se conserva en el bytecode y puede ser usada sin problemas desde Java:

    $ls -lR
    .:
    total 8
    -rw-r--r-- 1 oreyes oreyes 274 2011-01-10 21:56 HolaMundo.ryz
    -rw-r--r-- 1 oreyes oreyes 281 2010-12-29 22:39 Usar.java
    $cat HolaMundo.ryz  
    //Este es codigo Ryz
    demo.HolaMundo {
      import( java.util.Date )    
      - name = "Soy un programa Ryz"
      + lastName =  "Ryz"
      // regresa el nombre
      name() : String {
        name
      }
      main() {
        out.println("Hola mundo Ryz!")
        hora =  Date()
        out.print("Ya son las " )
        out.println( hora  )
      }
    }

    Para compilar ( al día de hoy ) se ejecuta la clase ryz.compiler.RyzC:

    $java -cp ../ryz/out/production/ryz/ ryz.compiler.RyzC HolaMundo.ryz
    $ls -lR
    total 12
    drwxr-xr-x 2 oreyes oreyes 4096 2011-01-10 21:59 demo
    -rw-r--r-- 1 oreyes oreyes  274 2011-01-10 21:56 HolaMundo.ryz
    -rw-r--r-- 1 oreyes oreyes  281 2010-12-29 22:39 Usar.java
    ./demo:
    total 4
    -rw-r--r-- 1 oreyes oreyes 1057 2011-01-10 21:59 HolaMundo.class

    La clase HolaMundo.class fue creada!! :)

    Como tiene un main, lo podemos ejecutar con el interprete de Java mismo.

    $java demo.HolaMundo
    Hola mundo Ryz!
    Ya son las Mon Jan 10 22:00:11 CST 2011

    Y lo podemos usar desde una clase Java

    $cat Usar.java

    // Una clase en Java típica
    package demo;
    class Usar {
        public static void main( String [] args ) {
            HolaMundo holaMundo = new HolaMundo();
            System.out.println("¿Quién eres? " );
            System.out.println( holaMundo.name()  ); // metodo
            System.out.println( holaMundo.lastName  ); // atributo
        }
    }

    Compilams con Javac

    $javac -d . Usar.java  

    $ls -lR
    total 12
    drwxr-xr-x 2 oreyes oreyes 4096 2011-01-10 21:59 demo
    -rw-r--r-- 1 oreyes oreyes  274 2011-01-10 21:56 HolaMundo.ryz
    -rw-r--r-- 1 oreyes oreyes  281 2010-12-29 22:39 Usar.java
    ./demo:
    total 8
    -rw-r--r-- 1 oreyes oreyes 1057 2011-01-10 21:59 HolaMundo.class
    -rw-r--r-- 1 oreyes oreyes  569 2011-01-10 21:59 Usar.class

    Y ejecutamos desde la clase de Java "Usar"

    $java demo.Usar
    ¿Quién eres?
    Soy un programa Ryz
    Ryz
  • Métodos anónimos ( a.k.a ) closures
  • Aunque existen desde los primeros lenguajes de programación, en Java fue dejado fuera con una buena razón, son un tanto extraños en la POO. Sin embargo con el advenimiento de los nuevos lenguajes se hicieron populares de nuevo y Java los tendrá en Java v8.

    Ruby los usar intensamente y Groovy "se inspiró" en Ruby, sin embardo en ambos, los closures se usand de una forma "rara" ( para mí ) aunque puedan ser parametros, no van dentro de la lista de parametros, van "al lado" con algo de magia:

    #ruby
    a = ... # a es un arreglo

    # sort a secas,  ordena en forma "natural"  ascendente
    a.sort()

    # sort con un bloque de código, ordena en forma customizada
    # en este caso descendente
    a.sort() { |x,y|
       y <=> x
    }

    Pero el bloque "{}" está afuera, además no parece una función, parece una "otra cosa". En Ruby ( y supongo que en Groovy por añadidura ) esto se mitiga un tanto, por que los paréntesis son opcionales, por lo que la llamada más probable a encontrar sería:

    a.sort
    # y
    a.sort { |x,y| y <=> x }

    En javascript es un tanto más "intuitivo" y es exteeeensamente usado:

    // a es un arreglo
    // natural, ascendente
    a.sort();
    // customizada (en este caso descendente )
    a.sort( function( x, y ) {
       return y - x;
    });

    Algo así me gustaría tener*:

    a = .. // a es un arreglo
    a.sort() // ascendente
    a.sort( ( x : Int, y : Int ) : Int {
       y .<=>  x
    })
* No está implementado aún

En fin, son varias más y espero poder seguir describiéndolas, si hay al menos una persona que tenga interés ( no escribí todo esto inicialmente, por que a mi en lo particular, las paredes de texto me desaniman a leer).

Espero les parezcan interesantes y se aceptan críticas y si vienen acompañadas de código mejor aún :) :) :)

Continuará...

Ryz es un trabajo en progreso, si nada de lo que escribí aquí funciona, es por que esta en etapa pre-pre-pre-alpha
Imagen de ezamudio

Dudas

Leyendo este último post me surgen varias dudas:

¿Cómo sabes que main() es un método estático? Es simplemente por el nombre? Ninguna clase puede tener un main() de instancia?

¿No sería mejor usar formato ISO para fechas (2010-01-10) en vez del que propones? El eterno problema de los que usan fechas en formato dd-mm-aaaa como nosotros, y los que usan formato mm-dd-aaaa (como los gringos). Y cómo puedo poner entonces una resta de 3 números?

El quitar palabras reservadas, es algo que realmente vas a poder hacer, siendo RYZ un lenguaje de JVM? si no usas por ejemplo la palabra reservada package, entonces puedes declarar una variable llamada así... pero no la podrías utilizar desde Java y creo que ni de Groovy (pierdes interoperabilidad).

Por cierto, lo que dices de métodos con o sin paréntesis: en Groovy si haces por ejemplo a.b, b no puede ser un método; se busca un getB() o una variable de instancia llamada b, pero si quieres invocar un método b() necesitas ponerle paréntesis.

Y por último... me da la impresión que estás haciendo el lenguaje conforme se te van ocurriendo cosas. Creo que te convendría mucho más primero diseñarlo, y luego irlo implementando. Y para diseñarlo que no sea solamente por ejemplos, sino que hagas los BNF de las distintas estructuras gramaticales y sintácticas del mismo, con lo que luego puedes verificar su corrección (de correctness, o sea que todo sea correcto, no de que haya que corregir algo, aunque así también encuentras problemas y los puedes corregir). Creo que esto es importante porque si lo dejas crecer así nada más de manera orgánica conforme se te ocurran cosas (o a los colaboradores que le vayan entrando), no habrá realmente una dirección sino se va a volver un verdadero relajo.

Y veo que has visto algo de Ruby y Python, pero no Groovy. Sería bueno que le eches un ojo también, y a Scala tal vez, simplemente para tomar ideas buenas de esos lenguajes y evitar los errores que hayan cometido en el camino. Incluso siendo tan nuevos creo que debe ser más fácil encontrar algo de la historia de cómo se han ido formando (más allá de "es que me choca Java pero me gusta la JVM y entonces por eso hicimos este lenguaje que tiene lo bueno pero no tiene lo malo"); tal vez ya nadie usa BNF y son ahora otras estructuras o notaciones pero de que tiene que haber diseño, creo que lo tiene que haber...

Yeap. Definitivamente. Has

Yeap. Definitivamente.

Has tocado varios puntos muy importantes ( y no ignorados ) y antes que nada, te agradezco el tiempo que te tomas en revisar esto.

Aquí van algunos puntos:
 
 

  • 1.-main recibe un tratamiento especial aquí y de hecho si es de instancia. Se crea y se instancía una clase cada vez que se invoca la clase. Para evitarlo basta con crear el método de clase ( Algo similar a lo que hace Java con el contructor sin parametros, si no lo pones, él te ayuda, pero si lo pones o pones otro, él ya no se mete.

    El métdo de clase, analogo al main de Java sería:

    // Ryz
    + __ main( args : String* ) {
    }
    // Java varargs
    public static void main( String ... args ) {
    }

    Y

    // Ryz con arreglo de Strings
    + __ main( args : Array[String] ) {
    }
    // Y java
    public static void main( String [] args )

    Y el main(), no se genera ya.

    Sobre restar 3 números... :) :) :) No quieres saberlo ( al menos no hoy, tampoco como se hace un while :P ) pero si está contemplado.

    Pero tienes razón sobre el formato de fecha, estupidez mía totalmente, fixing. Actualmente usa java.util.Date, mi objetivo es utilizar la librería Joda time.

  • 2.- Si se puede pero ( efectivamente ) se sacrifica interopeabilidad, aunque lo que se pierde es una interoperabilidad que Java no tenía en primer lugar. En Java no se pueden invocar esos métodos, pero es porque en Java son ilegales, punto, no podian ser llamados antes y claro no se pueden llamar después. Lo curioso es que Java mismo hace este tipo de cosas ( aunque no nos demos cuenta ) y otros lenguajes como Scala y Clojure también ( y no lo digo como pretexto, sino como mmhh curiosidad, yo lo aprendí, justamente cuando quizé usarlo) .

    Un ejemplo donde Java lo hace ( y peor aún, sobre identificadores validos!) , es en el siguiente código:

    $cat Externa.java  
    // Codigo valido en Java
    class Externa {
      private final String s = "atributo de la clase 'Externa'";
      private class Interna {
          private void x() {
              System.out.println( s );
          }
      }
      public static void main( String ... args ) {
        new Externa(). new Interna().x();
      }
    }

    Pero esta versión no es válida, aún cuando access$100 es un identificador legítimo en Java!

    class Externa {
      private final String s = "atributo de la clase 'Externa'";
      private class Interna {
          private void x() {
              System.out.println( s );
          }
          // errh, no se puede:
          public void access$100( Interna i){
          }
      }
      public static void main( String ... args ) {
          new Externa(). new Interna().x();
      }
    }

    La razón:

    Externa.java:12: the symbol access$100(Externa.Interna) conflicts with a compiler-synthesized symbol in Externa.Interna

    Es decir, Java mismo a veces hace este tipo de cosas ( que no son malas en lo absoluto )

    En nuestro caso sería diferente, por que no estamos queriendo acceder a un método válido. Pero efectivamente, algo que mencionas ( de forma tácita ) es que la interfaz pública del objeto no es interoperable. En este caso , el approach algo similar a lo que hace Scala ( aunque no me crean, se me ocurrió esto y cuando investigué sucede que coincidimos - buen, casi - ) es el siguiente:

    // This is scala
    class Some {
     var n = ""
     def name = n
     // Este método no puede ser llamado desde Java:
     def name_= (value:Int) : Unit = n = value
    }
    val s = new Some()
    s.name = "Magic" // sugar for name_=

    Pero scala generan un método de conveniencia para Java:

    //this is Java
    ...
       Some s = new Some();
       s.name_$eq( 0 );
    ...

    Y en Ryz

    // this is Ryz:
    class.Some {
        // este método no se puede invocar en Java
       name=( i :  Int ) {
       }
       main() {
         s = Some()
         s.name= "X"
       }
    }
    // this is Java
    ...
    import class$.Some;
    ...
    Some s = new Some();
    s.name$eq( "new name");
    // o mejor aún:
    s.setName( "with setter");

    Pero también se genera un método de conveniencia ( de hecho 2 ) y que conste que no lo acabo de inventar :) ( recuerdan lo de "que es entrar y que es salir en "<" vs. ">" ? )

    Ya sé que parece como que raro ( y lo es ) , pero incluso Groovy hace algo similar:

    // from Groovy
    class Property {
       def name = "The name"
    }
    // from Java
    class UseIt {
       public static void main( Stirng ... args ) {
            Property p = new Property();
            p.setName( "OtherName" ); // de donde vino el set? Pues Groovy lo puso por nosotros.
       }
    }

    Que en este caso no es usar una palabra reservada, sino crear un método de conveniencia ( el setter ). Mi punto es que para conseguir la interoperabilidad hay que echar mano a recursos como estos.

    Así que esta dentro de la delgada linea entre bug y el feature.

    Hay incluso una propuesta para permitir estos nombre raros desde Java, pero la sintaxis es horrenda, espero que jamás la aprueben ( perdí el link por cierto )

  • 3.- En realidad no, el lenguaje ya está diseñado ( al menos el 95% del alcance para la primera fase), pero efectivamnte, no de una manera formal y la implementación esta en curso. Estoy consciente de que utilizar un generador de parser es lo mejor, por que cubre miles de casos que a mano son simplemente poco factibles de cubrir y el cambio en una regla de producción propaga los cambios sobre todo el código.

    En Java el de cajón es ANTRL, que es muy bueno, también está JavaCC, incluso eclipse en la versión Helios ( no sé que número sea ) incluyó un Language Development Framework que está increíble, por que al final el lenguaje creado tiene soporte del IDE mismo ( autocomplete, method look up etc. ) y esta realmente impresionante ( ver el video )

    Pero ( simpre hay un pero ) el aprender este tipo de herramientas toma bastante tiempo, y es un área de investigación muucho muy amplia y practicamente todo te lleva a revisar libro del dragon que es un moustruo de 800 paginas de lectura no precisamente ágil. No digo que no valga la pena, si que lo vale, y durante mucho tiempo esto precisamente es lo que me tuvo detenido ( por años ) , hasta que dije : "Al diablo!" Y empecé con TDD.

    Si bien es verdad que herramientas como estas ( incluso ya alucinando con incluir LLVM para el backend ) no hacen el desarrollo infalible, si ayudan y ahorra muchísimos errores triviales.

    Para la versión beta, espero poder incluir una herramienta así, en la alpha, estoy explorando la semantica e interoperabilidad con Java. Por lo pronto ya me compré este libro ( 350 pgs ) del autor de ANTRL ( y ahorita lo tengo para nivelar tele )

  • 4.- Si leo Groovy y Scala aunque no como quisiera, especialmente Scala que es de tipeo estático ( de hecho el author de Groovy dijo: "Si hubiera sabido de Scala en ese entonces, no hubiera creado Groovy en primer lugar", e inicialmente empecé revisando Groovy, pero la verdad es que el tamaño de ambos ( Groovy 185k LOC , y Scala 200k LOC ) es un tanto difícil de manejar. Ambos son lenguajes mucho muy completos y están terminando su infancia para empezar con una buena madurez.

Imagen de ezamudio

BNF

OK a todo... pero no mencioné generadores de parser, yo hablaba de Backus-Naur, para el cual unicamente necesitas un editor de texto como Notepad, TextEdit, vi, emacs, etc. Es de las cosas básicas que ves en la universidad (espero que lo sigan viendo) y tal vez el problema es que lo ves tan al principio que nunca te imaginas que algún día vas a necesitar usarlo porque se te ocurrió hacer un lenguaje de programación.

Que yo sepa, hoy en día se sigue usando formalmente, incluso para tecnologías relativamente recientes en Java, incluso por ahí te encuentras la sintaxis de Java en BNF (parece ser un ejercicio que le dejaron a alguien pero es muy útil para diseño de lenguajes). O tal vez hablamos de lo mismo porque ANTLR puede leer BNF?

Re: Xaaaacto Ruby, Python,

Buena la explicación ;).

Está interesante, ahorita más tarde me bajo el source y a estudiarlo. Me quería enrolar en un proyecto así =), ay luego (haciendo administración del tiempo) aplico para committer. Claro no sin antes estudiar bien el lenguaje.

Saludos!

Si, hablamos de lo mismo. Lo

Si, hablamos de lo mismo. Lo interesante de ( la ) BNF es que una herramienta ( como YACC, BISON, ANTRL ) pueda leerlo y generar el código necesario para crear el frontend del compilador, y una vez con el AST en mano, tu generes el backed.

Le pones una regla de producción y luego el generador escribe el código necesario para parsearlo.

Por ejemplo ( del link ) un string está definido como:

string  ::= "''" { character } "''"

O sea ( " ) seguido de un caracter , seguido de otra doble comilla ( " )

También se puede definir todo precisamente como tu dices, sin tener que pasarlo por una herramienta, con el simple objetivo de "ponerlo por escrito" por que si bien es cierto, que ya digo que lo tengo diseñado, también es cierto que solo está en mi cabezota ( y en mi cuaderno ) y definitivamente para poder crecerlo de forma controlada, hay primero que plasmarlo.

Así que un trabajo que voy a empezar es hacer la especificación del lenguaje ( quzá es esta a la que te refieres? ) donde se describe que cosas si tiene el lenguaje y que cosas no, pero principalmente que cosas significan cada una. Ahí se puede usar cualquier notación, pero obvio, los diseñadores de lenguajes, prefieren o BNF o algo que se le parezca mucho.

Como curiosidad busque en Google "language specification" y me salieron estas de varios lenguajes:

Java http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html
Go http://golang.org/doc/go_spec.html
Python http://docs.python.org/reference/
Scala http://www.scala-lang.org/docu/files/ScalaReference.pdf

@wishmaster77 Como bien

@wishmaster77 Como bien menciona el Maistro del Softgüer Henrí Zamudio, hay que tener primero una especificación del lenguaje para poder estudiarlo, pero ahorita no hay nada como eso.

Lo que hay son "test specs" que funcionan de la siguiente forma:

En el directorio http://code.google.com/p/ryz/source/browse/#hg%2Ftest-resources

test-resources
 - 00.loading
 - 02.classes
 - 03.attributes
 - 04.methods
 - 05.import
 - 06.blocks
 - 07.structural-typing
 - misc
 

Existen varios archivos ShalalaSpec.ryz que definen alguna parte del lenguaje y en el encabezado tienen una especificación que es validada con TestNG.

Por ejemplo: 02.classes/SimpleSpec.ryz que fue de los primeros que hice tiene el siguiente contenido:

/*
className: simple.class$.One
classFile: simple/class$/One.class
*/

simple.class.One {
}

Dice en simples palabras que:

1) Cuando esta clase de compile debe de generar una clase java que se llame "simple.class$.One"
2) Que el archivo .class generado se será "simple/class$/One.class.

Uno de los más recientes que ya incluso prueba "comportamiento" es este:

04.methods/BehaviorSpec.ryz

/*
className: methods.invoke.InvokeStatement
classFile: methods/invoke/InvokeStatement.class
extends: java.lang.Object
implements:
attributes:  
methods: public-static main : void , \
         public main : void
behavior : new,  invokestatic main([Ljava.lang.String;) | stdout=Hello Oscar\n,\
invokestatic createInstance() | result=methods.invoke.InvokeStatement@0,\
invokevirtual toString() | result=methods.invoke.InvokeStatement@0,\
invokevirtual modifyNumber() | result=2
*/

methods.invoke.InvokeStatement{

  number : Int = 0
  main(){
    out.println("Hello Oscar") // TODO: change to:  out.print "Hello world"
  }
  __ createInstance():InvokeStatement {
    InvokeStatement()
  }
  hashCode(): Int  {
    0
  }
  modifyNumber() : Int {
    self.increment()
    number
  }
  increment() {
    number = 2
  }
}

La clase ryz.compiler.TestCompiler que se encarga de

A) Leer estos archivos Spec.ryz y
B) Pasarselos al compilador RyzC
C) Leer ese encabezado
D) Comprobar que se cumpla el spec

Por ejemplo, en esté codigo es donde se verifica que se haga la compilación:

    @Test(dataProvider="sourceFiles")
    public void runTests(Properties spec) throws IOException, ClassNotFoundException {

        String className  = spec.getProperty("className").trim();
        String testFile   = spec.getProperty("fileName").trim();
        String sourcePath = spec.getProperty("sourcePath").trim();

        testUtil.addSourceDir(new File("./test-resources/"+sourcePath+"/"));

        try {

            testUtil.assertMissing(className);
            testUtil.compile(testFile);
            Class clazz = testUtil.assertExists(className);
            extendsAssertion.assertDefinition(clazz,  spec, testFile);
            implementsAssertion.assertDefinition(clazz, spec, testFile);
            attributesAssertion.assertDefinition(clazz, spec, testFile);
            methodsAssertion.assertDefinition(clazz, spec, testFile);
            assertBehaviour.assertDefinition(clazz, spec, testFile );
 
        } finally {
            testUtil.deleteFromOutput(spec.getProperty("classFile"));
            testUtil.deleteFromOutput(spec.getProperty("otherClasses"));
        }

    }

Todo lo que haga de código en el compilador, será solamente para satisfacer estos specs.

Saludos!!

Imagen de ezamudio

Spec

Exacto, me refiero a que lo primero que deberías hacer (o no sé si lo primero pero ya lo debes tener y si no lo tienes pues es prioridad 1) es una especificación formal del lenguaje. No tiene que estar escrito en piedra, es modificable, pero te da una guía ya muy bien definida de lo que quieres que haga el lenguaje, te permite detectar inconsistencias, incongruencias, etc etc. Va de la mano con los BNF.

Y además la spec será de mucha utilidad si más gente comienza a trabajar en el lenguaje, porque no tienen que estarte preguntando exactamente qué debe hacer cada cosa, pero tampoco van a hacer lo que se les ocurra en ese momento.

Imagen de IRr3v3rsible

MUY BIEN!!

YA BAJE EL CODIGO, LO ESTOY ANALIZANDO Y AUNQUE SIENDO SINCEROS HAY ALGUNAS COSAS QUE NO ENTIENDO, ESPERO ALGUN DIA HACER ALGO COMO ESTO!!

EN HORABUENA!!

NOTA: INTERESANTE PLATICA! OJALA CONTINUEN PARA ACLARAR ALGUNOS CONCEPTOS!

ESPERO ALGUN DIA HACER ALGO

ESPERO ALGUN DIA HACER ALGO COMO ESTO!!

Je je je.. .ojalá no, esto es un ejemplo de "no hacer".

En realidad es bastante sencillo ( en términos de diseño ) porque mi intención de aquí a Abril es hacer una prueba de concepto completa y no un compilador eficiente.

En términos de implementación admito que sí esta algo revuelto, pero por otro lado apenas son como 1300 lineas de código, es decir aún es "imprimible" :P

Mi siguiente objetivo después de eso es utilizar un generador de parser como ANTRL. Hoy en día comparado con eso es muy ineficiente.

Digamos que el hilo principal del "compilador" está aquí:

http://code.google.com/p/ryz/source/browse/src/ryz/compiler/RyzClass.jav...

   public void transformSourceCode() {
        for( String line : sourceLines ) {
            for( LineTransformer t : transformers() ) {
                t.transform( line, generatedSource );
            }
        }        
    }

Es decir.

Por cada linea de código  "line"
  Y por cada transformador de codigo "t"
      Deja que el transformador "t", transforme la linea de código "line"

El concepto es tan burdo que da pena, pero, lo que hace cada transformer es ver si la linea tiene un formato especifico o no.

Por ejemplo este es el transformer que hace match contra una sentencia como

something.toString(somethingElse)

http://code.google.com/p/ryz/source/browse/src/ryz/compiler/LineTransfor...

class StatementTransformer extends LineTransformer {
    public void transform(String line, List<String> generatedSource) {
        Matcher m = Pattern.compile("\\w+\\.\\w+\\(.*\\)").matcher(line);
        if( m.matches() ) {
            generatedSource.add(String.format("    /*invocation*/%s;%n",line));          
        }        
    }
}

Es decir: Si hay

statement = unaPalabra /*seguido de*/
    unPunto  /*seguido de*/
    otraPalabra  /*seguido de*/
    unosParentesis

Entonces simplemente reescribelo.

Acá te dejo una referencia del lenguaje, con una especificación semi-formal similar al BNF

http://code.google.com/p/ryz/wiki/RyzLanguageReference

Imagen de Jose_Gastelum

io ahorita tmb estoy haciendo un compilador

lo estoy haciendo en java para java solo que abarcare en modo de consola por que es muy extenxoooo ya tengo el lexico voy por el sintactico en unos dias terminare el 2do analisis esta bien lo que comentas

Orale, super! A que te

Orale, super!

A que te refieres con "modo de consola"?

Imagen de IRr3v3rsible

Interes!

Ps mas que nada por la inquietud de crear un proyecto importante, no importa si no sale al mercado. Explorarias ciertas areas que no te enseñan en la escuela, no cualquiera se avienta en hacer algo como esto...por cierto cuanto tiempo llevas? años? meses?...

¿Haciendo esto? como 4 meses

¿Haciendo esto? como 4 meses ( de nov para acá ), aunque como es hobby, le dedico a penas una hora cada 3-4 días en las noches, por lo que voy muy lento.

Imagen de Shadonwk

#rumor una liberación de #Ryz

#rumor una liberación de #Ryz para el 30 de abril, día del ñoño #dicen

Imagen de Sr. Negativo

Re:#rumor una liberación de #Ryz

@Shadonwk ¿Es verdad? o solo es un comentario (sarcástico)???

¿Qué no le corresponde a @OscarRyz anunciarlo?

Ja jajaj... Así como Google

Ja jajaj...
Así como Google tiene todos sus productos en Beta, yo creo que Ryz siempre estará en Alpha. Aún así mi idea es(ra) tener toda la fucionalidad a manera de demo para inicios de abril ( que viendo mi calendario, yo creo que ya valió ) y a este le llamé el pre-pre-pre-alpha..

Así que no creo que haya release en un buen rato.

Lo que sí es más seguro es un platica en el próximo Opentalks, pero será hasta que confirme con Benek.

Imagen de Sr. Negativo

Re:Re:#rumor una liberación de #Ryz

Tal vez salga para el día de los inocentes...yo caí (ups!)

Espero ahora si asistir a los OpenTalks y ver tus avances @OscarRyz... suerte!

Imagen de Shadonwk

un poco de risa es bueno de

un poco de risa es bueno de vez en cuando... @OscarRyz te hubieras echo la idea de sacar un alpha sin tantos pre detrás para ese día...

Bueno, lo que pasa es que los

Bueno, lo que pasa es que los pre's tienen una razón, sin ellos lo único que hay son buenas intenciones, pero nada de código.

Bueno, Yo soy un principante

Bueno, Yo soy un principante de 4 semestre en la universidad y no entiendo muy bien esto, pero en verdad es sorprendente lo que haces, en serio no puedo imaginarme al grado de complejidad que implica todo esto, pero te deseo lo mejor, QUE TENGAS MUCHO EXITO!, gente como tú son el orgullo Mexicano :-D!! Suerte y un saludo!

jejeje gracias David, aunque

jejeje gracias David, aunque al paso que voy me perfilo para la decepción mexicana :P

Nahh ya en serio, el lenguaje SI es de verdad y esta más o menos bien definido. La implementación del compilador es lo que está de risa.

Básicamente hice un programa en Java que lee un archivo fuente y lo transforma a un .class, es mucho muy similar a tomar datos de un archivo y transformalo para hacer un JSP ( bueeeeno es un simil ).

Si es complejo cuando se hace bien, y cuando se hace como lo estoy haciendo pues no es muy diferente el código espaguetti de cualquier otra aplicación.

Espero eventualmente tener tiempo para hacer algo más eficiente, elegante, correcto y mantenible.

Por lo pronto sigo dedicandole unos ratos para hacer que esto cobre vida.

Imagen de ingscjoshua

mmmmm

Hola Excelente ver esa aportación y lo mejor decir no esque java sea malo yo voy a mejorar lo que en java no es tan bueno me parece excelente concepot y aunque en las cosas que aqui comentan no tengo ninguna experiencia generando lenguajes me parece muy buen acerbo cultural lo que hoy he aprendido y pues algun dia espero poder ayudar aunque sea documentando o con alguna funcion!!! :) despues de todo creo que todos buscamos como mejorar nuestro trabajo y esto habla de lo grande que eres como desarrollador JAVA tanto que ya estas haceindo un lenguaje sobre el!! Excleente sigue adelante !!! ojala algun dia dieras una platica de esto!!!:)

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