Article
· Feb 2 4m read

Coding practices - to brace or not to brace

Introduction

This article attempt to summarize and update on the exchanges in this post. Please feel free to comment.

ObjectScript is based on MUMPS, a programming language dating back to 1966. At the time, and for quite a long period, memory and cpu resources were scarce, as was terminal screen space, and a very concise (and easily decodable) syntax was preferred (as, for example in C). Nowadays,  we no longer have the same memory and screen limitations,  and code readability and maintainability is far more important.

While ObjectScript is still compatible with all the old compacted syntaxes coming from mumps, it also support much more readable, "human friendly" syntaxes summarized in this article.

p.s. : this of course does not apply to, nor deprive the fun from, code sports like "golf" and other exercises in style, free as they are from mundane concerns such as readability.
 

Block syntax

A block statement, or compound statement, it let you group any number of statements (including 0) into one statement.

ObjectScript currently supports two syntaxes for blocks :

  • Curly brace block syntax
  • Dot block syntax 

Curly brace block syntax

It is similar to that in C, Java, C#, … making the following short example look very familiar to most programmers :

if a=0 {
   write "foo",!
   write "bar",!
}

Dot block syntax 

This is the original MUMPS block syntax. It is supported for backward compatibility with (very) old code. Its use is strongly discouraged, as it can get quite confusing, especially when combined with the short version of commands and the lack of reserved words, as in the following (intentionally a little mischievous) example : 

j=1:1:d dr i
 . i '$test b
 . i i'="" d
 .. s d=$p(l," ",1) 41)
 .. s w=$p(l," ",2)
 .. w d,?10,$e(^title(d),1,80),!

Post-conditionnals

This is an implementation in ObjectScript of the concept of guarded command, as defined by Dijkstra (1975).

It is a conditionally executed statement, where a boolean expression "guards" the execution of the statement. 

<command>:<condition> <command arguments>

 It is functionnally equilavent to

if <condition> <command> <command arguments>

Although the concept is well defined, the syntax is not common, so when should it be used instead of an if statement ?

  • execution flow control : quit, continue, throw
  • default value assignment  : set

some examples :

quit on error,  continue on condition

quit:$$$ISERR(sc)
#Dim a as %Integer
while a > 0 {
…
continue:a=5
…
}

throw on condition

#Dim obj as %RegisteredObject
throw:'$isobject(obj) ##class(%Exception.General).%New("object not found")
 

Assign default value

#Dim obj as Foo
…
set:'$isobject(obj) obj = ##class(Foo).%New()
…

Use return instead of quit for return values

In new code, use return instead of quit, as quit can be used both for exiting current execution context and return a value.

'quit' has two different meanings :

  • when use with no argument, it exits current execution context (e.g. loop)
  • when use with an argument, it exits current routine/method and returns value

'return' is an addition to objectscript meant to improve code readability, as it implements only the second meaning.

Command arguments

The use of a  comma-separated list list of command arguments should be avoided, as for some command, it gets confusing.

For example,

if a=0,b=1 {
...
}

 

Is much less readable (to the 'modern' reader) than

if (a=0)&&(b=1) {
...
}

Ternary operator - expressional 'if' 

The $select function can be used as ternary if operator :

$select(<boolean expression>:<true value>,1:<false value>)

 Switch/case 

Either

  • $case() when switch intent is to select a value
  • If elseif elseif … when switch intent is to select behaviour/ log

Command keywords

Command keywords are not case-sensitive and most commands come in two variants, fully named and shorthand.

  • Favor the use of full command keywords, except for the most common ones like 'set' and 'do'
  • Use all lowercase for command keywords
  • Avoid using legacy goto <label> command for flow control

Function names

As commands, function names are not case-sensitive and most functions come in two variants, fully named and shorthand.

  • Favor the use of full function names instead of shorthand, e.g. use $extract() instead of $e
  • Use all lowercase for intrinsic function names
Discussion (4)6
Log in or sign up to continue

Very useful.

I tend to avoid post conditionals nowadays as I long ago realised, as with your other examples, readability was far more important.

Only one I do not personally do is the Command Arguments example, I'm old and set in my ways and like using the comma 😁

Another possible mention might be "goto".

Oh, and your note on functions not being case-sensitive is only for system (intrinsic) functions.

I think the message overall is we no longer have the same memory and screen limitations and so spaced out, readable, and maintainable code is far more important than the old compacted method of writing mumps/objectscript. 

Nice write up, I agree to most of your comments.

Nowadays I personally try to avoid $Select() and $Case() because I realized that it's often difficult to read, particularly for new comers.

I fully agree on using full command keywords, in my case including for most common ones although I admit that sometime I almost automatically type a single letter Quit with postcondition to exit a loop (Q:key="")! 😁

As for "Use all lowercase for command keywords"..well, this is really a matter of taste, I like commands with capital first letter, I find it increase readability, but, again, it a subjective opinion.
One thing for sure, whatever you choose, stick with it! Be consistent.
In fact when I happen to modify existing code, I try to adapt new code to the existing style (if any 😱 ).

About using full function names for intrinsic functions....well, I agree but meanwhile I have to admit I'm not THAT consistent, I sometime use abbreviated/single letter for some functions like $d, $zdth, $i. Maybe I need to improve on this. 😊

I have mixed feelings about the (relatively) new Return command.
While I understand the usefulness in some circumstances (i.e. error processing) I really (really, really) don't like its usage "in the middle of code".
To me good code should have one, and only one, "exit point" at the end, I consider trowing Return commands here and there in the middle of code (like a method) the same of using a Goto.
That's why I still don't use it that much even now, last line is the only exit point and I use Quit, changing it to Return makes very little difference.