Type Checking and Syntax Verification
There are three important features that may turn off developers coming to moto from other embedded scripting languages. The necessity of these features is well understood to experienced C or Java developers but is often misunderstood or considered a hassle to many who come from the world of embedded scripting commonplace in web development. The features are as follows
- Moto requires users to declare variables before they use them.
- Moto requires users to specify the types of variables and (usually) explicitly cast variables from one type to another.
- Moto does extensive syntactic and semantic checking of files before it interprets or compiles them.
Granted these sound more like hassles than features but as a developer for many years in other web scripting languages, let me give my perspective as to why they are so important:
1) Moto requires users to declare variables before they use them.
I spent over a year coding on a large commercial, Coldfusion based system. Coldfusion allows you to write code like the following pseudo code :
if(var is true)|
That might be fine except for what happens when var isn't true. In that case the above code will fail with an error because foo was never defined to be anything. One might think that this would be an obvious error to test for but consider the following
else if(var == 2)
else if(var ==3)
This code might work 99 out of 100 times but then on that 100th run var is set to yellow ... uh oh that's a crasher. Now of course the above code could be fixed by adding some default value for the variable mood, perhaps with a final else. But this denies a very fundamental principal about programmers and scripters alike. We are LAZY and we will not do something if we don't have to. By forcing us to to declare the variable 'mood' before using it, moto saves countless hours of bugfixing down the road (when var equals yellow). Moreover moto tells us right away that this might be a problem and that we need to fix it:
ex1.moto:4: Variable 'mood' not declared before used|
ex1.moto:6: Variable 'mood' not declared before used
ex1.moto:8: Variable 'mood' not declared before used
ex1.moto:9: Variable 'mood' not declared before used
2) Moto requires users to specify the types of variables and (usually) explicitly cast variables from one type to another.
The same sort of example applies here. Consider a language where 'everthing is a string' until used otherwise. Coldfusion is like this. I might write a program like the following (notice the typo in the last else if, that's not a zero)
else if(var == "2")
else if(var =="3")
else if(var =="4")
print mood + 1
Now lets suppose the case when var equals 4 occurs very rarely ... one out of every 50 times ... but on that 50th time I try adding an int to something that's not an int. Boom! The behavior is undefined. Maybe I'll get an error. Maybe the int will be implicitly cast to a string and I'll get 100O1. It depends on the language but it's almost never what you want. But again, unless every case is getting tested this bug is going to get by.
Think this example was a stretch ? What about when var equals 5 ? What happens then ? Something is bound to go wrong with the above code. It's just a matter of when.
A related issue that is just as common when 'including' a large number of files into the same page is the use of a variable with the same name to store different types!
if (default not defined)
if(default not define)
And once again we have a runtime error!
In moto you have to declare the type of a variable before you use it. If default is an int you need to say:
You also need to be explicit about your operations. If you want to convert from a string to an int you need to say
in moto you can say
and you'll get 101
or you can say
and you'll get 11
but if you say
ex2.moto:1: Illegal binary operation: <String> + <int>
3) Moto does extensive syntactic and semantic checking of files before it interprets or compiles them.
The reasoning presented so far really boils down to the following:
"Not forcing programmers to declare variables and their types before using them, or implicitly casting variables from one type to another, lets programmers make really common errors that are really hard to test for and only show up at runtime"
There is an important corollary to this:
"Runtime errors are bad."
Why are runtime errors bad ? Well, apart from being hardest type of error to test for, runtime errors are bad because you only get them one at a time! Consider the following piece of really bad code:
c= 18 + "c";
In some languages (names have been left out to protect the guilty) the programmer would type this, hit the page with his browser and get
error on line 1: b is undefined
The programmer then goes and changes his program so it says
c= 18 + "c";
hits reload on the browser and gets
error on line 3 : cant add an int to a string
The programmer changes it again to
c= 18 + "3";
hits reload again and gets
error on line 4 : can't get length() for an int
That's three reloads because each time the programmer changed things there was oonly one error returned at a time. Try the same program in moto and you get:
ex3.moto:1: Variable 'b' not declared before used|
ex3.moto:1: Illegal binary operation: <Object> + <String>
ex3.moto:1: Variable 'a' not declared before used
ex3.moto:2: Illegal binary operation: <int> + <String>
ex3.moto:2: Variable 'c' not declared before used
ex3.moto:3: Variable 'c' not declared before used
ex3.moto:3: No such method: Object::length()
All the errors all at once. In fact, using the moto command line tools you can find all the syntax and type casting errors in every page of an application all at once:
The dirty little secret is that these little extra hurdles actually make
1) Programmers more productive because they see more errors at one time!
2) Code less error prone because two of the most common errors programmers make can't happen!
Copyright © 2000 - 2003 David Hakim