Bob Balaban's Blog

     
    alt

    Bob Balaban

     

    And just when you thought you had division down....

    Bob Balaban  March 3 2008 01:45:58 PM
    Greetings, Geeks!

    Everyone who knows me knows that I'm a big fan of LotusScript (it's not dead yet!). I've been writing code using the language for about 15 years now, and I was pretty sure that I'd explored most of the sometimes strange nooks and crannies of its functionality (with the possible exception of "Like", which I have yet to find a real use for....but that's another article).

    Until this morning, that is, when I tripped over a subtle issue with, of all things, arithmetic division.

    I won't go into all the details of my app, they're not relevant. Let's just say I wanted to know the maximum number of 2s in some number, call it N. If N did not have an even number of 2s in it (i.e., if N is not a multiple of 2), then I wanted the nearest possible integer result -- that is, I wanted to do a division and have the result truncated if there was a fractional value.

    So, for example, if N is 6, the result should be 3. If N is 7, the result should be 3, if N is 8, the result should be 4. Simple, right?? You just divide N by 2 (you know both are integers when you start), and assign the result to another integer variable, which should force it to truncate any remainder. Here's the basic code:

      Dim two as Integer, N as Integer, result as Integer
      two = 2
      '....obtain N from somewhere
      result = N / two

    Easy, right? Simple, right? WRONGWRONGWRONG!!

    Rather surprisingly, I noticed I was getting the wrong answer sometimes! When N was 4, "result" was 2 (well, it better be!). But when N was 5, "result" was 3!

    So I muttered to myself, "Self! someone or something evil is rounding on me! But the variables are all integers! What gives?" I went to the Designer Help, which contains surprisingly good and thorough documentation on the LotusScript language. I noticed that "division" is defined as always returning a floating point number!! And, unlike in C and other languages, when LotusScript converts a float to an integer, it automatically  ROUNDS the number (C and C++ truncate).

    As an interesting (to me, anyway) aside, this has always been confusing for people, there's nothing in many (or even most) programming languages that makes it obvious whether float-to-int assignment will either truncate or round. Perhaps that's why in Pascal if you code a direct assignment, the compiler will complain. You have to specify either the Trunc() or Round() function explicitly in that case.

    All very interesting, but I needed a way to force the assignment in LS to give me a truncated integer result. So I thought to myself, "Self! There must be another operator for integer division!" I know I'd never heard of trunc/round functions in LS before, and I sure didn't want to write them. I hadn't ever heard of there being 2 division operators before either, but given the observed behavior of "/" (the floating point division operator), I assumed there would be another one for integer division. I knew about the Cint() function, which converts any data type to integer, but I already knew that that would also round a floating point value.

    Back to Designer Help. Found it! It's the backslash: "\". Thank goodness "\" isn't used as an escape character in LotusScript, as it is in C/C++!

    I replaced "/" with "\" in my code, and all was well. Go figure!

    (Need expert application development architecture/coding help? Contact me at: bbalaban, gmail.com)
    Follow me on Twitter @LooseleafLLC
    This article ┬ęCopyright 2009 by Looseleaf Software LLC, all rights reserved. You may link to this page, but may not copy without prior approval.
    Comments

    1Tim Tripcony  3/3/2008 3:25:14 PM  Fix

    Just a suggestion: for this type of operation, I'd use Fix:

    Let result = Fix(N / two)

    The expression temporarily evaluates to a Double, and Fix chops off the fraction and returns only the Integer... no rounding.

    2Michael Gollmick  3/3/2008 3:44:16 PM  And just when you thought you had division down....

    Very cool tipp! I did not knew that too and immediately thought about using something like

    result = ( N -( N Mod two ) ) / two

    as you probably did too. But having an operator to 'fix' that behavior is much better - and is also around 30% faster than using the Mod operator version.

    3Brian Miller  3/4/2008 8:05:10 AM  And just when you thought you had division down....

    Ick! Double ick! From a syntactical standpoint, using the "\" for something besides a meta-escape is pretty horrible.

    One complaint I have about LS as a language is that it's poorly planned. There are a lot of great things that *could* be added to it, but there's no room in the language because all the appropriate characters or constructs are taken up by something else that it shouldn't be.

    Want to incorporate array literals into LS? Well, the common JS-style using square brackets - [a,b] - is unavailable. Why? Because square brackets are reserved by some product-object nonsense that only actually works in smartsuite anyway.

    Want to use JSON-style hash literals? Well, you can't use curly braces. They're reserved for string literals, even though both pipes and quotes serve the same function, albeit a little differently.

    It's not hopeless, but it's pretty wretched.

    4Bob Balaban  3/5/2008 7:34:57 AM  And just when you thought you had division down....

    @1 - Thanks for that, Tim! Yet another intrinsic I didn't know about...

    @2 - I probably would not have done it quite that way, but your point is right on

    @3 - I agree with your aesthetic conclusion, Brian, but no use blaming LotusScript. There are lots of funky constructs like that in the language, and virtually all of them were put in for Visual Basic (or even ancient BASIC) compatibility. I mean, really, the Date format alone (a double where the integer portion is the number of days since the reference date, and the fraction is the ratio of the number of elapsed seconds since midnight to the number of seconds in 24 hours) is enough to generate "What were they thinking??!!" type thoughts...

    5Brian Miller  3/6/2008 3:22:54 PM  And just when you thought you had division down....

    @4 - Funny you should mention that one, Bob, as I rather like that particular quirk. It actually makes date math a bit easier for me, if you can believe it.

    The point that I've been trying to drive home is that while the original idea might have been to mimic VBA, LS has clearly matured far beyond its original vision in usage, while VBA itself has withered significantly. Now that people are starting to create and explore new(er) and interesting languages, it's high time that IBM start adding some modernity to the current abilities of LS. There's no need to retain the syntax exactly, as the benefit of doing so has long passed. If anything is to be imitated now, it should be VB.NET. It's not a perfect language either, but it includes much of the "good stuff" that we would want, that isn't there today.

    Oh, and the "Like" operator can be quite useful. But, not nearly as useful as it would be if it had a full regex implementation built in. But, that's an old gripe not worth reliving for too long.

    6Andrea Baglioni  3/11/2008 6:27:37 AM  Duplicated subform in the same form

    Hi everybody,

    i wanna say what do you thing abuot the beaviour of Lotus Domino 8 if you include a subform more than one time in the same form: Lotus Domino 8 give an error, the previous releases allows it!

    Thanks al lot

    Andrea

    7Bob Balaban  3/31/2008 7:14:34 AM  And just when you thought you had division down....

    @5 - I understand your point, Brian, and there are lots of new features I'd like to see in LotusScript as well, but given the demands and overall product enhancement priorities IBM/Lotus have for Notes/Domino. I think it's safe to say that LS is just not very high on the priority list.

    You say, "There's no need to retain the syntax exactly..."

    If you mean there's no longer any need to exactly copy features from BASIC, then I agree. But it is also very true that, once implemented, it is very dangerous (and undesirable) to change the syntax or functional behavior, of any feature in the language. There is simply too much existing code that would break.

    One area I'd love to see improved in 8.5 Notes is the integration between "Front-end" LotusScript and Eclipse/Expeditor plugins.

    8Erik Brooks  4/8/2008 10:02:20 AM  And just when you thought you had division down....

    As part of this discussion, everybody should also check out the Int() function in LS -- not to be confused with Cint().