IvoryScript further reading
<span id="making-sense-of-values"></span> Making sense of IvoryScript values

Making sense of IvoryScript values

Values provide information. Integers provide quantities for calculation, characters and strings express text, and truth values provide the basis for logical reasoning. Such values form some of the fundamentals of a programming language.

A value is denoted by some combination of symbols, or tokens. For example, in IvoryScript:

         #!42
         #!'a'
         #!"forty two"
         #!True
      

denote an integer, a character, a string and a truth value respectively.

The language makes a specific distinction between a value and an expression with a potential value. For example:

         42
      

does not denote the integer value forty-two in IvoryScript. It is an integer expression constant. This is perhaps easier to understand with an expression like (7 * 6) - no assumption is made that its value is 42.

There is obviously a design choice as to whether a constant such as 42 should denote an integer value or an integer expression value. The choice of the latter for IvoryScript was for conformity with other expression forms. Thus:

         #!42
         #!(7 * 6)
      

both denote the integer value forty-two.

Many different forms may denote the same value. For example:

         #42
         #!42
         !42
         #!(7 * 6)
      

The first #42 is known as a literal constant. It has identical meaning to #!42 — nothing is implied by the difference, which allows for more consistent terminology. This is more than a distinction in notation. Expressions are first-class values in IvoryScript. They may be associated with names, passed as arguments, returned from functions, contained within other values, copied or persisted irrespective of their potential value.

Other expression values

Constants are only one form of expression value. Other source expression forms include name occurrences, function applications, lambda expressions, let expressions, case expressions and conditionals.

A name occurrence:

            x
         

is an expression whose value is that associated with the name in a particular scope.

Function applications (without brackets in IvoryScript) are also expressions:

            f x
            f x y
         

an expression whose reduced value is determined by the function and its arguments. That value may also be an expression value.

Lambda expressions provide function values:

            \x -> #!(cos x)
         

Perhaps surprisingly, a lambda function is also an expression value. This provides consistency with a function application where a function is returned - analogous with an expression constant. For example, \x -> #!(cos x) and trigFn #"cos" where:

            trigFn f =
               #!(case f of {
                  "sin" -> sin;
                  "cos" -> cos;
                  ...
               })
         

A let expression associates values with names for use within another expression:

            let {
               x = 7;
               y = 6
            } in
               #!(mulInt x y)
            

Selection between expression values may be written using case:

            case x of {
               0 -> e1;
               1 -> e2;               
               
               otherwise -> eDefault
            }
         

or, where appropriate, using conditional syntax:

            if condition then e1 else e2
         

These forms describe values and relationships between values.

More elaborate expressions follow the same principle. For example, the value corresponding to 1 + √2 can be denoted explicitly as:

         #!(addDouble #1.0 #!(sqrt #!(fromIntDouble #2)))
      

This can also be expressed more simply as:

         1.0 + (sqrt 2)
      

The relationship between these forms will be considered separately.

Expressions therefore need not be regarded as computations awaiting execution: they are values in their own right. An integer is a value; an integer expression is a different value.