Category > geekstuff
Posted by postfuturist on 2009-11-24 23:02:36
JavaScript is an excellent programming language. As a language, its strength lies in the simplicity and regularity of its syntax. I'm going to show you how much simpler it is than even Python or Ruby. OK, here is how you define a function in JavaScript:
function hello(target) {
alert("Hello, " + target);
}And here is how you create an anonymous function:
function (target) {
alert("Hello, " + target);
}There really aren't many surprises here. Basically, omit the name and you have an anonymous function object. The following is very similar to the first excerpt (not exactly, but close enough):
var hello = function (target) {
alert("Hello, " + target);
}There are no arbitrary limitations or unwieldy syntax shifts in JavaScript surrounding named and anonymous functions. You can call a function with another one:
foobar( function() { do_something(); return 42; });Python calls anonymous functions lambdas and gives them strange syntax and arbitrary limitations. Here is a normal Python function:
def hello(target):
print("Hello, " + target)
An anonymous function looks like this:
lambda target : "Hello, " + target
Oh, wait, it looks wierd and doesn't actually print anything. It only returns a string value. Yeah, that's Python's lambdas. There's been a lot of talk about it, and Python 3 has dumped them completely. Named functions are still first class objects in Python, so you can use those in most of the ways you would use an anonymous function, so JavaScript's calling a function with another function gets expanded a little in Python:
def thing:
do_something()
return 42
foobar(thing)
It is still elegant, just not as useful, IMO.
Ruby's named function:
def hello(target)
puts "Hello, " + target
end
Ruby's anonymous function:
proc { |target|
print "Hello, " + target
}
# --OR--
Proc.new {|target|
print "Hello, " + target
}
# --OR--
lambda {|arg|
print arg
}While the syntax may be... disconcerting, Ruby anonymous functions are just as powerful as JavaScript's.
In my day job, I write code mostly in PHP. The common PHP installation on a given server these days is PHP 5.2. This language is severely lacking. It does not have first class functions, though it is dynamic. It has classes, but they were strangely modeled after Java, a statically typed language. It is a sad little language deployed just about everywhere. In my daily work I bounce between JavaScript and PHP. Since the advent of V8, Google's insanely fast JavaScript implementation, I have thought it would be fun to use JavaScript on the server side. You get all the power and flexibility of a dynamic language, running several times faster than Python and Ruby with the ability to share code between server and client-side. My dreams have come true in the form of Node.js.
Now I know that server-side JavaScript has been around for a long time, it just hasn't seemed appealing for a number of reasons. First of all, I've only been doing professional web development for about a year, and I've only learned to appreciate JavaScript during that time. Secondly, early server-side JavaScript was in the form of ASP + JScript running under IIS. A crappy JavaScript implementation running on a closed Microsoft web stack is not my idea of appealing.
I've dabbled with using the "better" languages on the server side such as Python (Django and Pylons), Ruby on Rails, and Perl (Catalyst and CGI.pm). The distinct advantage is that these languages have large libraries and communities with vast quantities of pre-written code available with liberal, open source licensing. The frameworks are also mature and powerful. However, this does not exist for PHP. There are some libraries and code fragments available but the community surrounding PHP kind of sucks. The reason for this is that good programmers hate the language and don't want to waste time building things in it for free. Instead, they build things in Ruby, Python, and Perl.
The advantage of using JavaScript on the server is the easier context switching between client and server code. With JSON as the communication layer, there is no impedance mismatch between your server and client. Data can flow freely in both directions. Anonymous data structures in JavaScript are extremely powerful. They exist in Python, Ruby, and Perl, but the syntax is a little different and there are some gotchas here and there. Using JavaScript on the server and JSON as the data transport, you get a homogeneous stack. I hate writing a bunch of code and then watching it fail miserably because I was using the wrong operator to concatenate strings or constructing anonymous list with the wrong delimiters.
Programming fluently is like speaking fluently, it takes a lot of time with a single language to get the point where you don't have to stop and look things up all the time. The time it takes to look up how to do X in language Y is a real productivity killer. Sure, you are learning, but it's something that you've already learned in a bunch of other languages, it's just that you haven't done it enough in this particular language. Or each language does it very slightly differently, so you get them confused over time. In the world of hobbyist programming, all the different language quirks are fun diversions, and you can ponder the benefits of this or that language feature or syntax or library API. But when you need to get things done for a client, they add up to annoyances. If I could just get and stay fluent in JavaScript and work with a complete JavaScript stack for web development, I think I could be very productive.
In time the JavaScript server-side frameworks and libraries will be built up and it will be a good thing.
Posted by postfuturist on 2009-11-03 01:04:13
This article will be a series of short rants.
1. A lot of people complain about broken suspend/resume on laptops with Linux. Usually, it is fixable, just search for your laptop model. In the case of this model, the fix is the same as Ubuntu/Kubuntu 9.04: add "pci=nomsi" to the grub boot line. This line now seems to reside in "/boot/grub/grub.cfg" instead of "/boot/grub/menu.lst".
2. I have to recant. I used to recommend installing the kubuntu-restricted-extras package. That has some dependencies that are not necessary, less than ideal, or outright bad. It installs Sun's proprietary Java runtime. It's pointless and bloated. Just install openjdk, it's standard, open source, and a better default Java. It seems to run Netbeans just as well as anything else. The restricted-extras package also installs the free Microsoft fonts, which is used a lot by the web browsers to render pages "more like Windows." It turns out that this is not a good thing. The replacement, open fonts already installed on your system look better, render cleaner, and generally are more pleasant than those crusty old Microsoft fonts. Why do we want fonts from MS, anyways?
3. Install and run Chromium daily build as your primary browser. Seriously, this browser outperforms Firefox 3.5 in every way. It is much faster, doesn't leak memory like Firefox seems to (still), and is just nicer to use. Get it here. Don't get me wrong, Firefox is a great browser. Despite that, Chromium is still a much better browser. It is, trust me. For example, when the Flash plugin crashes, Chromium tells you that the plugin has crashed and continues functioning. Conversely, Firefox crashes completely and you lose everything, in every tab. The problem with Firefox is the crufty old Mozilla code base which was inherited from Netscape. It is a single process model that is extremely bloated and bug prone. I've looked at the code, it is disgusting. It's not the fault of the Mozilla Foundation. They've worked hard to improve it, but it looks like a lost cause in comparison with Chromium and other KHTML derivatives like Safari. Chromium is derived from WebKit, which was a fork of KHTML, a rendering engine created by the KDE project, used most famously in the Konqueror web browser. So, it is fitting to run Chromium on Kubuntu, a KDE desktop.
4. KNetworkManager? Not sure what happened here. This network connection manager is completely brain-dead. Immediately install Wicd, and reboot.
Posted by postfuturist on 2009-10-29 00:17:59
I've always avoided Perl because of its reputation. And, well, it looks funny. The Perl folks like to golf, which leads to more confusion and incomprehensible code. But then I started picking up bits of information. The creator, Larry Wall, is linguist, not a computer scientist nut. There are constructions in the language that are unseen elsewhere but flow naturally making for a language which is beautiful at its core.
print "hello" if $happy;
It's a stronger, more elegant voice than the much more common:
if ($happy) { print "hello" };Both are valid Perl. The first one requires less punctuation because the keyword sits between the two statements and there is therefore less ambiguity. It may seem strange to a programmer's eye but it
is a cleaner syntax. They are also both valid English, and even in English the second construction requires a comma in the middle to disambiguate the meaning. The language feels like it was constructed by a linguist because it has linguistic constructions.
There are issues. The language is baroque in it's complexity. Regular expressions are a powerful, fundamental part of the language, and contribute to the "line noise" quality. The sigils, those symbol prefixes on variable names, are uncommon in modern languages and the use in Perl is confusing.
my @array = ("1", "2", "3"); # the @ signifies an array
my $number = $array[0]; # but you have to use the $ when extracting a scalar
my $arrayref = ["4","5","6"]; # and references to arrays are scalar
$#array -= 1; # what the hell is going on here? (shrinking the array)That's just character, though. What's really going on is a lot of choices. Any programming paradigm fits Perl. It is fully "functional" so you can have anonymous functions, pass functions around like other data, and take advantage of closures.
sub outer {
my $a = 0;
return sub { return ++$a; };
}
my $inner = outer();
print $inner->(); # prints "1"
print $inner->(); # prints "2"It's object oriented capabilities are deceptively simple but are, in fact, very open-ended and able to be used in any manner you see fit. Here is a simple example.
package Foo;
sub new {
my $class = shift;
my $obj = shift;
return bless $obj, $class;
}
sub bar {
my $self = shift;
print $self->{baz};
}
package main;
my $foo = Foo->new({baz => "hello"});
$foo->bar(); # prints "hello"
I will not explain in detail exactly what's happening on each line, but it will suffice to say that Foo is a class and $foo an instance of that class. At first, the system seemed unwieldy, but when I saw what Perl hackers have built on top of it,
Moose, I began to understand how powerful this language truly is.
The real treasure of Perl is CPAN, a huge collection of Perl libraries where one finds likes of Moose and its extensions which are legion. This rabbit hole goes very deep indeed. Perl does very little to stop you from accomplishing your tasks, large and small, and provides the tools to create abstractions at many levels and with many paradigms. It's my latest obsession.
Posted by postfuturist on 2009-10-11 22:17:48
This page : Synaptics Touchpad : Community Ubuntu Documentation has a fantastic fix for the problem of bumping the touchpad while typing. This is a big problem typing on the Compaq CQ60 215DX, the laptop I use. It has a large touchpad and the natural position of my hands while typing causes me to bump it which is very annoying as this treated as a mouse click.
To fix this problem you must first enable SHMConfig (only for Ubuntu 9.04 or earlier, skip this step for 9.10 or later). Create a new file called /etc/hal/fdi/policy/shmconfig.fdi and put the following text in it:
True
Reboot the computer.
Now add the following command to startup (omit '-S' on 9.10 or later):
syndaemon -t -i 1 -S -d
There are a couple ways to do that. If you are using a regular Ubuntu / Gnome desktop you can add it through System -> Preferences -> Startup Applications. If you are using KDE / Kubuntu you can add a startup script to this folder:
~/.kde/Autostart
Such a script would look like this (omit '-S' on 9.10 or later):
Kubuntu 9.04:
#!/bin/sh
syndaemon -t -i 1 -S -d
Kubuntu 9.10:
#!/bin/sh
syndaemon -t -i 1 -d
You could save the file with a name like:
~/.kde/Autostart/syn.sh
The file should be made executable. You can do that with the following command:
chmod +x ~/.kde/Autostart/syn.sh
Now, after the next reboot, or if you run the script manually, the touchpad will ignore bumps that cause clicks and scroll events for one second after every key press. So, as long as you are typing, no disrupting clicks.
Posted by postfuturist on 2009-08-20 01:16:26
In JavaScript functions are also objects, just like arrays are also objects. Functions, when treated like objects, act like objects. They exist as instances and are referenced from variable names or object properties which are also just references. Here is a simple, empty function assigned to a variable (reference).
var emptyfunc = function() {};Now, this function doesn't do much, but it is a full-blown instance of an object, and can have property values assigned to it.
var myfunc = function() {};
myfunc.foo = "bar";
myfunc["baz"] = "boz";There is a shorthand for creating a function instance that looks more like C-style function definitions. It may look like a C-style function, but it is a named reference to a nameless function object, just like the previous examples.
var adder1 = function(a,b) { return a + b; );
function adder2(a,b) { return a + b; }; // identical to adder1What separates functions from normal objects is that they may be called, as functions, and not just treated as objects. They may be called in two different ways. The first way is as a normal function that you might use in any language, with named formal parameters, return values and such.
var adder = function(a,b) { return a + b; };
var mynum = adder(2,2);
document.write(mynum); // 4JavaScript functions have something special about their "object" part, it is not initialized as an empty object, but with a single property "prototype" which references a (usually) empty object.
var adder = function(a,b) { return a+b; };
document.write(typeof(adder)); // function
document.write(typeof(adder.prototype)); // objectThe prototype property on the function exists to facilitate prototypical inheritance when the function is used to create an object (the second way it can be called). I'll explain what prototype does later. This second way of calling the function uses the "new" keyword and instead of returning a normal value (or null when there is no return statement reached) it returns a new object. The new object may be referenced in the function itself as "this".
var creator = function()
{
this.foo = "bar";
}
var newobj = new creator();
document.write(newobj.foo); // bar
This type of function is referred to as a constructor function. There is nothing different about a constructor function. One function can do both tasks, but this is rarely useful, as a constructor function called normally (without the "new" keyword) would not have a new object reference "this" to deal with, but would be messing with the "this" object in the surrounding scope. Since there are two syntaxes to create functions, one way of differentiating the functions is to use one syntax for normal functions, and the other for constructors. YMMV.
// assignment syntax for normal functions
var normalfunc = function()
{
return "hello";
}
// function definition syntax for constructors
function constructorfunc(a)
{
this.value = a;
}
var phrase = normalfunc();
document.write(phrase); // hello
var myobj = new constructorfunc(phrase);
document.write(myobj.value); // hello
These constructor functions are similar to class definitions, and indeed some JavaScript references are so bold as to call them classes. They are not. They are only functions (objects) which create other objects. If you haven't guessed it yet, the prototype property of the function serves as a prototype for the objects it creates (or so it appears). The constructor functions above have prototypes that are empty objects (default), so the "this" object created in the function starts out as an empty object that inherits the properties of the constructor's prototype.
function ABC()
{
this.normalvalue = "1";
}
// add a property to the prototype object
ABC.prototype.protovalue = "2";
// initialize new object from ABC constructor
var abc = new ABC();
document.write(abc.normalvalue); // 1
document.write(abc.protovalue); // 2
When you go to access a property of an object, the runtime first looks at the object, and if it can't find the property, it goes to the prototype of the object's constructor. So the object appears to be a clone, but is still secretly "borrowing" attributes from the constructor's prototype at the time of creation. Here is my proof.
function B() {};
B.prototype.foo = "bar";
var b = new B();
// change the foo property of b's constructor prototype
B.prototype.foo = "baz";
// and magically b appears to have changed too
document.write(b.foo) // bazIt gets trickier. If you assign a value to b's "foo" property, it creates a new "foo" property on the b object, so changes to the "foo" property of the prototype will no longer affect b.
function B() {};
B.prototype.foo = "bar";
var b = new B();
// add foo property to b object
b.foo = "hello";
// change the foo property of b's constructor prototype
B.prototype.foo = "baz";
// but that no longer affects b, as b has it's own foo
// property and no longer needs to borrow it from
// the prototype
document.write(b.foo) // helloAll objects actually are created as though from a function object called Object. This means that you can monkey with the prototype used for all objects.
Object.prototype.what = "yikes";
var emptyobj = {};
document.write(emptyobj.what); // yikes
This can have dire consequences. It is probably a good idea to neither mess with Object's prototype or use the "for in" style of looping through an object's properties.
Object.prototype.leech = "hello";
var myobj = {a : "1", steak : "sauce"};
for(x in myobj)
{
document.write(x + " : " + myobj[x] + ", ");
} // a : 1, steak : sauce, leech : hello,
Please leave comments if you found this useful (or if you hated it). Stay tuned for more.
Posted by postfuturist on 2009-08-18 23:55:57
An array in Javascript is a superset of an object that contains an ordered list of references. Here is the simplest Javascript array imaginable:
[]
The references in an array are not named, so creating an array of (references to) values and assigning that to a reference (variable) is easy.
var myarray = [1,2,"3","four"];
Arrays elements can be referenced through a square bracket syntax similar to the properties of an object are referenced. The difference is that the index is numerical, with the first reference in the array being the zeroth.
var anarray = ["foo","bar",1000];
document.write(anarray[0]); // foo
document.write(anarray[1]); // bar
document.write(anarray[2]); // 1000
Since arrays are also objects, named references may be added after creation.
var myarray = [1,2,3,"ABC"];
myarray.name = "MJ";
myarray["othername"] = "Michael";
There is no "literal" syntax to initialize a JavaScript array with object properties. Some web pages suggest iterating through an array with the "for(x in y)" syntax, but this is prone to bugs, as this iteration will iterate also through the object properties of an array.
var myarray = [1,2,3,"ABC"];
myarray.name = "MJ";
myarray.push("hey");
for(x in myarray)
{
document.write("(" + x + " -> " + myarray[x] + ") ");
}
// (0 -> 1) (1 -> 2) (2 -> 3) (3 -> ABC) (name -> MJ) (4 -> hey)
document.write(array.length); // 5
To just iterate through the array elements and not the properties, the traditional C style for loop works best:
for(var x = 0 ; x < myarray.length ; x++)
{
document.write("(" + x + " -> " + myarray[x] + ") ");
}
// (0 -> 1) (1 -> 2) (2 -> 3) (3 -> ABC) (4 -> hey)
As you can see from these examples, arrays have some built-in properties and functions, like "push()" to add items to the end of the array and "length" which returns the number of array elements (not object properties). These helper functions and properties do not exist in the array's object property map, they are just part of the language and the JavaScript runtime knows what to do. In addition to the push() function, there is a pop() function which removes the last item of the array and returns it. To add items to the front of an array, there is the unshift() function and to remove them from the front of the array, shift(). There are others. Here is a taste:
var test = ["a","b","c"];
test.push("d"); // ["a","b","c","d"]
var letter = test.pop(); // letter is "d" and test is back to original state
var first = test.shift(); // first is "a" and test is ["b","c"]
test.unshift("A"); // ["A","b","c"]
test.splice(1,1); // removed second element, so test is ["A","c"]
var large = concat(test, ["d","e"]); // large is ["A","b","d","e"]
var short = large.slice(1,2); // short is ["b","d"]
var desc = large.join("+"); // desc is a string : "A+b+d+e"
The functions all act on the array elements, not the object properties. Arrays can contain themselves, too.
var myarray = [3,2,1,"ABC"];
myarray.push(myarray);
print(myarray[4][4][4][4][0]); // 3
Like objects, arrays have a special Java-like syntax for initializing them in addition to the literal syntax in the previous examples.
var e = new Array();
e.push("first");
var another = new Array("first", "second"); // same as ["first","second"]
Posted by postfuturist on 2009-08-18 20:51:28
To understand JavaScript objects, you have to understand references. A variable in JavaScript is a reference to an object or a primitive value. Here is the declaration of a variable holding a numerical value:
var foo = 9;
JavaScript objects are very simple. Here is the simplest JavaScript object imaginable:
{}JavaScript objects are maps, which is to say a collection of mappings of names to references. Here is an object which has a few named references:
{ somenumber : 99, somestring : "ninetynine"}Usually an object is assigned to a variable (reference) so it can be referred to later.
var myobj = {foo : "bar"};The mappings are sometimes referred to as properties. They may be accessed from a reference to an object using the dot (.) syntax or the bracket syntax.
var myobj = {mynum : 9};
document.write(myobj.mynum)); // 9
document.write(myobj["mynum"]); // 9JavaScript objects can have properties added to them after being created.
var myobj = {foo : "something"};
myobj.bar = "hey";
myobj["baz"] = 100;
var similarobj = {foo : "something",bar : "hey",baz : 100};There is another syntax for creating an empty object. It is related to the Java-like syntax that JavaScript uses to create objects with prototype-based inheritance (which will be explained later).
var myobj = new Object();
myobj.blah = "100";
var identical = {blah : "100"};
Since the properties of an object are references, they may refer to other objects or to the object itself, recursively.
var complexobj = {innerobj : {prop : 100}, other : 9};
document.write(complexobj.innerobj.prop); // 100
complexobj.self = complexobj;
document.write(complexobj.self.self.self.innerobj.prop); // 100Got it?
Posted by postfuturist on 2009-08-13 10:29:54
So, to get my iPhone 3GS for only $199 (plus AT&T's $18 "phone upgrade" fee) I only had to sign another 2 year contract with AT&T and agree to an additional $30 per month charge for data. I already pay Comcast for internet connectivity at home. When I am home, the phone gladly connects to the network via wi-fi. So, I am really paying $1 a day to get internet connectivity through a cell connection that I am already paying for, only when I am not in my house. On top of that, I still had to choose a texting plan, as though something as simple as text messages exists outside of a cell connection and service and an unlimited data plan. At the end of the day, it's all data. At some point in the future we will just play a flat fee for connecting to cell towers. Voice, text messages, and random internet connectivity such as surfing the net, listening to streaming music and everything else will all fall under one umbrella. At that point, I doubt we will be willing to pay nearly $100 a month (in today's dollars) for such service.
Even with the "unlimited data" Apple has tried to limit the load on the towers by severely restricting connectivity when not on Wi-fi. Youtube videos look awful unless you are connected to Wi-fi. Can the higher quality videos not stream fast enough on 3G? Of course they can. Remember, 3G is fast. However, you wouldn't know it because the software just automatically requests low quality videos if the iPhone tells it that it is not on a Wi-fi network. I am paying for unlimited data, but I am not getting it. That's where the hacker side of me gets angry and does something about it.
Since my iPhone is already jail-broken, I can install Cydia apps. 3G Unrestrictor removes the unnecessary and debilitating limitations by allowing you to "lie" to your apps, telling them that they are connected via Wi-fi even when they are only on 3G or Edge connections. It makes no difference to the apps, really, because data is just data. So, now I can watch decent quality Youtube videos on-the-go. It can allow Skype to work without a Wi-fi connection, too. The fact that Apple and AT&T have conspired to limit your use of the unlimited data is maddening. I don't know how long consumers will put up with it. Hopefully, there will be a class action lawsuit or the government will realize that this type of bait and switch with locking down people's use of the internet is illegal.
Meanwhile, Apple is trying to make jail-breaking illegal. Yeah, good luck with that one. Jail-breaking does not exist for the purpose of pirating apps, though I suppose it is possible (I don't know how, haven't tried). It exists for using the phone to its fullest, you know the unlimited data plan I'm paying an extra $30 a month for. Getting an iPhone and not jail-breaking it, is not worth it. If you want a heavily restricted device with very low-quality video streaming, go for it. I live in the free world.
Oh yeah, I pay for Cydia apps, and feel good about it. Apple doesn't get a cut of the money for apps they didn't write. They do get a hefty 30% for all the AppStore apps they didn't write. It must feel great to be a monopoly. The Cydia apps are better anyways. Almost everything I've bought off Cydia, like 3G Unrestrictor, would never be allowed in the AppStore. To be fair, I also buy apps from the AppStore, just because they are only available there, and I know that at least most of the money is going to the developers.
Apple happens to be good at making hardware and decent at making software. These days though, they are excelling at being evil. Microsoft, with recent donations of GPL code to the open source community and their hesitating embrace of open standards and open source interoperability, looks like a big dumb teddy bear in comparison to Apple.
Here's a quick tip, if you have access to the Cydia store, install SB Settings. I was listening to streaming audio today, and it stopped working through the 3G connection. It turns out that the internet wasn't working at all through 3G. With SB Settings, I just switched off 3G, and the phone connected with Edge. Presto, the internet works again, and audio streaming work. With 3G Unrestrictor, none of my apps need to know that they are not on Wi-fi and keep streaming audio or doing whatever it is they do. It turns out that Edge is plenty fast for a lot of things: including streaming music. Remember its all data, no matter what Apple or AT&T tells you.
Posted by postfuturist on 2009-08-10 23:15:10
In an earlier post I detailed my experiences installing Kubuntu on the Compaq CQ60 215DX. The only shortcoming was that suspend - resume was broken. A commenter left an important note with the fix, adding pci=nomsi to the grub kernel line in the file /boot/grub/menu.lst. That's it.
Thanks again Cappy, whoever you are!
Posted by postfuturist on 2009-08-09 14:29:48
I bought the iPhone 3G S. It is almost a laptop in your pocket. Of course once you jailbreak it, it is. Instead of just a really nice phone, it becomes a really portable general purpose computer that happens to be a phone.
The first problem that jailbreaking solves is the same problem that push notifications don't solve. The Backgrounder app available for free in the alternative app store Cydia allows you to switch back to the main menu (springboard) without closing the currently running program. So now I can fire up tunes in Pandora, Slacker, Last.fm, or any other music playing app other than Apple's player and then go run some other app like Safari or some game. It's amazing how daft Apple is to not include this basic piece of functionality. Alone it is worth the price of admission for jailbreaking your phone.
Many of the apps available from Cydia are just not possible from the Apple App Store either due to Apple's unwillingness to allow certain classes of apps or limitations in their development system and API's. iBlacklist does what no App Store app can do nor AT&T, which is to block certain callers. Also worth the price of admission.
I wrote some of this blog entry while walking to a cafe and listening to music streamed gratis to my iPhone via Slacker. En route I passed some flowers swarming with bumblebees.

Copyright 2009, 2010 by Stephen A. Goss