Monday, April 23, 2007

JavaScript is powerful, people. Believe me.

There are many people who still believe that JavaScript is somehow an inferior programming language, and that Java or C++ is somehow better. Today I shall attempt to put some of these beliefs to rest.

First a little history. JavaScript started in the Netscape browser as a new feature to combat the competing Internet Explorer (we can see how well that worked out). It was originally called Mocha, but Netscape decided to change the name to JavaScript after a deal with Sun to include Java technology in the browser. Of course, Microsoft had to have their own JavaScript, and called their JScript to avoid potential trademark concerns. As of this blog, the latest JavaScript is 1.7.

JavaScript and Java are, for the most part, only related by name. Their similar syntax is because both are derived from the C programming language (about which I have previously commented). While Java is a statically typed language (each variable has a specific type), JavaScript is dynamically typed (variables' types are determined by context). It is this superficial similarity that leads to our first misconception.

1. Doesn't JavaScript lack support for Object Orientation?


Many programmers who are not practiced in JavaScript will say that JavaScript does not support object oriented programming because it does not support classes. This belief is, of course, wrong. It is true that JavaScript does not use the traditional Class-based paradigm used by C++ and Java, in which objects are instances of classes, and new classes can be built by inheriting from other classes. Instead, it follows the Prototype-based paradigm, in which new objects can be built by cloning an existing object or ex nihilo (“from scratch”).

In JavaScript, a new object can be created in multiple ways. The first is through an object literal, such as:

var myObj = { property: "someValue" };

The second is through a constructor function, like the following:

function MyType(a)
{
    this.property = a;
}

var myObj = new MyType("someValue");


Both create a new object with one property, whose value is the string "someValue". The second is more like the C++ and Java style of object creation and simulate a class.

JavaScript (and all Prototype-based language) also provide a mechanism for inheritance. This is where the prototype comes in to play. Just what is the prototype? It is an object upon which other objects are built. For example:

function BaseType()
{
    this.funcA = function()
    {
        alert("Base::funcA");
    };

    this.funcB = function()
    {
        alert("Base::funcB");
    };
}

function DerivedType()
{
    this.funcB = function()
    {
        alert("Derived::funcB");
    };
}

DerivedType.prototype = new BaseType();

var myDeriv = new DerivedType();
myDeriv.funcA();
myDeriv.funcB();


The above will display the following:

Base::funcA
Derived::funcB


Every DerivedType starts out with all the functions of a BaseType, but the constructor then overrides the property funcB with its own version. This is inheritance.

2. Isn't JavaScript only used in web pages?


This one is pretty easy to refute. JavaScript is used in the core of the Mozilla Firefox browser, and when writing extensions one uses JavaScript. There is even a command line version of the JavaScript engine, so that JavaScript shell scripts can be made.

3. Doesn't JavaScript not always work? Isn't it unstandardized?


The official standard for JavaScript is called ECMAScript. If there is a standard, why does JavaScript work in some browsers and not in others? The question answers itself: not all browsers implement the same JavaScript. They all implement ECMAScript, but this is the barest form of JavaScript. The parts that usually vary are the DOM and the event model.

The DOM (Document Object Model) is a way of expressing XML documents (usually the HTML page) as a collection of objects in parent-child-sibling relationships. The W3C has recommended a standard DOM, defining objects and their functions. Most browsers follow this recommendation in their implementation of ECMAScript, but some (read: MS Internet Explorer) do not. This makes writing cross-browser scripts that use the DOM difficult, and has led many to think that JavaScript is unreliable.

var xyz = document.getElementByID('xyz');

The same code in JScript:

var xyz = document.all['xyz'];

Another issue is the event model. Again, there is a recommended standard from the W3C for how events should work. And again, some browsers (guess who!) have decided not to use the standard.

JavaScript:
function listener(e)
{
    alert(e.srcElement);
}
xyz.addEventListener('onclick', listener, false);


The above in JScript:

function listener()
{
    alert(window.event.srcElement);
}
xyz.attachEvent('onclick', listener);


There are a few significant differences. First, notice that in the W3C standard, the listener function takes the event object as a parameter, but the JScript version has a global event object. Secondly, notice that the implementations use different functions with different numbers of parameters to add an event to an object.

Act III: Epilogue


I hope we've learned something from this rant. JavaScript is not to be taken lightly; it can be used to do anything another programming language can do, because it is what is a Turing-complete language. JavaScript is sometimes difficult to use in web pages because different browsers use different implementations of the ECMAScript standard, but most browsers use compatible language features, but Internet Explorer does not.

Labels: , ,

Thursday, April 19, 2007

There's No Law of Conservation of Sanity?

Σ0 = 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + . . .
Σ0 = (1 − 1) + (1 − 1) + (1 − 1) + (1 − 1) + . . .
Σ0 = 1 − 1 + 1 − 1 + 1 − 1 + 1 − 1 + . . .
Σ0 = 1 + (−1 + 1) + (−1 + 1) + (−1 + 1) + (−1 + 1) + . . .
Σ0 = 1

Has something been created from nothing?

Labels:

Wednesday, April 18, 2007

6° (or -14°C) of Separation

In Linked, Barabási discusses the notion of “six degrees of separation”, according to which any two individuals are connected by no more than 4 other individuals. This is a direct result of our modern society; people are more connected, be it by computers or long distance travel, than ever before.

One such connection is the internet; it allows us to instantly communicate with people nowhere near us. This makes six degrees of separation quite feasible. I, through online communities such as deviantART, have friends in Great Britain, Egypt, and Denmark. I've never been there, but in one “step” I have crossed the Atlantic. Five more steps and I should easily be able to connect with anyone in Europe.

When I was in elementary school, there was a student who had immigrated with his family from India. Through him, I have a link to people in a country on the other side of the globe. Long distance travel like this makes the separation between individuals much smaller. Our acquaintance functions much like deviantART; they both make connections between nodes that otherwise would be multiple steps apart.

Works Cited


Barabási, Albert-László. “Linked”. 2002. London, England: Penguin Books, Ltd.

Labels: , ,

Monday, April 16, 2007

What's Up at the Rescue Mission

Since my last blog about the Rescue Mission, a lot more has happened. We've built a new index page for them and have started work on the next batch of pages that need updating. But in this post I would like to focus on Dreamweaver Templates.

In Dreamweaver, developers can built templates, which are basically web pages that have no content. Then new pages can be built off of these templates and the content is filled in; nothing else on the new page (the code copied from the template) can be changed. This is a great tool for developers who want to let others build new pages that will play well with the current web site. Standard things such as navigation, theme, and scripts can be put directly into the template, so others need only worry about filling in the content.

But this is only the most basic use of templates.

When a template file is modified and saved, Dreamweaver offers to update all pages based on that template. Suddenly, managing a large web site becomes a lot easer; there is no need now for PHP or other server side languages to built pages, which slows down load time. Instead, the page is built from the start.

At the Rescue Mission, Jeremy and I have used templates to make all the pages work and look the same. We can put the CSS and JavaScript in the template, so the people at the Mission do not need to worry about it.

Templates can be built off of other templates, creating what is known as nested templates. This way, templates can be built from more general templates. If the outer template (the original template) is modified, the nested template and all pages based on it are updated. If the inner template is modified, only pages based on it are updated.

We used nested templates to easily build one-, two-, and three-column layouts for the Rescue Mission. The index page uses the three-column layout, while most other pages use the two-column layout. Each layout is based on a basic layout that defines theme and behavior (scripts). The inner templates only require a short bit of new code to make columns. Again, updating is easy; only one file should ever need to be modified.

By using Dreamweaver templates, we hope to allow the Rescue Mission to keep their web site looking professional and uniform after we are gone, and to build new pages without a lot of work. To this end, we also plan to set up a blog, which would of course make the page even easier to update with news and announcements.

Labels: , , ,

Sunday, April 15, 2007

Why do I dislike C++?

Let me count the ways...

1. Overloading Operators


Let's suppose we have the following:

std::vector<int> stack;
vector<int>::const_pointer iter = stack.begin();


This instantiates a vector of integers and an iterator for that vector. So far so good.

To access the element at which iter is currently looking, we type:

int b = *iter;

In other words, it looks as though we dereference iter. So it would follow that we can code:

int * ptr = iter;

WRONG! iter is not actually a pointer to anything, but rather a class that has cleverly overloaded the * operator to return the object at which it is currently looking. So how do we get a pointer to the current integer? As far as I can tell, like this:

int * ptr = &(*iter);

That's right, we use the & and * operators, usually inverses of each other, to get our pointer. Thank you, Standard Template Library.

2. Constants


C originally lacked constants; they were not added until shortly before the creation of C++ and therefore needed to be built around the existing language. Although constants in C++ generally are not a problem, there is one case that bothers me.

const int * a;
int * const b;


These are not equivalent statements. a is now a mutable pointer to a constant integer, while b is a constant pointer to a mutable integer. It gets better.

const int * const c;

This declares c to be a constant pointer to a constant integer. Surely there could have been a better way to do this — it seems very clunky to me to use the same keyword twice in the same statement.

3. C-Strings


This one is really a problem with C, but it was inherited by C++.

Back in the good (bad?) old days of the '60s, the next generation of programming languages was emerging. FORTRAN, COBOL, and BASIC all have a string type, which holds a series of characters and can have functions called on it to determine its length, the position of substrings, and so on.

But not C.

The makers of C decided that a string type would be superfluous. How did they decide to implement the string concept? A simple array of one-letter chars. It would end with a null character (the character whose ASCII value is 0, represented as '\0' in C). In C, arrays are extremely simple. They are really only pointers, and as primitive types they cannot store extra information such as their length.

How will we know how long our strings are, the developers must have asked themselves. We will count them, they answered themselves, or keep track of it in another variable. How will we call functions on strings, they further wondered. We will pass the function a pointer to the string and an integer for the length. How will we return strings? We won't; we'll modify their values as side effects of the functions. Won't that make otherwise simple operations like concatenation or comparison difficult and ugly? Who cares, this is C.

Years later C++ was created, and with it came a string class via the Standard Template Library. However, the remnants of c-strings still linger. String literals are first interpreted as c-strings, then converted to strings if needed. The getline member function of an input stream expects a c-string; there needs to be a special non-member function to read in to a string object.

4. Switch


The switch statement in C++ reeks of the days of assembly; it is essentially a glorified GOTO.

switch (someVar)
{
    case VALUE_1:
        // Do something

    case VALUE_2:
        // Do something else
        break;
}


What is wrong with this picture? Any programmer can tell me that I forgot the break in the first case. If someVar is indeed equal to VALUE_1, the program will do something, then it will continue right on and do something else. It seems odd for C++ to rely on a statement to tell it where the code in a block ends; C++ normally uses curly braces for that. We must examine this more closely.

100 IF someVar = VALUE_1 THEN GOTO 500
200 IF someVar = VALUE_2 THEN GOTO 700

500 REM Do something
700 REM Do something else
800 GOTO 1000

1000 END


The above is our switch program written in BASIC. We can see the behavior much more plainly here. The switch is like a series of IF statements that then GOTO the proper place in the program. The cases are labels. The break is also translated into a GOTO. If the break in C++ or the GOTO in BASIC is forgotten, the program just keeps on going. There are no actual blocks, only a series of labels.

For the record, BASIC does have a switch construct too, called SELECT. It looks and behaves just like its C++ cousin.

Almost half a decade later, we have decided that GOTO is probably not the best idea anymore. Very few, if any, modern languages make use of it (Java keeps it as a reserved word but has never used it).

It gets better though. Because there are no blocks in a switch statement, there is only one scope.

switch (a)
{
    case 1:
        int i = 3;
        break;

    case 2:
        int i = 4;
        break;
}


This code would produce an error, because i is declared twice in the scope of this switch. One solution might be:

switch (a)
{
    case 1:
        {
            int i = 3;
        }
        break;

    case 2:
        {
            int i = 4;
        }
        break;
}


Here we force each i to have its own scope. At this point, though, we have triple indentation. It might have been easier to just use a series of if statements, as they would each have their own scope.

These are some of the gripes that I've had with C++ so far as an undergraduate computer scientist. It was quite good to vent, and now I'll be able to refer people to this blog when I say that I dislike C++. I'll probably wind up returning to this entry later, once I've had time to discover more of C++'s more, er, fascinating idiosyncrasies.

Labels: , ,