new

action

Syntax
new shelf-name ({string-expression})? insertion-point?
set new  shelf-name  ({ string-expression})? insertion-point?
         to expression

Argument definitions

insertion-point
A phrase describing where in the shelf the new item should be inserted. The insertion point is identified using the keywords before or after. If no insertion point is specified, the item is placed in the last position on the shelf.


Purpose

new inserts a new item onto a shelf and can only be invoked on shelves that have been declared variable:

  local integer x variable initial-size 0
  new x

By default, the new item is inserted after the last item on the shelf. You can insert the new item before or after another item:

  new x{"wilma"} after [2] 

To make the new item the first item on the shelf, you can use before [1] or after [0].

A new item can be given a key as it is inserted:

  new x{"fred"} before {"barney"}
  new x{"wilma"} after [2] 

The set new action combines the new and set actions into one action so that

  new x{"fred"} before [1]
  set x{"fred"} to "flintstone0"
can be replaced with:
  set new x{"fred"} before [1] to "flintstone0"

Putting these code fragments together gives us the following program:

  process
     local stream x variable initial-size 0
     new x
     set key of x to "barney"
     set x to "flintstone1"
     set new x{"fred"} before [1] to "flintstone0"
     set x{"fred"} to "flintstone0"
     new x{"wilma"} after [2] 
     set x{"wilma"} to "flintstone2"
     repeat over x
            output x || " has key " || key of x || "%n"
     again
  ; Output: "flintstone0 has key fred
  ;          flintstone1 has key barney
  ;          flintstone2 has key wilma"

Generalization of new

The new operator can now be used wherever you refer to a shelf item. OmniMark has always allowed the use of new with the set statement:

  process
     local integer foo variable
     set new foo to 17
     output 'd' % foo

Now you can use new whenever you refer to a shelf item, for example, in an increment statement:

  process
    local integer my-numbers variable
  
    increment new my-numbers 

Here the new action creates a new item on the my-numbers shelf and then the increment action increments it.

The conditional or guarded form of new

OmniMark does not allow you to add a new item to a shelf if the key you specify already exists on the shelf. With previous versions of OmniMark it was necessary to test for this conflict to avoid a program error:

  local integer my-numbers variable
  ...
  new my-numbers when my-numbers has key "my-key"
  increment my-numbers {"my-key"}
In OmniMark 8, you can use the guarded form of new to express this logic much more succinctly. The guarded form of new is new?:
  local integer my-numbers variable
  ...
  increment new? my-numbers {"my-key"}

The guarded form of new is used only when creating a keyed item. If a key is not specified, an error will occur.

The following example shows how you can use new? to easily remove duplicates from a data set. The following is a list of index entries with page references. The problem is to remove the duplicate entries, but also to maintain a count of the duplicates as an indication of when a topic is most heavily discussed. The data is as follows:

  OmniMark 1
  streaming 2
  OmniMark 4
  OmniMark 4
  streaming 4

Using the guarded new operator, this problem is easily solved like this:

  declare record usage-type
    field integer reference variable
  
  global usage-type usage variable
  
  find letter+ => word 
       blank 
       digit+ => page 
       "%n"
    increment new? (new? usage {word}):reference {page}
  
  process
    submit #main-input
    repeat over usage 
      output key of usage
      repeat over usage:reference as page-ref
        output ',' unless #first
        output ' ' || key of page-ref || " (%d(page-ref))"
      again
      output "%n"
    again

The inner guarded new of the find rule's increment action creates a new word entry if the word has not been encountered. The outer guarded new creates a new page reference if the page has not been encountered and then it passes the page entry, new or otherwise, to increment, which increases its count. The output of this program when given the input above is:

  OmniMark 1 (1), 4 (2)
  streaming 2 (1), 4 (1)

It is the following line that illustrates the power of guarded new and the ability to use new in any context:

   increment new? (new? usage {word}):reference {page}

Written in the old style, this one line would require the following:

  new usage {word} unless usage has key word
  new usage{word}:reference {page) 
   unless usage{word}:reference has key page
  increment usage{word}:reference {page) 

Related Syntax
Related Concepts