At 11:49 AM 4/6/2007, Warner wrote:
On Apr 6, 2007, at 11:27 AM, Thomas Hicks wrote:
At 06:26 AM 4/6/2007, Warner wrote:
On Apr 5, 2007, at 10:06 PM, Thomas Hicks wrote:
Speaking of Groovy....
Whatever happened to Warner's Groovy challenge? (see quote below)
Did anyone succeed in creating High Order Messaging in Groovy?
(Warner?)
I *was* going to try and do it last weekend, but ran out of time.
I've pulled it out again and was going to see if I could take another
stab at it this weekend.
Not knowing Ruby, but skimming the given articles, it seems that the
first author was trying to accomplish several different things
under the
rubric of "Higher Order Messaging": high-order functions, extending
the Ruby
syntax, and automatically calling methods which did not exist
before the call.
Groovy can do the first thing and has many built-in methods which
take
closures as arguments (exs: each, findAll, inject). I don't know if
it can
be extended to create/call methods which do not exist though
since the
Ruby example apparently uses a special, built-in error mechanism
(method_missing) to intercept the errant call (hmmmm....I wonder if
some
AOP code injection could accomplish this in other languages).
It definitely can do the "methods don't exist", it's part of what the
Builders use for creating xml.
http://groovy.codehaus.org/Builders
OK, but I suspect the crucial question is "When does this happen"?
Ruby's method_missing would appear to be called at runtime whereas
the Groovy Builders look to me like a "parse-time" operation
(caveat: I'm
still learning Groovy). And while you could use the Groovy support
classes
which underlie the Builders, I have this gut feeling that you're
missing a
crucial runtime "hook" that will allow you to translate a syntax like:
claimants.where.retired?.do.receive_benefit 50
Well, Groovy has this concept of MetaClass, where you can catch
methods before they are called (which is what you would do here, I
suspect, just starting to dig into it). Basically you define a
"delegate" for the class and the delegate is what gets called, which
is very similar to the ruby HOM example I sent.
Ah...cool...that sounds like the right thing.
BUT, personally, I question whether this expression is a worthy
goal anyway.
Yes, and no. Syntactically I like it, but seriously is it that much
more succinct than the findAll{} closure? Not really.
Here's my base case I'm starting from:
assert [-2, -1, 0, 1, 2, 3, 4, 5].findAll(it != 0} == [-2, -1, 1, 2,
3, 4, 5]
this can also be rewritten if you don't like the magic "it" object
(ie - it reminds you too much of Perl's magic)
assert [-2, -1, 0, 1, 2, 3, 4, 5].findAll(item -> item != 0} == [-2,
-1, 1, 2, 3, 4, 5]
Both Ruby articles describe the shortcomings and limitations of the
HOM
approach, some of them quite fundamental.
I think the Groovy expression:
claimants.findAll { it.retired() }.each { println (it.toString()) }
You can also get rid of the las statement as well (if I'm correct) to:
claimants.findAll { claimant - > claimant.retired(); println claimant }
(I think, try it and let me know if I'm right :-P)
No, that didn't work -- it printed all the claimants.
I would have been mystified if that had worked because the
contract with findAll is that the closure must return a boolean for
each object passed to the closure. findAll collects the objects for
which the closure returns true.
cheers,
-tom
which can be shortened (by defining the closures separately) to:
claimants.findAll(retired).each(printPerson)
is pretty darn clear and succinct!
Also there's something wrong about the HOM syntax; with data,
operations, and
control structures all mashed up together. I would claim that human
cognition
doesn't operate this way; as attested by human languages which have
specific
syntax for distinct concepts like subjects, objects, agents,
actions, modifiers,
concrete things, and so on.
That's not to say that it isn't a very interesting, instructive,
and fun exercise and
I thank-you for it. I've appended some Groovy code relevant to this
exercise below.
To run it, I had to 'groovyc Claimant.groovy' and then 'groovy hom'.
yeah, personally I like the exercise because it's forcing me deeper
into Groovy and how it works. And it also helps me try out concepts
that I will probably use when writing my DSLs.
-warner
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]