New CAST instruction for Spin2

It's been bugging me for a long time that there's no way in Spin to do a deterministic one-of-n branch.

The CASE instruction serially tests cases and then jumps to a code block when a match is found, but that's slow for many cases.

When you know you want to run a particular block of code based on an index value, it would be nice to have something akin to a jump table, but in a structured format.

I made a new instruction called CAST, which is kind of like CASE, but takes an index value and uses it to look up an offset word to select the routine to run. This means only one decision has to be made, instead of a bunch of serial decisions.

What syntax looks best?
  cast x
    : block_0
    : block_1
    : block_2
    : block_3
    : block_4
    : block_5
    : block_6
    > block_other

  cast x
    0: block_0
    1: block_1
    2: block_2
    3: block_3
    4: block_4
    5: block_5
    6: block_6
    >: block_other

  cast x
      : block_0
      : block_1
    2 : block_2
      : block_3
    4 : block_4
      : block_5
    6 : block_6
    > : block_other

  cast x
      : block_0
      : block_1
    2 : block_2
      : block_3
    4 : block_4
      : block_5
    6 : block_6
    OTHER : block_other

The compiler tallies up the cases and produces an internal FLE (force less-than-or-equal) value to make sure the branching is bounded.

The OTHER case, which is optional, could be expressed with OTHER or maybe ">". And the values can be implied sequentially, so they are not requisite. Might it be good to allow expected values (0,1,2...), but not require them?

The 2nd example which lists every value is easiest to read, but a pain to rearrange. The 1st example can be rearranged, but the case numbers are not immediately apparent. The 3rd and 4th examples show the optional numbering with different OTHER approaches.

Which is best, if any?
«134567

Comments

  • I like the second example. If the blocks are long, it makes it very clear where you are.
    Also you could skip some numbers if you don't want anything to happen for them.
    The ">" selector looks a bit odd, but I guess you have to use something.

    Bean
  • Bean wrote: »
    I like the second example. If the blocks are long, it makes it very clear where you are.
    Also you could skip some numbers if you don't want anything to happen for them.
    The ">" selector looks a bit odd, but I guess you have to use something.

    Bean

    ">" is supposed to mean "out-of-bounds" or "greater-than".

    This is internally a jump table, so there are no dead spots, as each entry needs an address. I suppose I could have empty blocks vector right to the last terminator.
  • yetiyeti Posts: 587
    edited 2019-05-21 - 12:25:46
    The numbered list style looks good.
    Optionally being able to leave out some numbers may be ok, but totally unnumbered may be confusing for long lists.

    I remember having counted long "on var goto ..." lists far too often in that 80ers era of MSBASIC and friends...

    For the compiler listing the indices in the source is redundant but it may help spotting a forgotten "case" for the human and the compiler.
    ◁ propeller-wiki ▷ ◁ FastSpin ▷ ◁ Help Spin at RosettaCode.org ▷ ◁ No Source – No Go! ▷ ◁ DK-E ▷ ◁ :-D ▷ ◁ Stay OmmmmmmPtimistic! ▷ ◁ Why Asimov's Laws of Robotics Don't Work ▷ ◁ DNA is a four letter word. ▷ ◁ Stop slavery! Free all mitochondria! ▷
  • VonSzarvasVonSzarvas Posts: 1,629
    edited 2019-05-21 - 12:27:22
    I also like 2nd the best, for same reason. Clarity, especially when the blocks are long.

    Would another option be to accept optional range numbering?
    cast x
        0:   block_0
        1:   block_1
        2-4: block_2
        5:   block_3
        6,7: block_4
        8:   block_5
        9:   block_6
        ?:   block_other
    
  • evanhevanh Posts: 7,928
    edited 2019-05-21 - 12:37:05
    Is CASE already taken? doh!, yes. :)
    If it's slow why not replace it?
    "We suspect that ALMA will allow us to observe this rare form of CO in many other discs.
    By doing that, we can more accurately measure their mass, and determine whether
    scientists have systematically been underestimating how much matter they contain."
  • I have a trend to prefer the second example (straight-thru numbering) since one can immediately notice to where the # indexes are leading to, and also avoid commom errors during code edition, such as inserting another element at the table, without rearranging the indexes accordingly.

    Sure, one can solely rely on the odd or even-numbered indexes, but them it'll have to depend on the parser, in order to verify the consistence of the sequence; there would be some errors to check for and correct.

    Henrique
  • Thanks, Guys.

    I kind of like everything being numbered, as well, because it's immediately clear. It's just a pain to rearrange.

    I will see about doing what VonSzarvas says. It starts to get back to CASE functionality pretty quickly.

    You can also call methods with indexes: BaseMethod[index](params). This is a runtime thing, so you need to know what you're doing. Same with using method pointers, which also have indexes, by the way.
  • Yanomani wrote: »
    I have a trend to prefer the second example (straight-thru numbering) since one can immediately notice to where the # indexes are leading to, and also avoid commom errors during code edition, such as inserting another element at the table, without rearranging the indexes accordingly.

    Sure, one can solely rely on the odd or even-numbered indexes, but them it'll have to depend on the parser, in order to verify the consistence of the sequence; there would be some errors to check for and correct.

    Henrique

    If we had a smart editor, it could dynamically show the numbering without your needing to type it. Maybe in the future.
  • evanh wrote: »
    Is CASE already taken? doh!, yes. :)
    If it's slow why not replace it?

    CAST is a faster/simpler cousin to CASE. CASE evaluates every case, whereas CAST just jumps. CASE is needed sometimes, while CAST is much more efficient in cases where an integer succession exists.
  • Maybe just call it "Jump" instead of cast? Cast means something else entirely to me...
    Prop Info and Apps: http://www.rayslogic.com/
  • How about calling this "CASET" or "CASE TABLE" instead of "CAST" (which could easily be confused with C or BASIC "CAST", which converts between types)?

    Even better might be to recognize a restricted set of CASE and automatically use a jump table if the cases are simple enough (and disjoint). That's more work, but might be nicer for the users.
  • Rayman wrote: »
    Maybe just call it "Jump" instead of cast? Cast means something else entirely to me...

    My first impulse was to call it FORK, but that means multi-threading in C.

    JUMP might be best, actually.
  • cgracey wrote: »
    ...
    Which is best, if any?

    @cgracey, I would prefer something like jl(cast) var label.
    That way, since you have an jump-list's ending label, if others are in between these can be not considered and thus become optional, so anyone is free to write them or not.
    JL x other
        : block_0
        : block_1
        : block_2
        : block_3
        : block_4
        : block_5
        : block_6
    other: block_other
    
    JL x EndJL
        0: block_0
        1: block_1
        2: block_2
        3: block_3
        4: block_4
        5: block_5
        6: block_6
    EndJL: block_other
    
    Propeller Object Exchange (last Publications / Updates) --- Oldbitcollector's guest map
    JustForMe
  • I like the idea of casting a net.... But could "CAST" be confused as an operation to change type ?

    Can't think of anything better really. Hmm.
    Maybe CASEn or CASEN (ie. CASE-Numeric)
  • ersmith wrote: »
    How about calling this "CASET" or "CASE TABLE" instead of "CAST" (which could easily be confused with C or BASIC "CAST", which converts between types)?

    Even better might be to recognize a restricted set of CASE and automatically use a jump table if the cases are simple enough (and disjoint). That's more work, but might be nicer for the users.

    Yes, I thought about making the compiler smart enough to compile this more-efficient method when circumstances allowed, but it will take some work and maybe new parsing approaches. I was thinking your compiler could probably handle that, easily.
  • Chip,
    Unless "ON" has another meaning, I think "ON x" instead of "CAST x" would make more sense (at least to BASIC programmers).
    Just my opinion....

    Bean
  • One nice thing about having a uniquely-named instruction for this operation, is that people will use it with intent. They would more likely get the benefit from a uniquely-named instruction than a subtle use case of a singly-named instruction.
  • cgraceycgracey Posts: 11,711
    edited 2019-05-21 - 13:30:30
    Bean wrote: »
    Chip,
    Unless "ON" has another meaning, I think "ON x" instead of "CAST x" would make more sense (at least to BASIC programmers).
    Just my opinion....

    Bean

    I've just been searching and there's no ~4-letter word in English that means what we need a word to mean.

    "ON" is pretty good, but it's an awfully small word, almost gets looked past:
      on x
        0: block_0
        1: block_1
        2: block_2
        3: block_3
        4: block_4
        5: block_5
        6: block_6
        >: block_other
    
  • My query was because of the chosen name too. CAST is not a good choice.
    "We suspect that ALMA will allow us to observe this rare form of CO in many other discs.
    By doing that, we can more accurately measure their mass, and determine whether
    scientists have systematically been underestimating how much matter they contain."
  • cgraceycgracey Posts: 11,711
    edited 2019-05-21 - 13:31:26
    evanh wrote: »
    My query was because of the chosen name too. CAST is not a good choice.

    We need a word that means "pick one and do it".
  • What about PICK ?
  • How about "JMP"? It has the advantage that it's already a reserved word in Spin, so it won't break existing code.

    Another good choice might be "GOTO", which isn't a reserved word but is probably less likely to conflict with anything:
       GOTO x
         0: do_0
         1: do_1
         other: do_other
    


  • XPICK, YPICK; XJMP; YJMP (not to be confused with Z80's IX and IY-based indexing...)
  • I like "PICK" almost as much as "ON" ;)

    Bean
  • Would this support cases when the index starts greater than zero ?
    In that case, using ">" may be confusing, as the index could also be less than minimum.

    OTHER or ? may suit both cases of less or more,
    As a shorthand I prefer "?". ie. something else or something unknown.

      on x
        2: block_2
        3: block_3
        4: block_4
        5: block_5
        6: block_6
        7: block_7
        8: block_8
        ?: block_other
    

  • How about "GOON" As in "Go On"
    GOON x
        2: block_2
        3: block_3
        4: block_4
        5: block_5
        6: block_6
        7: block_7
        8: block_8
        ?: block_othe
    
    Terry's Workbench

    Feel the need for speed between your PC's com port and Prop?
    Try the FTDI 245 and the FullDuplexParallel Object.
    Check out my spin driver for the Parallax "96 x 64 Color OLED Display Module" Product ID: 28087
    22FPS video from the P2 on the Parallax "96 x 64 Color OLED Display Module" https://www.youtube.com/watch?v=ja84rf38QHM
  • ersmithersmith Posts: 3,403
    edited 2019-05-21 - 14:52:25
    Please, let's not overload ? with more meanings -- it's already used in conditional assignment and random number generation. Using it as an alias for "other" will make parsing (and reading) code more complicated.

    "other" is already there, and is reasonably clear to the reader, so I think we should use it.

    I know that experienced Spin users like to save keystrokes, but it's a false economy -- code is read a lot more often than it is written, and having cryptic short aliases for everything makes it harder for new users to come to grips with code.
  • ersmith wrote: »
    Please, let's not overload ? with more meanings -- it's already used in conditional assignment and random number generation. Using it as an alias for "other" will make parsing (and reading) code more complicated.

    "other" is already there, and is reasonably clear to the reader, so I think we should use it.

    I know that experienced Spin users like to save keystrokes, but it's a false economy -- code is read a lot more often than it is written, and having cryptic short aliases for everything makes it harder for new users to come to grips with code.

    Agreed.
  • How about some variation of "Execute Index" ?

    Maybe "Exe#" or "Execute#" ??

    J
  • The > symbol has too many different meanings in spin.
    I agree about using OTHER: or even suggest ELSE:
Sign In or Register to comment.