Functions: conversion

You can define a conversion function to convert data from one type to another. It is possible to define an ordinary function to perform this operation:

  define string function 
     i-to-s value integer x
  as
     return "d" % x
  
  process
     local integer foo initial { 5 }
  
     output i-to-s foo

A conversion function is different however. A conversion function is called automatically whenever a variable of one type is specified where data of another type is expected. For instance, the keyword output expects a variable of type string and you will get a compile time error if you specify a variable of type integer:

  process
     local integer foo initial { 5 }
  
     output foo
Normally, you would have to format the integer value as a string as follows:
  process
     local integer foo initial { 5 }
  
     output "d" % foo
However, if you specify a conversion function to convert an integer to a string, you can output an integer value without using the formatting operator directly:
  define string conversion-function value integer x
  as
     return "d" % x
  
  process
     local integer foo initial { 5 }
  
     output foo

Notice that the conversion function does not have a name. Since it is called implicitly by OmniMark and is not explicity named in your code, there is no reason for it to have a name. Because they are not named, you can only have one conversion function for each conversion type. And because OmniMark defines conversion functions for many common type conversions, you cannot define conversion functions for those conversions. For instance, OmniMark defines a conversion function from string to integer, so you cannot define one of your own.

The above example notwithstanding, OmniMark provides all the conversion functions you reasonably need for the built-in OmniMark data types. OmniMark libraries that define opaque data types also provide all the conversion functions you reasonably need for working with those types and the built in OmniMark types. There are therefore only two reasons why you would likely need to define your own conversion functions:

  1. if you write an external function library containing new opaque data types, and
  2. if you create your own data types using OmniMark records.

While you will seldom need to define a conversion function between different record types, it can be useful to define a conversion function from a record type to a string, as this can allow you to output the value of a record simply by naming the record in the output action. The following program illustrates this technique:

  declare record day-type
     field integer day
     field integer month
     field integer year
  
  define string conversion-function value day-type d
  as
     local string month-text initial { "January", "February", "March",
                                       "April", "May", "June", "July",
                                       "August", "September", "October",
                                       "November", "December" }
  
     return "d" % d:day
         || " "
         || month-text[d:month]
         || ", "
         || "d" % d:year
  
  process
     local day moon-landing
  
     set moon-landing:day   to 20
     set moon-landing:month to 07
     set moon-landing:year  to 1969
  
     output moon-landing