Groovy:comparativa con otros lenguajes
Hace tiempo que estoy tratando de aprender este lenguaje y la verdad todavía no le "agarro la onda". Y creo que la única forma es perder el miedo a conocer algo nuevo.
Pero, antes de empezar ¿Qué es Groovy?
Según San Google, es un lenguaje de programación implementado sobre la plataforma Java y que sigue el paradigma orientado a objetos.
Algunas de sus características:
- Compatible con programas en Java
- Dependiente de la Java Virtual Machine (JVM)
- Genera bytecodes al igual que Java
- Bueno, bonito y barato(más bien gratuito)
- Bastante parecido a Python, Scala y Ruby
Un ejemplo sencillo: "El famoso hola mundo"
Hola.groovy:
Hola.py:
Hola.rb:
Hola.scala:
Es increible lo parecidos que son, sin embargo cada uno tiene su propias peculiaridades.
También me llama la atención que las clases (class
) son un tanto extrañas (según yo), se puede omitir el ";" , se pueden emplear librerías Java import java.paquete.clase;entre otras cosas.
Otros ejemplos ahora con clases:
Gente.groovy
Gente.py:
def asignaNombre(self,nombre):
self.nombre
def obtenerNombre(self):
return self.nombre
miObjeto = Gente()
miObjeto.asignaNombre(‘El Negativo’)
print “Nombre ”, miObjeto.obtenerNombre()
Gente.rb:
def initialize(nombre)
@nombre=nombre
end
def nombre
@nombre
end
def to_s
“#{@nombre}”
end
miObjeto = Gente.new(‘El Negativo’)
miObjeto.nombre
miObjeto.to_s
Gente.scala:
Ahora una clase con Java
Java.java
¿Qué más sigue? los Clousures
Según San Google,"es un bloque de código anónimo definido entre llaves"
Algo asi como:
Ustedes perdonaran la calidad de estos programitas, pero no todos somos @ezamudio u @OscarRyz.
Tu...¿Qué harias con Groovy?
- Inicie sesión o regístrese para enviar comentarios
Corregí un par de cosas en
Te complemento los ejemplos de los closures:
Python
def b():
print "Tu tienes 5 años"
return b
c = a()
c()
Ruby
a = -> {
"tu tienes 5 años"
}
a.call
Scala
t()
Java
public void run() {
System.out.println("Tu también tienes 5 años");
}
};
r.run();
Y porque no:
Ryz
out.println("Tienes 5")
}
b()
Gente y hola mundo:
nombre : String
verGente() {
out.println( nombre )
}
__ main( args : String* ) {
g = Gente()
g.nombre = "Ryz"
g.verGente()
}
}
___ main(args : String* ) {
out.println("Hola, mundo")
}
}
Diablos creo que ya me tengo que poner a trabajar de nuevo en eso.
JVM
Eso es porque Groovy corre sobre la JVM. Si compilas el código groovy, se compila a bytecode de Java, te queda un
.class
y puedes correrlo en Java solamente importando dos o tres jars que requiere groovy.Haz la prueba, crea un archivo Ejemplo.groovy con este código (NO le vayas a poner Prueba.groovy, luego verás por qué):
String nombre
}
Prueba p1 = new Prueba()
p1.nombre = 'Uno'
Prueba p2 = new Prueba(nombre:"Prueba Dos creada a las ${new Date()}")
println p1.nombre
println p2.nombre
Si lo corres, obtendrás algo así:
Pero eso fue interpretando el archivo como un script de Groovy. Ahora compílalo con groovyc:
Como puedes ver, de un solo archivo, se crearon dos clases. Así es: Groovy te permite definir varias clases en un archivo. Y no son clases internas ni nada de eso, cada una es clase de primer nivel. Puedes analizarlas con javap:
Y la otra clase también:
Si hacemos una clase similar en Java (pero no tendría el constructor default que agrega Groovy como el que usamos para la segunda instancia):
private String nombre;
public void setNombre(String value) {
nombre = value;
}
public String getNombre() {
return nombre;
}
}
Ahora, regresando a Groovy, para correr el ejemplo que hiciste en Groovy pero con java:
Tienes que hacer algo así:
O si no quieres usar ese jar que tiene varias cosas adicionales que tal vez no necesitas, entonces:
Son los dos jars que he visto que se necesitan, no sé si para cosas más complejas se necesite algo más. Tal vez para ciertas cosas más avanzadas del lenguaje, se requieran otras bibliotecas, pero incluso usando closures, con esas dos la haces. Eso es muy útil para poder integrar clases Groovy a aplicaciones Java, afectando de manera mínima las dependencias de dicha aplicación.
Deberían ser maestros de programación
Solo falta que sus códigos cobren vida y tengan voluntad propia. No ya en serio, muy buena explicación del lenguaje. Yo apenas voy aprendiendo un poco.
def TuEdad={
println "Ahora tengo 10 años"
}
println "¿Adivina cuantos años tengo?"
TuEdad()
Me falta investigar más sobre los Clousures Gracias por las aclaraciones.
Closures
Piensa en los closures como funciones que se pueden pasar como parámetros a métodos o a otros closures. Lo que ni a mi me queda todavía muy claro es el contexto del cual pueden tomar variables, pero por ahora no nos compliquemos con eso. La diferencia entre un closure y un método, es que el closure no está pegado a un objeto, es más similar a una función como de lenguaje procedural. Los closures tienen un valor de retorno (indefinido) y pueden recibir parámetros.
def c1 = {
println "hola"
}
//Este es un closure simple con un parametro
def saluda = { nombre ->
println "Hola, $nombre"
}
//Este closure espera recibir como parametros un closure y una cadena
def c3 = { algo, nombre ->
algo(nombre)
}
def despide = { nombre ->
println "Adios, ${nombre}"
}
c1()
saluda("Negativo")
despide("Positivo")
//Esto hace lo mismo que las dos lineas anteriores
c3(saluda, "Negativo")
c3(despide, "Negativo")
//Ahora vamos a pasar el closure a unas listas
//El metodo each() de la lista toma un closure como parametro y lo invoca
//con cada elemento de la lista, pasando el elemento como parametro
["benek", "oscarryz", "ezamudio"].each saluda
//se puede llamar con o sin parentesis
//Y ademas each devuelve la lista al final
println( ["wishmaster", "java.daba.doo"].each(despide))
//La lista es un buen ejemplo para closures porque tiene varios metodos para ellos
//Si el closure no declara parámetros, tendrá uno implícito llamado "it"
println( ['a', 'b', 'C', 'd', 'E', 'f'].collect { Character.isUpperCase(it.charAt(0)) } )
println( ['a', 'b', 'C', 'd', 'E', 'f'].findAll { Character.isUpperCase(it.charAt(0)) } )
println( ['a', 'b', 'C', 'd', 'E', 'f'].find { Character.isUpperCase(it.charAt(0)) } )
println( [1,2,3,4,5].collect { it * 2 } )
//Esto suma todos los elementos
println( [1,2,3,4,5].inject(0) { it, prev -> it + prev } )
Algunos videos
Si quieren pueden el siguiente video en donde se hace una introducción al lenguaje:
Introducción a Groovy from Grails.org.mx on Vimeo.
Y en este otro se habla un poco mas de Closures
Ciclos en Groovy y Colecciones from Grails.org.mx on Vimeo.
Mas comentarios...
Bueno a mi me interesaría aprender más sobre este lenguaje y claro por supuesto también de los otros que mencionan, de hecho no sabía que existían esos lenguajes y mucho menos que es programación implementado para la plataforma java hasta que me registre en este foro y fui leyendo los temas que exponen. Pero muchos como yo no sabemos ni cómo debemos compilar un "hola mundo" aun que hicieron el favor de poner como es la clase completa, intente ponerla en una clase normal de java desde eclipse y claro me arrojo los errores de sintaxis.
Entonces qué tipo de archivo debo abrir, se requieren algún jar en especifico? Y también me llama mucho la atención que no hay mucha fuente de trabajo para estos lenguajes, estuve buscando ofertas de trabajo donde soliciten la experiencia en estos lenguajes y realmente son muy escasas la vacantes que encontré.
Yo incursione en esta carrera por obras del destino porque realmente mi intención era estudiar otra cosa pero le he tomado el gusto y estoy viviendo de esto, pero que ventaja hay en aprender estas variantes si no hay una demanda como lo es java normalito.
Re: Corregí un par de cosas en
Creo que esa manera de llamar closures en Ruby aplica para la serie 1.9.x; en Ruby legacy (y creo todavía soportado) es :
#el ->, ni bronquearte con los yield en cosas
#faciles, además parecido a python
cosa = lambda { |parametro1, parametro2|
----puts "Parametro 1 vale #{parametro1} \n Parametro 2 vale #{parametro2}"
}
#de ahí basta con
cosa.call("Chachito", "caramelo")
Te faltaron también closures en JavaScript:
----alert("El valor de e es " + e);
}
Y ya que andamos por estos rumbos les aporto las de python:
#lambda o funciones previamente definidas
x = lambda z: z ** 2
#O también
def funcionera(cosa="NoCosa"):
----if(cosa == "NoCosa"):
--------print ("No parametrasteSS nada compadre!")
----else:
--------print ("La cosa que parametrasteSS es", cosa)
#Aquí asignas el "closure"
f = funcionera
#Aqui lo llamas
f("Shalalalala")
#O también
f()
Y pues en Java los closures no existen se llaman implementaciones (para lo que necesitas definir una interface, ¿o estoy mal?), porqué a fin de cuentas es lo que hiciste usar una interface que no viene siendo otra cosa más que pasar por "argumento" un método u acción.
¿Ese código ya será el definitivo pa Ryz?...Si es así que chido, pero cómo sugerencia estaría chido que quitaras ese "__main(args : String*)", o sea el asterisco que sigue al tipo del parámetro, por poco me espanto y creo que es un puntero XD...y creo que a más de uno nos pasaría (cómo me está pasando con ObjC).
¬¬, me mandaron cómo
¬¬, me mandaron cómo duplicado un comentario al editarlo!!!
La corrección es en Python:
----print "Hola mundo"
closure = a
#Es algo raro regresar la referencia a una función dentro de otra función.
#De hecho es redundante.
Y en ruby hay otra forma, con lambda:
----puts "El parametro trae #{param}"
}
cosa.call("Un valor")
Tengo una duda con Ryz, ¿porqué depués del tipo de parámetro a recibir pones un *?; eso me aterra y recuerda a los punteros en C. ¿O tienen alguna notación especial?.
Re: Mas comentarios...
Estos lenguajes muchas veces son complemento de Java y ayudan a extender o facilitar funcionalidades. Por ejemplo, con Groovy, Scala, Jython y JRuby puedes usar las closures y compilando directo a Java.
¿Quieres desarrollar en Web sin complicarte tanto la vida, pero necesitas utilizar el Tomcat?... Para esto tienes de nuevo a Groovy, Jython y JRuby. Donde puedes utilizar los frameworks de estos lenguajes SIN de cambiar tu plataforma.
¿Quieres agregar a tu proyecto actual algo de programación funcional? Sin mover TODA tu plataforma, usas Scala o Jython y listo (no sé si Groovy sea funcional).
En fin, yo diría que está chido aprenderlos, porqué te dan las facilidades y librerías que tiene java + características específicas de algún lenguaje de programación.
El String*, espero que sí ,
El
String*
, espero que sí , creo que lo copié de Python o de Ruby donde String* es como "0 o muchos Strings" es decir, el equivalenta en Java a varargs en JavaString ... args
y digo creo, porque no recuerdo a quien se lo copie exactamente.String*
El
String*
yo lo he visto en Scala.def upper(strings: String*): Seq[String] = {
strings.map((s:String) => s.toUpperCase())
}
}
val up = new Upper
Console.println(up.upper("A", "First", "Scala", "Program"))
Ahh si , entonces fue de
Ahh si , entonces fue de Scala :P en Ruby es
*thing
Python y ruby lo manejan pero
Python y ruby lo manejan pero es aplicado al parámetro no al tipo (bueno, si el tipado dinámico y eso), creo que para tu caso quedaría y es antes del nombre:
___ main(*args : String ) {
out.println("Hola, mundo")
}
}
Y me gustó mucho el estilo pythonico del private con ___[espacio]metodoNombre. Ryz parece que en cuanto tenga las primeras versiones tendrá varios adeptos.
El scope de variables en las
El scope de variables en las closures (al menos en Ruby y Python) depende en donde lo defines, si éstas reciben parámetros y estás dentro de una clase persona, si tienes un parámetro llamado nombre y dentro del closure te refieres a nombre, pues te refieres al parámetro; de lo contrario te refieres al de la clase o scope que estes manejando (mientras sea alcanzable).
mas dudas
a mi me gustaria saber si Groovy es Grails, porque me parece que empece un libro de y me empezo a explicar de Grails.
hacia donde se enfoca Groovy, hacia facilitar o ser un complemento de lenguaje de programacion?
no es mas dificil aprender un lenguaje nuevo con todo lo que conyeva en vez de buscar la manejra en java?
preguntas...
Son varias preguntas pavul...
Groovy no es Grails. Grails es un framework hecho en Groovy, para desarrollo web. Groovy es un lenguaje de programación de tipado dinámico, para la JVM, con capacidades de scripting y otras monerías; no es un complemento de lenguaje, es un lenguaje por sí mismo. Tiene su propio compilador e intérprete. Tiene mucha sintaxis opcional, de manera que puedes escribir código prácticamente idéntico a Java o puedes usar su propia sintaxis.
En cuanto a tu última pregunta: a veces es más difícil hacer algo en Java, que simplemente hacerlo en otro lenguaje. Y si consideras que sólo necesitas aprender ese lenguaje una vez, mientras que ese "algo" en Java no sabes si lo vas a tener que hacer varias veces... y si además te gusta la programación, aprender un nuevo lenguaje generalmente es una experiencia muy grata.