RE: Null and Undefined as Objects in JavaScript

I regret not making everything an object, FWIW. “Make it look like Java” + lazy/fast machine types for numbers + zero time to implement in May 1995.
- Brendan Eich (creator of JavaScript)

Wouldn’t that have been something.

Sweet, sweet Reia

Reia is sweet. At first glance, it looks like Ruby with parenthesis and pattern matching. Pattern matching! From my brief stints with SML (and Erlang,) I’ve longed to take pattern matching back with me to every language I use.

At second glance — well, I’m still in the midst of taking a second glance, actually. But, here, some encouraging words:

Reia is its own language and is not a fork of Ruby. The syntax is heavily inspired by Ruby, however past the cosmetic level things get very, very different.

Reia runs on the Erlang VM and attempts to use the object system itself as the concurrency mechanism. All objects in Reia execute concurrently and synchronize with messaging.
- Tony Arcieri (Reia developer)

Concurrent objects? Huzzah! Jörg W Mittag, please tell us more:

Talk about coming full circle …

In Smalltalk-71, Alan Kay experimented with having each object running in its own process and communicating with asynchronous message sends. There is an older quote from Alan Kay, where he says that one thing he very much regrets, is not emphasizing the message sending aspect of object-orientation enough. And just recently, he said that not running objects in parallel, was one of the biggest mistakes of Smalltalk.

Smalltalk-71 was what inspired Carl Hewitt to invent the Actor Model. … Now, Ruby, a very faithful implementation of the Smalltalk object model, and Erlang, a very faithful implementation of the Actor Model, combine and produce Reia, an object-oriented parallel actor language, in which the concepts of process == actor == object have been unified, just like in Smalltalk-71.

Interesting.

I already had Erlang on my list of languages to learn, as the functional style woos (if you’re into that sort of thing). Still, Reia looks comfortable and fun. I’ll have to finish my current glance and perhaps take a few more at it…

Don’t Push Your OOP On Me

Implementations of classical inheritance in JavaScript always leave a bad taste on my tongue. John Resig articulates why:

I’m not convinced by this argument. “Because it’s what we’re familiar with” does not imply that it’s the best solution - or even a good solution - neither does “everyone else is doing it.” I’ve been doing JavaScript development for a while now and I’m becoming less-and-less convinced that the traditional MVC/Classical inheritance styles of development (carried over from Java or Ruby, for example) do not translate to JavaScript/DOM well and can, in fact, be improved upon in some dramatic ways.

That said, I was working on a way to achieve multiple inheritance in JavaScript via mixins - but in a traditional prototypal manner! It’s cool man, really!

An Object That’s Not

In JavaScript, objects just love their prototypes. And why wouldn’t they? Whenever they are in need of a property, hey, they can always check up the inheritance chain and try to find it. It’s good to know someone always has your back!

But, what if no one had your back?

$ js
js> var obj = {};
js> obj.toString();
[object Object]
js> obj.__proto__ = null;
null
js> obj.toString();
typein:4: TypeError: obj.toString is not a function
js>

hwaaa!

js> obj+obj
typein:5: TypeError: can't convert obj to primitive type
js> typeof obj.__proto__
undefined
js>

Poor obj has no prototype to inherit from anymore - we set it to null. It knows nothing of the built in wonders inherited from Object.prototype. No toString, no hasOwnProprty, no nothing.

There’s even a way to wipe out Object.prototype for everyone (I’ll leave this as an exercise for the reader.)

Direct access to the inherited prototype can sure do some wacky things, indeed. I’ll post on the more useful functionalities I’ve found in a bit.

The Miller Device on null and Other Lowly Un-values

null and undefined are weird. Normally, you would check for them directly by using x === null or typeof x === undefined, etc, but what if we use the Miller Device?

An example of usage:

var myArray = [];

if(Object.prototype.toString.apply(myArray) === '[object Array]') {
  // do array operations
}

Every browser gives consistent results for JavaScript’s other top level objects:

object = [object Object]
array = [object Array]
string = [object String]
number = [object Number]
NaN = [object Number]
Infinity = [object Number]
function = [object Function]
boolean = [object Boolean]
date = [object Date]
regex = [object RegExp]
error = [object Error]

Testing for null and undefined is a bit more interesting:

Firefox, Opera:

null = [object Window]
undefined = [object Window]

IE 6-8:

null = [object Object]
undefined = [object Object]

Safari:

null = [object DOMWindow]
undefined = [object DOMWindow]

Chrome/V8:

null = [object builtins]
undefined = [object builtins]

Spidermonkey console:

null = [object global]
undefined = [object global]

In each case besides IE and Chrome, the string representation of the global object is being returned. IE returns the uninteresting [object Object] string, and Chrome hints again at why it should be distinguished from Safari, at least when testing JavaScript, by returning [object builtins].

If you were to use The Miller Device to detect null or undefined, you would simply use it on both the left and right sides of the comparison:

if( Object.prototype.toString.apply( MyObject ) ===
    Object.prototype.toString.apply( null ) ) {
  // FAIL
}

jsUnity

I was looking for a lightwieght, context-agnostic testing framework for JavaScript so I could describe the behavior of whatever script I was writing (and found one, thanks to Ates making it.) The particular script I was working on had no need for a browser or any of the extra environmental cruft - it was pure JavaScript, ready to be plugged in wherever it may go. Or perhaps it will never leave the comfort of a Spidermonkey shell, the point is I just wanted a quick run-down of what it should do, and not have to launch a browser just to see.

JavaScript decoupled from HTML? It is rare indeed. Even with server-side JavaScript you could still be dealing with a document.

Enter jsUnity (nice pun, by the way,) which lets you plug your test suite into any environment. You just supply a custom jsUnity.log function for logging to that environment.

jsUnity.log = function (s) { document.write(s + "</br>"); };

This rubs me the right way. This concept could be extended to allow other customizations for specific environments. The core test suite can stay light while modules are built around it.

The globally scoped assertions kind of bug me, but seem to be modeled after JsUnit style tests. Ideally, those assertions could reside in a module, making them as easy to use and safe to extend.

It’s a start, a nod in the right direction. Plus, there’s always github for forking.

Hey, JavaScript and HTML are a couple for now, but the way HTML has been flirting around, you never know… JavaScript needs to keep it’s figure right and assets in order - mmhm.

Odd: Using prototype as a Singleton

I was perusing the JsUnit code examples and noticed how they used the object’s prototype as a singleton:

var result = TextTestRunner.prototype.main( args );
JsUtil.prototype.quit( result );

Code like this appears throughout the page!

This strikes me with much fear and confusion. Surely, for use as a singleton, any arbitrary property name would be more appropriate than prototype, the home of instance method and property definitions. Why use a secondary namespace instead of the object itself, anyway?

The code base is old, so maybe conventions were not as strong then (though this seems largely fundamental,) or something was lost in translation.

In any case, I’m still looking for a good testing framework to use on the console, or in arbitrary contexts. Edit: found one.

C File Descriptors: A Novice Dialogue

In the Operating Systems class at my university, one of the projects we have to complete is a Unix shell. It’s a basic shell which should support piping, redirection, inverse redirection, and background processes. Needless to say, this was an immensely interesting and useful project, though sometimes difficult for the unassuming undergrad.

I had completed it in a previous semester, but a friend called on my guidance last semester for implementing pipes and redirection. She contacted me via IM:

Qi: hey Zact
  Zach
 me: zact??
 Qi: lol
  sorry
 me: ha, np

What follows is my attempt at explaining file descriptors, forks, and redirection, without much formal knowledge and not having worked with C in a year. Dijkstra would certainly not approve of such malling of a radical novelty, but my friend was grateful nonetheless and the dialogue does indeed prove to be useful in achieving a basic understanding of the premises of the project (namely, forks and file descriptors.)

Read at your own peril.

To follow along, also have the tutorial code handy.

All of this trouble was not in vain, however:

Qi: THANKS MUCH MUCH MUCH
  i owe you one
  after exams are done
  i'll cook some noodles
  ;)
 me: !!!!!!!!!

I would have been fine with naught, for I gained much from this as well, if not more.

Removing duplicate characters

An interesting string method was brought to my attention on the ruby-talk mailing list: string.squeeze. It removes duplicate characters in a string, and performs better than regular expressions or splitting-joining, to boot. Craig posted some benchmarks:

require 'benchmark'

n = 1_000_000

Benchmark.bm(10) do |x|
 x.report("gsub") { n.times do
    "This     is  a test   string.".gsub(/ +/, ' ')
  end
 }
 x.report("gsub!") { n.times do
    "This     is  a test   string.".gsub!(/ +/, ' ')
  end
 }
 x.report("split.join") { n.times do
    "This     is  a test   string.".split.join(' ')
  end
 }
 x.report("squeeze.strip") { n.times do
    "This     is  a test   string.".squeeze(' ').strip
  end
 }
end

               user     system      total        real
gsub        4.470000   0.040000   4.510000 (  4.578173)
gsub!       4.390000   0.020000   4.410000 (  4.468695)
split.join  3.500000   0.020000   3.520000 (  3.556669)
squeeze.strip  1.980000   0.010000   1.990000 (  2.003622)

Nice!

Committing to a better editor

Yeah, I use vim. You know, for those trivial edits or during remote sessions. Nevermore! I finally got tired of selling myself short. This past weekend I committed myself to use vim (mostly gvim) for any and all of my daily coding. This is something that was long overdue, and after getting real friendly with vim this weekend, I wish I would have done it much sooner. …

Once I got comfortable with the basics by going through vimtutor, I started configuring my .vimrc file with some convenient mappings. I have a habit of pressing Crtl-S constantly while coding, so I mapped that in vim to save by putting this in my .vimrc file:

map <C-S> <Esc>:w<CR>
map! <C-S> <Esc>:w<CR>

Sweet! I then googled around a bit and picked out additional scripts and mappings that looked useful (most of them found on Vim Tip Wiki.) My .vimrc file is here.

Then it was on to plugins. This blog post by Jamis had a bunch of useful tips. I don’t even need a project browser pane thanks to FuzzyFinderTextMate. I just launch gvim from the root of my project (I made a little convenience script to make this even easier) and every file is a few keystrokes away. I should note I used vim 7’s new graphical tab feature the first day, but soon found buffers to be quicker and more capable/compatible with plugins, though tabs were a good way to ease into things.

I also love the snippetEmu plugin (the snippets for JavaScript were severly lacking, so I added some.)

I put my whole configuration directory including my .vimrc file on github so I can pull it down into whatever work environment I’m in. Feel free to peruse.

If you are still using Notepad++, Gedit, or some other not-bad-but-not-terribly-awesome editor, commit to something better! That is, if you really are serious about this. This is serious business, darn it!

Yeah, I know, it’s awkward. Similar to learning Linux/git/anything worthwhile, it can be awkward at first, but the payoffs can be astronomical. That was the case for me after installing Ubuntu about, eh, two years ago. If I’ve gained this much from vim in just a weekend, I can’t imagine how my work flow will be in two years.

Times are tough, invest in your future!