=====================================================================
     Nested Functions
     =====================================================================
     PRODUCT: R:BASE            VERSION: 4.5
     =====================================================================
     AREA: FUNCTIONS            CATALOG: GENERAL INFORMATION
     =====================================================================
 
     New to 4.5 is nested TEXT functions. Previously, non-TEXT functions 
     could be nested to any depth but if any part of the function included 
     a TEXT datatype value, you could not do any nesting. Using the nested 
     TEXT function capability of 4.5 groups of commands can be replaced by 
     a single command. 
 
     Use nested TEXT functions to customize the display of menu text. 
     For example, 
 
     CHOOSE vchoice FROM #VALUES FOR +
     ( RJS(CTXT(empid),6) & emplname ) FROM employee
 
     The employee id value, empid, must be converted to text via the CTXT 
     function. But prior to 4.5, it could not also be justified for display 
     purposes. The employee id then needs to be parsed out of the menu 
     choice. The leading spaces are not desired in the result and can , in 
     4.5, be removed at the same time as the employee id value is 
     extracted. For example,
 
     SET VAR vempid = (LJS(SGET(.vchoice,6,1),6))
     
     Or convert the employee id value to INTEGER with one command,
 
     SET VAR vempid_int = (INT(SGET(.vchoice,6,1)))
 
     There is often a need to split a column into two or more parts based 
     on a space or other delimiter. Prior to 4.5 this required writing a 
     DECLARE CURSOR program. For each row you would find the space with 
     one command, then use additional SET VAR commands to parse the full 
     name value into its pieces, then get the next row and do it all over 
     again. With 4.5, this can be done in a single UPDATE command. Here's 
     the command that splits a full_name column into first_name and 
     last_name.
 
     UPDATE test SET first_name = +
     (IFEQ( (SLOC(full_name,' ')), 0, ' ', +
     ( SGET(full_name, (LMAX(SLOC(full_name,' '), 1) - 1), 1) ) )), +
     
     last_name = ( SGET(full_name,20, (SLOC(full_name,' ') + 1) ) )
     
     The command includes some additional expressions to account for the 
     situation where there is only one name. In that case the SLOC doesn't 
     find a blank and returns a 0. Since the first_name portion is found by 
     subtracting 1 from the location of the blank, if there is only one 
     name, the expression is illegal and cannot be evaluated. The command 
     errors out if we don't include the additional expressions.
     
     Here's a breakdown of how the command works:
 
     UPDATE test SET
     
     Identifies the table name to be updated. Following the keyword SET is 
     the list of columns and expressions to be updated.
 
     first_name = (IFEQ( (SLOC(full_name,' ')), 0, ' ',  ))
 
     The SLOC function finds the location of the first blank in the 
     full_name column. The IFEQ function tests the value returned by SLOC. 
     If it's a 0 (i.e. a single word name), then a space is returned to the 
     first_name column, if not, the first name is extracted from the full 
     name.
 
      = ( SGET(full_name, (  - 1) , 1 ) ) 
 
     The SGET function extracts a specified number of characters from a 
     string. Here we are computing the number of characters to retrieve, 
     , based on the result of the SLOC function. We subtract 1 
     because we don't want the trailing space. The final 1 tells the SGET 
     to get the characters starting at position 1 in the full_name column.
 
      = (LMAX(SLOC(full_name,' '), 1) 
 
     The LMAX function is used to make sure the SGET has a valid number of 
     characters to retrieve. The SGET needs a number >= 0 for its second 
     and thrid arguments. Even though the SGET function is not being 
     executed when there is only a single word name, R:BASE needs to be 
     able to parse all parts of the IFEQ function (the SGET is argument 4) 
     and see valid expressions. If there is only one name, the SLOC returns 
     a 0. Subtracting one from zero means the second argument in the SGET 
     is negative and the SGET can't evaluate, the expression is invalid. 
     The LMAX function returns to the SGET the number representing the 
     location of the first blank or a one. This makes sure that the SGET 
     will never have a negative agrument for the number of characters to 
     return. 
 
     last_name = ( SGET(full_name,20, (SLOC(full_name,' ') + 1) ) )
 
     The expression for last_name uses the SGET to return 20 characters 
     starting at the position of the blank plus one. The SLOC function 
     finds the position of the first blank.