Up to Main Index                              Up to Journal for July, 2023

                     JOURNAL FOR SATURDAY 22ND JULY, 2023
______________________________________________________________________________

SUBJECT: Bare indexes anyone?
   DATE: Sat 22 Jul 21:17:43 BST 2023

After showing “The Cottage” yesterday I had some comments. They mentioned how
busy the code was with indexes everywhere. For example the drop function:


    // drop an item you are carrying
    drop: func
      if !exists player["cmd"] 1; goto dropWhat       # <- here
      alias = player["cmd"][​1]                        # <- here
      inv   = player["inv"]                           # <- here

      item = call findItem inv alias
      if item == false; goto notFound

      player["inv"] = delete inv item["id"]           # <- here
      world[player["loc"]]["inv"][item["id"]] = item  # <- here
      println "You drop " item["name"] "."            # <- here
      return

      notFound:
        println "You have no \"" alias "\" to drop."
        return
      dropWhat:
        println "You go to drop... something?"
        return
    endfunc


Mere does not have objects, and maybe never will. Instead it uses maps as a
kind of poor man’s object. But what to do? I’ve been tinkering away last night
and today trying to come up with a solution. My latest effort is what I call
“bare indexes”. This is the drop function again, but using bare indexes:


    // drop an item you are carrying
    drop: func
      if !exists player\cmd 1; goto dropWhat          # <- here
      alias = player\cmd\1                            # <- here
      inv   = player\inv                              # <- here

      item = call findItem inv alias
      if item == false; goto notFound

      player\inv = delete inv item\id                 # <- here
      world[player\loc]\inv[item\id] = item           # <- here
      println "You drop " item\name "."               # <- here
      return

      notFound:
        println "You have no \"" alias "\" to drop."
        return
      dropWhat:
        println "You go to drop... something?"
        return
    endfunc


A side by side comparison of the interesting bits:


              Normal Indexes                          Bare Indexes
              ¯¯¯¯¯¯¯¯¯¯¯¯¯¯                          ¯¯¯¯¯¯¯¯¯¯¯¯
  if !exists player["cmd"] 1; goto d…t    | if !exists player\cmd 1; goto d…t
  alias = player["cmd"][​1]                | alias = player\cmd\1
  inv   = player["inv"]                   | inv   = player\inv
                                          |
  item = call findItem inv alias          | item = call findItem inv alias
  if item == false; goto notFound         | if item == false; goto notFound
                                          |
  player["inv"] = delete inv item["id"]   | player\inv = delete inv item\id
  world[player["loc"]]["inv"][item["id"]] | world[player\loc]\inv[item\id]
    = item                                |   = item
  println "You drop " item["name"] "."    | println "You drop " item\name "."
  return                                  | return


A bare index starts with a backslash ‘\’ followed by the literal index value.
But, strings do not need to be quoted. The bare index will then be expanded.
In general “\literal” expands to “[literal]”. If the literal is a string it
will be quoted. However, string literals may not contain spaces when used as a
bare index - normal indexing can be used instead.

Spaces may precede the backslash. For example “player \cmd \1”, “player\cmd\1”
and “player["cmd"][​1]” are equivalent. Bare indexes only work with literals
and not variables. Normal indexing and bare indexes may be mixed.

You may prefer “player["cmd"][​1]”, others “player\cmd[​1]” or “player\cmd\1”.
Which variant to use, and when, is up to you and what makes the code readable.

Some more examples with various bare index literals:


    >cat bareIndexes.mr
    m = [string](
      "s"  "xyzzy",
      "ia" []int(3 5 7),
      "ua" []uint(3u 5u 7u),
      "fa" []float(3.3 5.5 7.7),
      "sa" []string("x" "y" "z"),
      "ba" []bool(false true false),
      "im" [int](3 "i"),
      "um" [uint](3u "u"),
      "fm" [float](3.3 "f"),
      "sm" [string]("three" "s"),
      "bm" [bool](true "b"),
    )
    println "string index: " m\s\1
    println "   int array: " m\ia\1
    println "  uint array: " m\ua\1
    println " float array: " m\fa\1
    println "string array: " m\sa\1
    println "  bool array: " m\ba\1
    println "     int map: " m\im\3
    println "    uint map: " m\um\3u
    println "   float map: " m\fm\3.3
    println "  string map: " m\sm\three
    println "    bool map: " m\bm\true
    >mere bareIndexes.mr
    string index: y
       int array: 5
      uint array: 5
     float array: 5.5
    string array: y
      bool array: true
         int map: i
        uint map: u
       float map: f
      string map: s
        bool map: b
    >


Originally bare indexes used the dollar ‘$’ and not the backslash ‘\’. But, I
wasn’t too keen on using the dollar ‘$’. It was too bulky and letter-like and
made the indexes run together too easily “player$cmd$1”. The colon ‘:’ was
already taken for labels. A period would have been nice, but precludes float
bare indexes and generally causes havoc with float literals. I did think of
using various Unicode symbols — people don’t like it when I use Unicode as it
makes code too hard to type :(

On some operating systems the backslash is used for paths, and “player\cmd\1”
sort of looks like a path into your data…

What do you think?

Have your say and let me know your thoughts: diddymus@wolfmud.org

--
Diddymus


  Up to Main Index                              Up to Journal for July, 2023