My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Friday, April 11, 2008

Io programming language List for JavaScript

Io is a small, prototype-based programming language. The ideas in Io are mostly inspired by Smalltalk (all values are objects, all messages are dynamic), Self (prototype-based), NewtonScript (differential inheritance), Act1 (actors and futures for concurrency), LISP (code is a runtime inspectable/modifiable tree) and Lua (small, embeddable).

This programming language is really interesting, starting from syntax, throw the entire guide.

One of its primitive type is called List, and this is a summary of this type:
A List is an array of references and supports all the standard array manipulation and enumeration methods.

It seems that List is all we need when we think about an Array of elements ... so why couldn't we have something similar in JavaScript?

// Io programming language List example
// followed by my JavaScript List implementation
a := List clone
a = List.clone()

a := list(33, "a")
a = list(33, "a")

a append("b")
a.append("b")
==> list(33, "a", "b")

a size
a.size
==> 3

a at(1)
a.at(1)
==> "a"

a atPut(2, "foo")
a.atPut(2, "foo")
==> list(33, "a", "foo", "b")

a atPut(6, "Fred")
a.atPut(6, "Fred")
==> Exception: index out of bounds

a remove("foo")
a.remove("foo")
==> list(33, "a", "b")

a atPut(2, "foo")
a.atPut(2, "foo")
==> list(33, "a", "foo", "56")

a := list(65, 21, 122)
a = list(65, 21, 122);

a foreach(i, v, write(i, ":", v, ", "))
a.foreach(function(i, v){alert(i + ":" + v + ", ")})
==> 0:65, 1:21, 2:122,

a foreach(v, v println)
a.foreach(function(v){document.writeln(v)})
==> 65
21
122

numbers := list(1, 2, 3, 4, 5, 6)
numbers = list(1, 2, 3, 4, 5, 6)

numbers select(x, x isOdd)
numbers.select(function isOdd(x){return !!(x%2)})
==> list(1, 3, 5)

numbers select(i, x, x isOdd)
numbers.select(function isOdd(i, x){return !!(x%2)})
==> list(1, 3, 5)

numbers map(x, x*2)
numbers.map(function(x){return x*2})
==> list(2, 4, 6, 8, 10, 12)

numbers map(i, x, x+i)
numbers.map(function(i, x){return x+i})
==> list(1, 3, 5, 7, 9, 11)

The map and select methods return new lists. To do the same operations in-place, you can use selectInPlace() and mapInPlace() methods.

and my implementation has mapInPlace and selectInPlace as well :)

Am I forgetting something? ... of course, the source!

P.S. because of nature of List, you can do stuff like this one:

list(1,2,3).append(4).remove(2).size;
// 3

an so on ;)

3 comments:

Erik said...

I haven't done an exhaustive comparison, but Prototype.js extends Javascript's Array to act more like an Io List (or a Ruby Array, their main inspiration).

Of course, it's all wrapped up in Prototype--not what everybody wants.

Andrea Giammarchi said...

not what everybody wants.
and the reason is basically this one:
Prototype.js extends Javascript's Array ...

Prototype extends in a non standard way while I've not extended native Array.

The only one way I could extend them is adding standard prototypes, like I did in my ArrayObject :)

Randal L. Schwartz said...

It’s too bad Io has an implicit non-overridable “asBoolean” method in the Object base class. That’s a mistake… the same one Ruby and Perl made. Only Smalltalk gets that right.

it’d be ok if I could at least override “asBoolean” for my classes as far as ifTrue: and ifFalse: are concerned, but no. Io has its own idea, and that’s that. And I can’t even get it to throw a “must be boolean” error instead. Sigh. So close, and yet so far away.