Feeds:
Posts
Comments

Archive for May, 2007

I got into a discussion with Giles Bowkett last week about 3D GUIs (see the comments on his post). It provoked some thought for me. Giles pointed me to an article on Jakob Nielsen’s assessment of 3D UIs. It’s almost 10 years old, though. Nielsen makes some good points, but it sounded to me like it was in the context of what was out there, not so much its potential.

When I imagined what a 3D GUI would be like, around the time this article was written, I tried to think of uses for it from a home user’s perspective. The first thing that came to mind is it extended “wallpaper”. Rather than having a background image on a desktop, you had a whole environment you could fashion to your taste–to actually decorate. That doesn’t sound very useful, and in fact sounds like a huge waste of productive time.

When I thought about it last week, I came to the conclusion that it would allow for a more flexible environment. One of the applications Nielsen talked about for 3D was modeling interior decorating. What if an interior decorating app. wasn’t its own app. like we know it today, but instead added capabilities to the existing environment? What about these 3D role playing games? They could extend the environment as well, rather than just being an app. in a window. Think of the “holodeck” as a metaphore. Everything that’s 3D could live in the environment, or in a sub-environment. Everything that’s 2D could live in a window in the 3D space, but could be found immediately. It wouldn’t have the problem in real 3D space where you can actually lose something :). A question that comes to mind is how do you switch apps like you can in 2D today, if this is the way things are done? Well, I think that would necessitate having multiple environments you could switch between quickly.

It could make apps. more extendable, because there would be a common programming metaphore for adding new elements to the environment. Say some third party company wanted to create an add-on to a game. They wouldn’t have to conform to the game developer’s API, because the original game was just a modification of the standard environment. The third party mod could do the same.

I referenced Croquet as an example of what I imagined. It’s not a pure 3D environment. There are still 2D elements that show up right in front of you no matter where you are in the space. I think that’s practical. I think 3D UIs can add more capabilities to what we’d call “thick client” computing today, but I think some shortcuts need to be added to the environment so that you don’t have to look and travel everywhere just to get something done. I agree that makes it harder than 2D today.

A question I have about it is, is it easier for people to think of “travelling around” to look at a collection of things, or to scroll a window up and down, and side to side?

Advertisements

Read Full Post »

The CBS show “60 Minutes” did a segment on the One Laptop Per Child project this past Sunday, with Nicholas Negroponte. It was good to see. The first half of the segment was devoted to Negroponte’s inspiration for the project, and seeing it to fruition. They showed children in one or two developing countries using it in the classrooms, and at home. They briefly showed some of the members of the OLPC development team. The major theme was that the OLPC promotes education. He said that a lot of children in these countries don’t go to school, and that the OLPC has helped rejuvenate education. He said that in the areas where the OLPC has been introduced school attendance has risen 50%. Word gets out among the children that “school is cool!” He said there are also areas that have no teachers, and therefore no school. He wants to get computers into the hands of those children as well, because he considers it to be a “school in a box.”

The next half was devoted to other, commercial players that want to get in on the action as well, especially Intel. They focused on the rivalry between OLPC and Intel, which could also be seen as a “proxy war” against AMD, whose CPU is used in the OLPC. Intel has come out with its own small-scale laptop for use in the classrooms in developing nations. Negroponte charged that Intel is producing its computers at below cost to undercut OLPC. I wonder, if this is true, if this is illegal. I’m not sure, since the sales are not in the U.S. Anyway, Negroponte looked pretty steamed about it. Intel’s Craig Barrett was interviewed, and he acted like they were doing nothing wrong, and just competing in the market. The conflict puts OLPC in an odd position, because they’re a non-profit, and they’re going up against for-profit companies who are looking for growth opportunities in developing countries.

The 60 Minutes segment indicated that OLPC has not had the sales numbers that they expected. Negroponte indicated that he’s been travelling around a lot trying to counter FUD against OLPC produced by the commercial interests.

Interesting. I didn’t expect it to play out this way. What came to mind as I watched it is that OLPC, out of its motivation to help kids in developing countries, has validated a market that commercial interests are now paying attention to. The commercial interests feel like they’ve got to get their foot in the door, or they could be shut out by the OLPC if it was allowed to go unchallenged in that market. I understand this rationale. It feels sad it’s come to this though. I think the OLPC is a wonderful vision of what computing can be. Not to say I think all computers should be just like it, but it’s great seeing kids use it.

Read Full Post »

I found this post, by Steve Yegge, through reddit. In a lot of ways he’s saying what I’ve read Alan Kay to say, only more bluntly: The current “state of the art” in the tech industry sucks. We build software like the Egyptians built pyramids. There are better hardware designs out there that have been ignored for decades, and the programming languages that most of us developers use suck, but they’re the only ones that run efficiently on the current hardware. Maybe that’s not entirely true, but he’s in the ballpark. He even said the languages some of us like so much like Lisp, Scheme, Smalltalk, etc. are just “less crappy” than the others. I don’t think Alan Kay would be that blunt, but I think he’d agree with the idea. Yegge’s main point is “Moore’s Law is Crap”.

Maybe he’s been reading Kay, or maybe Yegge came to the same conclusions himself. I’ve quoted this article before, but I guess it bears some repeating. Here’s what Kay (AK) said in an ACM Queue interview with Stuart Feldman (SF) from 2005:

(AK) If you look at software today, through the lens of the history of engineering, it’s certainly engineering of a sort—but it’s the kind of engineering that people without the concept of the arch did. Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves.

The languages of Niklaus Wirth have spread wildly and widely because he has been one of the most conscientious documenters of languages and one of the earlier ones to do algorithmic languages using p-codes (pseudocodes)—the same kinds of things that we use. The idea of using those things has a common origin in the hardware of a machine called the Burroughs B5000 from the early 1960s, which the establishment hated.

SF Partly because there wasn’t any public information on most of it.

AK Let me beg to differ. I was there, and Burroughs actually hired college graduates to explain that machine to data-processing managers. There was an immense amount of information available. The problem was that the DP managers didn’t want to learn new ways of computing, or even how to compute. IBM realized that and Burroughs didn’t.

The reason that line lived on—even though the establishment didn’t like it—was precisely because it was almost impossible to crash it, and so the banking industry kept on buying this line of machines, starting with the B5000.

Neither Intel nor Motorola nor any other chip company understands the first thing about why that architecture was a good idea.

Just as an aside, to give you an interesting benchmark—on roughly the same system, roughly optimized the same way, a benchmark from 1979 at Xerox PARC runs only 50 times faster today. Moore’s law has given us somewhere between 40,000 and 60,000 times improvement in that time. So there’s approximately a factor of 1,000 in efficiency that has been lost by bad CPU architectures.

The myth that it doesn’t matter what your processor architecture is—that Moore’s law will take care of you—is totally false.

Finally, Kay said:

…so both Lisp and Smalltalk can do their things and are viable today. But both of them are quite obsolete, of course.

In a different interview two years earlier done with O’Reilly at OpenP2P.com he said of Smalltalk:

“Twenty years ago at PARC . . . I thought we would be way beyond where we are now. I was dissatisfied with what we did there. The irony is that today it looks pretty good.”

Something else Yegge identified that I’ve just begun to see is that there’s a consensus of complacency about all this, even today. Most people don’t care, and want nothing to change. They’re comfortable where they are, and they don’t want to have to learn anything hard.

Yegge focuses on parallelism as a problem that could be solved if our hardware and languages advanced. Right now I’d settle for a processor that could efficiently and natively run bytecode, even if it only did it well serially at first. That would be progress.

Anyway, I really liked Yegge’s post, even though it’s just a rant. He expresses in strong terms how I feel about our industry. He says he’s “nauseous” about it. I’m not that bad, but I know enough to get a bit depressed about it sometimes. He says a lot of what I think to be true.

An article that’s had an influence on me since I read it is Paul Murphy’s “IT Commandment: Thou shalt honor and empower thy (Unix) sysadmins”. In it he gives a history lesson on how the “data processing mindset” and science-based computing developed, and how even though they both use computers, one uses computers as an extension of bureaucratic control, and the other is actually focused on computing. He has a bias against Windows, so he can’t help but put a dig in against it, but the article made an impression on me as far as the overall concept.

At the root of all this is a fundamental confusion: data processing is not computing.

Data processing started with mechanical tabulators in the nineteenth century, developed into a professional discipline during the 1920s, and became a cornerstone of business operations during the late nineteen twenties and early thirties. That was the period, too, in which fundamental organisational structures (like stringent role separation), fundamental controls (like the service level agreement), and fundamental functional assumptions (like the emphasis on reporting, the focus on processing efficiency, the reliance on expectations management, and tendency to justify costs on layoffs) all became more or less cast in stone.

When computers entered this picture in the late 1940s they weren’t used to replace tabulators, they were used to control tabulators – and cost justified on layoffs among the people who had previously controlled batch processes. Thus the first assemblers were physically just that: controls enabling the automated assembly of jobs from card decks and the transfer of information from the output of one batch run to the inputs of the next one.

Science based computing had nothing to do with any of this and focused, from its origins in the mid to late thirties, on problem solving and the extension, rather than the replacement, of human ability. Thus when Atanasoff and Zuse dreamt of solving computational problems, Shannon applied computing to communications, or Newman used a Collosus in raid planning, none of them had the slightest interest in financial reporting or other commercial tasks.

That science community focus continues with Unix today – particularly in the BSD and openSolaris communities – but it’s been there from the beginning. Thus when Thomson and his colleagues first worked on Unix, they talked about forming communities (PM’s link).

Another way of looking at the different mindsets is that the data processing mindset has looked at automation as a way of freeing workers, and making existing business processes more efficient. Rather than having people focused on boring, repetitive tasks, let the machines do them. This will allow people to disassociate themselves from those tasks and focus on more creative activities. That’s a nice way of putting it, and I’m sure that’s been realized by many people. The thing is it also causes distress among many, at least for a time. They can end up feeling worthless, because the job they worked so hard at can be done by a machine better. What’s also implied is this more creative work probably will not involve using a computer that much. There’s a clear separation of work functions: there’s machine work, and there’s work people do.

Science-based computing has had a different vision. Rather than automating existing business functions, computers should extend workers’ abilities. I think someone from this point of view would say that if you have workers that are doing boring, repetitive processes, there’s something wrong with your business process. That’s where the inefficiency is, not in the workers. It sees computers as being a part of enabling people to do and understand more, to become more active participants in the business process. It sees the potential of workers to grow in their roles in the company, to not be limited by a job title. They are not seen as computer operators. They are knowledge workers. They gain and work with knowledge as a part of their job, leveraging it for the benefit of the business. It’s not a matter of taking an existing process and automating it, but rather transforming the business process itself in light of what computers can do for the company. It sees the computer as a new medium, and as with any new medium, information is conveyed, managed, and manipulated in a different way. I think this is the reason Alan Kay has railed against the mindset of the “paperless office”, because it implies automating what used to be done on paper–an old medium. Computers are not a new form of paper! Though they can be used as such if that’s what we choose to do with them.

Looking at things the way they are now, what I’ve discovered, as I’ve looked back over my career, is that computer science is not in the driver’s seat when it comes to business computing. Business computing is where most of the computing jobs are that you can find in the want ads. In my experience what business computing is really about is computer engineering and an Information Systems approach of process automation. This involves connecting systems together, and automating pre-established business functions, with computer science as a support function. It doesn’t matter if the company asked for someone with a CS degree in the want ad. In these environments CS comes in handy for those unusual situations when two pieces don’t quite come together and you need to make them work by creating some “chewing gum and duct tape”, or create a technology function that your company needs but no one’s invented yet. Actually, the latter is the fun stuff…er, usually. Otherwise, all you’re doing is going through the motions of connecting “this” to “that”, making it look nice to the user, and making it flow nicely. Not to say these aren’t noble goals, nor that they are easy, but the science and technique involved in making this happen has nothing to do with CS as far as you’re concerned. The technology you’re using was created using CS. You’re using the product of that effort to do your job. I think the truth of the matter is that most people trained in CS don’t use most of the skills they were trained for. Up until recently, that was true for me as well. CS helped me do my job better, but my job was to support the existing technology.

Where I’m headed, I don’t know. All I know is I’m happy where I am. I’m learning about Smalltalk. I feel drawn towards Scheme as a means to update my computer science knowledge. I was trained in computer science, but I’ve come from a business computing background in my professional life. That’s what I’ve been focused on for 7 years. I’d like to bring whatever new knowledge I learn back into that realm. Just because these technologies have tended to not be used doesn’t mean it always has to be that way. I think they have something to contribute to business. It’s just a feeling at this point. I need to try something more advanced to crystalize in my mind where it can be used.

Edit 5/18/07: Following up on my commentary about typical IT business practice, I used to support some of the practices in the “data processing mindset”, as just accepting the way things were. An idea that’s been around for a while is that programmers are replaceable. I think managers have gotten into this mindset with the advent of de facto programming language standards within companies. The idea is that a programming language becomes popular, and a lot of companies use it in their IT/software shops. I think the idea is this makes the workforce more fluid. Programmers can be laid off, or they can quit their jobs, and move on to other jobs, with no disruption to projects that need to get done. If the company needs to replace them, they can hire from a pool of developers who have the same skills as those who left. All they need to do is spec. out what skills they want. In my experience this is a better idea in theory than in practice. What’s often neglected is the knowledge the employee has about how the company’s IT works, and/or how their customers’ IT works. Just because the new people may have 5 years experience with C# or Java has no relation to how well they know your business, which is likely zero. Usually they’re going to have to learn that completely on the job, and business knowledge is critical. After all, what’s being modeled in the software? Not C# or Java.

Another thing a lot of companies never seem to acknowledge is that a lot of technical knowledge is gained on the job. That’s just how it goes. Most of the time no new programmer is going to know everything they need to know to get every project done they will ever do for the company. A lot of that knowledge will have to be learned along the way. So the idea of “replaceable programmers” in my mind is a myth. Yes, companies can and do try to implement this philosophy all the time. Managers and employees try to compensate for its fallacies in various ways, but it’s still disruptive, because the people with the knowledge are either pushed out, or are walking out the door. With IT being around for as long as it has, you would think most companies would’ve figured out by now that this isn’t working as planned. Instead it sounds like it’s been getting worse, with more companies expecting new workers to have “X years of Y”, as if they’re hiring secretaries, assembly line workers, electricians, or plumbers.

The right questions to ask someone you might hire involve, among other things, gauging whether they can write software well, whether they’re familiar with the language and architectural paradigm you’re using, and whether they have what it takes to learn new skills effectively. These are all open-ended criteria, but they’re more realistic to what the goals actually are than asking if someone has 4 years of C# or Java, HTML/CSS, Javascript, XML, and (the kitchen sink) experience.

Read Full Post »

I’ve uploaded some corrections to both the C# and Smalltalk versions of my first case study of these two. I’ve put up a new C# version. The old one is still there (and can be referenced from the post I just linked to). The link to the new version is below. I’ve replaced the Smalltalk code with a new version.

Edit 10/18/2017: I’ve hosted the code samples on DropBox. DropBox will say that the files cannot be previewed, but it will display a blue “Download” button. Click that to download each zip file.

Case study code

C# EmployeeTest

Smalltalk Employees-Test package

I was inspired to make these changes by a blogger’s scathing post on my case study (Update 5-24-2013: This blog has apparently disappeared). By the way, if you want to see what this same app. would look like using C#/.Net 2.0, read his code. My code is in C#/.Net 1.x. Leaving aside his pompous language, he found a bug in my C# exception code in the Employee class, which I’ve fixed, and he found that I was using overly complex code to convert some of the data to strings. As I said in my defense, “My C#-fu is not what it used to be.” I’ve optimized those places. I also changed the exception’s message so it’s more descriptive.

He criticized the way I named things. He had some good suggestions for changing the names of things, which I have not followed here. I figured I should fix the bug and the needlessly complex code, but I wasn’t going to rewrite the app. I want to move on. I’ll try to be more conscious of how I name things in code in the future.

The only change I made to the Smalltalk code was making the exception message (for the same reason as in the C# code) more descriptive.

The end result of doing this was in terms of lines of code, the C# code and the Smalltalk code came out virtually the same in size. The Smalltalk code increased to 71 LOC (from 70), and the C# code decreased from 75 LOC to 73. The difference in size is statistically insignificant now. I haven’t bothered to look, but maybe C#/.Net 2.0 would’ve required less LOC than the Smalltalk solution in this case. As I said in my first post, this was not a straight line-of-code count. I used certain criteria which I discussed in my first post on this (at the first link in this post).

I think what this exercise put into relief is that there are certain problems that a dynamic language and a statically typed language are equally good at solving. What I’ll be exploring the next time I feel inspired to do this is if there are problems Smalltalk solves better than C# can.

Edit 9/29/2015: Since writing this, I lost interest in doing such comparisons. I think the reason is I realized I’m not skilled at doing this sort of thing. I had the idea at the time that I wanted to somehow apply Smalltalk to business cases. I’m less interested in doing such things now. I’ve been applying myself toward studying language/VM architecture. Perhaps at some point I’ll revisit issues like this.

Read Full Post »

As promised, here is the first case study I did comparing the “stylings” of C# and Smalltalk. I used C# 1.0 code on the .Net CLR 1.0/1.1. I set up a programming problem for myself, creating a business object, and looked at how well each language handled it. I was inspired to do this by Hacknot’s “Invasion of the Dynamic Language Weenies,” (it has to be viewed as a series of slides) where he said there was no discernable difference in lines of code used in a static vs. a dynamic language, nor were there any advantages in programmer productivity (my response to his article is here). I figured I’d give it my own shot and see if he was right. Up to that point I hadn’t bothered to question my impressions.

What follows is the programming problem I set up for myself:

Create a program that records name, home address, work phone, home phone, salary, department, and employment class of employees. The program must store this information in some fashion (like a data structure).

On input, it must validate the department and employment class of employees when their information is entered. The departments are as follows:

– Manufacturing
– Sales
– Accounting
– Board

The employment classes are as follows:

– Employee
– MidLevel <- Management designation
– Executive <- Management designation

Workers with “Employee” or “MidLevel” class designations can be placed in Manufacturing, Sales, or Accounting departments. They cannot be placed in the Board department. Executives can only be placed in the Board department.

The program will restrict access to the employee information by the following criteria. “all access” means all employment classes may see the information:

name – all access
home address – MidLevel and Executive only
work phone – all access
home phone – MidLevel and Executive only
salary – Executive only
department – all access
class – all access

No elaborate keys are necessary. For the purposes of this exercise using the labels “Employee”, “MidLevel”, and “Executive” as “access tokens” will be sufficient evidence for the information store that the user is of that employment class, and can have commensurate access to the data.

==========================

Edit 10/18/2017: Here are the two versions of the project. I use DropBox to host the files. DropBox will say that the files cannot be previewed, but will display a blue “Download” button. Press that to download each file:

C#/.Net 1.x Employee test

Smalltalk Employee test

The C# zip file contains the test project I used.

The Smalltalk zip file contains the “file out” of the Employees-Test package I created, the test code (as a separate file), and the test output I got. It contains two sets of these files. The files in the main directory have been converted to use CR-LF for easy reading (by you) on PCs. They have the suffix “.txt”. The Squeak folder contains the files in their original format, which use LF as the end-of-line character This will be human readable on Unix-compatible systems, and within the Squeak environment. They have the suffix “.text” or “.st”.

For those not familiar with Squeak, the “file out” operation causes Squeak to create a single text file that contains the source code for a package, plus its metadata. A package is a collection of classes. The only code that a programmer would normally see in the Squeak environment are the class definitions, class comments, the method names and parameters, and the method code and comments. There’s some other code and comments that Squeak puts out when it does its file out operation. This is done so that when the code is read by Squeak (or some other Smalltalk system) in what’s called a “file in” operation, it can reconstitute the classes and their methods as they were intended. Normally code is accessed by the programmer strictly via. a “code browser”, which is the equivalent of a developer IDE within the Squeak environment. All classes in the whole system, including this package, are accessible via. a code browser. There’s no need to look up code via. directories and filenames. Code is accessed via. package name, category, class, and method.

The code that carries out the test for the Smalltalk version is included in a separate file in the zip, called “Employee test data.text” in the Squeak folder (“Employee test data.txt” if you want to display it on the screen on a PC). The test code for the C# version is included in main.cs in the C# project zip file.

I timed myself on each version, evaluated how many lines of code (LOC) it took to accomplish the task in each one, and I looked at code readability. I’ll comment on the other factors, but I’ll leave it up to you to judge which is more readable.

As I said earlier, the Smalltalk version came out slightly ahead in using fewer lines of code, despite the fact that a little more code had to be written for it to accomplish the effect you get with enumerations in C# (validating that a symbol–rough equivalent to an enumeration–is in the set of legal symbols). To keep things fair between them I did not count comments, or lines of code taken by curly (C#) or square (Smalltalk) braces. I also did not count test code, just the code for the business object and helper classes. Within these parameters I counted every line that was broken by an end of line character.

I wrote the C# version first. It came to 75 LOC, and took me 125 minutes to code, debug, and test.

The Smalltalk version came to 70 LOC, and took me 85 minutes to code, debug, and test. Another way of looking at it is 93% the LOC of the C# version, but I wrote it in 68% of the time.

A possible factor in the shorter time it took with the Smalltalk version is I wrote the solution first in C#. I can’t deny that doing it once already probably factored into the shorter time. I made a point, however, of not looking at the C# code at all while I was writing the Smalltalk version, and I wrote them on different days. Though I didn’t break it down, my guess is that debugging the code may have taken longer in the C# version. Since I haven’t worked in .Net for a while I’m a bit rusty. Despite having worked out the basic scheme of how to do it the first time, I was writing it in a different language. So I don’t chalk it up to me just repeating what I had already written.

This is my first crack at doing this. I hope to present more test cases in the future. Since I consider Smalltalk worth evaluating for real world uses, I think it should be evaluated seriously, which means taking measurements like this. Though this isn’t scientific, I’m doing this for me, to check my own perceptions. I just thought I’d share it with the reading audience as well. Something I’ll try in the future is writing a test case in Smalltalk first, and then in C#, and I’ll see if that has an impact on how much time it takes me with each. What I may also do is do future C# test cases in C#/.Net 2.0, just to be more current.

If you’d like to try out my sample projects:

I explain below how to run the Smalltalk and C# tests. Smalltalk first.

I wrote and tested my Smalltalk code using Squeak 3.8.1, from Ramon Leon’s site, onsmalltalk.com. I’ve tested it on the standard Squeak 3.8 version as well (which I got from squeak.org), and it works. Ramon has updated his public version of Squeak to 3.9, which still works with my Employee test package. So you can use any of these versions.

The best thing to do would be to unzip the Employee test files into the same directory as where you installed Squeak. My instructions below will assume you have done this.

Here’s a little Squeak primer. For those who are new, you’ll need this to try out the Employee test. These instructions will work on PCs and Unix/Linux machines. For Mac owners, I’m not sure how this would work for you. My guess is clicking the single mouse button would be equivalent to left-clicking.

When you run Squeak you will see a new desktop interface appear. It’s inside an application window frame supplied by your operating system. As long as your mouse stays inside this window, and the window has focus, most of your mouse and keyboard actions will be directed at objects and activities in the Squeak desktop space.

What follows are instructions for helper applications which you’ll be asked to open in the Employee test instructions (below), to load the necessary files, and execute the test.

File list – This is kind of like Windows Explorer. You access it by left-clicking on the Squeak desktop. This brings up what’s called the “World menu”. Within this menu select “Open…”. A second menu will appear. From it, select “file list”. You will see a new window open, which is the File list app. It has a top row which contains a text box on the left where filter expressions go, and then there are a series of buttons. Below this are 3 panes. The middle-left pane is the directory tree of the drive you’re running Squeak on. The middle-right pane is a listing of all the files in the currently selected directory. The lower, 3rd pane contains the text of whatever file is selected in the middle-right pane.

Workspace window – This gives you a text workspace to work in. You can work with code, and assign variable values within it, and it will keep them persistent for you (the variables won’t disappear when you’re done executing a task), for as long as the window is kept on the desktop. You bring up a Workspace by clicking on the right tab on the Squeak desktop (called “Tools”). You should then find the Workspace icon, and click and drag it onto the Squeak desktop.

Transcript window – This is like an active log viewer. It’s basically output-only. You carry out your tasks in the Workspace window, but the output (for this test) goes to the Transcript window. You bring up a Transcript window by clicking on the “Tools” tab. You should then find the Transcript icon, and click and drag it onto the Squeak desktop.

DoIt (action) – This is how you interactively evaluate an expression in Squeak. It’s a universal command. Anywhere, in any window on the Squeak desktop, where you have legal Smalltalk code, you can select it with the mouse, just as you would with text in your native operating system, and hit Alt-D. This will evaluate the expression, carrying out the instruction(s) you selected with the mouse.

Running the Smalltalk Employee test

Run Squeak, and open the File list. Go to the middle-left pane and click on the small triangle to the left of the currently selected directory’s name (this is the Squeak directory). This will expand its directory tree. Select the Squeak sub-folder (this came from the zip file), and select “Employees-Test.st” in the middle-right pane. You will see a button appear in the top row of the window that says “filein”. Click on this button. This will load the Employees-Test package into Squeak.

Click on “Employee test data.text” in the middle-right pane of File list. Click on the lower pane, where the text of this file is displayed, then press Alt-A, and then press Alt-C. Open a Workspace window from the “Tools” tab, and then press Alt-V. (Note that many of the keyboard commands are the same as on Windows, but they use Alt rather than Ctrl).

You should also open a Transcript window (from the “Tools” tab).

Select the Workspace window. Select and evaluate every line of code in the Workspace. You can do this by pressing Alt-A, and then pressing Alt-D. This will “select all” of the text in the window, and evaluate it, which will initialize the collection of Employee objects, and run the test. Look at the Transcript window. That’s where the output will be.

The employee class symbol (in the last line of the Workspace) is set to #Executive. This will output all of the input data to the Transcript window. You can change the employee class symbol (to #Employee or #MidLevel) to get different results. All you need to do hereafter is select and evaluate the very last line of code in the Workspace to rerun the test.

Running the C# Employee test

Unzip the project files into a directory, load the project into Visual Studio.Net (2002 or 2003), build the project, and run it. The output will show up in a console window. The test code is initialized to use the Employee.zClass.EXECUTIVE enumeration. This will output all input data. You can change the employee class enumeration passed in to emp.PrintUsingViewerToken() on line 178 of main.cs (to Employee.zClass.EMPLOYEE or Employee.zClass.MIDLEVEL) to get different results.

Edit 5/16/07: I’ve made corrections to the C# version. See my post here.

Read Full Post »

This is the best introductory, conceptual article on Lisp I’ve ever seen. It’s written by Slava Akhmechet.

Lispers have long felt that it’s very difficult to get lay programmers to understand Lisp, because there’s no common context to help people relate to its unique syntax and powerful features. Slava went against the grain and managed to pull it off. His message is “XML = Lisp with angle brackets”. Or, put another way, “You’re soaking in it!” Are you using Ant? Are you using Hibernate and/or Spring? Are you using CodeSmith to generate code? If so, then you are already halfway to understanding Lisp, because even though the syntax is different, the underlying concepts are the same. XML is your code, and the XML processors are analogous to a Lisp interpreter running your code against some pre-loaded libraries. The difference is Lisp gives you more flexibility and control (ie. more power).

If you don’t understand Lisp macros, but you know how to program in C/C++, he helps you make the transition from C/C++ macros to Lisp macros.

He sums it up with: “Lisp is executable XML with a friendlier syntax.”

Once you understand these analogies, he introduces you to Lisp code.

If Lisp has mystified you, this is a great introduction that will help you get on your way. It won’t make you totally comfortable with it right off the bat, but it will help you get over the initial comprehension barrier. To increase your comprehension, and to learn what Lisp can really do, the following books have come highly recommended to me. I must admit I haven’t read them yet: On Lisp (online book), by Paul Graham; and Practical Common Lisp (online book), by Peter Seibel.

Some others that cover Scheme, a Lisp dialect: The Little Schemer, by Daniel Friedman; and Structure and Interpretation of Computer Programs (aka. “SICP”, online book), by Harold Abelson, Gerald Sussman, and Julie Sussman.

Read Full Post »

I received the following notice yesterday from Joaquin Montalvan:

Dear MARK,

…just thought I’d let you know that THE WAIT IS OVER!!!

“VISUAL FUTURIST: the art & life of syd mead” is
“Officially” available to the public at Syd Mead’s “Official”
Website here: http://sydmead.com/v/11/store/syd-mead-documentary/

JOAQUIN MONTALVAN
Sledgehammer Films

==========================

Great news! It is on the pricey side, $29.99 for the DVD, plus quite a bit more for shipping and handling, if you’re in the U.S., but if you’re a Syd Mead fan (as I am) it might be worth it. Check it out at the link. You can also watch the trailer for the film on YouTube here.

Related post: Documentary on Syd Mead coming out

Read Full Post »

A couple weeks ago I happened upon an article by Hacknot called “Invasion Of The Dynamic Language Weenies”. It starts out well enough, complaining that our industry is dominated by unsubstantiated claims (what else is new?). I’m going to use the pronoun “he”, because 1) I don’t know this person’s real name, and 2) it’s a safe bet that the person who wrote this is male. That’s just the reality of our industry today. He qualifies what he says by saying that this fever is invading the software development realm. I think it’s been there for a long time. What about Sun’s claims back in the mid-1990s that Java was “write once, run anywhere” technology? I can tell you from experience that was hype. Some people will tell you it still is.

At first he focuses on an article he read in the Feb. 2007 issue of IEEE Computer, called “Programmers Shift to Dynamic Languages“, by Linda Paulson. He goes through some quotes that seem based more on emotion than fact and says, “See? This is what I’m talking about” (I’m summarizing). He then launches off of a claim that is made in the article:

What really piqued me was the following quote from Stephen Deibel, chairman of the Python Software Foundation and CEO of Wingware, a company whose principal offering is Wing IDE — an IDE for Python development. In support of the claim that DLs make for more compact code, the author offers the following quote from Deibel:

Python would use 10 to 20 percent of the amount of code that Java or C++ would use to write the same application.

He spends most of the rest of the article expressing doubts and sneering about this claim. I didn’t like the tone, but I agree with the doubts. I think the claim is pretty extreme. Maybe Python in combination with some libraries that take care of a lot of stuff for the programmer, like Rails does for Ruby, does the trick. Like with O-O, programmers will probably gain more power out of the library they’re using than from their own code.

It’s amazing some of the stuff you can do with Rails. All you have to do is watch the “Creating a weblog in 15 minutes” screencast on the Rails site to see that. Try doing the same thing in Java or .Net and see if you can do it as fast and in as little code, to see what I mean. This isn’t to say that Java and .Net couldn’t get similar gains in app. development speed by taking the same approach Rails does. I think it’d be possible, but difficult to implement mostly because of the way Sun and Microsoft structured the mechanism of dynamically creating classes. It’s so verbose as to cause most programmers to not even venture into this territory.

He continues:

Actually, I had trouble imagining how it might be true even within limited domains. Though I’ve principally used Java for the last 10 years or so, and C/C++ for five years preceding that, I have a basic familiarity with Python, having written a few utilities here and there with it. Reflecting on those experiences I could see no basis for such a startling claim to code brevity.

But it’s not only this claim made for Python that I find impossible to reconcile with my own experience and reason. I find many of the claims made for other DLs to be equally dubious. I have a basic knowledge of DLs such as Perl and Ruby, and have worked with PHP quite a bit. Reflecting on my experiences with these, I cannot find any support for the grandiose claims made by proponents of some of these languages either.

I was tweaked by Hacknot’s argument here, so I decided to do a case study using C#/.Net 1.x and Smalltalk. I cover a bit of that here, but I’ll deal with most of it in a later post. I’ll just say that in terms of lines of code written/generated, the differences were not as great as I anticipated. I was a bit surprised. Smalltalk still came out (slightly) ahead of C#. It was a simple example, the equivalent of a console application. Perhaps if the task was more complex Smalltalk’s power would’ve been more evident. In my opinion the Smalltalk code was clearer in expressing the process. It took less time to write as well. In any case, I was humbled. I had been taken in by the notion that DLs would dramatically reduce the lines of code one would have to write, just generally. I never bought the notion that it would be 80-90% smaller, but I thought a reduction of 25-50% would not be unreasonable.

To set up further argument, Hacknot gives his definition of dynamic vs. statically typed languages:

What Is A Dynamic Language?

There is no canonical definition of a Dynamic Language, but some generalizations are possible. A dynamic language generally possesses one or more of the following features:

  1. Dynamic typing – Variables need not be declared before use. Their type is not determined until runtime.
  2. Runtime code modification – Class hierarchies and other logical aspects of the code’s structure can be modified on the fly e.g. methods may be added to classes / objects.
  3. Interpretation – Source code is read at runtime, translated into machine code as it is read, then executed.

Dynamic languages include JavaScript, PHP, Tcl, Ruby and Python. They are often referred to as “scripting” languages.

By contrast, static languages have the following general features:

  1. Static typing – Variable and parameter types must be explicitly assigned so that they are known at compile time.
  2. Fixed code structure – Classes and other code structures are immutable at runtime.
  3. Compilation – Code is compiled into some intermediate form, often machine code, which is later executed.

Static languages include C, C++ and Java.

I’ve heard about others equating dynamic languages to “scripting languages”. To me this never seemed justified. One would be hard pressed to find anyone familiar with Lisp or Scheme calling them “scripting languages”. In my experience scripting languages are task-oriented. They’re designed to help you glue processes together to create a new process. Some examples are Bourne Shell/BASH, and AWK. I would even include Perl in this list, because it first became popular among Unix system administrators as a more powerful scripting language (more powerful than writing a script in a shell). When web apps. became popular Perl got brought into that. From what I hear it’s still a so-called “write-only” language. You can write a program in it, but it’s difficult to go back and modify it later. It’s been that way for years. Scripting languages are generally like this. Trying to read and understand a shell script can be a real trip.

Ruby, as an example, can be used as a scripting language, but it more closely resembles a language that would be used for building applications. I can’t speak for Python too much because I haven’t used it.

He is correct about his 3 properties of dynamic languages, but he leaves out some things. Here’s a good article on dynamic language properties. Dynamic languages often have:

  • Late binding, meaning that an object is not bound to other objects until it’s called for at run time. This allows code to be modified while a program is running, and it’ll still work. If you’ve used “edit and continue” within Visual Studio, this is emulating what I’m talking about here, within the context of an early-bound environment. Essentially what “edit and continue” does is recompile the changed module, and literally patches the updated binary code/bytecode into memory. Not easy to do. Even so, Microsoft developers missed this feature when Visual Studio.Net was first introduced, because it wasn’t there. It was re-introduced with VS 2005. Late-bound languages accomplish the same thing naturally, though I imagine in a different way. They’re designed for this.
  • An Eval() function, which allows code to be compiled/interpreted dynamically at runtime. This may be incidental code that needs to be formed dynamically, executed for a particular function, and is then thrown away. It can also be used to create a script interpreter environment within a running application.
  • Higher-order functions. This is a technical name for a function which takes one or more functions as argument(s), and/or returns a function. It’s helpful to think of this in mathematical terms. For example, a derivative in Calculus takes a function and produces another function. This doesn’t mean it has to be used in a mathematical context. I am saying that a background in mathematics helps in understanding this concept.
  • Modification of code/code generation at runtime. This allows a program to modify a code library, or itself, to suit its needs. Lisp is well known for this.
  • Closures, also known as Lambda expressions, or anonymous methods (recently added to .Net). They are blocks of code that basically act like a named function, but have no name. A program merely carries references to them for as long as they are needed. A key characteristic is like normal functions they are lexically scoped, which means that they acquire the scope where they are defined, no matter where they are ultimately invoked. They are often used to carry out an incidental step in a program. They come in handy, because they substitute for rarely used class methods. They are constructed or used at runtime by higher-order functions.
  • Functional programming. Some dynamic languages have functional programming features. This means that the value of a variable, or the state of a program is always represented by a function, and a variable can only be assigned to once. (h/t to Giles Bowkett for the link)
  • Continuations.  These allow a program to access, and even change its own state at will. This can mean persisting the call stack and restoring it to its former state later, or it could mean changing where the return value of a function actually goes (ie. you can have it go somewhere else besides the function’s caller).
  • Introspection, also known as reflection. This allows a program to look at an object and figure out at runtime what type it is, what methods it has, what the parameters are to those methods, etc. Java and .Net have this as well.
  • Macros. This is a meta-programming construct which allows the programmer to add new features to, or change the syntax in a dynamic language. Lisp is known for this feature. This is especially useful in creating embedded domain-specific languages (DSLs).

Giving Hacknot the benefit of the doubt, he was trying to come up with a list that was common to all dynamic languages. With the exception of Visual Basic, most other dynamic languages have some of the features I list above.

So what do these features get you? Here are some that I can think of:

  • Modification of code/code generation at runtime – An example of this is what the Rails framework does, in the Ruby language. Based on metadata in the database it dynamically creates the code for the object-relational mapping (ORM) model, which the programmer can access from his or her application code, and it creates code for what’s called a “scaffold” of the web client interface.
  • Continuations –  An example of where this becomes really powerful is the Seaside web framework for Squeak, and exception handling in CLOS (Common Lisp Object System) (h/t to Giles Bowkett).
  • Closures – A good example of what this gains you can be seen in the following Smalltalk code:

| list output1 output2 |
list := #('Jim' 'John' 'Mike' 'Matt' 'Cindy' 'Melinda' 'Sally').
output1 := list collect: [:each | 'student: ', each].
output2 := list select: [:each | (each at: 1) = $M].

output1 will be all of the names with “student: ” prepended to them: #(‘student: Jim’ ‘student: John’ ‘student: Mike’ ‘student: Matt’ ‘student: Cindy’ ‘student: Melinda’ ‘student: Sally’).

The select method does a test, in this case it tests whether each name starts with the letter M. output 2 will be #(‘Mike’ ‘Matt’ ‘Melinda’).

Both collect: and select: methods are higher-order functions that form new collections out of what’s in “list”, by iterating over it and sending each element to the closure that was sent to the method. The closure is in []’s. Each closure takes parameter(s) (the “:each” part) and produces output (whatever the expression in []’s evaluates to). The pipe (‘|’) separates the parameters from the code. Each time the closure is called by collect:, it returns “student: <student name>”, and collect: adds that to a new collection it’s made. Each time the closure is called by select:, it tests the value. If the closure returns true, that entry is added to the new collection select: has made. If it returns false, it does not get added. When collect: has iterated over all the elements of “list”, it returns its new collection. The same goes for select:.

The actions carried out by collect: and select: could’ve been carried out using a foreach loop in .Net or Java, but once you understand the principles involved, this approach is simpler.

Hacknot is largely correct about his feature list for static languages, but I’d call them characteristics of an early-bound language instead, since I’ve read that Python has static typing features, as well as dynamic types. I’d take issue with his characterization that static languages have a fixed code structure. In large part this is true, but in Java and .Net it’s possible to construct classes at runtime, and instantiate them, though this is very cumbersome. The other features I would add to the list Hacknot gave are:

  • Early binding. All modules that make up a program are bound together into an executable at compile time. This executable image generally cannot be modified except by recompiling the program. Hacknot correctly points out that this doesn’t mean that the entire body of source code has to be recompiled each time. The compilation step may only need to compile one module, which can then be integrated into the executable. There are other ways of speeding this up. Microsoft’s compilers have incremental compilation, for example, where it tries to only recompile what’s been changed inside a module, to make the process go faster. What this usually means is that in order for the program to be modified, it must be stopped, so that it can be recompiled, and then reloaded into memory for execution. In this case it must always start from a predetermined entry point in the program. ASP.Net somehow gets around this, probably by caching the JITted version of modules.
  • Templates/generics, also known as parameterized types. This is a feature that was created in O-O languages to try to get around a couple of the inconveniences of static typing: manually creating repetitive code, or just taking Object as input and/or returning Object. They make it possible to create a class, or automatically generate a new function at compile time, where the programmer tells the class or function what type(s) to use within itself. This technically creates repetitive code, but the programmer doesn’t have to deal with it. He or she can just deal with the code template. This preserves the feature of static typing, because once the new class or function is created the types within it are fixed. The way they’re typically used are as a way of automating type casts.

Hacknot argues that static typing is like documentation for your “intent”:

Consider that when you remove type qualification from the source code, you’re also removing some documentation of your intent. . . . Consider also — if it’s good form to give your identifiers meaningful names to aid in comprehension, isn’t it equally good form to explicitly assign them types, for exactly the same reason?

Hacknot touches on this later, but I’ll address it here. He likes static typing because it’s something that can be caught by the compiler. This also means that all types are enforced. It’s binding. It’s not like a variable name where its meaning, as far as its type, is flexible. Even in strongly typed languages programming teams I worked with often named variables like “iCount” and “strItem”, simply because we didn’t want to bother to go looking in the code for where a variable was declared, and what type it was. We wanted to just get it from the name. This began to fade once I got into .Net programming, but I still used this technique from time to time.

As far as intent goes, let’s take a look at some code. This is from a real project I did as a test case between C# and Smalltalk, which I’ll discuss more in another post. I’m using a Hashtable, which contains arrays as values in the key-value pairs (this is .Net 1.x code):

public static bool ValidateClassForDepartment(
Employee.zDept department,
Employee.zClass employeeClass)
{
return (Array.IndexOf(((Employee.zClass [])
deptClassAssociations[department]),
employeeClass) != -1);
}

By the way, just at first glance, is my intent clear here? What am I doing? Modern business apps. use collections all the time. They’re essential to doing any serious development. But why would I have to do this, if strong, static types are supposed to help someone see exactly what my intent is? In fact a lot of functions within .Net and Java have been like this (for .Net up until Version  2.0). They input and return objects of type Object, because the designers wanted them to be generic. There was no way they could anticipate all of the different types that programmers would want to use and receive. Object is at the top of the class hierarchy, so it’s a safe bet. But what does this do for the programmer? Not much. Not even a compiler could catch a type mismatch in this case. The error would not be caught until the program was run. Even in the days when the C language was popular, library functions often took parameters or returned a value of type void *, because there was no way to anticipate what a caller would pass in, or what type would be returned.

Say I was unfamiliar with this collection, but I knew I needed to fetch values out of it. I wouldn’t know how the values were put in there, because I hadn’t looked at that code yet. So I fetch out Objects. What can I do with them? There a couple ways I could figure this out. I could go to the source code where these objects were inserted, and see what type they are. Or, I could run the code in a debugger and inspect what types I’m getting. How is this different from using a dynamic language? It’s not. I would use the same techniques to figure out what type(s) are in the collection.

In the case of the .Net code I am either forced to type cast what I get out of Hashtable to the type I need, or I suppose I could’ve subclassed Hashtable, and created my own type-specific accessors. Do I like extra overhead? No! This is the downside of static typing–inflexibility in library functions. Let’s take a look at the same functionality in Smalltalk, a dynamic language, using a Dictionary container (the equivalent of Hashtable in .Net):

validateEmployeeClass: empClassSymbol
forDepartment: deptSymbol
^(deptClassAssociations at: deptSymbol)
includes: empClassSymbol.

I don’t know about you, but this looks clearer to me; less cruft. The one part that’s probably unclear to those unfamiliar with Smalltalk is that the “includes:” method is doing a test of whether the array includes empClassSymbol. I was able to get this clarity because of the dynamic nature of the language. I don’t have to type cast because all variables are just references to objects. The references pay no attention to the type they’re referencing. I can put an array into a Dictionary and get that same array back out when I access it.

Hacknot asks a question here, but then backs away from exploring the answer:

What about Python’s other dynamic feature, runtime code modification. Can it result in a reduction in code volume of 80 to 90 percent? I find this impossible to assess, as I have insufficient familiarity with self-modifying code. But I might mention that this lack of experience is quite intentional. Even when I find myself using a language that permits runtime code modification, it is a feature I am loathe to use for it seems to me to hold great potential for producing a code base that is hard to understand, and therefore difficult to debug and maintain. Additionally, there is significant cognitive complexity that goes along with dynamically modifying code, not unlike the intrinsic difficulty that accompanies multi-threaded code. In my view, this level of complexity is to be avoided if possible.

I think all he’d have to do is take a look at a framework that generates its own code at runtime, like Rails, and then see how little code the developer has to write to see that perhaps runtime code generation/modification is a good thing.

He equates “runtime code modification” to “self-modifying code”, and misses the point.  He then says, “It’s too scary, so I won’t go there.” This is just my opinion, but I think it’s this sort of attitude which eventually leads to permanent unemployment among developers like him. The fact that he thinks multithreading is scary as well, and should therefore be avoided, only reinforces this point. Multithreading is increasingly becoming an issue that developers must deal with, because CPU cores are reaching a speed limit. The only way program speed can be increased is by multithreading. It’s just a matter of how it will be achieved. I personally don’t employ multithreading at the drop of a hat either, but I use it where I think it’s necessary.

Self-modifying code sounds scary to a lot of folks, but think of it this way. A lot of .Net and Java programmers are increasingly writing parts of their programs in XML as a metalanguage. They run the XML through code generators to get their .Net or Java code pieces, using it to generate code that they’re probably not going to look at. They just want the functionality out of it. Now imagine if instead of using XML they used .Net or Java code to generate code in their respective languages. This is essentially what “self-modifying code” is: generating code using the same language you are generating code for; using Java to generate Java code, or using .Net to generate .Net code. It doesn’t have to be scary. Where I think it gets into “weird” territory for most people is that most dynamic languages put the programmer into a constantly “active” environment, like Lisp, Smalltalk, or Ruby. In these cases, there’s little distinction between a program being in an active or inactive state, since it’s possible to modify a program while it’s running. This is unlike the traditional development model of writing code when a program is inactive (non-existent in memory), compiling the code, and then activating the program.

It’s possible to generate Java code in Java and .Net code in .Net, but it’s a verbose, laborious process. Some have ventured into that territory, but most have not. The reason “self-modifying code” becomes a feature in dynamic languages is the fact that it’s easier to do.

Hacknot asks some good questions here, but the answer may be that the developers he’s complaining about accept some things, which I’ve covered above, as a given. He doesn’t seem to understand what their basis for judgement is:

To reiterate, the abbreviation that brings ostensible benefit to the original author of the code may be an impediment to other’s comprehension of the code. Further, how do we know that the presence of compile-time type checking is not a nasty inconvenience, but an efficient eliminator of even nastier runtime errors caused by unanticipated type coercions? Without a detailed assessment of the negative effects of dynamic typing, how can we possibly determine its net effect on development speed? It seems to me that we can’t. But it also seems that many DL enthusiasts are willing to ignore such inconvenient issues, even when directly confronted by them.

For instance, I notice that in “Programming Ruby”, at the top of Dave Thomas’ list of techniques for debugging Ruby problems is “Run your scripts with warnings enabled” — in other words, examine the sort of information that a compiler would already have given you, were you using a static language! This tendency to exaggerate the advantages of some language feature while deliberately ignoring the disadvantages of that same feature is characteristic of much DL advocacy.

I thought this quote was interesting:

Indeed, the gap between what I wrote and what I intended is where so many bugs lie, that I have come to appreciate the value of being as precise as possible in specifying my intent. Therefore I use Design By Contract, because each contract is one more opportunity for me to spell out to myself, the compiler, and future maintainers, exactly what I intend and what assumptions I’m making.

An awareness of my own limitations is the most significant factor in determining my approach to software development as a whole. That’s why the dynamic language features that a weenie would call “flexible” I would call “an opportunity to err”.

“The gap between what I wrote and what I intended is where so many bugs lie”. I think this gets to the heart of why I like dynamic languages. The intent shines through more. It’s not burdened with cruft, which obscures the intent of the process I’m trying to express, which it sounds to me is what he’s talking about here. Design by Contract is not a bad idea, but this is not something that is achieved by merely using a statically typed language. It helps, but often more code needs to be added to insure that inputs and outputs meet requirements and assumptions. In a dynamic language a little more code would have to be added than in a static language to insure types were correct, and to produce an intelligable error message if they weren’t.

A proposal in a paper I found while writing this might make things easier on everybody. It argues that future languages should contain both static and dynamic typing features, so developers don’t have to make a black or white choice. And indeed, such languages are appearing. As I said earlier, I believe Python is one of them. Groovy is another. Whenever Microsoft comes out with their Orcas release of .Net, it will be another answer to this.

I thought his statement about “understanding my limitations” was interesting. He’s basically saying, “This is my skill level and I’m sticking to it,” which is fine. If he wants to stay where he is, he has every right to stay there. What I’m wondering about is why he’s so stuck up about other people making other decisions. He does say later that he really dislikes the emotionalism that is encouraged within our industry, which is a valid criticism, but he also really disses dynamic languages, as if they have no worth whatsoever. I think such judgements coming from him are really unjustified. He comes at dynamic languages from the standpoint of someone who’s uncomfortable with them to begin with.

Here’s a series of doubts Hacknot has about the claims made for dynamic languages. They’re not really based on anything, but for what it’s worth, it raises questions that should be answered:

Most DLs are interpreted rather than compiled. This means that your test/debug cycle no longer includes an explicit “compile” or “link” step which, DL weenies claim, makes for a “development cycle [that] is dramatically shorter than that of traditional tools.” Maybe so, but how significant an impact does that have on overall development speed? You don’t have to wait for the compile/link to occur, but you still have to wait for the thing to execute so you can test it, and interpreted languages are often slower to execute than compiled ones. So how much do you really gain overall? And there are other confounding factors. Perhaps the compile-time type checking of a static language serves to catch bugs that a DL won’t pick up until runtime, in which case some of your test/debug cycles for a DL will be spent catching type-related problems that a static language would’ve detected before execution began. I say “perhaps” because I just don’t know — I’m only speculating. I don’t have the data and so I can only guess as to what the net effect is on development speed. The problem is, the dynamic language weenies don’t appear to have the data either; but somehow they’ve attained surety in its absence. Again we see the advantages of a feature (interpretation) being extolled but its disadvantages being ignored.

Like I was saying earlier, modern development has often demanded things of developers that belie what Hacknot is talking about with respect to the advantages of statically typed languages. There have been plenty of cases where static typing doesn’t gain you anything, because the developer had to make a “generic” choice.

I think he’s totally off base in saying that debugging is slowed down because “you have to wait for the program to execute.” I’ve written some Ruby on Rails code on my 1 Ghz laptop. Granted it was for a simple app., but it ran plenty quick. For an interpreted language it ran fast.

Hacknot complains that the “dynamic language weenies” haven’t provided any data to back up their claims “but somehow they’ve attained surety”. I think it’s a matter of these developers having attained a sufficient level of experience with static languages that they assume everyone else has come to the same conclusions as they have about them. Obviously they were wrong, as Hacknot is a perfect case in point.

Many language comparisons performed by DL enthusiasts focus on concision as if it were the sole measure of programmatic worth. However there are many aspects of a code base that contribute to an overall assessment of its condition, volume being only one of them. Structure, commenting, consistency, naming, performance and maintainability all influence the efficiency with which programmers can work on a body of code. I would say the primary influencers are the qualities of the programmers themselves.

I think this is true for the most part, except that experienced developers tend to like technologies that support them to the best of their abilities. A weak language can waste a developer’s time. This is something he doesn’t cover at all: the powerful features in DLs. I don’t know if it was deliberate, but in effect he’s set up a strawman by saying the “weenies” claim that all of the advantages flow from them not having to deal with types in their application code. I certainly wouldn’t argue that. There are some advantages that flow from this, transparency in process being one of them, but not major ones, in my opinion. I personally like concise code. It’s easier for me to read. The less cruft I have to wade through the better. Granted it’s really helpful if the developer puts clear names on things, and structures the program well. Obfuscated code is never a good thing, in my opinion. And static typing doesn’t help with this. A process that’s written in obfuscated code is going to be nearly as bad in a static language as in a dynamic one. Yes, in a static language there is more information, but it’s not going to give you the answer as to what the intended process is. I’ve seen code written in a statically typed language written by a programmer who only used single-character variable names for everything. His process was unintelligable. I could pick out parts of it, but I could never get the whole thing without going to him and asking, “What were you trying to do here?”

I’d liken strong typing to training wheels, of a sort. Not that developers don’t need it for a significant part of their career, but after a point strong typing can feel like a straightjacket. It gets in the way, rather than supporting you.

One of the least influential factors influencing development speed is the amount of typing you have to do. We have IDEs with numerous keystroke-saving mechanisms built in such as smart editors, keyword expansion, templates, macros and so on. If code volume were significant as an influencer of overall productivity, then we would expect touch typists to be at a significant advantage to the hunt-and-peck typists which are so common in our occupation.

Yet there is no shortage of syntax-obsessed language comparisons of the form:

Here’s a toy task implemented in SSL (some static language). Observe that it takes 20 lines of code to implement. Oh, the humanity! Now here’s the same task implemented in SDL (some dynamic language). It only takes 10 lines. Therefore you’re twice as productive in SDL as in SSL.

I guess what he’d really like to look at is a full-fledged project with some real meat on it. Obviously it’s hard to do that in discussion forums. People don’t want to look at reams of code just to see someone make a point. I think what he’s really expressing here is he wishes there were more formal studies done, which is a perfectly reasonable request.

I can only speak for myself. There have been many cases where I have had ideas that I’ve abandoned because I felt as though there was too much work involved. It was the amount of code I’d have to write and the machinations I’d have to go through to get it done. If it could’ve been expressed more simply, I would’ve been inclined to go ahead with it. To say that the amount of code you have to write doesn’t matter I think just misses the mark. I think I should only have to write as much code as necessary to adequately express my intended process. I prefer using formal logic for this. It’s closer to what I’m actually thinking. I’d rather not be concerned with how the computer is going to execute it. In my opinion, most static languages force the programmer to think in terms of how the computer is going to execute your process. They take the focus off the process, and put it on the mechanism that executes the process. I’m using “mechanism that executes the process” as a metaphore for, as Ramon Leon often says, “the work that programmers do to help the compiler do its job” of translating the source code into object code. I’d suggest that this is the reason Hacknot said earlier that so many of his bugs come from what he wrote being different from what he intended. He got distracted by the mechanism and was not focused on the process he intended to write.

Regarding the arguments made that dynamic languages are gaining legitimacy because of corporate backing:

Let’s not be so naive. Corporations are out to make money. They are not interested in advancing the software development field, championing an ideology or improving your productivity, except in so far as those activities will yield some financial return. If a company appears to be hopping upon your favorite DL’s bandwagon, they are simply acknowledging “There is money to be made here.” Commercial exploitation is not a hallmark of engineering worth. It will be in many corporations best interests to actively fuel the hype surrounding a DL in order to generate sales of their own related products and services. Hence the advent of the execrable job title “Technology Evangelist”.

When the dynamic language hysteria dries up — and it surely will — these same companies will eagerly pursue the very next trend to surface, just as soon as they can find something to sell to the niche market it has created. We’ve seen this same pattern so many times throughout the history of this industry, its reoccurrence is utterly predictable. Recall that when OO first came to the fore, companies everywhere were suddenly remarketing their existing fare as being object oriented.

He’s kind of beating a dead horse here. C++ and Java, the two languages he’s used most would not be the standards in the industry that they are without the hype he complains about. In fact, I’d venture to guess he wouldn’t have been using these languages, but some older ones.

Some of what he says is true here, but I think dynamic languages are here to stay. Groovy has support by Sun for Java. Microsoft, though they haven’t come out with it yet, has been moving forward with adding dynamic language features to .Net for the past two years, and is set to release these modifications next year. In fact these DL features are necessary for some of what Microsoft wants to accomplish with .Net.

The present IEEE article concluded with a statement from Carl Howe, principal analyst for Blackfriars Communications, a market research firm. He is also apparently a “longtime Unix coder”. He claims:

Languages are tools for programmers. As the problems change, people use new languages.

I suggest that of all the factors driving the current interest in DLs, a changing problem set is about the least important.

Even in the wider development community, the need to solve new problems is rarely to be found as a force driving adoption. Howe seems to be suggesting that adoption of a new language occurs when a developer finds themselves facing a problem that is not addressed well by existing languages, forcing them to search further a field for something more suitable. I suggest that the exact opposite is generally true. Enthusiasts start with the desired solution in mind — the new toy they want to play with — and go looking for a problem to apply it to.

I think this is where Hacknot starts coming off the tracks. What attracted me to Ruby on Rails, and then to Squeak and Seaside was the fact that I had been working on web applications for the past year-and-a-half, and I had been using ASP.Net 1.x. My experience with ASP.Net began well, because it provided a good training ground for learning how web applications work, but over time I became disturbed by some real shortcomings I saw in it. There were situations I had reached where the development tool I was using, Visual Studio.Net, was of no help at all. The page model that the ASP.Net API insisted I use really caused problems for me on one project, where I had to deal with taking submits from sections of a page, not the whole page at once, and updating multiple sections of the display as a result. I got it done, but at the end I was ashamed of the code I wrote. I kept up the code as best I could, but it was basically a mess. What I kept hearing from others is that even with these shortcomings, ASP.Net was still better than the Java equivalent in terms of the amount of code one had to write to get the same thing done. This was important to me because I had tight deadlines. C# and Java have been weak languages (VB.Net fairs a bit better, but not much), which are gradually getting stronger with time. The reason they can seem reasonable for many tasks is because of the tools, APIs, and components that support them.

I was attracted to Ruby on Rails because right off the bat I could see it solved problems much more efficiently than ASP.Net 1.x could’ve dreamed of doing. There are qualities to the Ruby language that enable it to do what it does well, which while possible in an environment like .Net and Java they’re more difficult to achieve. Groovy, based on the JVM, has its Grails framework (which is similar to Rails). Work is being done as I write this to create a Ruby.Net compiler. I think it will be achieved one of these days.

There were some aspects of RoR that puzzled me though. I’ve later come to know that the reason for the confusion was that the RoR version I was looking at used associations to simulate the named parameter syntax in Smalltalk. In fact there were many similarities I could see between Ruby and Smalltalk.

I was attracted to Seaside on Squeak (a modern version of Smalltalk), because it enables the web developer to write code as though they’re working on a desktop application, which is really what I wanted all along, from the time I first started writing web apps. State is maintained by the framework using continuations, alleviating the developer from having to think about it. .Net and Java simply cannot do this, not without a ton of work done on them, with significant costs in performance. Seaside does not have this impediment. Further, it uses a component model for building web pages. So you can have multiple independent components on a page that each receive their own submits, and/or update their own section of the page.

The statelessness of the web demanded new solutions to the problem, because the older languages were inadequate for the job, at least in the way they were being used. The older languages were fine for the GUI and console app. era. They could get the job done reasonably well, though I’m sure dynamic languages could’ve shined even then if the hardware speeds had been fast enough. The real problem I’ve seen with the web is that the technology behind it has been one kludge after another. Giving credit where I think it’s due, ASP.Net was a step in the right direction, but it’s a far cry from RoR and Seaside on Squeak.

One of the more desperate claims weenies are prone to making is that their DL of choice has a syntax that is somehow more natural, expressive or intuitive than those of other languages. Sometimes they’ll go even further, claiming that the DL syntax is so intuitive that it enables some sort of direct mind-CPU connection.

I don’t think I’ve ever claimed that the native syntax of a dynamic language was more “natural”. This can come close to being achieved using domain-specific languages in a DL. I have used the term “expressive”, but I think that’s accurate. If you compare between code written in a DL vs. an SL, you’ll see that the intended process tends to jump out at you more in a DL than in the equivalent SL code. As for the “direct mind-CPU connection”, well, I think that’s way off. The CPU doesn’t even enter into it. That’s what I’m trying to get away from, in fact.

I think where the “natural” adjective comes from is there are programmers who have a background in mathematics, like myself, who see what can be done in terms of syntax, and they really like it, because it matches with how they like to translate problems into a codified form, whether it be in mathematical terms, or in programming language code. “The language of math” is one that’s often tripped me up, but as a hobby I occasionally venture into those waters to learn more about it. The syntax of Smalltalk feels good to me though (there I go with the emotions…).

I’m using these rather well chosen examples to illustrate what should be self-evident — all programming languages are arbitrary, artificial constructs which must be learnt. They cannot be intuited. Further, what constitutes a “natural” syntax is infinite in scope and varies dramatically between individuals depending on what languages they have been exposed to in the past, amongst other factors. The language designer chose a syntactic option that was most natural to him at the time.

This is true. Every programmer who uses a programming language written by someone else is adapting ideas to the model of that language. Some languages are better at accomplishing some tasks than others. They are not all created equal, despite the claims about “all languages being Turing Complete”. Ah yes, but the question is how much effort do you have to go through to get something done. Yes, you could implement continuations in Java, but how much effort would you have to put into that, and would it even be worth it?

The rest of Hacknot’s post is not really worth commenting on. I don’t like arguing with people who froth at the mouth. He dismisses dynamic languages as the mere whimsy of fanatics, and blames the advocacy behind them for the sorry state of our industry.

The blame is misplaced. The reason for the emotionalism is partly because the people who choose to stay in this business are generally the people who are passionate about what they do. They’re the ones who survive in it. Being in the technology business is tough. Another part of it is some people know who the true buyers of technology are, and they’re not us developers. They’re people who, in the least, hopefully have a bit of a clue about technology, because that’s the most we can expect of them right now. If you’re an experienced developer you know who I’m talking about. They are guided by salesmanship, not technological merit. One reason technologists resort to hype is because they know this. If languages were never hyped, we’d still be programming in assembly language today, or maybe Cobol and Fortran. Frankly I’m thankful we’re not.

I’ll give my own opinion in response. I understand his frustration. I used to get frustrated with the claims that open source (basically, read “Linux” into that) is inherently “secure”, “never crashes”, and “will take over the desktop from Windows”. Time has borne out that these claims are not true as absolutes. It certainly doesn’t mean that open source software is bad or inadequate to solving real problems. I’ve never liked it when advocates make something out to be more than it is. There are instances, I’ve discovered in the last year, where open source software is really good, and ahead of anything else out there. It’s actually innovative. I think some of that breathlessness Hacknot complains about is people acknowledging this innovation.

Secondly, dynamic languages were not just invented by “corporations who are out to exploit the gullible”. They were invented by some serious academics. A few I can think of are Dr. John McCarthy who invented Lisp, Dr. Gerald Sussman and Dr. Guy Steele who wrote Scheme, Dr. Alan Kay who invented Smalltalk, and Guido van Rossum who invented Python, among others. All of these people are trying to advance the state of the art of computer science, not take it backwards as Hacknot suggests.

I think DLs, with the exception of a few, represent a purist vision of the future of programming. Future programming languages will probably not look exactly like them, but their influence will most definitely be felt. It already has been. The ideas of OOP, introspection/reflection, closures/lambda expressions came out of work that was done decades ago in the DL realm. The truth is that modern programming languages are playing catch-up to what DLs represent. I personally, as a developer who cares about his craft, will be better off for it, thank you very much. Unlike Hacknot I don’t think dynamic languages are the path into a fever swamp for technology. Quite the contrary. They’re the next step in making our industry a mature profession, though they’re not the endpoint. Just a step along the way.

Giving credit where it’s due, a lot of what I’ve stated as problems with static languages, in terms of application development issues, have been solved in .Net 2.0, and recent versions of Java. I’ve read up on .Net 2.0, though I have not done any work in it yet. I look forward to seeing more of what Groovy can do, and what Orcas ends up being from Microsoft. I’d like to see these languages progress to include more of the powerful features I’ve discussed, down the road.

Read Full Post »