My take on JavaScript

May 26, 2008 by gnuvince

As a web developer, you’ll need to use JavaScript one day. There’s no escaping it, eventually you or your client will want a feature that can only be done with JavaScript. I know, I’ve been there. For a long time, I’ve avoided JavaScript like the plague, but you can ignore it only for so long before you have no choice but to sell your soul and get into the language. As I learned JavaScript, I found things that are good that I liked, and things that aren’t so good that I dislike.

I like the language: JavaScript is Lisp is C’s clothings. I like that JavaScript is a small, orthogonal language and that it doesn’t have a gajillion features (though it seems JavaScript 2.0 will not continue on this path), but instead has few limitations of what you can do with the primitives of the language and how you can combine them together. This makes for a language that is simple to learn, but that has more power than a lot of other more complex languages such as Java or C#. The heavy use of higher-order functions and closures is probably the best part of JavaScript.

JavaScript also has problems, Douglas Crockford pointed some out in his Yahoo! videos: unless explicitly specified, variables are global, some keys in an object need to be quoted (reserved keywords), the globbing into one namespace of all the imported scripts, the weak typing, etc. But the language still remains nice.

I dislike the standard library: the JavaScript standard library really sucks. The function getMonth() of the Date object returns the month with a 0 offset instead of a 1 offset like in any other language (and like in the real world.) Strings are missing a lot of useful function such as trim() or sprintf(). The childNodes property doesn’t only return elements, but also strings of blanks. The parseInt() function tries to guess the base of the string to convert, so you always need to specify the radix to prevent possible errors with numbers starting with 0. Generally, I’ve found the standard library to be incomplete and weird.

I also dislike that because there is no module system, everything is in the same global namespace. It’d be nice if the DOM manipulation and the Date manipulation methods could be cleanly separated. Maybe in JavaScript 2…

I dislike the implementations: JavaScript has a reputation of being slow, and I think it deserves it. The interpreters in the browser are no speed horses, and they make the language look bad. Too much JavaScript makes a page very slow and no fun to use. We can hope that the Tamarin project will accelerate JavaScript to bearable speeds.

There’s also the inter-browser compatibility fun: Internet Explorer 6 and 7 use JScript which implements the version 1.5 of JavaScript, Firefox 2 implements JavaScript 1.6 and Firefox 3 implements version 1.7. It would be fun to take advantage of the cool new features of JavaScript such as generators and list comprehensions, but we can’t, because we need to think of the people who use the Microsoft browsers.

There are also slight differences between browsers that one needs to be aware (and wary) of. For example, Firefox allows you to have a trailing comma after the last element of an array literal and all will work normally; this also works in Internet Explorer, but the length of the array is one more than the number of elements ([1, 2,].length will return 3 instead of 2.) These bugs are always fun to hunt down (although I guess I should be using JSLint.)

JavaScript seems to be the opposite of many programming languages that enjoy a good implementation and library, but with a lacking language: the language is good, but the rest isn’t so much. Fortunately, I believe it’s easier to get a better library and implementation than making a new and better language, so JavaScript is on the right path.

Sometimes, imperative programming is the right choice

April 14, 2008 by gnuvince

I like functional programming, and I usually try to write my programs in any language with as few side effects as I can possibly manage without making the code impossible to read or completely unidiomatic. For many problems, I find functional solutions more elegant, and easier to come up with. But there are times when modifying a variable just seems like the cleanest and easiest thing to do.

I was writing a small Python script today, and I needed a function to give me the disk usage of a directory (yeah, I know the function is probably not as accurate as it should be, but for the task at hand, it’s Good Enough (TM).) I started out with nested generator expressions, but I quickly found out that an imperative version would be much more readable. Judge for yourself:

def dirsize(dirname):
    return sum(sum(os.path.getsize(os.path.join(t[0], filename))
               for filename in t[2]) + os.path.getsize(t[0])
               for t in os.walk(dirname))

def dirsize(dirname):
    size = 0
    for t in os.walk(dirname):
        size += os.path.getsize(t[0])
        for filename in t[2]:
            size += os.path.getsize(os.path.join(t[0], filename))
    return size

Haskell programs for the Beastie Boys fans

April 1, 2008 by gnuvince

A few weeks ago, I wrote a Python script to entertain myself and a friend on IRC. We were fond of doing the YOU GOTTA FIGHT! FOR YOUR RIGHT! TO PAAAAAAAAAAAAARTY! lines from the Beastie Boys’ song, and eventually, we started replacing “party” by anything that began with “pa”. So I wrote the script to make sure we never ran out of weird things that you must fight for.

I decided to port the script to Haskell. Here it is. Please Haskellers, let me know if it could be improved.

module Main where

import Data.Char
import Data.List (isPrefixOf)
import System.IO
import System.Random

findWords :: String -> IO [String]
findWords filename = do
    content <- readFile filename
    let allLines = lines content
    return $ filter (\word -> "pa" `isPrefixOf` (map toLower word))
                    allLines

pickAction :: [String] -> IO String
pickAction words = do
    n <- randomRIO (0, length words - 1)
    m <- randomRIO (10, 20)
    let (c:cs) = words !! n
    return $ c : (replicate m 'a' ++ cs)

main :: IO ()
main = do
    words <- findWords "/usr/share/dict/words"
    action <- pickAction words
    putStrLn "YOU GOTTA FIGHT!"
    putStrLn "FOR YOUR RIGHT!"
    putStrLn $ "TO " ++ (map toUpper action) ++ "!"

7 ways to copy “protected” photos

March 28, 2008 by gnuvince

We updated a website at work this week, and a request of a collaborator of our client was that their photos be “protected” against theft and illegal copy. To them, this meant deactivating the contextual menu to prevent people from clicking on “Save image as…”

We and argued that this would not prevent anybody from saving an image and, more importantly, that it would degrade the user experience, but our protestations fell unto deaf ears.

Here are seven ways to download the images you want, even if right click is disabled.

  • Use Opera: Opera doesn’t honour the oncontextmenu directive, so your right clicks will happily give you the menu with the “Save image as…” option
  • View source: “Use the source, Luke!” Find the image you want, it has to have a URL, paste it in the address bar, File => Save, bingo!
  • Use Firebug: This is exactly like viewing the source, but it’s easier to find the URL of the particular image you’re interested in
  • Save entire page: In the File menu of many browsers, there’s a “Save page as…” option, and you can select to save the entire page, not just the HTML. This will download all the media files used on that page, including the “protected” files!
  • wget: wget -r http://website.com. Nuff said.
  • Drag and drop: Open an image editing program, and just drag the “uncopiable” into the canvas. Optionally remove the watermark.
  • Take a screenshot: Just press on PrintScreen, paste the image in any image editing program and get the image.

University of Waterloo and introduction to programming

March 20, 2008 by gnuvince

It has been reported that the University of Waterloo dropped Java in favor of Scheme for first year students. A lot of discussion revolves around whether this is a good choice.

I would argue that introducing CS students to programming through Scheme rather than through Java has a lot of beneficial side effects.

  • REPL: The first thing that Scheme has that Java doesn’t is a REPL, a read-eval-print loop. This is a program that is available in a lot of languages, and only the C-family of languages seem to be lacking them. A REPL allows the user to input expressions and get an immediate answer. REPLs are great for exploration, testing and just toying around with the language. And because the result is instantaneous, students are more likely to try different things than they are to make modifications to a program and keep compiling and running it.
  • Small core: Scheme is unarguably a simpler language than Java. The entire R5RS standard is 55 pages (which I assume is the revision they will use, since DrScheme has no plans to move to R6RS as far as I know. I was misinformed regarding R6RS, PLT-Scheme will in fact support it. Thanks John and Jeremy. I wonder if the classes at Waterloo will use it or R5RS.) The book Java in a Nutshell is over a thousand pages long! There’s just a lot less stuff to learn in Scheme than in Java.
  • Simpler syntax: Some people argue with this claim because they get lost in a sea of parentheses and claim that Java has a more “natural” syntax. Nevertheless, in terms of simplicity, Scheme’s syntax wins. You don’t have to remember if a semi-colon goes after this particular line, you don’t have to remember that if there’s only one statement in your if/while/for/etc. you don’t need the braces, etc. A lot of anecdotal evidence suggests that students who learn Java are confused by syntax errors and that they represent the majority of the questions asked in class.
  • Dynamic typing: Without saying that static typing is harmful, I think that the constraints it imposes, while beneficial in the long run, significantly complicate a programming language. If I take Haskell as an example, there are a lot of concepts such as type variables, type classes, monads, etc. that exist solely to satisfy the compiler. In a large production program, this can help the programmer, but to the student, these will get in the way of comprehension.

    You want a tree in Scheme? Just use a list, there’s no need to define a new recursive type.

  • Functional paradigm: Although Scheme is not a strictly functional language, it supports this paradigm much better than Java. Programmers who grew up with BASIC, C, C++ and other imperative languages will tell you that functional programming is a lot harder, but I believe that it is easier for a student to reason about a functional program than about an imperative one. As they show in SICP, all you need to do is expand your function call. For instance, to understand the function map:
    (define (map f xs)
      (if (null? xs)
          nil
          (cons (f (car xs))
                (map f (cdr xs)))))
    
    (define (plus1 n)
      (+ 1 n))
    
    (map plus1 '(1 2))
    (cons 2 (map plus1 '(2)))
    (cons 2 (cons 3 (map plus1 '())))
    (cons 2 (cons 3 '()))
    (2 3)
    

    With imperative programming, you need to keep track of all the variables that get mutated in your program. This is harder.

  • The students learn: With Java, students learn to program in Java. With Scheme, students learn to program. Because the Scheme language is so simple, students can quickly be introduced to more complex topics. In Java, the static typing, the complex syntax and the lacking means of abstraction and combination hinder this fast progress (try writing a general, simple map function in Java.)

Some people voiced concerns over the practicality of showing Scheme instead of Java; those concerns are unfounded in my opinion. First of all, a person that knows programming well shouldn’t have any problems picking up Java. Once you know the fundamental concepts of programming, learning a new language is learning new syntax, idioms and libraries. That is not to mean that it is a trivial task, but the transition is easier. Next, the job of the university is not to teach the currently popular technologies, it is to teach the fundamentals of the discipline. Technologies come and go, but the core of computing changes much more slowly and is applicable to many technologies.

The new and improved {% active %} tag

March 19, 2008 by gnuvince

A few months ago, I described a Django template tag that I wrote to identify the currently active page.

At the time, I was satisfied with my solution, and I must say that it worked perfectly for all these months. The one thing I didn’t like about it though was that it wasn’t DRY. I had to specify an regular expression in the tag that would identify the current page. Those regexes were usually a copy of the ones in my urls.py file. This caused me some head scratching a couple of times when I changed a URL regex in urls.py, but forgot to change it in my _nav.html template.

Today, I took the time to remedy the situation and I am satisfied enough with the result to share it.

import re
from django.core.urlresolvers import RegexURLResolver
from project.app import urls

@register.simple_tag
def active(request, view='', pattern=''):
    '''
    Return 'active' if *pattern* matches *request.path* (the current location
    in the browser). The empty string is returned otherwise.  The pattern is
    either given by the user or taken from the URLconf.

    *request* (required): an HttpRequest object
    *view*    (optional): a view name
    *pattern* (optional): a regular expression string
    '''
    path = request.path[1:] # Strip the leading /

    if view != '':
        for urlpattern in urls.urlpatterns:
            # Skip include()s, they don't have the _callback_str attribute.
            if isinstance(urlpattern, RegexURLResolver):
                continue

            if view == urlpattern._callback_str:
                pattern = urlpattern.regex
                break

    if pattern == '':
        return ''

    if re.search(pattern, path):
        return 'active'
    else:
        return ''

active takes two arguments: a request object and either a view name or a regex. If a view string is given, the function will try to find the matching regex in the urls module. If none can be found, the empty string is returned. If a regex pattern is given, this will be used to test the current path. This parameter exists to make sure that you can use any regular expression if you so desire. Leaving both parameters blank will return the empty string.

I hope this helps you.

Trying xmonad

March 10, 2008 by gnuvince

For nearly a year now, the cool Haskell folks that procrastinate hang around on Reddit have been boasting about their new and shiny window manager, xmonad. I’ve always wanted to try it, but I always found something less productive to do instead, like playing Dr Mario.

Well, this weekend was the weekend that I gave xmonad a whirl. As far as window managers go, I’m a pretty conservative guy. When I started using Linux back in 2000, I used Window Maker for about a year. After that, I switched to Blackbox, and have been using *box wm’s since then. I went from Blackbox to Fluxbox to Openbox. Thankfully, they all behaved pretty much exactly the same, so it was easy to switch from one to the next. I’ve had the same background image for 4 years and the same Openbox theme for 3 years. If xmonad is gonna get me to switch, it’s gonna have to be pirate awesome (ninjas suck!)

Installation

The installation of xmonad is pretty easy if you have GHC and the proper extensions installed. I only needed to install the latest version of the X11 bindings. Installing xmonad is as easy as runhaskell Setup.hs configure && runhaskell Setup.hs build && runhaskell Setup.hs install. Installing the xmonad-contrib package is equally easy.

Using xmonad

I’ve never used a tiling window manager, and at first, I thought it was a little weird. The window manager says where your windows will appear and what size they’ll be. This takes some time getting used to, I’m not even sure I’m comfortable with it, but I’m trying. The tutorial on the official website was a great way to get started. I quickly got comfortable launching a bunch of urxvt windows, so I went and configured xmonad!

Configuring xmonad

Configuration of xmonad is done by modifying a Haskell script, ~/.xmonad/xmonad.hs. I started by changing some key sequences, which is very easy to do. The documentation says that after you are done, you save the file and you try to open xmonad.hs in GHCi. If you get no error, you can reload the window manager (with mod-q, more on that in a bit) and the changes will automagically appear. Now, how cool is that? A way to check your configuration file. Openbox uses an XML file, and there’s no way to know if you screwed something without trying the configuration. And if you decide not to check your configuration in GHCi and just reload xmonad, what happens? You get an xmessage window telling you there’s an error in your configuration file.

Like I said earlier, mod-q restarts xmonad with your current configuration. Now, it doesn’t restart as you would except. The screen doesn’t even flicker. The new configuration just happens. I don’t know the exact mechanism, but I can tell you that the command-line to do that is pretty long: the entire window manager state is passed as an argument to xmonad when it restarts. ps(1) will show you exactly how long.

One thing to be aware of with mod-q is that by default, it assumes that xmonad is in your PATH. If it isn’t, you will need to put the complete path in xmonad.hs.

-- Restart xmonad
, ((modMask              , xK_q     ),
      broadcastMessage ReleaseResources >> restart "/home/vince/usr/bin/xmonad" True)

Floating layer

Some applications don’t work well in a tiled window manager. For example, The Gimp, MPlayer, Pidgin, etc. are better used as floating windows. Fortunately, xmonad is prepared for those: you can float any window you want, and you can even set windows to be automatically floated in your xmonad.hs configuration. Those floating windows are always above the tiled windows, they can be moved around with mod-button1 (the mouse left button) and resized with mod-button3 (the right button.) Note that only the bottom right corner is used for resizing, so you can’t resize to the left, you will need to move your application to the left and then resize it to the right.

xmonad-contrib

Xmonad has a lot of nice third-party modules. All of them are pretty well documented and for those I tried, work as expected. Using those modules is usually just a matter of importing them in xmonad.hs and binding a key sequence to an action they export.

dzen and dmenu

Xmonad follows the general UNIX philosophy of doing one thing and doing it well. It xmonad’s case, that is laying out windows. Xmonad lets other application do tasks it shouldn’t be doing. For example, instead of having its own launcher, the default xmonad configuration has shortcuts for dmenu and gmrun. Also, instead of having its own status bar code, xmonad users can use dzen or xmobar. With the help of a plugin, DynamicLog, you can control what appears on those bars (by piping information to dzen or xmobar.)

Performance

A lot of programmers think that “if it’s not C or C++, it’s slow and memory hungry.” That is, of course, a myth, but one that seems to cling with way too many smart programmers. Xmonad is neither slow, nor memory hungry. The system loads in less than a second, and memory usage stays low. You definitely don’t need 32 GB of memory to be able to use it.

Documentation and community

Both are great! The #xmonad IRC channel on Freenode has nearly 100 users, and every time I asked for help, I got a fast, courteous and correct answer (and if you can’t get an answer, keep asking, dons will eventually wake up and answer you. dons++)

The documentation for xmonad is much longer than its code, something rarely heard of in the open source community. There’s a tutorial for users, a tutorial for developers, a tutorial for extension developers, every third-party module has documentation, the entire source code is commented, etc. It’s hard not to find what you are looking for.

Features that are missing

So far, I really like xmonad, I will try it for about a week to see if it can displace Openbox. One thing that I like to do in Openbox is to start a movie in MPlayer and set the window to be displayed on all workspaces, always on top. Xmonad doesn’t seem to have an easy way to toggle a “display on all workspaces” action, but since anyone can code a plugin, I see this as something that I should resolve. There’s also another action that I want to look into, making it possible to disable the border (the red line that indicates the current active window) on a per-window basis.

Length of Haskell and JavaScript programs

February 16, 2008 by gnuvince

I am learning two languages these days: Haskell and JavaScript. Haskell because it’s such an interesting language and JavaScript because I need to know it better than I do right now for work.

An exercise I like to do when I learn a new language is to write a cribbage point counting module. It’s not too hard to do, but it’s longer than the classical fib() and fact() functions.

In a somewhat old post (though only recently posted to reddit) Georg noticed that his CSS library was shorter in Haskell than in Python. Although my cribbage exercise is smaller, easier and more trivial than his CSS library, I noted the same thing.

The Haskell version is 133 lines, while the JavaScript version is 241 lines long. You can view the difference in the (big) image below.

I can’t point exactly why Haskell is so much shorter, but I think that pattern matching and currying have a lot to do with it. Also, I added some functions in JavaScript that are already available in Haskell and code to make usage a little less wordy (Haskell didn’t need anything like that.)

cribbage.png

Static typing ∧ Dynamic typing

February 15, 2008 by gnuvince

I would like to talk about static typing and dynamic typing. This topic has been written on and debated a lot on the Internet and I’m no Simon Peyton-Jones, Larry Wall or Alan Kay, so these opinions are probably nothing new. I am not bringing anything new to the debate, except perhaps bad metaphors. The reason I am writing this post is that I can’t seem to figure out what I think about typing, and I want to write it down to hopefully untangle my own thoughts.

I’m also more interested in the reliability vs flexibility aspect of the debate, so I will not be discussing the issue of speed.

Definitions

To make sure we all understand each other, I’ll start by defining some terms.

Static typing: A typing system where the values and the variables have types. A number variable cannot hold anything other than a number. Types are determined and enforced at compile-time, or declaration-time.

Dynamic typing: A typing system where the values have types, but not the variables. It is thus possible to successively put a number then a string inside the same variable. Types are determined and checked at run-time.

Weak typing: weak typing is often used to mean dynamic typing, however they are two different things. Weak typing refers to how typing is done. Examples of weakly typed languages include JavaScript, Perl and PHP (which, incidentally, are also all dynamically typed languages.) A weakly typed language will do type conversions in the background if the programmer hasn’t done them explicitly. For example, in Perl, 3 + "4" returns 7. The + operation is specifically defined to operate on numbers, but since "4" is a string, Perl implicitly converts it to a number before performing the addition.

Strong typing: strong typing is the opposite of weak typing. This family includes Lisp dialects, Python, Haskell, etc. A strong typing system will not try to implicitly convert values for us. With those languages, the previous example would fail. We would need to explicitly convert "4" to a number.

Type inference: A technique by which the compiler determines the type of a variable or function without help from the programmer. For example, the compiler can deduce that the variable s in s = "Hello" will have the type string, because "hello" is a string.

OK, with definitions out of the way, let’s see what’s on my mind…

Static typing is great…

We live in an era where the influence of computers has never been greater: we work from home, we buy products from Internet stores, we pay our bills online, the billing systems of every company is computerized, the global market is just a bunch of bits, etc. In a time where so much of our society’s infrastructure is dependent on computer software, it is essential that those programs be reliable (something that doesn’t happen often enough, unfortunately.)

One of the many things that can help us make sure that our programs are safe and sound is static typing. Or at least, that’s what the static typing advocates would have us believe. With such a system, all the interactions between the different functions and variables are checked during the compilation phase and any mistake is treated as a fatal error, and the compilation stops. With static typing, it is impossible to build a program that would try to apply the length function to a number. With a dynamically typed program, the compiler wouldn’t check for that possibility, and the error would happen at run-time.

That sure makes static typing sound like a sweet deal! After all, humans program computers, and we’re not known for our infallibility. In fact, we’re quite the opposite: anything can disrupt our concentration and this can lead to the introduction of bugs in our software.

Surely, it is nice to know that the compiler is there to point out our mistakes when we’re not fully focused. Static typing also helps us make modifications to existing code: if it doesn’t compile, we know there is a problem with our modification. It also helps us use the code of other programmers, because there is a protocol on how functions should be used.

In the Haskell and ML communities, there is a saying: “if it compiles, it works.” This is not a fact, of course, static typing cannot help us with everything that could go wrong in our program, but it shows how dependant these programmers are on the type checker to find common mistakes (and even not so common mistakes.)

… but so constraining!

This safety comes at a price however: some tasks become a lot harder with a statically typed language and a few are practically impossible. For instance, in Haskell the functions fst and snd respectively return the first and second element of a two-elements tuple. They do not work on tuples of any other size. It is not possible to write a generic version of those functions.

Static typing also impairs code generated at run-time. A lot of dynamically typed languages have a function called eval that can evaluate arbitrary code at run-time. Although the use of eval is generally discouraged, it can be used to generate code that simplifies the programmer’s task. One of the best known example is Ruby on Rails, which creates methods with the names of the columns of a table in a database for a model. This sort of code generation is much harder in statically typed languages, because the code is generated after the compilation phase, and therefore, it cannot be type checked without being ran.

Dynamic languages such as Smalltalk, Lisp and Erlang also allow hot code swapping: we can load new code while the application is running and the new code will immediately be used. I have yet to see this in a statically typed language.

Another problem of static typing is that it introduces an extra layer of complexity in the language; the static languages all have their own set of extra features (templates, generics, type classes, etc.) to make sure that the compiler is satisfied that what we are writing is sound.

def my_len(L):
    x = 0
    for e in L:
        x += 1
    return x

The previous Python function (naïvely) returns the length of a list. The list can contain elements of any types. (Actually, this isn’t true; it doesn’t work only on lists, it returns the length of any iterable object.) To write the same function in C++, we would need to use templates to convince the compiler that the function is type safe.

Dynamic typing is like flying!

At the other end of the spectrum, we have dynamic typing. Dynamic typing is also perfect for the kind of world we live in: face-paced and ever changing. Clients want their software really quickly, they want their software to be extremely flexible and they will change their minds about what it is they want three times in the first month. And programmers are expected to deliver, we do not have the luxury of bridge engineers to say “it cannot be done.” Dynamic languages are extremely flexible in what they allow the programmers to accomplish.

Generally speaking, dynamically typed languages are much more permissive than statically typed languages; in a sense, they seem closer to how “real life” works. If I’m packing a bag for a trip, I can put anything I please into it. The bag will not spit out my iPod because there are clothes in it and it can only hold one type of objects. (I told you the metaphors would be bad.) This is how lists (or arrays) work in dynamically typed languages: we can put anything we want into them, the language doesn’t mind one bit.

This flexibility is really helpful when we want to quickly develop a prototype, when we want to test something, or when we’re not even sure of how something is going to work. For example, instead of using a proper tree data structure and creating all the functions to support that tree, we could simply use a regular list — which can contain scalar values (leaves) and other lists (branches) — to explore if a tree seems like an appropriate structure for the problem at hand.

As I mentioned earlier, dynamically typed languages also offer features that are much harder to implement in statically typed languages.

Hot code swapping is an extremely powerful feature that I’ve seen only in dynamic languages. Being able to load new code without shutting down an application is a really important feature to have if we want programs that can run for months, even years without interruption. The most common example are the Ericsson switches written in Erlang which have nine nines of reliability (99.9999999%), but the benefits are also visible in applications like Emacs where a user using elisp can add significant functionality to the program without having to restart it.

I also briefly mentioned that dynamically typed languages are the kings of code generated at run-time. This feature has been used to fix existing methods, add methods to existing classes, generate classes and methods at runtime, using the programming language as the configuration language, etc. We can use this to “fix” parts of the language, improve parts of the language and grow the language.

Dynamically typed languages are also often simpler than static languages. The rules of Forth or Lisp can be learnt in a couple of hours; I know a lot of programmers who learned Python in an afternoon. I don’t believe anyone can claim that the rules of C++ can be explained this quickly (much less mastered.)

But without a parachute!

This flexibility and simplicity is achieved by assuming that the programmer knows what he’s doing. But we agreed that humans are fallible, so how do the programmers working with Python and JavaScript manage to create solid software? With a whole lot of testing. By writing automated unit tests, the programmers make sure that all the functions of their program behave as they expect them with valid and invalid input. Any time they change something in the program, they re-run the tests to make sure that they didn’t break anything.

Dynamic typing advocates claim that type errors are actually pretty rare and that unit testing makes static typing unnecessary. While it is true that tests go a long way toward making software reliable, they are not a proof, they are a demonstration that the code behaves properly for the subset of inputs that they test. Also, because tests are written by the same fallible humans, they could possibly be wrong.

The myth of short code

A common misconception among some programmers is that the reason why people like dynamic typing is because it makes the code shorter. We don’t need to type those pesky type descriptions everywhere, so the resulting code is obviously shorter.

The existence of type inference nullifies this point. With good type inference, a programmer can enjoy the benefits of static typing with the terseness of dynamic typing.

This does not mean that type inference closes the debate and that we should all use static typing. As I described earlier, they are other more fundamental differences between the two typing systems. Furthermore, I believe that powerful abstraction mechanisms are the more likely culprits for short code. Ruby (dynamic) and Haskell (static) both usually require less code to write the same things as in Java (static) or PHP (dynamic). I firmly believe that the reason is that Ruby and Haskell support more advanced abstractions (like lexical closures ;)).

Optional typing

In a typical “we want our cake and it eat too” fashion, programmers have asked about static typing and dynamic typing “can’t we have both?” Some languages already support the mixing of both types. In Common Lisp, a dynamic language, it is possible to declare the type of variables. The next versions of Perl and JavaScript, both dynamically typed, will have optional static typing. It was announced recently that C# 4.0 would have a dynamic keyword to allow optional dynamic typing.

The obvious question then is: “how should optional typing be done?” Should we add static typing to dynamic languages or vice versa? I thought about this, and I think that the former is preferable; create a language that is flexible and can be used to explore a problem space and its solutions, and when the prototyping is over, make it easy to add type annotations to get the safety of static typing.

Conclusion

I stated in the beginning of this post that I wanted to try and untangle the different opinions I had on type systems, and I believe this post was successful in that respect.

I had a very easy time talking about the importance of reliable software, I cannot imagine not caring that a program I build is robust. I also had an easy time talking about the importance of flexibility in the current market.

This leads me to believe that both approaches are valid and can be used to make solid software, but that languages which will be able to mix both techniques and give to the developers the advantages of both systems are obviously going to become very popular in the near future, and I can already feel that I’m going to like them.

Finally, I would like to thank Jeremy Fincher and Steven Pigeon for proof reading this post.

Users have always have stupid questions.

February 8, 2008 by gnuvince

On two occasions I have been asked, – “Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?” In one case a member of the Upper, and in the other a member of the Lower, House put this question. I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question

This is a quote by Charles Babbage who invented a calculating machine in the 1800’s.