Posts filed under 'code'

Duplicity and the Duplo Generation

Matt Aimonetti, author of the Rails on the Run blog, recently posted a controversial article in which he asserted this belief that new Rails developers are being sabotaged by the multitude of pre-written and reliable components available to them:

The problem is that a generation of Rubyists has grown up being used to getting everything pre written for them. They haven’t yet passed the “Duplo stage” and basically write applications putting a few blocks together, only writing 10 to 20% and barely understand 5%. 

Unfortunately, Matt is wrong - and not only that, but he’s being elitist.

Fractal Wrongness

 OK, so maybe he’s not that wrong. But he’s definitely not correct. This line of thinking is harmful to the Rails community at large, and much more so than any clueless newbie could be. Though this argument, Matt is separating the community into two sides: on one hand, those like DHH, Jamis Buck, and Michael Koziarski, who know Rails inside and out (and not just how to build Rails applications, but the inner workings of Rails), build Rails components, and have a fundamental grasp on the advantages and disadvantages posed by the Web, and on the other the Typical Newbie, who mashes pre-assembled parts into a hideous, insecure conglomerate of which he has only the most superficial understanding.

This is not true. There are many people - I count myself among them - that use components not because we’re too lazy or stupid to understand how they work, but because we’re focused on creating things that nobody else has yet. Reinventing the wheel is immensely frustrating, boring, and a waste of time; Rails components allow us to avoid reinvention and focus on what matters, and to condemn this mindset simply because not all developers have the time or energy to understand every tool they’re using is absurdly foolish.

My Common Sense

Fundamentally, Matt is also hurting himself with this statement, as in condemning the low end of Rails development he’s furthering the stereotype that Rails developers are either cretins or douchebags. Jeff Atwood put it a little too bluntly when he stated (somewhat in jest) when he stated the following:

when you’re using Rails and OS X, you’re using the platform of choice for douchebags. 

But frankly, attacking newbies who are attracted to Rails by the promise of never having to write Yet Another Damn Authentication System is going to make you seem like a douchebag. And sure, there is a problem with newbies who refuse to understand that programming is not merely a matter of snapping components together. But that isn’t a problem specific to Rails; it’s everywhere, in server-side, desktop, and enterprise software, in Python, C++, and Ruby, on OS X, Windows and Linux. To blame an entire community for allowing this to happen is ludicrous and ultimately harmful.

Don’t think. 

Addendum: Matt published an extension of his ideas in this post, in which he clarifies certain aspects of his ideas. Go! Read it! 


2 comments March 21, 2008

Announcing Nuki 0.1 (VoodooPad, watch out!)

Dear interwebs,

Today I finished the first release of a simple, database-backed and web-accessible Wiki software written entirely in Nu and making use of the NuHTTP and NuMarkdown libraries. I call it Nuki (pronounced ‘nookie’), and I wrote it to teach myself how to integrate Core Data and NuHTTP in a simple application.You can check it out from Subversion here. Read on to see what I learned whilst writing this application. 

(more…)


2 comments January 6, 2008

NSDate Weirdness (and Nu!)

Now that Nu is released to the public in all its glory, I’ve been doing a lot of coding exercises in it. As is my wont, I wrote a program that prints out the current Discordian date, and in the midst of looking at the NSDate and NSCalendarDate documentation, I found this fascinating class method on NSDate:

+ dateWithNaturalLanguageString:(NSString *)string:

Creates and returns an NSDate object set to the date and time specified by a given string.

Parameters
string
A string that contains a colloquial specification of a date, such as “last Tuesday at dinner,” “3pm December 31, 2001,” “12/31/01,” or “31/12/01.”

Return Value
A new NSDate object set to the current date and time specified by string.

Discussion
This method supports only a limited set of colloquial phrases, primarily in English. It may give unexpected results, and its use is strongly discouraged.

This piqued my interest in a big way; it reminded me of the way Lotus Agenda could recognize date input such as “next Thursday” and “eight days from now”, as detailed in the fantastic book Dreaming in Code. I couldn’t just leave it alone, so I whipped up a little Nu script for you. Run it and it will present unto you a prompt, at which point I invite you to enter such phrases as:

  • next Tuesday
  • September 22, 1988
  • 3 hours from now

You will see that those phrases - and a multitude of others - are parsed correctly as NSDates, leaving you free to actually work on other things rather than futz around with NSScanners. Give it a try! And look at Nu as well!


(global readline (NuBridgedFunction functionWithName: “readline” signature: “**”))
(puts “Press Ctrl-C to quit.”)
(while 1
(set input (readline “>>> “))
(set date (NSDate dateWithNaturalLanguageString: input))
(if date
(puts (date description))
(else
(puts “Your input of ‘#{input}’ could not be parsed. Try again!”))))


Add comment December 27, 2007

15 Programming Exercises

Being what could be charitably described as a programming language junkie, over the past few years I’ve amassed a number of programming exercises aimed towards establishing fluency with a new language; some of these are barely beyond Hello World or FizzBuzz, while some can get quite tricky. Mackenzie Morgan expressed interest in improving her Python-fu; after listing half-a-dozen of these ideas, I said “Hey, maybe this would make a good blog post.” As such, I present to you a list of programming challenges. Many of these have been culled from various sources on the Internet, and I have endeavoured to provide credit where due.

  1. In general, each language treats collections differently - some (Nu and Smalltalk) start indexing from 1, whereas most start indexing from 0; Ruby returns nil when one tries to access an element outside of an array index, whereas most others throw some sort of an exception; each language has its own set of ideals that it deems best. Your challenge is to take your favorite language and turn this paradigm on its head - if you use a relaxed, permissive language such as Ruby, write a NeuroticArray class that panics at the slightest opportunity; if you use a stricter language such as Java or Haskell, write a RelaxedArray structure that throws as few errors as possible. Bonus points will be awarded if the public interface to your new collection is nearly identical to that of the original type.
  2. Write a text munger, as detailed in this Ruby Quiz link. The most obvious solution to this problem is to remove the head and tail characters of each word, shuffle the remaining letters, and replace the head and tail characters; as such, this teaches character manipulation, sequence shuffling, and string concatenation.
  3. Implement a collection-backed regular expression matcher, as detailed in this Ruby Quiz. This teaches about object-orientation (strictly speaking, OOP is not necessary for this exercise), regular expressions, and increases awareness of the limitations of languages (Ruby’s built-in limit on regular expression length inspired this quiz).
  4. Write a simple script that obfuscates English text by adding any possible accent or umlaut to each letter in a sentence. This teaches the basics of regular expressions and associative arrays.
  5. Write a high-level input library, as detailed in this Ruby quiz. Not only does it teach how to write a good API, but it also forces you to consider the various needs of the people who use your API’s. Can you satisfy everybody, or will you be forever mediocre?
  6. Write a tool to turn Hacker Keys into English-readable strings. This is an excellent situation in which to learn about the power (and limitations) of regular expressions, and also shows programmers about the dangers of constantly-changing specifications. Bonus points will be awarded if your solution reads in the hacker key specification from configuration files; even more will be awarded if you write a tool that parses user input into a hacker key dump.
  7. Write a parser for HQ9+ or HQ9++. These exceedingly simple esoteric languages are very useful for learning the basics of regular expression usage, and implementing an REPL is always challenging and interesting.
  8. Build your own Scheme interpreter. Scheme’s syntax is extremely minimal, as such, with a good parsing toolkit - please, if you value your sanity, do not try to write a parser using nothing but regular expressions - writing a Scheme interpreter is far, far easier than you’d think. The fantastic Haskell tutorial Write Yourself a Scheme in 48 Hours is an excellent introduction to a language that is, at times, terrifying. (In a conversation with my mom about the ambitious scope of this particular exercise as applied to Haskell, I said “Imagine, Mom, if immediately after learning how to say ‘Hello’ in Japanese, the second assignment was to write a Russian-Japanese dictionary.”)
  9. Write an ID3v1 tag parser, as detailed in this Ruby Quiz. The ID3v1 format is extremely simple, and a parser can be written easily and understandably in even a very low-level language. This will teach about file input and output, and also present the difficulties associated with programs that deal robustly with malformed input.
  10. Write a graphical frontend to a system tool such as fortune. In lightweight scripting languages this task will be much easier than with heavy-duty languages such as Objective-C or Java; however, no matter what langauge you choose this will teach you about construction of a simple GUI and how to interface with the operating system. Bonus points will be awarded if you write a cross-platform tool that invokes the correct tool for a particular task no matter its operating systme - e.g. a tool that invokes the tracert tool on Windows and the traceroute command on *nix.
  11. Most programming languages have support for more than one GUI toolkit; write a program that compares the widget support for as many different toolkits as possible. Not only will this illustrate the sheer magnitude of the difference between a good and a bad API, but programming a GUI correctly provides a very visceral satisfaction. The difficulties of building a project that links into multiple heavy-duty libraries may play a part in this project, depending on the language used. You could also contrast GUI builders with writing the widget-placement code manually in this project.
  12. Finish the Ruby Quiz (yes, I do realize that half of these ideas are links to the Ruby Quiz, now will you shut up?) metakoans.rb exercise. If you can’t finish it - I sure couldn’t, on my first try at least - look at the solutions that other people submitted and try to understand them. If you’re feeling brave, implement the quiz and the solution in your language of choice. If you’re feeling like a goddamn hero, solve the continuation koans.
  13. While programming in any language, one will build up an often-used set of useful functions and modifications; clean up, comment, and publish these extensions. You never know who might find them useful!
  14. Take a simple program you’ve written - for example, one that prints out the lyrics to the 12 Days of Christmas - and remove all familiar concepts from it. If you’re working in C, don’t use a for loop. If you’re using an imperative language, recurse rather than iterate. If you’re using a language with mutable state, program in a purely functional style.
  15. Solve all the Project Euler problems that you can - and make sure that you pick the right algorithm for the job. There is a world of difference between what you learn when you write a brute-force solution that takes the whole night to run and a complicated but effective solution that takes 10 seconds to run.

Have any more ideas? Did I leave out your pet exercise? Leave a comment.


6 comments November 11, 2007

Programming Limericks

GOTO Considered Harmful

GOTO makes your code like spaghetti
Please don’t throw it around like confetti
A conditional clause
Has far fewer flaws
So just structure your program, already.

Good Agile, Bad Agile

It’s hip to use Agile scrums
To prepare for change (when it comes)
But, frankly, it seems
To be harmful to teams
Excepting my Googler chums.

What’s Nu?

We fused Cocoa’s power with Scheme
To produce a language supreme
Of glorious beauty
That kicks Ruby’s booty
And makes Python look powered by steam.


2 comments November 4, 2007

Compensating for the Suckage of OS X Terminals

Every terminal in OS X that I’ve tried (Terminal.app, iTerm, Terminator) refuses to send a myriad array of valid keystroke combos over SSH. This wouldn’t be a problem except for the fact that I use Emacs, the Uber-Editor.One of these unsupported keystrokes is Control-Meta+any key (for those not fluent in Emacs, Meta is Alt); considering that this is one of the key commands in Emacs, the only alternative - pressing Escape to activate the Meta key, then entering the desired key command - is very inefficient and tends to interrupt the flow of typing. 
Until I can figure out the proper incantation to get Emacs to recognize a key as pressing Control-Meta, this shortcut will help with the inefficiency: 
(global-set-key "\C-c\C-v" 'ESC-prefix)
If anyone on the Lazyweb has any suggestions on how to fix this problem, please leave a comment. 


5 comments September 12, 2007

“Haskell Curry? Yes, I dated his daughter.”

Last week I had the opportunity to talk with Alonzo Church, Jr. (he prefers to be called “Al”), son of the Alonzo Church (you know, the one who only invented the freaking lambda calculus). We had a lovely conversation; we talked about Alan Turing, Fortran, COBOL, the future of computer science, and all sorts of other interesting topics. The highlight of our conversation, though, was this:

Me: “So, I’m learning a new-ish programming language named Haskell right now. It’s very strange.”

Al: “Did you say Pascal?”

Me: “No, Haskell. It’s named after a logicial named Haskell Curry –”

Al: “Oh, Professor Curry! Yes, I knew him! My father worked with him!”

Me: “No way! That’s awesome!”

Al: “Yes! In fact, I dated his daughter!”

Me: “You DOG!”


11 comments August 21, 2007

How Tim Burks and Nu Stole the Show at C4[1]

Edit: Fixed some factual inaccuracies about the language itself.

Tim Burks, noted contributor to RubyCocoa and creator of RubyObjC, gave a talk at C4[1] about his experiences with creating a Ruby <-> ObjectiveC bridge, and the problems he overcame in doing so. It was an interesting presentation, and we were all suitably appreciative when he showed his custom visual chip-design software written in Ruby with a Cocoa interface.

And then he dropped a bombshell.

For the past year, Tim’s been working on a new dialect of Lisp - written in Objective-C - called Nu. Here are its features (more precisely, here are the ones that I remember; I was so awestruck that many went over my head):

  • Interpreted, running on top of Objective-C.
  • Scheme-y syntax. Everything is an s-expression (data is code, code is data). Variable assignment was done without let-clauses (which are a pain in the ass) - all one has to do was (set varname value).
  • Variable sigils to indicate variable scope.
  • True object-orientation - everything is an object.
  • True closures with the do-statement - which, incidentally, is how Ruby should have done it.
  • Macros. HOLY CRAP, MACROS! When Tim showed us an example of using define-macro for syntactical abstraction, Wolf Rentzsch and I started spontaneously applauding. His example even contained an example of absolutely beautiful exception handling that should be familiar to anyone with any ObjC or Ruby experience.
  • Symbol generation (__) to make macros hygenic and prevent variable name conflicts.
  • Nu data objects are Cocoa classes - the strings are NSStrings, the arrays NSArrays, etc.
  • Ability to create new Obj-C classes from inside Nu.
  • Interfaces with Cocoa libraries - you can access Core Data stores from within Nu in a much easier fashion than pure ObjC, thanks to Tim’s very clever idea of using a $session global to store the NSManagedObjectModel, NSManagedObjectContext, and NSPersistentStoreCoordinator.
  • Ruby-style string interpolation with #{}.
  • Regular expressions.
  • Positively drool-inducing metaprogramming, including a simulation of Ruby’s method_missing functionality.
  • A web-based templating system similar to ERb in 80 lines of Nu code - compare that with the 422 lines of code in erb.rb.

Tim showed us a MarsEdit-like blog editor written entirely in Nu, using Core Data as its backend - and then showed us the built-in Nu web server inside that program, complete with beautiful CSS/HTML/Ajax.

As F-Script is to Smalltalk, so Nu is to Lisp. Tim said that he hopes someday to open-source Nu; if he does, he will introduce what is quite possibly the most exciting development in the Lisp-related community in a long time. I don’t think I speak for just myself when I say I cannot wait to get my hands on it.


3 comments August 12, 2007

Inform 7: Natural-Language Programming Lives

When most programmers think of natural-language programming, they usually think of Applescript - an ambitious yet doomed-to-failure language with English-like syntax that Apple developed in order to automate OS scripting tasks. Frankly, Applescript in its current incarnation is pretty dismal - any reasonably complex script is positively overflowing with ends and tells, reminiscent of Ruby’s slower, dumber cousin. (Incidentally, 99% of the pain of Applescript can be removed with Ruby or Python bridges.)

These painful memories, combined with other influential condemnations, will probably lead many programmers to shun Inform 7 and its mission to be “built by writing natural English-language sentences.” However, if you will wait a moment, I will show you the masterful elegance with which Inform 7 mixes modern programming paradigms and the English language.

For those of you unfamiliar with Inform, it’s a system for writing text adventures - well-known examples include Adventure, Zork, and the famously difficult adaptation of The Hitchhiker’s Guide to the Galaxy. Inform was created in 1993; in its first six versions, games were written in a procedural programming language with a syntax looking like a cross between Perl and Applescript. Now, however, games are written entirely in English and then translated with the I7 compiler.

The following is not meant to be a full-fledged I7 tutorial; the official site does that far better than I ever could. This is simply a demonstration of how I7 manages to express complex programming concepts entirely in English.

(more…)


3 comments June 18, 2007

Map, Filter and Reduce in Cocoa

After working in Scheme, Python or Ruby, all of which (more or less) support function objects and the map(), filter() and reduce() functions, languages that don’t seem to be somewhat cumbersome. Cocoa manages to get these paradigms almost correctly implemented.

map()

One would think that Objective-C’s ability to pass functions around as objects in the form of selectors would make writing a map() method easy. Observe, however, the crucial differences of the NSArray equivalent to map(). (For those unfamilar with it, map(), when given an array and a method/function taking one argument, returns the result of mapping the function onto each item of the array.)

From the NSArray documentation:

makeObjectsPerformSelector:

Sends the aSelector message to each object in the array, starting with the first object and continuing through the array to the last object.

- (void)makeObjectsPerformSelector:(SEL)aSelector
Discussion

The aSelector method must not take any arguments. It shouldn’t have the side effect of modifying the receiving array.

This is different on no fewer than two levels. Firstly, even in the NSMutableArray subclass, this method is not allowed to have side effects. Frankly, I can think of few situations in which I would need to map an idempotent function onto an array; the point of map() is to be able to apply a function quickly to every element of an array and get back the changes! Secondly, an unaware or hurried programmer would think that this function was implemented so that one could write code like this:

- (void)printAnObject:(id)obj
{
NSLog([obj description]);
}

and then do this:
[anArray makeObjectsPerformSelector: @selector(printAnObject:)];

This is not the case - the above code would just make each element call printAnObject:, not call printAnObject with each element. I’m sure that to some it seems obvious, but I, for one, found this to be an insidiously tricky wart.

However, there is a (limited) workaround.

NSArray’s valueForKey: method (somewhat counter-intuitively) returns the result of invoking valueForKey on each of the array’s elements. As such, one can map KVC functions onto arrays. For example:

NSArray *arr = [NSArray arrayWithObjects: @"Get", @"CenterStage", @"0.6.2", @"because", @"it", @"rocks", nil];
[arr objectForKey: @"length"]; // returns [3, 10, 6, 7, 2, 5]

This can be used in many helpful ways; sadly, it only works on KVC-compliant properties/methods.

Anyway, moving on…

filter()

With OS X 10.4, Apple introduced the NSArray filteredArrayUsingPredicate: method, which allows one to filter an array based on criteria established by an NSPredicate. Observe:

NSArray *arr = [NSArray arrayWithObjects: @"This", @"is", @"the", @"first", @"CenterStage", @"release", @"I", @"helped", nil];
arr = [arr filteredArrayWithPredicate: [NSPredicate predicateWithFormat: @"SELF.length > 5"]]; // arr is now [@"CenterStage", "@"release", @"helped"]

Verbose, but useful.

reduce()

Frankly, Apple don’t give us any way to do this in pure Cocoa. The best way I’ve found (if you really need this, which is less often than one needs map() and filter()) is to use the F-Script framework and apply the \ operator to an array. Unfortunately, this takes a bit of overhead.

In conclusion, Cocoa and Objective-C almost bring us the joys of functional programming. We can only hope that Leopard and Obj-C 2.0 improve on these in some way.

List comprehensions, anyone?


3 comments June 18, 2007

Previous Posts


About Me



I'm a college freshman, passionate about technology, programming (especially Cocoa and Python), and Apple.

By the way, 'important shock' is an anagram for 'Patrick Thomson'.

Meta

Links

Categories

Top Posts

Blog Stats