Genii Weblog


Civility in critiquing the ideas of others is no vice. Rudeness in defending your own ideas is no virtue.


Tue 4 Jan 2005, 11:08 AM
It is fun to skip around to people's websites and see if they have adjusted their copyright dates to 2005 yet.  (OK, I have an odd sense of fun, so sue me)  Here are a few, very randomly selected.

Big Computer Companies

Still says 2004
Still says 2004
YES
YES
Still says 2004
YES


Other Big Companies

YES
Still says 2004
YES


Media

Still says 2004
YES
YES
YES
Still says 2004


Smaller Computer Companies

YES
YES
Still says 2004
Still says 2002.  Yup, you read that right, 2002.
YES


Blogs

Ed has a generalized comment "Entries are copyright (c) Ed Brill, as of date of posting", so he escapes unscathed
Joe also just skipped the date entirely, although he doesn't even mention the date of posting language.
Still says 2004, but his company page for Sapphire Oak Technologies is at 2005.
Still says 2004
I can't find any copyright anywhere, but look at his company page at The Cayuga Group, LLC which is still at 2002.
Still says 2004

Now, wasn't that even more fun than you expected?  Of course, any may have changed by the time you look, but this is what they were as of January 4 at about noon EDT.  Don't forget, you read it first here.

Copyright © 2005 Genii Software Ltd.

Tue 4 Jan 2005, 04:03 AM
There was one trick I learned when writing my Limits to Cleverness post that I thought might be worth expanding on.  In that post, I had a very long formula which essentially said

sorted := @Sort(Speaker; [CustomSort]; @If(@Do(first_stuff) > @Do(second_stuff); @True@False));

Now, leaving aside the specific intent, take a look at just the condition used in the @If

@Do(first_stuff) > @Do(second_stuff)

I have used @Do before on occasion, as it has been part of formula language for a long time, but I never thought about the fact that, like almost everything else in formula language, it evaluates to a value.  I have always just used it to group multiple statements.  But it does return a value.  To quote the Designer Help for @Do
Evaluates expressions from left to right, and returns the value of the last expression in the list.
But even in the Designer Help, they seem to forget this.  The examples they give don't use the returned value, and the separate example in the "Order of evaluation for formula language" which describes @Do shows this:

@Do function
@Do executes a number of statements in sequence and can be used as an execution path within an @If function:
@If(LogicalValue; @Do(TrueStatement1; TrueStatement2); FalseStatement)
which misses the fact that it could equally well be 

@If(@Do(Statement1; Statement2; LogicalValue); TrueStatement; FalseStatement)

or, as I used it before

@If(@Do(Statement1; LogicalValue1) > @Do(Statement2; LogicalValue2); TrueStatement; FalseStatement)

which might sometimes be more compelling, but never seems to be suggested in the Help documentation.

Using temporary values inside @Do
There are many reasons to use @Do for its return value, but the most useful I have encountered since discovering this are the ability to setup temporary values and then use them, and the ability to convert the single expression in newer functions such as @Transform, @Sort and @For.  For those of you who only want to learn ND6 tricks, this latter use will be particularly interesting.

Let's take a very simple example, even though by virtue of its simplicity it is not a good use of the technique.  Let's assume you wanted to do an @DbLookup that returned a number list, and returned the sum of the numbers:

sum := @Sum(@DbLookup(""; ""; "PartsLookup"; part; 2));

Any good developer might cringe at this construction, because it doesn't handle errors.  A traditional way to handle this might be:

ret := @DbLookup(""; ""; "PartsLookup"; part; 2);
sum := @If(@IsError(ret); 0; @Sum(ret));

but another option is: 

sum := @Sum(@Do(ret := @DbLookup(""; ""; "PartsLookup"; part; 2); @If(@IsError(ret); 0; ret));

It isn't obviously better in any way, although it is interesting.  You would be better off with the first construction.  So, let's take a somewhat more complex, but better, example of an @For loop that checks each of the items in a list until it finds one that isn't in a lookup view or that has an obsolete product number (starts with "x").

pArray := "Rosebud Sled":"Holy Grail":"Tickle Me Elmo";
L := 1;
U := @Elements(pArray);

@For(i:=L;  i<=U & @Do(pNum := @DbLookup(""; ""; "(PartNums)"; pArray[i]; 2); @If(@IsError(pNum); @False@Begins(pNum; "x"; @False@True));  i += 1;
           @StatusBar(partsArray[i] & " exists!"));

Now, this would be a lot harder without @Do.  You could repeat the @DbLookup twice, once to check for an error, and the second time to check for the leading "x", but it is a lot simpler and more efficient to set the value once and check for an error and then check the value.  You could move all of this lookup and termination logic into the loop, but it would make the logic more verbose and awkward, since the termination condition is meant to be where it is.
Phew!  This post is probably long enough for now.  I'll tackle using @Do in other functions more in another post.

Copyright © 2005 Genii Software Ltd.