Tuesday, November 27, 2007

Maintaining Strong Typing in LotusScript

Update 28.11.07: Tim Tripcony wrote a somewhat related article about using ByVal for input parameters. Recommended read!


Upon reading "Code Complete", I discovered that a way of using Subs I've previously thought of as bad practice, actually is quite normal.

The author writes (I apologize if I interpreted this wrong) that some developers think that functions should be used for mathematical calculations/simple operations and procedures used for more advanced stuff. In LotusScript, from his description, a Sub is a procedure and a Function is a function (duh..).

He also suggest that when you make procedures, you put input parameters (read) first , and output-parameters (modify) second, to make it easier to read the code.

One of the advantages with using subs this way is that you can always maintain strong typing. This enables you to capture coding-errors at compile-time, instead of at runtime.

In the code below:
createToyotas is a sub that has an outputparameter, List As Toyota
toyotas is a function that returns a variant containing List As Toyota

The compiler recognizes that a "Toyota" doesn't have a method "destroyWorld", whereas the variant, also a Toyota, passes through compiling.

Error caught at compile-time with strong typing, whereas the variant doesn't cause an error until runtime.

In most cases you could probably pinpoint the runtime-error quite fast, but catching it at compile-time is preferrable for me at least.

Also, the most common error would probably be a spelling-mistake, not trying to run a random thought-up method.

Performance-wise, there may also be advantages, especially if you're using inheritance/creating many objects/etc.

When debugging there doesn't seem to be much advantage using strong typing over variants.

>> Extremely simple db with some (messy)test-code (test-agent, StrongTypingAdvantage)

If you can think of other advantages, or disadvantages for that matter, please post a comment!


tbahn said...

IMHO, functions should be used for routines which only return one value without side-effects.

One could argue that a list (or arrays) of values isn't "one value".

You could probably use a self-defined data type (not tested), but you can always use a "container" class.

But I would use a sub, too. :-)

NotesSensei said...

I think compiler wise there is not much difference between a function and a sub in LotusScript.
While I 100% subscribe to strong typing you could actually argue subs are BAD. Always have a function that returns a status code. So you would know if the parameter manipulation has succeeded. Also returning custom objects from functions allows for strong typing too.
:-) stw

Tommy Valand said...

I can't say that I can see the advantage in having statuscodes for all kinds of procedures (e.g. getters/setters).

For critical procedures, I'd throw an exception (Error in LS) and halt the entire routine if something went wrong, rather than just returning a status-code.

When using status codes, do you use constants to increase readability of the code?

tbahn said...

I prefer throwing errors, too. IMHO returning status codes is "cluttering" the code. You have to actively react on the error status (don't ever forget :-)), whereas errors can "bubble" up until they are handled.

Naibaf said...

I'm with Stephan. I hardly use subs at all, except for where there's no other way (like sub new). I do use error trapping of course, but still I almost always find something more or less useful to return (often just a Boolean).

Most important, I don't see it as a valid argument, that a function should never have side effects. Proper naming conventions do much more to keep your code maintainable.