Wednesday, November 25, 2009

JavaScript, a Disappointment

Yesterday I needed an improved version of the JavaScript textarea widget. Ah! I'll write my own text editor.

That's not a trivial task, but it's the core of my C++ book (an excellent tutorial, but sadly it dates back to DOS). I had already done the design and the step-by-step, how to build it thinking. That's probably half the battle. I thought that I could have a working, if minimal, text editor in about a day.

Nope. Was into the project for about an hour when it came time to program the Insert key to toggle insert/overstrike modes. Brick wall. There was no way to distinguish Insert from the minus sign. None. And this in Opera, which is the best of the PC browsers.

Redesigned the project to work with the unimproved JavaScript textarea widget.

As I write this, Obama is pardoning the turkey at the White House. I am not pardoning this turkey.

Wednesday, November 11, 2009

Storage under Technological Deflation

Around 1980 I worked for a small time-sharing company. We held a little party to celebrate the day we added one more disk drive, reaching a full gigabyte. (The drives each held 80MB. They were about 18 inches square, 40 inches tall. They filled a room about 15x20 feet.)

Yesterday I flipped through a BH Photo catalog. (Good company, great catalog, good but not great prices.) A terabyte drive is now $100.

What does it mean for software that disk storage is now nearly free? I'm thinking about it.

What does it mean for software managers that 24 inch, 1920x1200 LCD monitors are down to $200? It means your programmers should have them! They will love you fand productivity will rise. (This from personal experience. I upgraded when the price broke through the $500 barrier, replacing my 2x2 array of 19" CRTs with one flatscreen. It now serves two PCs, Windows and Linux, via a KVM switch.)

Back to writing SketchUp Rubies. WebDialog front-ends in JavaScript, SketchUp API in Ruby. Monty spends his days with Kitten, not with me.

Wednesday, September 23, 2009

JavaScript Objects, Opera's Error Console

The News:

Saw Steve Forbes on CNBC yesterday. He's still spouting the supply-side nonsense that Reagan abandoned after a single-year trial. Well, his reporters are still out there reporting, and they do a good job. Wonder what Oracle is up to? Here's Ellison's game plan.

Yet another attempt to mount a frontal assault on IBM. This stupidity seems to be contagious.

JavaScript Objects

Let's create a JavaScript object.


var martin = { name: "Martin Rinehart", current_activity: "blogging" };


That's right. No class; no constructor; just create an object.

Today I've got to figure out how to do a hash in JavaScript. Let's add that:


martin.next_google = "javascript associative array";


That's right, too. Need an attribute? Assign to it. Python works this way, too. Ruby requires more Java-like planning.

Sometimes a constructor is a good thing. A regular function, first letter capitalized by convention, serves as a constructor:


function Person( name ) { this.name = name; }


Let's use that constructor to create an array of Persons.


var names = [ 'Tom', 'Dick', 'Harry' ];
var people = [];

for (name in names) { people.push( new Person(name) ); }


If you are used to Java, that probably seems more organized. You UML fans are probably breathing a sigh of relief. Forget it.


martin.kayak = 'flatwater';
people['Harry'].kayak = 'whitewater';
people['Dick'].hobby = 'gourmet chef';


Harry and I share an additional characteristic. Note that Harry is a Person; I am not. Dick, and no one else, has a hobby. (Did you notice that I did that google? JavaScript arrays are associative.) JavaScript objects are also associative arrays:


people['Tom']."rock climbs" = "Half Moon";


Actually, all the characteristic names here are strings. If you have names (no spaces or funny characters), you don't need to type the quotes. This is a convenience. Is it a good practice?

Now, is this very free-form object model conducive to good code? I don't know. JavaScript is, traditionally, bug-ridden. (Not yours, of course? I doubt it. Open the Opera browser. Click Tools/Advanced/Error Console. Now visit one of your own sites. IBM's JavaScript is a mess. Why should yours be different?)

But study that Error Console dump. Are any of the errors caused by attempts to access non-existing characteristics? I've never seen that. Your own JavaScript will get cleaned up when your developers find out that you'll be running your own sites in Opera with the Error Console turned on.

Tuesday, September 22, 2009

Mid-Twentieth Century Languages

In the News:

Dell to buy Perot. Having trouble competing with HP? Here's an idea: go head-to-head with IBM.

Mid-Twentieth Century Languages

Ruby's powerful and full of Tim Toady. Python's powerful and pythonic. In one area, however, both are bad reminders of the 1960s.

I refer to the fact that both are strictly interpreted, according to the lamest definition of the term. They begin processing at the top of the file. Declarative code? Processed. Imperative statements? Processed.

The intelligent way, of course, is to read the file handling all the declarative code first. Functions, for example, are defined and ready for use when the imperative code is processed. Functions may be declared where they make sense. The structure of the source code is not dictated by the processor; it's decided by the programmer.

Ruby and Python? Nope. Don't place your imperative code at the top of the file; library functions at the bottom. You cannot call a function from statements above the function's definition; you cannot instantiate an object ... This is stupid.

JavaScript eats your source code's declarations first, then goes on to process your imperative code. JavaScript is not the world's most advanced language. That Ruby and Python are less advanced than JavaScript should be an embarassment to both.

If you remember Pascal from the early days of microcomputers you remember being forced to write your main program at the bottom of your file. This was, and is, a tragedy if you valued readability. This is how you must structure your Ruby and Python.

JavaScript gets this right. Java lets you put "main()" where you choose. This should be completely standard in this century.

Friday, September 11, 2009

Error Handling

Today is 9/11/09. John and I played an hour of tennis once a week from 7:30 to 8:30 in the morning. We played eight years ago on this day, quite happily ignorant of the events unfolding in Manhattan. By 9:00 we were a half-hour apart, at our respective offices, watching TV. We haven't played since. And so it goes.

Error Handling Overview

Some processes can generate errors despite the most skillful coding. Disk I/O is one example. (User enters name of a file that doesn't exist. Data cannot be written because the disk is full.) I first met try/catch logic in the mid '90s in Java as a way to handle these sorts of errors. This is now a feature of most mainstream languages.

The basic idea is to surround a block of code (such as disk I/O code) with a "try this" instruction. Following the block to try there is an "if an error occurred" block. Some languages, Java included have an optional "whether or not there was an error do this" block. Code in the "try this" block (including, importantly, subroutines called in that block) can "throw" an error, often an Error or Exception object for use in the "if an error occurred" block.

Error Handling in Java

This is the basic Java syntax:


try {
}
catch (Type1ExceptionOrError var1) {
}
[catch (Type2ExceptionOrError var2) {
}]...
[finally {
}]



Java has both XxxException and XxxError classes. The builtin classes can be extended by the programmers to create more Exceptions and Errors. Multiple catch clauses allow code to be written to handle particular Exception or Error types. Importantly, catch (Exception e ) {} will catch all exceptions, though it loses the ability to use any added information in extending classes. Errors can be handled similarly, but are generally not handled. A Java Error would be something like a hardware failure that the program probably cannot deal with successfully.

If I were redesigning the language I would eliminate the finally block entirely. The catch blocks should simply branch to the code that follows the last catch block.

I would then use only a single catch block. If needed, the programmer can put a switch inside that block which calls code appropriate to the exception type.

That said, let's look at the ways some other languages address the issue.

Error Handling in JavaScript

JavaScript follows Java's try catch finally lead, with two important differences. First, there is only a single catch block. Second, the thing caught may be anything: object, string, number, ...

In JavaScript: The Good Parts, Doug Crockford eliminates the finally block, leaving exactly what I recommend for Java.

Error Handling in Python

Very like Java, but the catch block is known as an except block.

Error Handling in Ruby

Similar to Java, but Ruby stubbornly goes its own way. You don't try, you begin. You don't catch, you rescue. You don't finally, you ensure.

Ruby also features a retry keyword that repeats execution of the try block.

"Martin, don't forget that stupid Tim Toady! You can use catch blocks, too."

"Thanks, Monty. I'll put that in."

Monty, my pet python, knows just enough Ruby to criticize it.

Error Handling in C++

Like Java you have try and catch blocks. Unlike Java there is no finally block. Also unlike Java, there is no restriction on the type of thing caught. Strings and integers, for examples, can be caught. There is also a generic "catch anything" variant, though there is no way to hand the thing caught to the code in this catch block, a disadvantage of strongly-typed languages.

Thursday, September 10, 2009

Google Books and the Three-Fold Path

News:

This NY Times article contains an excellent set of links to the pro and con positions re the settlement of authors and publishers v. Google. (The settlement will a: liberate books, or b: obliterate books say those who support or oppose it. I'm betting on c: boost books' Google search rankings.)

The Three-Fold Path to HTML Documents.

I have just released my first serious Ruby plugin for Google SketchUp. It is useful for creating multi-scene animations of a 3D model. Any non-trivial SketchUp Ruby UI is shown as a page in a browser, an HTML document. Here are the alternatives for creating an HTML document.

HTML

First, there is HTML, a simple set of markup commands that are the cyberspace equivalent of typesetting instructions. Let's look at a sample:


<table align=center bgcolor=#fofoff border=1>
<tr>
<th>Heading, column one</th>
<th>Heading, columne two</th>
</tr>
...
</table>



The basics are a set of tags that come in <tag> ... </tag> pairs. Here you see table, table row, and table heading tags. Omitted are the table datum ( <td> ... </td>) tags that will be part of the additional rows that provide the table's contents. These tags can have embedded attributes. Here the table is centered, its background set to light blue and border set to one pixel wide. Other tags imply attributes. Table heading cells default to centered and boldface.

If you decide to learn basic HTML, to improve your blog posts, for just one example, my easyHTMLtutorial.com will get you up and running quickly. HTML is simple. It's also the underpinning of the second path to HTML documents.

JavaScript: document.write()

There are times when you leave the simplicity of HTML and use JavaScript programming to create your HTML customized to your viewer's data. My Ruby is one example: it creates a table of checkboxes based on the user's model. There is one row for each "layer" (grouping of model components) and one column for each "scene" in the animation. It can only be created after querying the user's model for, for example, a list of the names of each layer. JavaScript for my Ruby's table would look like this:


// query model for data
// construct a "model" object from the results
document.write( '<table align=center bgcolor=#fofoff border=1>' );
document.write( '<tr>' );
for ( var i = 0; i < model.scenes.length; i++ ) {
document.write( '<th>' + model.scenes[i].name + '</th>' );
}
...



This uses JavaScript's document.write() method to write HTML into the page. It is not as simple as plain HTML but it lets your UI be tailored to the users' specifics. In this case, it is writing as many column headings as the user has scenes in his model, using names read from the model. At a cost of one level of indirection, this creates a web page tailored to the user's data. Unfortunately, it is not always an option.

DOM scripting

In my Ruby, for reasons I'll skip here, document.write() was not an option. While technically, simple document.write() calls are a form of DOM scripting (Document Object Model), there is another, less simple, low level at which you can create a web page.

Each web page is a set of objects attached to the "document" object, or attached to other objects which are, in turn attached to the document. In our table example, the table is attached to the document. The table row is attached to the table and the table headers are attached to the table row. Skipping lots of details, the basic idea is this:


var table = document.createElement( 'table' );
// set table attributes here
document.appendChild( table );
var row = table.insertRow();
head = document.createElement( 'th' );
head.innerHTML = 'The Column Heading Text';
row.appendChild( head );
...



Working at this very low level, your JavaScript is in total command. The cost: the simplicity of HTML is gone. If you have to drop to this bottom level, the amount and cost of the JavaScript rises dramatically. Switching from document.write() to bottom level DOM scripting was one of the reasons my two-week Ruby project took six weeks to complete.

"We don't go here unless we need to. Right, Monty?" Monty, my pet python, doesn't hear me. He's busy playing with the kitten.

Friday, August 28, 2009

I Love JavaScript (Sometimes)

News:

From Business Week Big Blue's Global Labs

Building a global chain of "collaboratories." Good luck, IBM. May I loan you my copy of Fumbling the Future?

JavaScript:

Something like this:


btn.onclick = click_func;
document.body.appendChild( btn )



That, obviously, will never work. This will:


document.body.appendChild( btn )
btn.onclick = click_func;



Did I say "obviously"? That, obviously, was sarcasm.

When coding you exhaust all the rational possibilities first. With code still failing, you move on to the semi-rational possibilities.

After exhausting the rational possibilities, I briefly considered DLing the source for Mozilla, to just take a look for myself at the troubled area. Briefly. Just long enough to learn that there are about 2.5 million lines of code there.

It was Saturday, the 15th, when my Ruby writing ground to a halt with The Bug from Hell. I believe I can proceed again, albeit with the simplicity of document.write() in the rear view mirror.

Started yesterday building tables the slow way. Create a table element and attach it to the body of the document. Create a row element and attach it to the table element. Create cell elements and attach them to the row element. Create contents and insert or attach (depending on type) content to the cells. On to the next row.

My UI includes a table with a table. It's very complex so that the user will think it simple. It took a half day to build it with document.write() . I'm thinking five times the code, and five times the time, doing it the slow way. That, of course, doesn't allow for additional "gotcha"s.

Anybody going to bet against more "gotcha"s?

Friday, August 21, 2009

The Bug from Hell

Executive Summary

One full week lost. Zero output units. It was the bug from hell. If you have any faith in your software schedules, read on.

I am writing a SketchUp Ruby. Stuff that worked Friday stopped working Saturday morning. I got to the bottom of the problem Thursday morning. In a lifetime of coding I've never been stopped for five days by one bug. It was subtle.

The trickiest bit about Rubies is that your UI runs in a browser. That means that the Ruby code that manipulates the model has to communicate with the JavaScript in the browser. (Note: this is another case where you have two languages to use and zero choices about which you use.)

JavaScript on the Front Line:

The general idea is that since the user is in charge, JavaScript notes what buttons are clicked or whatever. JS can then call a Ruby function that will dig up whatever data is needed or manipulate the model in the manner requested. If it needs to send data, Ruby prepares a bit of JavaScript, like this:


script = 'name_of_javascript_function( whatever, facts, are, required )'


Ruby hands this script to a webdialog object (prepared by the web dialog and passed to the Ruby callback). The webdialog executes the script, presumably calling JS functions that make use of the data. The whole communication thing is at best inelegant. This is NOT pythonic.

"No, no, Monty! I didn't mean you. You are totally pythonic."

Monty, my pet python, has been crabby since I turned him into a vegetarian. Sorry for the interruption.

Ruby in the Trenches

Saturday morning I moved the JavaScript out of the HTML file and into a separate JavaScript file so I could validate the HTML. I've got validated HTML, but the code no longer worked. It seems that JavaScript correctly calls Ruby. Ruby correctly gathers the data wanted and correctly forms the script needed. But Ruby is definitely not succeeding in getting back to JavaScript. The final step, executing the JavaScript script, is not happening. At one point the JavaScript function that I wanted called by the script was reduced to launching an alert box that said, "Hooray! Finally!". It never said "Hooray! Finally!".

Note that the tool set is completely primitive. There is no NetBeans, no Eclipse, no debugger. On Windows, we can choose any browser we like, provided we choose MSIE. At one point it reported that I had an error in my JavaScript at line 51 million and something. Ugh. The tiniest little bit of error checking and it's too buggy to be helpful.

For debugging, you stick print statements into the Ruby and pop up alert boxes in JavaScript. Before Saturday ended I knew that my JS was correctly calling Ruby, that Ruby was preparing a valid script passing correct data and was calling the correct method of the webdialog (the webdialog that JS had passed to Ruby). And that was the end of the road.

Swapping Code

By Tuesday I knew that the same code that worked also failed. I started with a successful, small test package and the unsuccessful, larger actual package. I began removing parts of the larger package deleting bits one a a time until I could find the guilty party. I ended with a still-failing package no larger than the test package.

Wednesday found me copying Ruby source functions from the test to the failing routine. Still fails. Copy from the failing to the test? Still succeeds. So repeat this with the JavaScript functions. Same result.

Early Thursday I am convinced that it is a timing issue. How else could two copies of the exact same code fail and succeed?

"Martin, what are you talking about? It's single-user, single-threaded code! Timing issue?"

"OK, Monty. You explain it."

That got me back to Saturday morning. I had taken the JavaScript out of the HTML, where it had been at the end of the body of the page, and put it into a JavaScript file. I linked to the JavaScript file from the <head> section of the HTML, a common practice that I will never again practice.

Moving the "load the JavaScript file" command from the <head> of the HTML to the end of the <body> of the HTML turned the failing code to successful code. Bug in the SketchUp linkage: if your HTML is not completely processed, the webdialog that it passes to Ruby cannot execute the JavaScript script.

Moral?

(In Ruby convention, getters for booleans are suffixed with a "?". This section should return a boolean.) Moral? Maybe.

I let my ego get in the way. Hot shot programmers fix their own bugs, right? Instead of punching ahead on my own, I should have recruited an associate. Wise old programmers get help when they need it. I'll try to remember that.

Monday, August 17, 2009

Scroll Down! Blogger's to Blame.

In the previous (following this one if you are reading chronologically) there is a giant bunch of empty space above the table. Scroll down, the table's there.

I don't know why. The HTML doesn't have any problem if you view it in a browser. This is a Blogger issue. And so it goes.

Broadband for Everyone

Broadband in America:

From Business Week, stimulus package broadband expansion funds are not going to cities.

Broadband Stimulus and the Underserved

I was curious about the situation around the world, so I asked Google. He showed me Internet World Stats. They showed me a table of broadband penetration, but, unfortunately, it was ranked by total broadband subscribers. U.S. has the most. China is second. That is pointless.

How do we compare, penetration per capita. U.S.: 21.9%. China: 3.7%.

Open Office:

Internet World Stats does not, unfortunately, provide a spreadsheet version of its data for download. I needed their data sorted by penetration. Briefly considered retyping into a spreadsheet, but decided to try for an easy alternative.

I swept my mouse over Internet World Stats whole table. Pressed ^C. Went to my text editor and pressed ^V. Scrambled data eggs.

I opened an OO spreadsheet. Pressed ^V in cell A1. Absolutely amazing! A very nice spreadsheet appeared. Even the report and column headers were sensibly laid out.

I selected column D and asked for a descending sort. Ooops. That sorted column D. Selected all the data and asked for a sort. It asked, "What column(s) and up or down, please?" Click, click, done. Just what I wanted to know. U.S. is seventh in the world behind some countries you might have guessed (Sweden) and some you might not (France).

I'd show you the whole table, but that might be hard. I'll try, anyway.

Whole Table:

Back to OO. Save as HTML. Open HTML in text editor, copy the parts from "<TABLE>" through "</TABLE>" tags. (Sorry to see that OO still uses capital letters.)

Pasted the HTML into the Blogger "Edit HTML" tab. Here's the result:













































































































































































































TOP COUNTRIES WITH THE HIGHEST NUMBER OF WORLD INTERNET BROADBAND SUBSCRIBERS IN 2007
# Country or Region Broadband Subscribers Broadband Penetration (%) Population ( 2007 Est. ) Source and Date of Usage Data
12 Netherlands 5388000 32.80% 16447682 ECTA - Mar./07
5 Korea, South 14042728 27.40% 51300989 OECD - Dec./06
20 Sweden 2478003 27.20% 9107795 ECTA - March/07
9 Canada 7675533 23.70% 32440970 OECD - Dec/06
6 United Kingdom 13957111 23.10% 60363602 ECTA - Mar./07
7 France 13677000 22.30% 61350009 Teleco - Mar/07
1 United States 66213257 21.90% 301967681 OECD - June/07
4 Germany 17472000 21.20% 82509367 OECD - June/07
3 Japan 27152349 21.10% 128646345 OEDC - June/07
13 Taiwan 4505800 19.60% 23001442 ITU - Sept/07
14 Australia 3939288 18.80% 20984595 OECD - Sept/06
10 Spain 7505456 16.70% 45003663 CMT - July/07
8 Italy 9427300 15.80% 59546696 ECTA - Mar/07
18 Poland 2640000 6.90% 38109499 OECD - Dec./06
16 Turkey 3632700 4.80% 75863600 ECTA - Mar/07
2 China 48500000 3.70% 1317431495 MII - Sept./06
15 Mexico 3728150 3.50% 106457446 OECD - Sept/06
11 Brazil 6417000 3.40% 186771161 Teleco - June/07
17 Russia 2900000 2.00% 143406042 ITU - Sept./07
19 India 2520000 0.20% 1129667528 TRAI - June/07






TOP 20 Countries 268150077 6.90% 3890377607 IWS - Nov.14/07
Rest of the World 36321302 1.40% 2684288810 IWS - Nov.14/07
Total World Subscribers 304471379 4.60% 6574666417 IWS - Nov.14/07

Saturday, August 15, 2009

JSON in Practice

Writing JSON:

I wrote a specific-purpose JSON writer, in Ruby, to encode the data I needed. It wasn't too tough:


# JSON to send to webdialog
def makeJson( layer_names, scene_names, vis )
ret = '{ '
ret += 'layers:' + makeJsonArr( layer_names )
ret += ', scenes:' + makeJsonArr( scene_names )
ret += ', vis:\"' + vis + '\"'
ret += ' }'
return ret
end

# convert array of names to JSON array
def makeJsonArr( names )
ret = '[ '
start = true
names.each do |n|
unless start
ret += ', '
else
start = false
end
ret += '\"' + n + '\"'
end
ret += ' ]'
return ret
end


Reading JSON:

Since JSON is syntactically correct JavaScript, this is the reader that decodes it in JavaScript:


function rubySays( data ) {
eval( 'obj = ' + data );


The rubySays() method then goes on to make use of the object it creates in its first line. I like code that weighs in at just tens of bytes.

Summary:

Writing JSON is easy. Reading JSON in JavaScript is effortless. Highly recommended!

Friday, August 14, 2009

Multiple Desktops

Today's Views:

Not news, views. AAPL Undervalued?

I know a couple things about stock prices. One is that rising EPS is a good thing. The other is that today's price of X is the price at which exactly half the people on Wall Street think X is overvalued while the other half believes X is undervalued. This is good to remember when you read an analyst who is in the undervalued camp. Half the people on Wall Street, and there are some very smart people on Wall Street, disagree.

Multiple Desktops:

I have a nice big desk and I keep it organized. This is good. Having several nice big desks would be better. Each project I am working on would have its own desk. Books, papers, 3D models, whatever would be on its own desk. Changing from project A to project B wouldn't require putting A's stuff away and opening B's stuff. I'd just move from desk A to desk B.

This is exactly what I have in Linux. I press Ctrl+F3 for this blog. Ctrl+F4 gets to my personal website. Ctrl+F11 gets to my Decaf language project. Almost all my desktops have a browser open, but none have the same tabs open. Most have a text editor, but each editor has different files open. I use 12 desktops (max: 20, but even 12 may be too many). Some have spreadsheets; some have pictures.

Multiple Desktops in Windows:

Windows sucks you back in like a black hole. Google SketchUp, for instance, runs in Windows and OS X, but not Linux. You want SketchUp Rubies? Any language you want, provided you want Ruby and any OS you want, provided you don't want Linux. Windows does not have multiple desktops.

Hold on. Windows has multiple users. Each user has a single desktop. Many users times one desktop each looks a lot like multiple desktops!

In Linux, Ctrl+Fx switches to desktop x. There's also a little display of an array of desktops where one mouse click switches. In Windows that's Start, Logoff, Switch User and then click on user. But if you hold down that special key with the windows logo and press L, you've got Start, Logoff, Switch User all at once. It's only a single click more difficult than Linux.

So go ahead and create a "User" for each of your projects. You will be very happily surprised at how nice it is to return to a browser with a handful of tabs open related to the project. And at how convenient it is to not have to put one project away to work on another.

You do have 2GB of RAM, don't you?

Thursday, August 13, 2009

Today's News:

Let's get to the really critical issue of the day: Will Windows 7 or Snow Leopard have better wallpaper? They're really on top of things at Fortune.


Snow Leopard vs. Windows 7: The War of the Wallpapers

The article's link to MSFT's wallpapers got you to its financial results, not its wallpaper. Use this one, instead.

I recommend that you get a camera and make some of your own. Here are a couple of mine: Catskills in Winter, Fall Scene from Kayak. (Big, fat files. Sorry.) The secret to good amateur photos? Take lots and lots. Then throw most of them, almost all of them, out.

Linux Desktops

Linux has two graphical front ends, GNOME and KDE. Free software champion Richard Stallman created a Unix workalike, naming it GNU (GNU is Not Unix). GNOME, (originally GNU Object Model Environment), and KDE (originally Kool Desktop Environment) are both excellent desktops. Both disavow their original acronyms.

I started with, and still use, KDE for the simple reason that it came preinstalled, as Windows typically comes. The computer was so cheap that I bought it just to satisfy my curiousity about Linux. Was it really as reliable as people said? Would the learning curve be steep?

Yes, it works for months at a time and no, there was almost no learning curve. I turned it on and started using it. A big button labelled "Launch" looked like it would be similar to MSFT's "Start" and it was. I was soon in familiar software: Firefox and Open Office. Then I found the Konqueror browser/explorer replacement. Firefox is maybe five years behind and Windows Explorer is utterly primitive by comparison.

I have learned to open a command window and use a handful of the original Unix commands, but this is no more necessary than using the DOS window in Windows.

What I have learned to love most, and even sort of simulate when I have to go back to Windows, is the multiple desktop feature. More on that, soon.

Open Office

Are you still paying Microsoft for its Office software? Why? It will not be long before you are asked this question by one of your directors whose own organization has switched successfully. The only acceptable answer is, "We're in transition right now. We'll be fully converted before the current licenses expire."

Wednesday, August 12, 2009

JSON: JavaScript Object Notation

Todays news:

Business Week tells us Why Apple Is More Valuable Than Google

Executive summary: Google makes money on search. Loses money elsewhere. Apple makes money on everything.

JSON: JavaScript Object Notation:

I'm working on Rubies, plug-ins for Google SketchUp written in Ruby. More exactly, since the UI takes place in a browser, written in JavaScript and Ruby. Google has provided a mechanism for Ruby to pass a string to JavaScript and for JavaScript to pass a string to Ruby. I need to share lists of strings and an array of booleans for my Ruby. Enter JSON.

Like XML, JSON stores stuff in human-readable strings. Specifically, it stores objects, arrays, strings, numbers, and constants 'true', 'false' and 'null'. Strings and numbers are very much like strings and numbers in C (and from C, C++, Java and many others).

Arrays are a comma-separated list of values enclosed in square brackets. Array values may be anything that JSON supports: objects, arrays, ... (list above). Arrays may be all of a single type, or any mix of types. Arrays are one dimensional, but as arrays may be members of arrays, this is not a restriction.

Objects are zero or more comma-separated name:value pairs, enclosed in curly braces.

Add whitespace between values, if you like.

And that's it! Very light but no less capable than XML. If you want to write a JSON reader/writer, the exact details (such as the short list of escaped characters) are at www.json.org. A JSON reader/writer is already written for all the languages I know.

Doug Crockford invented JSON, sort of. JSON copies the notation Brendan Eich invented for JavaScript. Crockford noticed that this notation made a simple but full-powered version of XML. Here's an example:


pet={type:python, diet:vegetarian, TimToady:opposed}
pets = [ python, kitten ]


Those are valid JavaScript statements. To the right of the "=" signs you see valid JSON. I love things like this. We backpackers say, "When in doubt, leave it out."

JSON can get just about anything talking to anything else. Highly recommended.

Tuesday, August 11, 2009

Regular Expressions and Perl

Today's News:


30 songs: $30? $4,000? $675,000?

Jury awards RIAA $675,000 from a grad student for DLing and sharing 30 songs. RIAA demanded $4k before trial. Grad student. Now he'll have to scrape up enough to pay a bankruptcy lawyer. RIAA won't get money, but it's got a hell of a legal precedent.

For the record, it took 42 seconds for me to find the file-sharing service my kids use.

Perl


First, Perl is a very kludgy language. The Perl programmer does a lot of work for the benefit of the interpreter. That is backwards. Scalar values' names must start with "$". Array names start with "@". If you have an array, @arr and want its first element you refer to $arr[0].

I assigned a task to myself: learn the three "P"s of the LAMP stack. That's Linux, the Apache server, the MySQL database and one of Perl, PHP or Python. I got far enough in Perl that I did not use it for CGI code. Too kludgy.

Consider this. Arguments are passed in the global variable @_. Suppose your second argument, $_[1], is a reference to a list. The reference is a scalar. The list is not. So you say:$ref = $_[1]; my @list = @$ref;. You now have a list variable, @list.

If that's not bad enough, consider this simpler substitute: my @list = @$_[1];. It looks identical, but it doesn't work. Ugh. I quit.

Regular Expressions

Perl did one thing well: regular expressions. It puts regular expression constants into the core syntax as most languages have string constants. You have "string constant" or /regular expression constant/.

A Perl statement has this format:

[optional statement part] [# optional comment part]

A regular expression to recognize this is /[~#]*#.*/. In English, that's any single character other than "#", repeated zero or more times, followed by "#" followed by zero or more characters of any kind. Add parentheses: /([~#]*)(#.*)/ and you can refer to the parts in your code.

For many text processing chores, regular expressions are so valuable that you forgive their unreadability. The programmer can partially solve this problem with extensive comments. Since Perl, most languages, including Python, feature regex constants delimited by forward slashes. Oddly, Ruby, designed to be a better Perl, does not. It features a regular expression class (JavaScript does this, also) which is somewhat less convenient.

Unfortunately, that sample regular expression won't handle itself as input. It would have /([~ as the statement part and #]*)(#.*)/ as the comment part.

The correct statement definition is:

Zero or more characters, including the "#" character if it is part of a string literal or a regex literal, optionally followed by a "#" character and zero or more comment characters.

There's a neat Perl program on my board that reads Perl source and emits html output. As the comments are output unprocessed, you can use HTML in the comments: lists, tables, images, ...

However, the processing that splits the Perl source into statement and comment does not use Perl's regex. It reads like a C program: got a quote character? Read forward until the matching close quote. Got a forward slash? Set the "in regex" flag. In regex, got a "["? Set the in character class flag. Got a "\"? The next char is escaped. And so it goes.

Challenge:

If you love your Perl and your Tim Toady, meet this challenge: write my "pl2html" program using Perl's regex. If you can get that done, I'll substantially revise this post.

Monday, August 10, 2009

The Big Gulp Method

Movie Review:

Julie and Julia

"Most strikingly, this is a Hollywood movie about women that is not about the desperate pursuit of men."

This blogger is NOT a moviegoer. For a movie about Julia Child, I make an exception. Mastering the Art of French Cooking was one of my bibles. Child's shows on PBS were my inspiration. Over the years my cooking has moved south: olive oil has replaced butter, seafood has replaced beef. Still, it all started with Julia.

The Big Gulp Method:

One of the Java-beginner articles on my website suggested that reading a file using Java's streamIO, as was universally suggested in every book I ever saw (my own excluded), was slow, foolish, and too much work for programmer and computer alike.

This was all that you needed:


RandomAccessFile raf = new RandomAccessFile
( "C:/mrwebsite/articles/raf.html", "r" );
bytes = new byte[ (int) raf.length() ];
raf.read( bytes );
raf.close();


In Python, that simplifies to:


file = open( pathname )
arr = file.read()
file.close()


In Python you can also use file.readlines() to populate an array with a text file, one line per array element. This feature is also available in Ruby with near-identical syntax and identical simplicity.

Of course, all of the above is simpler than file I/O in a finished application. Whatever the language, you have to try the file input (does the file exist?), catch errors and provide options for the user to recover from the errors.

Still, the big-gulp method of reading the file into a byte array (or line array, for text) is fast and easy.

Typical Tutorial:

So why do we still see this?


a = open("sample.txt", "r")
line = a.readline()
while line:
    print line
    line = a.readline()
a.close()


That bit happens to be from about.com, but it's typical of what is given to beginners. Beginners do as they are shown and we are doing file I/O in a way that made sense when RAM size was measured in kilobytes, not gigabytes. And so it goes.

Friday, August 7, 2009

JavaScript, Again

Opinion in Fortune:

"... most dismissive report ever produced by a Wall Street analyst" Fortune's Apple-watcher summary of an analysis of Microsoft's plan to launch stores to compete with Apple stores.

JavaScript, Encore:

The function concept and the basic syntax goes back to Fortran, c. 1960. (Born in 1956, Fortran, now structured and object-oriented, is still alive and well where scientists need to do serious number crunching.) In Fortran-descendant C you would write:


function add (num1, num2) {
    return num1 + num2;
}

(Actually, it's been a long time since someone wrote an "add" function, but you get the idea.)

That code will run, with only minor changes, through a wide range of compilers and interpreters, including Ruby and JavaScript. Unlike any of the others, here's JavaScript's functional programming alternative:


add = function( num1, num2 ) {
    return num1 + num2;
}


With the code in variable "add" you can use "add" like any other variable. For example, you can pass it to another method:


foo = function( bar ) {
    return bar(2, 2);

foo( add );
}

"foo" is a function with a parameter named "bar". "bar" is a method that foo will call with the arguments "2" and "2". This is certainly the hard way to get to four, but it has lots of powerful uses. Passing a comparison method to a sort routine, for instance.

This also means that in JavaScript, as in C, you can have an array of functions as easily as an array of strings (and without C's pointer mess). If you've ever needed an array of methods where you can't have one (Java comes to mind) you know how important this is.

Perhaps the best thing about this syntax is its pythonicness. Python itself has this capability but in a messy way with lambda functions. I do hope that the designers of future languages will learn from this innovation. (I doubt it, though. For functional programming you would study Lisp, as Python's designer Guido van Rossum did, and come up with lambda functions.)

Thursday, August 6, 2009

JavaScript

First, All the News that Fits

NY Times, yesterday: Google’s Android Jumps to the Living Room

Earlier this summer: Microsoft Wants Gadgets to Run Windows

JavaScript

You have people writing JavaScript right now. You did not choose this language. You did not invent the Internet. (Al Gore did, remember?) Brendan Eich, then at Netscape, invented this small scripting language for the then-dominant Netscape browser. If you want to run code within your visitor's browser (something as simple as rotating product pictures) you can do this in any language you choose, provided you choose JavaScript.

Yesterday I was writing JavaScript. SketchUp Rubies, written in Ruby, run their user interface in browser windows. Half or more of a Ruby may be JavaScript, not Ruby.

Actually, I don't write JavaScript. I write the subset that Doug Crockford (Yahoo's JavaScript guru) identifies in his book JavaScript: the Good Parts. JavaScript has other parts, but you can ignore them without losing any functionality. Stick to the good parts. Here's one:

python = {species:'python sebae', diet:'vegetarian'};

python.name = 'Monty';



I just created an object named "python". It had two characteristics (data members, if you prefer), "species" and "diet". (No, python sebae is not a vegetarian species. This is my pet python. I don't want him to eat the kitten.) After creating the object, I gave it another attribute, "name". No, there is no class from which this object was instantiated. As yet, python has no methods.

More exactly, python is an Object. Object is the superclass of all objects. As a practical matter, this is important if you are creating a JavaScript interpreter. You can ignore it if you are writing JavaScript.

This simple syntax (I'd call it pythonic!) is the basis for JSON, JavaScript Object Notation. JSON, invented by Doug Crockford, is a simpler alternative to XML for storing and retrieving objects. (For security reasons JavaScript cannot do disk I/O except for cookies. JavaScript plus X is needed for generalized disk I/O. For SketchUp Rubies, X is Ruby and the SketchUp API.)

Where JavaScript gets most pythonic is in its functional programming, which is a thing of beauty. I'll see what I can come up with for that topic tomorrow.

Wednesday, August 5, 2009

Not Well-Known for Marketing Prowess

In the News:

Business Week on Google Marketing Apps

Google apps (I've tried word processing and spreadsheet) are good and getting better. Now GOOG wants corporate America to buy premium versions at $50/seat/year. Enter a big billboard campaign backing a 400-person sales army.

Analysis:

8 persons per state. Let's blanket New York. We'll have 4 persons for the NYC metro area, one each in Albany, Binghamton, Buffalo, and Schenectady. We'll spread the metro folks one each in Westchester, Manhattan, the other boroughs and Long Island.

OK, that's not fair. New York will have twice the average, because it's a populous state. So in Manhattan we'll have one person covering finance, another covering advertising.

Stop! Too much sarcasm, Martin.

Reflection:

I've done marketing in Manhattan for a small time-sharing company. We had eight sales people backed by me and a half-dozen engineers.

Oracle, before the Sun acquisition, had just under 20,000 people in sales and marketing. That's an order of magnitude estimate of what you need to market to the world.

In the quarter ended June 30, 2009, MSFT spent 24% of revenue on sales and marketing. In the same quarter GOOG spent 9%. Clearly these are different business models. Let's ask Wall Street what it thinks of these two companies.

GOOG's revenue, latest quarter, was about one third of MSFT's revenue. GOOG's market cap was about two thirds of MSFT's market cap. Wall Street's opinion is that GOOG will grow its earnings a lot faster than MSFT will.

Summary:

So the question is this: should Google add a serious marketing effort to sell apps? If I were Google I would say no. I'd pick just one small target (e.g., drug companies) and look to convert that segment.

There's no real hurry about this. MS Office still dominates a market when the competition, Open Office, is free and superior in many ways.

Every fact in this post was extracted via Google searches. The spreadsheets (all .XLS) that I downloaded along the way were viewed and crunched with OO.

Tuesday, August 4, 2009

Python on Python

Yesterday my python slithered off, mad because I was writing Ruby. I feared he'd swallow the kitten. Since Python lets you create attributes on the fly, I solved the problem:


python.diet = 'vegetarian'


Actually, Python has nothing to do with snakes. The name comes from the British comedy troupe, Monty Python. My python is named Monty. Ruby gets its name from lists, such as wedding anniversaries, where Ruby follows Pearl.

When Python and Ruby engineers debate the merits of their respective languages, the discussion is generally learned and respectful. Monty, on the other hand, can really get going.

"Hey, Monty! Want to talk about Tim Toady?" (He never passes this one!)

"There you are. Tell me what you think of Tim."

"Martin, Tim's a fraud. There's maybe sixteen different ways to loop through an array in Ruby. You got some hotshot coder who never does it the same way twice. OK, boss. Who's going to maintain that crap? Some junior coder who just learned Ruby? I don't think so. You're stuck with hotshot. Hope you like paying his six-figure salary."

"Let's show a little real code." Monty dictates a little Ruby and Python.
Python



ids=[...] # array, listing division's employee ids

for id in ids
    # code processing
    # each id

Ruby


ids=[...] # array, listing division's employee ids

ids.each { |id|
    # code processing
    # each id
}


"You could write that loop other ways in Python, but no one would. That's the one, obvious way to do it. Ruby dudes will write every loop differently to show off their Tim Toadiness. And no, I did not forget curly braces in Python. You indent and you get code that looks like, and is, blocked."

"I could go on, Martin, but I just got this sudden urge for some broccoli. Broccoli? I never ate broccoli. What's going on?"

Monty slithers off. Actually, in Ruby looping by the "each" method is the preferred way, in most instances. The simplicity of the Python illustrates the quality that Pythonistas call "pythonicness."

Monday, August 3, 2009

Ruby, Python and Tim Toady

In the News:

Why Bing Is Gaining on Google

A triumph of creative headline writing. Bing soars from 7.2% to 8.2%. Google: 78%. Yo, Steve. When your competitor's name becomes a verb, they've solved the problem. If you don't want to take my word for it, google it.

Python v. Ruby:

Executive summary: two excellent modern, multi-paradigm languages with fiercely partisan fans who never tire of arguing for their personal choice. In the end, the one you prefer probably depends on where you stand on Tim Toady.

First, the basics. Both languages are interpreted, not compiled. Both are more than fast enough for business computing. Neither is strongly typed. Neither is more error prone than, for example, Java.

Both are object-oriented. Almost everything in Python is an object. Everything in Ruby is an object. (In Ruby, "2+2" is a notational convenience for "2.+(2)". That's an object "2" with a method "+" called with another "2" object as argument.)

Ruby's OO constructs are more Java-like. Python's object model struck me at first as chaos. You start with what in C++ or Java would be two instances of the "dog" class, "fido" and "rover" for example. If fido does tricks, you stick an array field to him: "fido.tricks = ["jump", "roll over", ...]. No need to extend any class, no problem that rover has no tricks.

Multi-paradigm means that unlike Java, you use OO coding when it works for you. You use other techniques and you don't force OO solutions on non-OO problems. For example, both support functional programming: the ability to pass code around and manipulate it as easily as other traditional languages handle strings.

Big difference: Rails. Ruby on Rails is the Ruby language with the Rails website framework. The Rails framework gets all the attention of the Ruby community. By contrast, Pythonistas are split among multiple frameworks, none enjoying the effort put into Rails. Rails JavaScript framework, Pythonistas argue, is based on Scriptaculous which is based on Prototype which has an enduring reputation for bad code.

Both languages work. Spectacular websites can be built successfully with either. Both will give you the same results as you could get with Java EE but with much less code, which will simplify maintenance. Would I recommend one or the other? For me, yes I would. For you? I would not. That's because I have a definite stand on Tim Toady.

Tim originated in Perl (which I recommend you avoid if at all possible). TMTOWTDI: There's More Than One Way To Do It. "Tim Toady" is the way it's pronounced. Ruby, which was designed as a better Perl, features Tim Toady. Pythonistas say, "There should be one, obvious way to do it."

I'd say more on this, but my Python just saw the Ruby code on my screen and slithered away looking very mad. I've got to find him before he swallows the kitten. (Why Ruby? SketchUp plugins can be written in the language of your choice, provided you choose Ruby. How can I explain that to my Python?)

Friday, July 31, 2009

Security through the Ming Dynasty

Planned Security

My expertise is languages, not security, but I thought this one analogy was illuminating.

The Great Wall of China is a misnomer. The Great Walls of China is correct, as their are many of them, built over about 2000 years ending in 1600 CE. The map below is a fraction of a map from Wikipedia.





The Chinese patched weaknesses as they were discovered over twenty centuries. With the advantage of hindsight, it does look like an organized, cohesive plan might have been more effective and a great deal less expensive. Does this look like our current security arrangements?

In my office I have one main Windows machine (XP Pro) and one main Linux machine (KDE). I have NAV on the Windows machine and I pay for its regular updates. I have nothing equivalent on the Linux box as no anti-malware software exists.

Chrome

ZD report on Chrome

Across the pond, the ZD folks are doing good work! This covers Chrome, the vaporware OS, and Chrome, the shipping browser. In my own browser testing, valid Firefox is valid Chrome.

Thursday, July 30, 2009

Embrace Chaos

Business News:

Bartz: "no bull---t". Ballmer: "no bull---t" Bartz and Ballmer with Business Week

SketchUp:

Rubies rule. I can say no more.

Crystal Ball:




"Martin, you've gotta come in here. I just lost another one of my best coders because we're a Java shop."

"Sure, Al. You know my rates?"

Fast forward to 8 A.M., next Tuesday. Al's conference room. CIO and his senior staff know they have a problem.

"Martin, we started as a Cobol shop. That worked pretty well until the Internet took off. So we went to Java. That was fine last century, but sticking with Java is costing us some of our best people. You know about these newer languages. What's happening?"

"You're a Java-only shop?"

"Pretty much."

"That means you don't have any databases?"

"Of course we've got databases. Too damn many if you ask me."

"OK, so you're a Java and SQL shop."

"I hadn't thought about it that way, but I guess that's right."

"And you're not yet on the Internet?"

"What the hell do you mean? Of course we're on the Internet."

"OK, so you're a Java and SQL and HTML shop."

"Yeah, that's true."

"But you've stayed away from dynamic web pages. Nothing 2.0 going on?"

"Martin, it's 2009. You know we're not stuck in the last century."

"Actually, I spent some time at your site. You're a Java and SQL and DHTML and CSS and JavaScript shop. Everyone understands that Java and JavaScript are entirely separate languages?"

All concur.

"Al, I'd say for starters that you are definitely NOT a Java-only shop. I bet if we looked at your B-2-B stuff there's some XML going on, too."

"Right"

"And you've got, maybe, a couple people looking at the iPhone?"

"Nothing definitive, but we're looking."

"You'll be doing Objective-C because the iPhone supports any language you choose, provided you choose Objective-C. There's a lot of that happening. I'm doing SketchUp extensions--any language I like provided I like Ruby. Built a cloud site around the Google chart API--Google's API is language neutral, but JavaScript is the only language that runs in most browsers."

"Martin, is it going to get better or worse?"

"Al, if you define 'better' as fewer languages, you're not going to like the future. If you define 'better' as more targeted, more capable, more domain-specific languages you'll be a happy camper. Embrace chaos. Give it a big hug."

"Any questions?"

Al looks around the room. No one cares to go first.

"Thanks, Martin. 'Embrace chaos.' I've got a question. How in hell am I supposed to go to the board and tell them that we're embracing chaos?"

"That, Al, is where you make the best use of high-priced, authoritative consultants. And while I'm being completely self-serving, you may want me to teach a management-level class on object models. Compared to Java, Python's model seems like chaos. Compared to Java and Python, JavaScript's prototypal inheritance is from a different universe."

"Al, I could use a short break. Then we can talk about a tactical plan. Maybe someone can think of a more marketable version of 'embrace chaos'."