Getting more comfortable with Limelight

April 29, 2009 at 6:45 pm (Graphic Design, Limelight, Ruby, Week 6) (, , , )

OK, Limelight is starting to get fun. I’m finding my bearings in the framework, and I’m learning how to test different types of tasks. It’s really easy to do functional and view testing by adding a macro-style uses_scene :board call in RSpec (it’s built into Limelight as part of its spec_helper.rb). This gives you access to props on the scene that you specify. I’m also seeing some really awesome features of IntelliJ, which I’m learning to use better and am even starting to prefer over TextMate for the refactoring tools: Rename and Extract Method are two of my best friends at this point. Watching over Micah’s shoulder yesterday as he tracked down some Limelight source code, I learned the beautiful Command-Shift-N command to find files by name and autocomplete (like TextMate’s Command-T, which I’d missed very much).

The fact that all of Limelight’s code is in Ruby means there are lots of opportunities to cut down on repetition, which is especially welcome when it comes to Styles and Props (Limelight’s analog of the stylesheets and HTML elements we’d see in Rails). There are some tricks you have to be aware of to share data across files. There’s nothing like Rails’ passing of instance variables from controller to view, as far as I know. But luckily there’s an object called the production that everybody has access to, and we can add attributes to that object to hold data that needs to be available across files (in my case, references to the object that communicates with my Java code and some styling concepts).

And speaking of styling, I’m now armed with a handful of design-oriented links from my designer friends. Most are website gallery sites, but there’s a blog or two in there as well. Now, I’m not under any false impression that I’m suddenly going to be a designer by looking at some websites, but I’m sure I’ll improve. I have two Scenes (like views) in my application, and I’m relatively happy with the styling I did today on the first scene (the game type choices, like “Computer (X) vs. Human (O)”), but the second scene (with the board) definitely needs some work. I got a nice, simple color scheme from, and I even did a little fade animation (you can easily change the transparency of props) as the scene begins.


Permalink Leave a Comment

Exploring Limelight

April 28, 2009 at 9:44 pm (Limelight, Ruby, Week 6) (, , , , , )

I spent the day continuing and accelerating my learning in the Limelight GUI framework. I’m sure I’ve mentioned before, but everything you write is Ruby code (there’s Java behind the scenes, so you run your applications with the JRuby interpreter and gems. Limelight is still very young (pre-1.0), and as with any framework, it takes time and advice to learn how the framework wants you to code. I ran across a couple of things that I felt would be more intuitive with a slightly different API (mostly styling-related), and Micah agreed and had me report them on the project’s Lighthouse page. There’s not a ton of tutorial documentation on Limelight so far, but here are the most important ones I know about already:

  • Installing Limelight
  • Calculator in 10 Minutes Screencast – Micah walks you through building a lightweight calculator application
  • Tutorial #1 – there’s a slight tweak you need to do to get it working this way, at least on the latest Limelight version
  • A Cook’s Tour of Limelight – great deeper-level overview of the parts of Limelight (Production, Props, Scenes, Players, Stages)
  • Style Attributes – similar to CSS style attributes, but with some awesome additions like built-in gradients and rounded corners (there are plans for drop shadows as well)

I’m sure as time goes by, there will be a lot more available, especially as JRuby gains in popularity. Keep your ears open!

I got the Tic-Tac-Toe game working with human players, which was a big step. There are still some kinks to be worked out with the “Play Again” process (I think my Java code is left waiting for input), but I’m excited to have it working, and to have spent the day getting better and more confident with BDD. Once I’ve patched those up, the real work will start on this assignment: styling it up, adding some effects, and in general just making it really presentable, with relation to the UI and design. I know my designer pals would be scared to hear about me designing anything, but I’d like to add some more design skill to the old bag of tricks, so I may be hitting them up for links to design blogs and other learning resources.

Permalink Leave a Comment

Let the names begin!

April 27, 2009 at 5:59 pm (Ruby, Week 6) (, , , , , , )

I decided it’d be better if I gave more semantically meaningful titles, so that people have more of an idea of what they’re getting into when they happily decide to read about what I did at work. Today, clearly, is an exception (at least as it relates to my learning), but let’s look past that and on to a future where I’m not speaking in numbers anymore.

Eric and I worked most of the day on behind-the-scenes work for our Rails app: mostly automating the deployment with Vlad the Deployer and writing automated browser-based tests utilizing Watir. Both technologies are pretty cool. I’ve lived with Capistrano for some time, though I mostly used the outstanding Rails Machine gem as a starting point. Well, it turns out Vlad owes a lot to Capistrano and Rails Machine as well, so it wasn’t all that different. There were a few gotchas I ran across, namely some weirdness with set deploy_via, :remote_cache, but for the most part we were just re-learning how to set a deploy recipe up from scratch. Not too difficult once we found the list of Vlad variables, and it’s great to have things automated now instead of having to SSH in manually and make the changes we need.

While we’ve done our unit testing with RSpec and used Cucumber for most of our integration tests, we found that there were certain things we needed Watir for: SSL and Javascript testing, in particular. I’m pretty certain there’s a way to hook Cucumber up to Watir, but we ended up just wrapping these new Watir integration tests with RSpec, which works just fine for our current purposes. There were a few problems that required us to SSH into our staging server (which we’re running these Watir tests against), but once we figured out the syntax for multiple SSH commands on one line, we were home free (we have SSH keys set up to manage the login process, which I highly recommend for anyone managing servers):

ssh 'cd /path/to/application/current/; rake do_task'

The single quotes are the key! Once again, thank you Google.

I also did a story by myself where our error page has a form to submit your email address if you have a problem and would like to hear back from the support team. Hopefully that story won’t see a lot of use, but I’m proud of it. The code is clean and will be easy to maintain, and there are good tests for it. I hope I’ll be able to say the same about my Limelight app once it’s done.

Permalink 2 Comments

Week 5, Weekend

April 26, 2009 at 8:20 pm (Reading, Watching, Week 5) (, , , , , , , )

I’m constantly amazed by the amount of information available online to help people improve and learn. To my wife’s chagrin, I spent several hours watching video lectures by Hal Abelson and Gerald Jay Sussman (from a 1986 course presentation at Hewlett Packard) and by Douglas Crockford (at Yahoo, I believe).

These aren’t directly related to my assignments for the apprenticeship, but I’m learning a lot. The Abelson/Sussman lectures (also on Google Video) are based on their book, The Structure and Interpretation of Computer Programs (SICP), which I understand was the introductory course at MIT for many years. I recommend the 256k mp4 versions if you’re downloading – the 64k are too hard to make out, and the high-res ones are huge! The language, Scheme, has got some pretty cool features, but to be blunt, the parentheses are pretty ugly. The really interesting part of this language, so far, is that functions are first-class objects, which can be saved into variables, passed into other functions, etc. This isn’t a completely foreign concept to me, as Ruby has closures like Procs and lambdas, but I think it’s the area of Ruby where I feel the least comfortable. Another pretty crazy thing is the way control structures like loops must work: recursion (a function might call itself with a modified index). I feel like I’d have had an easier time beginning to understand the minimax algorithm if I’d watched these videos first – the tree structure in particular was clearly explained, in one example, as it related to recursion.

I’d seen Caleb Cornman‘s tweets about the Crockford videos (they’re also available for download from the YUI Theater site), and realized (for the umpteenth time) that even though I’ve written a decent amount of Javascript in my day, I know basically jack about how the language works. I’ve generally just let the Rails helpers, JQuery, or Prototype to do the dirty work for me, hacking in the rest as needed. So that can work, as it does for many others, but trust me when I say that you don’t want to be debugging ugly Javascript. I’m a little weirded out that I just happened to be learning about lambdas and Lisp, and Crockford mentions several times that how Javascript is the first language with lambdas to really hit the mainstream. Javascript has no concept of classes, only objects! I’m surprised, but intrigued to learn a lot more about the subject. Currently debating whether to start with Crockford’s Javascript: The Good Parts (recommended highly by Jim Suchy) and David Flanagan’s Javascript: The Definitive Guide (the only book Crockford recommended other than his own). The local library has the 4th edition of the Flanagan book – I wonder how much has changed in the most recent (5th) edition… Anyone familiar with these and have advice?

I spent some time during and after each of the videos fooling around with practicing Scheme and Javascript, in Emacs and Firebug (a Firefox add-on), respectively. I’m starting to get the hang of Emacs, which is encouraging. I’d need to do a lot more reading and practicing to get as good with it as I am with Vim, but I feel like I should at least have a rudimentary knowledge of how to get around in Emacs, since it’s one of the most-used editors on Unix machines (and has such strong Lisp integration).

I also did a lot of reading, from Refactoring by Martin Fowler et al., and a book I’m reviewing for the Pragmatic Programmers. I won’t say much about the review book, but it’s very good so far, and I think it’ll turn out wonderfully. They were looking for someone who wasn’t an expert, and as I told Micah, that’s me!

Refactoring is so much more readable than I’d imagined. I had always thought of it in the same category as the Gang of Four Design Patterns book, which I flipped through once at a bookstore and found it to be far beyond my understanding. I think at this point it’d be easier, but Refactoring is extremely clear and easy to read. I wish I’d read it sooner, because it describes a lot of the things I’ve done to clean up my Tic-Tac-Toe (and to make changes to it as they came up). The automated tools in IntelliJ made the process easier, of course, but I’m also discovering that some of my bigger changes could have been made much easier by applying the steps in the refactorings catalog.

It’s always a good sign when you’re excited to get back to work and do some coding, but I’m wondering if I should be doing more actual coding at home. I may get into some Limelight Tic-Tac-Toe tonight – I think that things should fall into place more quickly now that at least some of the game logic is hooked up between Java and Ruby.

Permalink 2 Comments

Week 5, Friday

April 25, 2009 at 10:22 am (Java, Limelight, Ruby, Week 5) (, , , , , , )

I took the steps necessary to have no parameters in the constructor for my Tic-Tac-Toe view class, so that we could implement the interface in JRuby during our Randori session over lunch. I’d spent a little time thinking about what it would take, so it wasn’t too bad. I had three parameters initially: a Controller, a PlayerFactory, and a Board.

Well, the PlayerFactory was only really being used in one method, and all we really needed there was an array of Strings that showed the types of games that were available, like “Computer (X) vs. Human (O)”. So I changed that method to take an array of strings, and changed uses of that method to pass in information from the PlayerFactory (they were all in the Controller, so no new package dependencies resulted).

Also, since the Controller already had a reference to the same Board object as the View, I just added a getter called getBoard() on the Controller, and used that to set the Board on the View rather than the constructor.

The last thing was taking the controller out of the constructor. The View needs the Controller, for sure, so I added a setter on the View, which any class that instantiates a View would need to call right after creating it. I don’t much like this, since I had to change all my test class setups, and it’s more work for anyone wanting to implement a View, but I think it’s necessary to make the connection to Ruby code.

I also started with the Limelight props and styles being built already, so for the Randori, we focused on implementing the View interface in Ruby. We worked in IntelliJ, and there were a few tongue-in-cheek complaints about that (from Textmate fans). I definitely don’t know IntelliJ as well as I know Textmate or even Vim, but the big plus it has for me is the ease of refactoring, and the color-codification of things that are not going to compile or run properly. At any rate, we got a lot done. After a bit over an hour, with rotation of pairs every 5 minutes, we almost had a running Limelight application that used two computer players. I just had to change a couple lines right afterwards to get it to work as expected.

I have to say, I was initially skeptical when Micah told me we could use my Ruby version OR Java version of Tic-Tac-Toe to implement it in Limelight. I knew my Ruby version worked, but looking back, I knew its OO design was weak; I don’t think there was any kind of display class at all, so I’d have had to change a lot – I may still do that. But to use Java classes in Ruby code? That sounds crazy, but honestly, it wasn’t too bad. But I guess the person showing us how to do this has written a framework using Java and Ruby, so you’ll have to decide for yourself:

require '/Users/colin/IdeaProjects/TicTacToe/tttt.jar'
module Board
def scene_opened(e)
@view = new View(self)

class View
include Java::trptcolin.baseGame.View
# implement methods

Now, it may only be this easy because we’re doing it through Limelight, but either way, I think it’s pretty nifty.

I felt a lot less embarrassed about my abilities during this Randori than at the last one, where I was basically useless. This time I had a lot of domain knowledge to offer (since I wrote the Java code and the Limelight props), but more importantly, I had a better idea of what to test when I was at the keyboard. I still felt slower than everybody else, but at least this time I felt like we were more or less on the same page.

Permalink Leave a Comment

Week 5, Thursday

April 23, 2009 at 8:48 pm (Java, Ruby, Week 5)

I dug into Limelight today, spending the morning experimenting with a view and styling for a Tic-Tac-Toe board. All the code is Ruby (running on JRuby), so there’s some pretty cool stuff you can do, especially with styling. My favorite features so far are gradients and rounded corners, which cause me nightmares in XHTML/CSS, but they’re as easy in Limelight as this:

gradient :on
gradient_penetration 90
gradient_angle 135
rounded_corner_radius 15
border_width 2
border_color :black

Besides that, other big wins over CSS that I see are the ability to store variables (in my case, things like board_size that I can use to calculate percentage widths of the squares and a simple macro-style inclusion of one set of styles into another (extends :square), which reminds me a lot of SASS. I haven’t seen evidence (and Eric M. and Paul confirm this) that there’s anything like CSS’s nested elements, but I often see those used hackily anyway (yes, that’s a brand-new word, feel free to copy).

Turns out my Java Tic-Tac-Toe will see a little more action after all: apparently it’s possible to have Ruby create Java objects, so that we can write a view in Ruby that will integrate with the rest of my Java program. However, there’s going to need to be some refactoring first, so that the Java view can be constructed more simply and have fewer dependencies. I guess tomorrow at lunchtime we’re going to do a Randori session with Limelight to do some of this integration. I’m excited to see how this sort of thing is done, but I have plenty of work ahead of me to avoid embarrassment as people have free reign over my code. I think I’ll do the refactoring to make the Ruby object creation easy before the Randori, and probably also make the hashing into an interface, so that people playing the game aren’t obliged to have their computers spend so many hours calculating the meaning of life storing records in the database (I stole that bit from Micah).

The alternative would be to rewrite TicTacToe in Ruby, which I’ve done once but I think it’s dirty enough, OO-wise, that it would be harder to integrate by lunchtime tomorrow. I may rewrite the game logic in Ruby at some point, but not yet.

Right now, my assignment is to get a really good user interface together, maybe even some little animations or something to make it look nice. In principle, I feel pretty comfortable with this; when I was implementing XHTML/CSS sites from Photoshop mockups, I got to see a lot of amazing designs, matching them basically pixel-for-pixel, and I think I gained an amateur eye for design by osmosis. But of course, now it’s a matter of learning Limelight!

Permalink Leave a Comment

Week 5, Wednesday

April 22, 2009 at 10:37 pm (Java, Week 5) (, , , , , , )

From yesterday morning to this afternoon I improved my understanding of the Hashtable a lot. Micah found a flaw in my hashing yesterday, but when I started to blog about it last night, I found I didn’t really understand my problem, so I held off until tonight.

I was doing this sort of thing:

private Board board;
private static Hashtable boardScores = new Hashtable();
// ... (calculating the score for a particular board position)
boardScores.put(board, calculatedBoardScore);

I had hashCode() and equals() defined on my Board class according to the squares filled on the board, but I wasn’t REALLY following the way that hashing works in Java (actually, in any language). My big flaw was in not realizing that while a given board position would always resolve to a given hashCode(), there’s no guarantee that it will be distinct from the hashCodes for other positions! So “XOX XOO X” (for a 3×3 board) might go in the same “bucket” as “OOXX OO X”, for all I know. Well, that’s not necessarily a problem when I store the positions in the Hashtable; the problem is getting them back out.

From Hashtable’s get() method:

if ((e.hash == hash) && e.key.equals(key)) {
return e.value;

And the key WAS a Board, which has equals() defined as having every square equal. So a hash lookup with Boards as keys really should work? No, actually! (This is where I got lost trying to work things out in my head last night) It’s true that the board is the key and 2 boards with different square configurations will not compare as true with equals(), but the keys are not really different boards. In fact, they were all references to the same board, which means that when if I get a hashCode() collision (which will most likely happen with the millions of boards that I’m hashing), there will be confusion, because the second part of the conditional in the Hashtable code above will always be true.

So anyway, Micah helped me to refactor to use new String objects as the Hashtable keys instead, which fixed the logic flaw, but took up even more memory and crashed the program at a lower depth search (running out of room in the heap). This all took place yesterday. Today I came in with the idea that I’d refactor things, write some more tests, and clean up some dependencies. I think I accomplished those goals, starting with a lot of refactoring (using IntelliJ’s built-in refactoring tools). I tried out a new-to-me tool called JDepend to check out problems with my packages, and I tracked down a few dependency cycles (that’s a BAD Java programmer. No dependency cycles. Nnnoo!). JDepend is an open source project by Mike Clark of Advanced Rails Recipes fame. It was pretty easy to use, and while class-level detail could’ve been nice, it was easy enough to do a “Find in Path” to track down the naughty dependencies. Here’s how it went:

  1. downloaded from Github (
  2. ran ant task to build it
  3. $ java jdepend.swingui.JDepend ~/IdeaProjects/TicTacToe/ (there’s also a textui and xmlui version)
  4. too many packages shown for me to process well, so I added in home directory to ignore junit, hamcrest, java
  5. ran again, started doing searches for dependencies in my packages and breaking them where necessary to avoid the cycles

Now my package dependencies were as follows:

  • main => depends on baseGame, boards, players, and ui
  • ui => depends on baseGame, boards, and players
  • players => depends on baseGame and boards
  • boards => depends on baseGame
  • baseGame => no other project dependencies

Before my refactorings, every single one had a dependency cycle (icky).

And then we came to the afternoon, when I finally got fed up enough with the memory constraints of the Hashtable to open a JDBC connection and write the millions of positions and scores to a database. This was new to me, but the MySQL website was helpful enough that it wasn’t a big deal to do. One false start (only 8 levels deep), ~10 million database records, 16 levels deep, and ~6 hours of writes and indexing later, my computer player can play a 4×4 board more quickly, but in exactly the same way as he did at 6 levels deep with the (corrected) Hashtable. Which was not that badly, except at the opening. He makes smart moves to avoid a loss (on both sides) at the end, but at the beginning he thinks all the positions are equivalent. My impression in thinking as deeply as I can about this for a week or so is that on a 4×4 board, it is extremely easy to force a tie. So easy that a player would need to make at least two bad moves in order to lose. There’s no forcing a win after one misstep like on a 3×3 board. I think in order to get the computer to play like a human, I’d have to use an evaluation function that added value for 2-in-a-rows and 3-in-a-rows, which I’d have to do anyway in a more complicated game like chess, since there are so many more possibilities to consider there.

At any rate, Micah decreed that today was my last day on Java Tic-Tac-Toe, and so I’m moving on to Limelight tomorrow. Micah’s actually the author of Limelight; it’s a framework based on Java and JRuby that allows you to write rich GUI applications in Ruby. Pretty cool stuff; I’ve looked at some here and there since arriving in Illinois, and Eric and I looked at some this afternoon. I don’t know yet whether I’ll be doing some more Tic-Tac-Toe or something else, but I’m looking forward to digging into the new technology.

Whew, how’s that for an epic send-off for Java Tic-Tac-Toe? Apparently that’s what happens when you write 10 millions records to a database!

Permalink Leave a Comment

Week 5, Tuesday

April 21, 2009 at 9:26 pm (Java, Week 5) (, , , , , , , , )

Eric and I spent the morning making some styling tweaks to the Rails application, and I moved back to Tic-Tac-Toe in the afternoon. I got the board score caching to work almost immediately, or so I thought. Micah sat down with me to help me with my Ant build, which had been broken since I split the project up into packages. The fix there turned out to be easy (with the right knowledge): I needed to add JUnit to the compile classpath. For some reason I had it in the classpath for the <junit> element for running the actual tests, but not in the compile.

So then we took a look at my caching mechanism, which was taking up the whole heap and throwing errors at 6 levels deep in the game tree. Micah helped me to increase the heap size to 512MB, which got us to 9 or 10 levels deep, but we still eventually took up the whole heap again. We spent some time with a profiler tracking down the objects being created, and of course it was the hashed objects (~ 6 million of them) taking up all the memory. We worked for awhile to decrease the memory we were using, but we didn’t end up making it any more levels deep. At this point, the 4×4 computer player still makes some weird moves near the start of the game, but he gets smarter towards the end and avoids losses.

Micah noticed that my caching didn’t have tests (cringe), so that was my next assignment. Because my minimax method was so big and complicated, I kind of went to town with the Extract Method refactoring and eventually figured out a way to get some tests written on the caching part. Along the way, I discovered that JUnit doesn’t allow you to test private methods, and got some “Extract Class” knowledge dropped on me by Doug, who said that if I had a private method that wasn’t already covered by tests on my public methods, maybe those private methods really belonged somewhere else, as public methods on another class! For now, I’m just changing the method I wanted to test into a public method.

I like the looks of this class a lot better now that it has smaller methods – it’s a lot more readable. I think I picked some decent names, like writeScoreToCache(), getCachedScore(), getValueToOtherPlayer(), finalScore(), calculateBestScore(), etc. There is still a lot to be done for this program to look like something out of one of these books I’ve been reading, but it’s getting closer. And I’m getting a lot better at seeing what the differences are, which I think is really positive.

Permalink 1 Comment

Week 5, Monday

April 20, 2009 at 9:37 pm (Ruby, Week 5) (, , )

Long day today: we closed out basically all of the outstanding bugs in our Rails application, and we’re going to be launching publicly soon. There are a few styling and wording tweaks left, but the actual bugs and other big things are all done. I ran across a problem with RESTful routing in Rails that somehow I hadn’t encountered before. I know that on an edit form, you generally need something along the lines of :html => { :method => :put } since browsers don’t really do PUT requests, at least not yet (it inserts a hidden _method input with value “put”). This was working great to direct the form submittal to the :update action, but we also had an observe_field that needed to submit to a different action (for a live-preview AJAX request). It turned out that the observe_field was trying to submit to the :update action as well. I have a feeling there’s a “Rails way” around this dilemma, but I ended up just changing the :update action to be a straight POST request (no PUT), adding a :member => {:update => :post} route to handle it, and things are going swimmingly now.

Paul and I stuck around late to do some styling tweaks, and I think we’ve got something presentable, though there are still some improvements to be made. Launching early and often is exciting: we’ve gotten so much done in just three weeks on this project!

Micah and I had a one-month retrospective on my apprenticeship, covering the things that were going well, the things that weren’t going as well, and the things that should change. We think that in general, things are going very well. I mentioned that while I’ve come a long way with TDD and RSpec, that part of my programming is definitely weak. It kind of ends up falling into the “good” column, since I’ve progressed so much, but I have a long way to go to make it as strong of a habit as the other 8th Lighters. It sounds like there’s another, tougher project on the horizon once I finish Tic-Tac-Toe. Micah says the big things left for my Tic-Tac-Toe game are caching of the board scores (my HashTable) and then a code review with him. I’m pretty confident in my ability to get the HashTable working properly, but I know that the code review is going to show me some weak spots. I’m definitely going to need to take a few passes through the codebase to refactor and add tests where I can. I feel certain that I’m going to spot a lot of bad things, since I started this project three weeks ago, and I’ve come so far since then. It makes me a little apprehensive, but I have to remember this talk from David Heinemeier-Hansson. Key thoughts: “The software doesn’t change… you got smarter… you learned more… When that tomato went from great to rotten, that was a process in you, where you improved.” Inspiring and happy thoughts.

Permalink Leave a Comment

Week 4, Weekend

April 19, 2009 at 6:44 pm (Week 4) (, , , )

I got a lot of reading done over the weekend: finished up Clean Code by Robert Martin (with chapters by other Object Mentors as well), which I’d been working on for a couple months or so now. Great book; I highly recommend it. I ended up finishing it late Saturday night, and then felt a strong urge to do some coding. So I took a look through some open-source project I’d contributed to in the past, mostly just playing around, and finally ended up spending a few hours doing some bug fixes on the Rails app Eric and I are working on. Bug fixes are so much more satisfying when you write tests to accompany them. This way, you feel confident that you’re not going to see that bug again, and you also get a chance to go back into the code and refactor if needed. Refactoring wasn’t much needed in this case, but I looked!

And speaking of Refactoring, I started reading that book (by Martin Fowler) last night as well. I’d been putting it off since I felt better about my abilities “in the small” than with larger-scale design decisions, but the introduction makes me realize that small improvements are going to lead to larger design improvements over time, so I’m excited about that. I certainly have a lot of room for improvement and learning on a small scale as well!

After hearing Eric Smith and Corey Haines tweet back and forth a little bit about SICP, I had to investigate. Turns out “SICP” is Structure and Interpretation of Computer Programs, a computer science textbook using Scheme (a LISP dialect), which I’d looked into when I first started getting interested in programming but which went way over my head at the time. Inspired, I watched the first course lecture (by Hal Abelson) on Google Video, read the first section of SICP, and played around with Scheme on my laptop (re-learning Emacs navigation along the way).

I’ve learned a lot this weekend, and I’m looking forward to getting back into Java a bit this week, along with Rails and whatever else is in store!

Permalink Leave a Comment

Next page »