New Release 86

General:. This page generally describes new functionality in the 86 series of revisions and uploads. This is Working Documentation that with maturity will be moved to the Master Documentation. Work on this release addressed the following areas:

Reshape of sequences: Reshape of sequences was not working properly.

Ancillary Functions and namespace persistence: There are three examples here. First, I define a function "a" which in turn defines a function "b". "b" tests for presence of variable "x" (i.e. x* = _1 where monadic * means scope which is _1 if "x" can't be seen.). In the first case, "x" does not exist and "b" returns early. In the second case, "x" is given as an argument; "b" sees it and runs to its end. In the third case, "x" persists in "a's" namespace and is thus seen by "b" which again runs to its end.

Initialization using #IX:

Define the run program. It contains three ancillary programs: HW, GB, and NC. These are initialized in the #IX block. The #IX block returns the string 'Initialized' on returning ( :<- ). In this example I display this message from initialization. In real life you would probably do the initialization silently.

$$ == run vvv ============================
$$ -- Initialization ---------------------
  'HW'#pgm{'Hello World'};
  'GB'#pgm{'Good Bye'};
  'NC'#pgm{'No Comprende'};
  'Initialized' :<-;};

$$ -- program body -----------------------

This is one technique of cleaning up the namespace before running the function. I want to preserve only the ancillary functions in this example. I list them as (.HW .GB .NC). I take a reference to the existing namespace and remove these objects. This gives me a namespace containing everything but this objects. I then take the existing namespace without this conditioned namespace. The result is a namespace containing only the listed functions. I save this in a reference to the name space. I then bring in the arguments.

@ ~(@ ~ (.HW .GB .NC)) => @; $$ clean up namespace
#args;                     $$ fresh arguments

Here I do the actual work. If the argument is 'hello' I run the HW function; else if it's 'bye' I run GB; else I run NC.

:?(x='hello'){HW}::?(x='bye'){GB}::{NC}}; $$ work
$$ == run ^^^ ============================

'<1>'(run)$; Runs the initialization and displays its message
'<2>'(run) $; Runs with no arguments
'<3>'('hello'[.x]run)$; With valid hello value
'<4>'('adios'[.x]run)$; With invalid bye value
'<5>'('bye'  [.x]run)$; With valid bye value

Default Values:. With Glee's blocks having state, it becomes useful for undefined variables to have assumed inital values. This eliminates the need for an Initial Expression in many cases.

Recursion (using #OP): This is the classical factorial example implemented using recursion. factorial is implemented here as a monadic user defined operator. The left argument l__ is tested to return ( :<- ) when it falls to one (or for safety, below 1). If it doesn't return, it multiples l__ by l__ factorial (the recursive call). With Glee you need to be careful using functions recursively. This is because separate invocations of the same function don't have separate namespaces. Further, in Glee, for safety, I limit the recursive depth (right now to 40). This is an area I need to explore. In practice, I don't use recursive functions often. If this restriction becomes an issue, I'll devise a way to save state before making a recursive call and restoring it on return ... kind of like I do with arguments using #arg.

Recursion (using #PGM): This is a repeat of the previous example using a program for factorial rather than a user defined operator.