Long time, no blog. I've been really tied up with a release at work ... but I'm on vacation for a couple of days so I can a couple of posts done.
Anyway, I've decided that it is time to move away from Groovy. I hope the language takes off, and if it seems to start gaining some momentum I'll be happy to pick it up again. I just really don't want to invest too much in a language that might die.
So what comes next? I've decided to go with Ruby. The fact that JRuby is pretty darn close to a 1.0 release was enough to convince me to go with Ruby. I really want to leverage my investment in Java, so having the language work on the JVM is important to me.
Also, the posts will cover more ground. I thought since Groovy was so new it wouldn't hurt to cover things in detail. I don't think there will be much value in that for Ruby given the number of great books (I'm mostly using the second PickAxe book myself), blogs, and so on. Instead, I'll try to convey more what it is to program in Ruby for a long time Java programmer.
At least, that is the plan for now ...
Tuesday, February 13, 2007
Sunday, January 21, 2007
Is Groovy Dead Already?
I just saw this little gem, "Groovy: Alive, But Barely Kicking" this morning. I must admit, it gave me pause. After all, who wants to see one of the "driving forces" of a language you're investing time time into to declare that the langauge "never jelled" and also imply that it was a success solely because it got other scripting languages to move onto the JVM?
The piece does get a quote from Guillaume Laforge (the current leader of the Groovy project) that emphasizes the key benefit of Groovy - it eases the migration of Java programmers, and works well with the existing work in Java. The question is, is that going to be enough?
The answer will depend, I think, on how hard it is to leverage existing Java code in these other scripting languages. I've not yet really looked into this, but I did see this little piece on using Velocity from JRuby. From the sample code shown, it doesn't look too hard to play with Java code, and the idea of creating a ruby wrapper object to call the java functionality seems like a pretty good approach to keeping what oddness there is in mixing the java and ruby approaches contained to small parts of the codebase.
Hmmm. I was going to wait until JRuby was 1.0 before playing with it, but now I'm not so sure of that plan...
The piece does get a quote from Guillaume Laforge (the current leader of the Groovy project) that emphasizes the key benefit of Groovy - it eases the migration of Java programmers, and works well with the existing work in Java. The question is, is that going to be enough?
The answer will depend, I think, on how hard it is to leverage existing Java code in these other scripting languages. I've not yet really looked into this, but I did see this little piece on using Velocity from JRuby. From the sample code shown, it doesn't look too hard to play with Java code, and the idea of creating a ruby wrapper object to call the java functionality seems like a pretty good approach to keeping what oddness there is in mixing the java and ruby approaches contained to small parts of the codebase.
Hmmm. I was going to wait until JRuby was 1.0 before playing with it, but now I'm not so sure of that plan...
Sunday, January 14, 2007
Getting Rolling with Tests
Last post I showed a simple function that simulates rolling X number of Y sided dice, with an optional modifier. Even as such things go, it was pretty trivial. It is hard to believe such simple code could have a bug in it, but experience shows that it can't hurt to be too careful, especially when dealing with unfamiliar territory.
So let's look a bit at testing. The first tool at our disposal is the assert command. This does exactly what you'd expect from an assert - if the expression passed to the assert is true, everything is fine. If it's false, the program fails, and you get a stack trace. Here's a really crude script that tries rolling three six-sided dice a 10,000 times, to see if you always get a roll between three and eighteen.
Note that this is an actual Groovy script. You could save it into a file like Dice.groovy, and execute it with the groovy command. Alternatively, you could use the groovyConsole command and interact with it. If you go ahead and run this ... nothing happens. In this case, that is good since the only thing that could happen is for the assert to fail. It is always a good idea to verify that your tests can fail. A simple way to do that here would be to have a modifier, i.e., add something to the roll and see that we will fail. For example you could change the roll to:
This should (eventually) fail when you run it, since you will sooner or later roll 3 sixes, which results in a 19 (18 + 1).
While this works, it's kind of ugly. If you're a JUnit fan, the fact that we don't get a screen telling us that all is well is a bit disappointing. Fortunately, this is easy to fix. Groovy actually has JUnit 3.8.x built in, and extended a bit to make unit testing, well, groovier. To make use of this, though, we need to leave the world of Groovy scripts and make use of objects (just as we would do in Java). Let's try:
There are a couple of things to note. First, you'll see that
The second change is that I decided to make use of the range type. The range type is a new basic type added by Groovy. It represents, in some sense, a set of "things" that can be ordered from a lower bound to an upper bound. The range type supports each so you can iterate over all the "things" in the range, ask if an object is in the range, and so on. And as I allude to here, any object can be in a range if it meets certain criteria. For more information, I suggest reading 4.1 in the "Groovy In Action" book.
I find that I'm still not really leveraging everything Groovy provides when coding. It never occurred to me to use the range type when I first entered in the test code. One disadvantage of Groovy's desire to be very java-like is that it makes it easier (I think) to fall back into Java idioms and habits. This is a plus in that I can be pretty productive, since I don't need to learn everything from scratch, and thus I can save myself the hassle of looking at documentation every five seconds. On the other hand, I really do want to learn the groovy way of doing things.
In any case, I find the simple way to run this is to save it in a script file (e.g., RollingTest.groovy) and run it with the command groovy RollingTest.groovy. This seems to work fine, and we get the basic JUnit text runner UI, showing us that our one and only test is passing.
Of course, having the method to test in the test case makes no sense. The right thing to do here, I think, is create an object to represent the concept of a DiceRoller, and have the unit test create a roller and call the roll methods.
The DiceRoller:
And the test class (now called DiceRollerTest):
We can run the test simply by typing
Note that I made the method to roll the DiceRoller static. This works (so far as I can tell) exactly as the static keyword in Java.
All of the above gets us started with writing tests in Groovy. Once again the post is getting rather long, so I'll call it quits here. Next time I'll dig deeper into the collection classes added as base types to Groovy.
So let's look a bit at testing. The first tool at our disposal is the assert command. This does exactly what you'd expect from an assert - if the expression passed to the assert is true, everything is fine. If it's false, the program fails, and you get a stack trace. Here's a really crude script that tries rolling three six-sided dice a 10,000 times, to see if you always get a roll between three and eighteen.
def diceRoller(number, sides, modifier) {
dieRoll = 0
number.times {
dieRoll += (int)(sides*Math.random() + 1)
}
dieRoll + modifier
}
10000.times {
roll = diceRoller(3, 6, 0)
assert roll >= 3
assert roll <= 18
}
Note that this is an actual Groovy script. You could save it into a file like Dice.groovy, and execute it with the groovy command. Alternatively, you could use the groovyConsole command and interact with it. If you go ahead and run this ... nothing happens. In this case, that is good since the only thing that could happen is for the assert to fail. It is always a good idea to verify that your tests can fail. A simple way to do that here would be to have a modifier, i.e., add something to the roll and see that we will fail. For example you could change the roll to:
roll = diceRoller(3, 6, 1)
This should (eventually) fail when you run it, since you will sooner or later roll 3 sixes, which results in a 19 (18 + 1).
While this works, it's kind of ugly. If you're a JUnit fan, the fact that we don't get a screen telling us that all is well is a bit disappointing. Fortunately, this is easy to fix. Groovy actually has JUnit 3.8.x built in, and extended a bit to make unit testing, well, groovier. To make use of this, though, we need to leave the world of Groovy scripts and make use of objects (just as we would do in Java). Let's try:
class RollingTest extends GroovyTestCase {
def void testRange() {
def rollRange = 3..18
10000.times {
def roll = diceRoller(3, 6, 0)
assert rollRange.contains(roll)
}
}
def diceRoller(number, sides, modifier) {
def dieRoll = 0
number.times {
dieRoll += (int)(sides*Math.random() + 1)
}
dieRoll + modifier
}
}
There are a couple of things to note. First, you'll see that
def keyword pops up a lot more often. This is one aspect of Groovy that really bugs me. When you're not just doing scripts (i.e., you're doing objects), than you really need to make use of the def keyword if you're variable doesn't have a type. This seems like a wart to me, especially since if you do scripts this issue doesn't arise.The second change is that I decided to make use of the range type. The range type is a new basic type added by Groovy. It represents, in some sense, a set of "things" that can be ordered from a lower bound to an upper bound. The range type supports each so you can iterate over all the "things" in the range, ask if an object is in the range, and so on. And as I allude to here, any object can be in a range if it meets certain criteria. For more information, I suggest reading 4.1 in the "Groovy In Action" book.
I find that I'm still not really leveraging everything Groovy provides when coding. It never occurred to me to use the range type when I first entered in the test code. One disadvantage of Groovy's desire to be very java-like is that it makes it easier (I think) to fall back into Java idioms and habits. This is a plus in that I can be pretty productive, since I don't need to learn everything from scratch, and thus I can save myself the hassle of looking at documentation every five seconds. On the other hand, I really do want to learn the groovy way of doing things.
In any case, I find the simple way to run this is to save it in a script file (e.g., RollingTest.groovy) and run it with the command groovy RollingTest.groovy. This seems to work fine, and we get the basic JUnit text runner UI, showing us that our one and only test is passing.
Of course, having the method to test in the test case makes no sense. The right thing to do here, I think, is create an object to represent the concept of a DiceRoller, and have the unit test create a roller and call the roll methods.
The DiceRoller:
class DiceRoller {
def static roll(number, sides, modifier) {
def dieRoll = 0
number.times {
dieRoll += (int)(sides*Math.random() + 1)
}
dieRoll + modifier
}
}
And the test class (now called DiceRollerTest):
class DiceRollerTest extends GroovyTestCase {
def void testRange() {
def expectedRange = 3..18
1000.times {
def roll = DiceRoller.roll(3, 6, 0)
assert expectedRange.contains(roll)
}
}
}
We can run the test simply by typing
groovy DiceRollerTest.Note that I made the method to roll the DiceRoller static. This works (so far as I can tell) exactly as the static keyword in Java.
All of the above gets us started with writing tests in Groovy. Once again the post is getting rather long, so I'll call it quits here. Next time I'll dig deeper into the collection classes added as base types to Groovy.
Let the Games Begin
In this post I'm going to go over some my early fumblings in Groovy. First, I've been reading a book on the language. I know some people don't have trouble learning languages just by looking at docs on the web sites, with a few tutorial articles thrown in. Personally, I prefer to deal with book. All the info in one spot, told (hopefully) in a coherent fashion.
The book I picked is "Groovy in Action." I'm not sure if it is available at book stores yet. I'm working with the eBook/PDF edition so I don't know. I'm not going to try and review the book - I'm still working through it. So far, though, I've been pretty happy with it.
Reading a book, though, isn't the way I learn a language "for real." Usually I don't get a language until I use it in a real project. Given limited time, I can't really use Groovy in a big project. Since this blog is about playful exploration, I decided that a little gaming project would be a good place to start.
And I don't mean video games. I have the utmost respect for game programmers, and know that there isn't really such a thing as a simple video game project. I mean little programs based on board games and such.
Which leads to the first little project - a dice roller. A lot of games require the use of dice as a randomizing element, and its hard to imagine anything simpler to start with. I'm going to try and make this interesting by seeing how far I can push this, of course.
Anyway, a few preliminaries. Die rolling is a bit interesting in the sense that there are many different types of dice. In addition to standard 6-sided die, there are many other types with a different number of sides such as d20. These are used a lot in Role Playing Games (RPGs), which I used to play a lot. Also, depending on what you're doing you will likely roll more than one die at a time. So we'll start with a function that will roll an arbitrary number of die, all of which have the same (arbitrary) number of sides. Since RPGs often modify the roll with a constant (e.g., add 2 to the roll), we add the concept of a modifier. This leads to a Groovy function that looks like:
Before I dig into the code, I suppose I should say why I choose to write a function like this, rather than define a bunch of classes like Die and such. First, I'm not really ready to go into classes just yet. And second, I suspect that would be overkill. I'm a big proponent of Object-Oriented Analysis and Design (OOA&D), but I like to start simple. Besides, it should be trivial to go down that road if it seems like we need to later. And since I'm just playing around, writing little scripts like this is just faster.
Anyway, the function itself is pretty trivial. From a Java point of view, the oddest thing would probably be the lack of type information. The function doesn't declare a return type, and none of the method parameters have any type information either.
This is Groovy showing us one way in which it is a dynamic language. However, I should point out that Groovy does allow you to specify the types. This is a little different from most languages, in that you can choose on the fly whether to type things or not. I still find this disconcerting - under what circumstances should I choose one option or the other? I really haven't figured this out at all. For now, I'm trying to be dynamic as possible, but sometimes I feel the urge to give an explicit type and will do so. I welcome any thoughts on how to choose this...
But this code is a bit weirder (from a Java perspective) than just dynamic typing. In particular, I'm using a closure, and taking advantage of the times method that groovy has added to the integer type. It felt strange, I must admit, to write a loop like this without falling back on the for loop. I did this because:
The last thing to notice is that the function doesn't explicitly return a value. Like a lot of dynamic languages, Groovy makes the return statement optional. If no return is specified, then the value of the expression evaluation is returned. If the last statement doesn't have a value then a null is returned (I think).
This is a pretty long post, already, so I'm going to call it quits here. Next time I'll try to get through things faster. I'll talk some about testing in groovy, and dig a bit into collections.
The book I picked is "Groovy in Action." I'm not sure if it is available at book stores yet. I'm working with the eBook/PDF edition so I don't know. I'm not going to try and review the book - I'm still working through it. So far, though, I've been pretty happy with it.
Reading a book, though, isn't the way I learn a language "for real." Usually I don't get a language until I use it in a real project. Given limited time, I can't really use Groovy in a big project. Since this blog is about playful exploration, I decided that a little gaming project would be a good place to start.
And I don't mean video games. I have the utmost respect for game programmers, and know that there isn't really such a thing as a simple video game project. I mean little programs based on board games and such.
Which leads to the first little project - a dice roller. A lot of games require the use of dice as a randomizing element, and its hard to imagine anything simpler to start with. I'm going to try and make this interesting by seeing how far I can push this, of course.
Anyway, a few preliminaries. Die rolling is a bit interesting in the sense that there are many different types of dice. In addition to standard 6-sided die, there are many other types with a different number of sides such as d20. These are used a lot in Role Playing Games (RPGs), which I used to play a lot. Also, depending on what you're doing you will likely roll more than one die at a time. So we'll start with a function that will roll an arbitrary number of die, all of which have the same (arbitrary) number of sides. Since RPGs often modify the roll with a constant (e.g., add 2 to the roll), we add the concept of a modifier. This leads to a Groovy function that looks like:
def diceRoller(number, sides, modifier) {
dieRoll = 0
number.times {
dieRoll += (int)(sides*Math.random() + 1)
}
dieRoll + modifier
}
Before I dig into the code, I suppose I should say why I choose to write a function like this, rather than define a bunch of classes like Die and such. First, I'm not really ready to go into classes just yet. And second, I suspect that would be overkill. I'm a big proponent of Object-Oriented Analysis and Design (OOA&D), but I like to start simple. Besides, it should be trivial to go down that road if it seems like we need to later. And since I'm just playing around, writing little scripts like this is just faster.
Anyway, the function itself is pretty trivial. From a Java point of view, the oddest thing would probably be the lack of type information. The function doesn't declare a return type, and none of the method parameters have any type information either.
This is Groovy showing us one way in which it is a dynamic language. However, I should point out that Groovy does allow you to specify the types. This is a little different from most languages, in that you can choose on the fly whether to type things or not. I still find this disconcerting - under what circumstances should I choose one option or the other? I really haven't figured this out at all. For now, I'm trying to be dynamic as possible, but sometimes I feel the urge to give an explicit type and will do so. I welcome any thoughts on how to choose this...
But this code is a bit weirder (from a Java perspective) than just dynamic typing. In particular, I'm using a closure, and taking advantage of the times method that groovy has added to the integer type. It felt strange, I must admit, to write a loop like this without falling back on the for loop. I did this because:
- I think this notation is more expresive of what I'm doing than a for loop
- The for loop in Groovy is actually not the for loop I've come to expect from years of C/C++/Java coding.
- I want to play with closures.
The last thing to notice is that the function doesn't explicitly return a value. Like a lot of dynamic languages, Groovy makes the return statement optional. If no return is specified, then the value of the expression evaluation is returned. If the last statement doesn't have a value then a null is returned (I think).
This is a pretty long post, already, so I'm going to call it quits here. Next time I'll try to get through things faster. I'll talk some about testing in groovy, and dig a bit into collections.
Sunday, January 7, 2007
Choices
I find myself with an interesting dilemma - I have way too many choices in front of me! Just in terms of languages I could start with Ruby, Python, Haskell, Erlang, ... or even Lisp, which seems to be enjoying a revival of interest. What to pick?
As it turns out there is a flurry of posts around Groovy right now, since it has just reached its 1.0 release. I completely forgot about Groovy - to be honest, I thought it had essentially stalled after the JSR for it was started. But it seems to have been marching on, and the effort is being portrayed as just beginning to bear fruit.
It's not clear to me how much a role Groovy will play, especially as more mature languages like Ruby (boy, that sounds odd - but it is true in this case) make their way to the JVM (see the JRuby project). Groovy's main advantage, as I see it, is that it is trying hard to make it easy for Java programmers to work with it. I certainly like the idea of being able to leverage the time investment I've made with Java. Others have articulated this better than I ... Richard Monson-Haefel's groovy post is one I particularly liked.
Of course, there are a lot of negative opinions as well. Most seem to argue that Groovy isn't as elegant as its competitors. One post(sorry, I lost the link) argued that Groovy was a mere collection of cool features thrown together without real thought. I believe the post equated this with Perl or C++. Given the how much both languages get used in the real world, maybe this isn't all bad. In any case, I don't think I can speak to such arguments without actually trying Groovy out.
So, for better or worse, I've chosen Groovy as my starting point. As this is really a "just for fun"/educational project, I won't be investing a lot of time into it. So I appreciate being able to lean on my Java knowledge as I get started.
Ultimately it isn't really too big a deal what I start with. I plan on trying out multiple things anyway, so its not like I need to be worried about being locked into one language.
As it turns out there is a flurry of posts around Groovy right now, since it has just reached its 1.0 release. I completely forgot about Groovy - to be honest, I thought it had essentially stalled after the JSR for it was started. But it seems to have been marching on, and the effort is being portrayed as just beginning to bear fruit.
It's not clear to me how much a role Groovy will play, especially as more mature languages like Ruby (boy, that sounds odd - but it is true in this case) make their way to the JVM (see the JRuby project). Groovy's main advantage, as I see it, is that it is trying hard to make it easy for Java programmers to work with it. I certainly like the idea of being able to leverage the time investment I've made with Java. Others have articulated this better than I ... Richard Monson-Haefel's groovy post is one I particularly liked.
Of course, there are a lot of negative opinions as well. Most seem to argue that Groovy isn't as elegant as its competitors. One post(sorry, I lost the link) argued that Groovy was a mere collection of cool features thrown together without real thought. I believe the post equated this with Perl or C++. Given the how much both languages get used in the real world, maybe this isn't all bad. In any case, I don't think I can speak to such arguments without actually trying Groovy out.
So, for better or worse, I've chosen Groovy as my starting point. As this is really a "just for fun"/educational project, I won't be investing a lot of time into it. So I appreciate being able to lean on my Java knowledge as I get started.
Ultimately it isn't really too big a deal what I start with. I plan on trying out multiple things anyway, so its not like I need to be worried about being locked into one language.
Saturday, January 6, 2007
Introduction and Premise
There's a lot of buzz these days around the next revolution in programming. Since I've been programming a long time, this isn't really new to me. It seems like every month or so a new silver bullet pops up, being hyped so much that we can only conclude that it will change programming as we know it. Somehow, though, it doesn't seem to happen.
So I've gotten in the habit of not jumping on the band wagon right away. I keep tabs on new ideas, and wait to see what happens. It can take months, sometimes years, for the industry to evaluate new ideas, hype them up to (literally) unbelievable heights, crash them back down to Earth, and ultimately figure out what (if anything) the idea is actually good for.
So when the buzz began to build around scripting languages, it was pretty easy to ignore at first. Programmers 10-15 times more productive? Hmmm. Somehow I was skeptical. I figured that this was likely going to be a flash in the pan. Then I heard about JPython (now Jython). The idea of using a scripting language to assemble "components" written in a more industrial strength language resonated with me. But not much seemed to come of it, and it slipped off my radar.
Scripting languages popped back into view for me when the Pragmatic Programmers started talking about Ruby. I'm a big fan of "The Pragmatic Programmer" book, and so I took a pretty strong interest into Ruby initially. But ... I was pretty busy at work, and Ruby seemed so different from what I was doing there that I didn't really dig into it.
And, of course, Rails burst onto the scene in a big way some time later. I was curious, but it didn't seem to relevant given that I'm mostly focused these days on the backend of applications (i.e., I don't do web development these days). But I did begin to start poking around more, and started running into more and more interesting ideas (e.g., continuations in web applications) and languages (Erlang has lately caught my eye).
And so when it was time to make some New Year resolutions, it was an easy call to make really learning more about dynamic languages a goal for this year. I look at this as an exploration/adventure, and plan on having fun with it. Really, I'm just playing around, though the play has a purpose.
Which brings me to this blog. I figure a blog is as good a way as any to keep notes on what I learn as I explore. As I said, I see this as a form of play, so the name "Playing with Sharp Objects" seemed pretty natural. I'm playing with bleeding edge (to me, at least) stuff. And since many of the dynamic scripting languages are object-oriented...
So now you know what this blog is about. If you're looking for an alpha-geek to dazzle you with their knowledge of esoteric realms, your out of luck. I think of myself as a pretty "mainstream programmer." If you want to follow along as I go digging into this unfamiliar territory (perhaps because you're like me) than I hope it will at least be an interesting trip.
So I've gotten in the habit of not jumping on the band wagon right away. I keep tabs on new ideas, and wait to see what happens. It can take months, sometimes years, for the industry to evaluate new ideas, hype them up to (literally) unbelievable heights, crash them back down to Earth, and ultimately figure out what (if anything) the idea is actually good for.
So when the buzz began to build around scripting languages, it was pretty easy to ignore at first. Programmers 10-15 times more productive? Hmmm. Somehow I was skeptical. I figured that this was likely going to be a flash in the pan. Then I heard about JPython (now Jython). The idea of using a scripting language to assemble "components" written in a more industrial strength language resonated with me. But not much seemed to come of it, and it slipped off my radar.
Scripting languages popped back into view for me when the Pragmatic Programmers started talking about Ruby. I'm a big fan of "The Pragmatic Programmer" book, and so I took a pretty strong interest into Ruby initially. But ... I was pretty busy at work, and Ruby seemed so different from what I was doing there that I didn't really dig into it.
And, of course, Rails burst onto the scene in a big way some time later. I was curious, but it didn't seem to relevant given that I'm mostly focused these days on the backend of applications (i.e., I don't do web development these days). But I did begin to start poking around more, and started running into more and more interesting ideas (e.g., continuations in web applications) and languages (Erlang has lately caught my eye).
And so when it was time to make some New Year resolutions, it was an easy call to make really learning more about dynamic languages a goal for this year. I look at this as an exploration/adventure, and plan on having fun with it. Really, I'm just playing around, though the play has a purpose.
Which brings me to this blog. I figure a blog is as good a way as any to keep notes on what I learn as I explore. As I said, I see this as a form of play, so the name "Playing with Sharp Objects" seemed pretty natural. I'm playing with bleeding edge (to me, at least) stuff. And since many of the dynamic scripting languages are object-oriented...
So now you know what this blog is about. If you're looking for an alpha-geek to dazzle you with their knowledge of esoteric realms, your out of luck. I think of myself as a pretty "mainstream programmer." If you want to follow along as I go digging into this unfamiliar territory (perhaps because you're like me) than I hope it will at least be an interesting trip.
Subscribe to:
Posts (Atom)