I remeber asking
Josh to do the comparison. Finally decided to check it out myself.
(G) - Groovy
(P) - Python
New Line
(G)
println
(P)
print
Object Instantition: Python does'nt need 'new'
(G)
h = new HelloWorld()
(P)
h = HelloWorld()
Lists: Same as lists in python and are first class.
(G)
list = [1,2,'hello', new HelloWorld()]
(P)
list = [1,2,'hello', HelloWorld()]
Empty Lists are denoted the same way:
(G)
list =[]
(P)
list =[]
Map: dictionaries in python and are first class. P uses '{' instead of a '['
(G)
dict = ['name':'python','oo':'yes']
(P)
dict = {'name':'python','oo':'yes'}
Empty Map:
(G)
dict = [:] //dont have a choice here because [] mean empty lists.
(P)
dict = {}
Iteration: Same as Python. Dont need '(' and ')' in Python though.
'for' iterates on any sequence (list,
string, map)
(G)
for (i in list): {println i}
(P)
for i in list: print i
for i in list:
# do something
else:
# do something else. # Optional. Gets executed when there is no abrupt exit while iterating.
Iterating a Map. Python iterates through the keys, while groovy returns
'flatten' method on list flattens nested lists if any, within a list: Missing in Python lists?! suprising!
(G)
a = [1,2,3,[4,5,6]]
a.flatten()
print a
groovy> a.flatten()
[1, 2, 3, 4, 5, 6]
join method: is a list method in groovy. Its a string method in Python.
'join' the contents of the list using a separator --> uhhm , join() does make more sense on 'list'
object then string.
(G)
l = ['h','e','l','l','o']
l.join('')
groovy> l.join('')
"hello"
(P)
>>> l = ['h','e','l','l','o']
>>> ''.join(l)
'hello'
tokenize method: Same as 'split' in Python. Returns a list with the tokens
(G)
groovy> 'java|python|perl'.tokenize('|')
["java", "python", "perl"]
(P)
>>> 'java|python|perl'.split('|')
['
java', 'python', 'perl']
control structures : if - else.
if-in conditional for lists and maps does not work in Groovy.?! I thought that was nice.
(G)
if (x > 2){
//do this
}else{
// do that
}
(P)if x > 2:
#do this
else:
# do that
map = {'orm':'hibernate','mvc':'
struts'}
list = ['java','groovy','python']
if 'orm' in map:
print map['orm'] # hibernate. looking up a key not present in a dict results in an error.
if 'java' in list:
# do something
Switch statements: Groovy - Yes
Python - No
Operator Overloading: Design is strikingly similar to that of Python's
Discussed in the special methods section below
Functions are objects: They can be passed around like any other normal object. Groovy is same as Python here.
in Python they are of type 'FunctionType' or 'MethodType' etc depending upon whether the function is a
builtin / not. In Groovy, function objects are of type org.codehaus.groovy.runtime.MethodClosure.
They are callable.
(G)
class Hello{
sayHello(){
return "hello world"
}
invokeThis(obj){
println " I have been asked to say " + obj())
}
}
h = new Hello()
f = h.sayHello
h.invokeThis(f) # " I have been asked to say hello world
This one is interesting ..Groovy Closures:
I'm not *very* comfortable yet. But initial impressions are that it looks like 'lambda's in Python?
The following example in Groovy
(G)
x = {a,b | println a+b};
x(10,20)
groovy> x(10,20);
>30
would translate to the following in Python
(P)
x = lambda x,y: print x+y;
x(10,20)
>> 30
Are lambdas same as closure?. The fact that they can be passed around they can be definitely be used as
'callbacks'. We define interfaces in java in order to do the same. Infact, the examples are so
reminiscent of Spring APIs...for eg Spring JdbcTemplate.So I like this feature. Good programming practices
should be embedded in the language itself.
Special methods on objects: Again the design is same as Python's:
Python allows for special methods on custom types. So the custom types can enjoy behaviour similar
to built in types. Python invokes those special methods when we access such a behaviour. They generally start wit
__ and end with a __
So,
(G)
if a & b are instances of the class Hello,
a + b maps to a.plus(b)
a - b maps to a.minus(b)
a * b maps to a.multiply(b)
a / b maps to a.divide(b)
a[b] maps to a.get(b)
(P)
In Python,
a + b maps to a.__add__(b)
a - b maps to a.__sub__(b)
a * b maps to a.__mul__(b)
a / b maps to a.__div__(b)
a[b] maps to a.__getitem__(b)
Eg:
class Money:
def __init__(self,amt):
self.amt = amt
def __add__(self,anotherM):
return Money(self.amt +anotherM.amt)
m1 = Money(10)
m2 = Money(20)
m3 = m1 + m2 # translates to m1.__add__(m2)
print m3.amt # 30
Documentation:
(G)
BAD. Finding information was'nt very easy.
Hopefully, will improve with a final release...not sure when though? It is currently beta 10
(P)
GREAT. Not surprising its been around for more than a decade.
Libraries: If Java has it, then so does Groovy.
I'm not a python regular and hence am not very conversant with Python Libraries.
Its obvious that this comparison is by no means comprehensive. But I downloaded groovy just yesterday night and I just wanted to get started. I might be wrong in certain places. Please do correct me. I figured couple of other things too but will update sometime later. Shall post my observations if you guys find it to be of any use at all.
I dont know anything about groovy performance. I guess they do get compiled to bytecodes.Once they have a final release, I do not see any reason why I should be using any other language. I was writing some sample code to get a hang of groovy and quickly realized that Groovy has access to *every* java api. I saw the movie 'Aliens' again yesterday ( i loved that movie
) after a long time. The alien would breed inside the human and eventually get rid of the host. I dont know why but i see a parallel here..LOL. Assuming performance is not an issue, its does not look like java vs c# anymore. Depending upon one's passion for java, it appears that we have a bigger danger lurking in our own backyard.