Steve Yegge: "Rich Programming Food", in which Steve explains why Compilers is the second most important course you can take as a computer science major, and should be required in any self-respecting computer science curriculum. I couldn't agree more.
I had to fight the temptation to label this "Required Reading", because I know that some of you who follow this link will be turned off by Steve's style, which I appreciate but which even I find a bit rambly at times. And I expect that his sense of humor, which resonates with mine and I therefore appreciate, is not for everyone.
But I do consider this worth a read, primarily because I whole-heartedly agree with Steve's contention that knowing how compilers work is key to understanding computer science. It is also, not coincidentally, key to getting better as a programmer.
I used to think that those two concepts were largely orthogonal. I still believe it's possible to be a successful programmer in industry without a good understanding of computer science. I myself have managed nearly 20 years of gainful employment on the strength of a computer science degree, some native ability, and the credibility that naturally goes with that much experience.
But it's been only recently that I've really started to get it, to understand the why's and wherefore's. Understanding state machines, and parse trees, and Big-O notation, and ... all that stuff I couldn't be bothered with as an undergrad ... understanding it as a grad student has made my life as a professional programmer a lot easier.
If you do follow the link, prepare to be challenged. And even if you don't make it all the way through the post, make sure to scroll down to the bottom for the punch line. Again -- I couldn't agree more.
Friday, June 22, 2007
Tuesday, June 19, 2007
Hear, Hear! (A Postscript to My Take on Closures in Java)
From Revised Report on the Algorithmic Language Scheme, Introduction, Paragraph 1, Sentence 1:
P.S.: This was written 'way back in 1998. Another fun quote:
Programming languages should be designed not by piling
feature on top of feature, but by removing the weaknesses
and restrictions that make additional features appear necessary.
P.S.: This was written 'way back in 1998. Another fun quote:
Those who cannot remember the past are condemned to repeat it. -- Santayana
Wednesday, June 13, 2007
Hacking JRuby: More on Method Arguments
I closed my last post with this observation:
In the comments, Ola Bini -- ThoughtWorker and JRuby committer -- graciously pointed out that there are, in fact, two static methods that we can use to simulate the function of
As Ola points out, this still is not quite the equivalent of MRI
I do plan to use
"...JRuby does not have an equivalent for rb_scan_args(), or at least not one that is called on a per-method basis."
In the comments, Ola Bini -- ThoughtWorker and JRuby committer -- graciously pointed out that there are, in fact, two static methods that we can use to simulate the function of
rb_scan_args(), both found in the org.jruby.runtime.Arity class: checkArgumentCount(), and scanArgs().checkArgumentCount() does just what it says. You pass it an array of argument values, along with the minimum and maximum number of all arguments, and it verifies that the actual number of arguments falls within that range (inclusive). So this provides some basic sanity checking of the number of arguments passed to the method you're implementing. If the number of arguments is valid, checkArgumentCount() returns the actual number of arguments passed. I guess you could argue that this isn't very useful, since you already know the number of arguments you expect, as well as the number given to you. But it is used in a number of places in the JRuby source code.scanArgs() will do a little more work for you. It will do the same sanity checking (it actually calls checkArgumentCount() to do so), although you specify the numbers slightly differently, passing the number of required arguments along with the number of optional arguments. If the actual number of arguments passed is valid, scanArgs() then creates a new array of length required + optional, copies the values of any arguments passed in (all required arguments plus any provided optional arguments), sets the values of any non-provided optional arguments to nil, and returns the new array. This actually is useful, as it transforms a variable-length array of arguments into one of fixed length, where the fixed length is always equal to the maximum number of arguments your method will accept.As Ola points out, this still is not quite the equivalent of MRI
rb_scan_args(), in that it doesn't handle "rest" or "block" arguments. But it does offload from us some of the burden of handling variable length argument lists.I do plan to use
scanArgs() to finish up my implementation of BigDecimal.mode(), but in order to so meaningfully I'm also going to have to change mode()'s method definition from taking a fixed number of arguments to taking a variable number of arguments (the first argument is required, the second is optional). That's going to involve digging into JRuby's mechanism for defining Ruby methods, which I've researched and found to be pretty cool, but it's going to take another few blog posts to sort out. Stay tuned...
Tuesday, June 12, 2007
Hacking JRuby: BigDecimal and Ruby Internals
I've submitted another patch for JRuby (viewable here), to implement the
The first parameter to
If the first argument is a Fixnum that is not equal to
Simple, huh?
Introducing:
One of the first things MRI does (in a lot of methods, as it turns out) is to call the function
The format string consists, minimally, of two digits. The first digit is the number of required arguments, the second is the number of optional arguments.
For example,
BigDecimal.mode() class method. In doing so, I learned quite a bit about JRuby's implementation strategy, as well as the internals of the C source code for MRI (Matz's Ruby Implementation) Ruby.BigDecimal.mode() explained
BigDecimal.mode() is a funky little method in the BigDecimal module, which is not part of the core API but part of the standard library that ships with Ruby. It's kind of multi-variate -- what it does, exactly, depends on how it's called. The first parameter to
BigDecimal.mode() is required, and it must be a Fixnum representing either the constant BigDecimal::ROUNDING_MODE or the exception mode to be set (more on that later). If it's BigDecimal::ROUNDING_MODE and there is no second argument, then mode() just returns the current rounding mode. If a second argument is present, it must also be a Fixnum, and it must equate to one of the seven rounding modes Ruby recognizes (e.g., BigDecimal::ROUND_UP, BigDecimal::ROUND_FLOOR, etc.). In this case, mode() sets the rounding mode (for all BigDecimals, remember, since this is a class method) to the value of the second argument.If the first argument is a Fixnum that is not equal to
BigDecimal::ROUNDING_MODE, then it is expected to have one of its bits set to correspond to one of the known exception modes (e.g., BigDecimal::EXCEPTION_INFINITY). Again, if there is no second argument, mode() simply reports the current exception mode(s) (each bit in the returned value corresponds to a single exception mode set). If there is a second argument, it must be one of 'true' or 'false'. If 'true', mode() sets the mode passed in the first argument. If 'false', mode() unsets (i.e., turns off) the mode passed in the first argument.Simple, huh?
Not So Fast...
When I picked up this task,mode() was just a default stub that printed a message to the console and returned nil. Not a lot to go on there. So I turned to the MRI source code to figure out just what it was supposed to do. Introducing: rb_scan_args()
One of the first things MRI does (in a lot of methods, as it turns out) is to call the function rb_scan_args()), which is implemented in the file class.c with the following signature:int rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)It takes the number of arguments passed, a pointer to a structure containing the values of those arguments, a format string of some sort, and...some other stuff. The number and values of the arguments are self-explanatory, but the format string and the trailing "other stuff" are decidedly not, so let's take a look at them.
The format string consists, minimally, of two digits. The first digit is the number of required arguments, the second is the number of optional arguments.
rb_scan_args parses the format string to find these numbers, then it walks the list of argument values and stuffs each value into its corresponding reference (which is what the "other stuff" in the signature actually is: a group of references to store the values of the arguments in).For example,
BigDecimal.mode() makes this call to rb_scan_args:if(rb_scan_args(argc,argv,"11",&which,&val)==1) val = Qnil;In English:
- get one required argument and store its value in the variable
which - get the optional second argument if it exists and put its value in
val - if
rb_scan_argsreturned 1 (i.e., only one argument was provided), then set the value of the optional argument to its default ofnil
Meanwhile, Back in JRuby...
This has gone on a bit long, so I'll just close by saying that JRuby does not have an equivalent forrb_scan_args(), or at least not one that is called on a per-method basis. The runtime is responsible for bundling arguments and calling the appropriate Java method based on the number of arguments actually present. This causes a bit of a problem right now for class methods that take optional arguments (as BigDecimal.mode() does), but that's a subject for another post.
Thursday, June 07, 2007
Umm, What Exactly Is Google Trying To Tell Me Here?
Dear Google,
Look, I know this is a weblog about programming and Java and stuff, and I know you're just trying to help out with the targeted, "relevant" ads. And I'm okay with that. Really, I am.
However...

I think the whole "help out the poor, socially inept Revenge of the Nerds rejects" vibe is a bit much, huh?
Love,
David
Look, I know this is a weblog about programming and Java and stuff, and I know you're just trying to help out with the targeted, "relevant" ads. And I'm okay with that. Really, I am.
However...

I think the whole "help out the poor, socially inept Revenge of the Nerds rejects" vibe is a bit much, huh?
Love,
David
Kickin' it Old School: Inspecting $CLASSPATH with sed and grep
Here's a fun
Note that the <return> above means to actually hit the return key following the backslash. This bit of awkwardness is
I needed this in the context of figuring out a broken Ant build while testing some changes I'm making to JRuby. Unfortunately, even the pretty-printed version of my Ant classpath was too long to sift through with the naked eye, so I turned to
That is, break up the classpath into one line per entry, and show me only the entries for jruby.jar. With this, I was able to determine that I had an older version of jruby.jar on my classpath that is incompatible with the current trunk. Problem solved!
I love a happy ending.
sed one-liner that I used today to break up the entries in my $CLASSPATH:
echo $CLASSPATH | sed 's/:/\<return>
/g'
Note that the <return> above means to actually hit the return key following the backslash. This bit of awkwardness is
sed's way of specifying a literal newline as part of the substitution string (how literal can you get?). The net effect is to replace the colon characters with newlines, resulting in a display of my classpath with one entry per line.I needed this in the context of figuring out a broken Ant build while testing some changes I'm making to JRuby. Unfortunately, even the pretty-printed version of my Ant classpath was too long to sift through with the naked eye, so I turned to
grep to look for exactly what I needed:
echo $CLASSPATH | sed 's/:/\<return>
/g | grep jruby.jar'
That is, break up the classpath into one line per entry, and show me only the entries for jruby.jar. With this, I was able to determine that I had an older version of jruby.jar on my classpath that is incompatible with the current trunk. Problem solved!
I love a happy ending.
Tuesday, June 05, 2007
Rant: JSP + OGNL + Collections == Train Wreck
The Story So Far
In my day job I'm using Struts 2, with JSP as the view templating mechanism. I have a collection whose size I'd like to report on the page. Unfortunately for my sanity, I have recent experience with Ruby on Rails, in which such a thing is as simple as:<%= @myCollection.size %>But no.
Problem #1
Struts 2 exposes properties on the Action class via OGNL, which has a nice, clean, property-based syntax, much like RHTML (which is what Rails uses for its view templates). So I should be able to ask for something like this:${myCollection.size}Assuming, that is, that I have a method
getMyCollection() defined on my action. Which I do. The problem here is that I also have to have a method called
getSize() defined on whatever getMyCollection() returns. Which is a java.util.Set. Which, for some reason, does not have a getSize() method. It has a size() method instead. Apparently the designers of the Java 2 Collections API were feeling a mite saucy when they went a-designin', and were daring their overlords to punish them for ignoring the Java Beans method naming convention that, as it turns out, OGNL relies on heavily.D'oh!
No problem, though. OGNL doesn't require method names to be bean-compliant, it just prefers it in its chain of figuring out what the heck you're asking for. You can invoke any method directly, as in:
${myCollection.size()}Problem solved! Let's save everything and reload:
Struts Problem Report
Struts has detected an unhandled exception:
Messages:
view.jsp(40,109) The function size must be used with a prefix when a default namespace is not specified
org.apache.jasper.JasperException: view.jsp(40,109) The function size must be used with a prefix when a default namespace is not specifiedWhat the...?! Oh. The JasperException must mean that the
${...} expression is being interpreted as JSP EL instead of OGNL. Bummer. Oh well. I'll just let the EL engine handle it.Which brings me to:
Problem #2
The JSP EL engine can't handle it. Neither the property syntax nor the method syntax works. The property syntax wants to use the (non-existent)getSize() method too (go figure). And the method syntax doesn't exist. So. Since it looks like JSP EL trumps OGNL when the page is rendered, I'll just turn off JSP EL evaluation (in web.xml) and let OGNL handle everything.
Or not. That results in a ton of errors from pages in my app that rely on JSP EL.
Solution
I'll try to wrap this up. It turns out that the answer is JSP functions. "All" I have to do to get the number of items in my collection is write a public function class and implement a static method -- which I get to name anything I want! Just like the Collections API designers! -- that takes the collection as a parameter and returns its size.Oh, and I have to write a snippet of XML in the form of a .tld file that tells the JSP where to find this function.
Oh, and I have to declare the .tld as a taglib at the top of the JSP. And that's all I have to do.
Sheesh.
Conclusion
Fortunately, it turns out that the hardest part of this work has been done for me, in the form of the JSTL implementation (documented here) of several useful JSP functions, includinglength().It doesn't help my mood any that in Ruby -- if the problem existed to begin with, which it doesn't -- I could have solved it simply by adding a
getSize() method, aliased to the size() method of the Set class, and everyone would be happy.Grumble.
Subscribe to:
Posts (Atom)