📖
A General Introduction to Contextual Programming
  • A General Introduction to Contextual Programming
  • Chapter 1 - Thinking Contextually
    • 1.1 What is a Paradigm?
    • 1.2 What is Contextual Programming?
  • Chapter 2 - Creating Context
    • 2.1 Organizing Data
    • 2.2 Decorators
    • 2.3 Adaptation
  • Chapter 3 - Evaluating with Operations
    • 3.1 Hello World!
    • 3.2 Expanding on 'When'
    • 3.3 Operation Hierarchies
  • Chapter 4 - Reacting with Behaviors
    • 4.1 Revisiting Hello World!
    • 4.2 From 'When' to 'Whenever'
    • 4.3 Working with Buckets
    • 4.4 Expanding Purpose
    • 4.5 Adapting Behaviors
  • Chapter 5 - Abstracting Evaluations
    • 5.1 Compositions
    • 5.2 Operables
  • Chapter 6 - Abstracting Contexts
    • 6.1 Contracts
    • 6.2 Context Identifiers
  • Chapter 7 - Looking to What's Next
    • 7.1 Final Thoughts
    • 7.2 Additional Resources
Powered by GitBook
On this page
  • Overview
  • A Simple Operation
  • Requiring Context
  • Greeting the User
  1. Chapter 3 - Evaluating with Operations

3.1 Hello World!

Previous2.3 AdaptationNext3.2 Expanding on 'When'

Last updated 8 months ago

Overview

For an application to progress, the state of its contexts must be changed. Operations are the constructs that, at a high-level, define when those contexts are changed/created, and at a more detailed level, how they are changed.

In general, a simple operation that has no required contexts has a declaration that looks like :

"Operation Name" ::  "Qualifications"? 'Operation Logic'.

Qualifications are where the 'when' aspect of Contextual Programming is defined. Statements after operation and before ? are all considered qualifications and often take the form of when "some condition", but they can also have other forms that will be shown later.

Operation logic is a series of statements that either create new contexts or directly manipulate the operation's contexts (if it has any). The operation logic is actually optional, leaving the operation name and its qualifications as the only required parts of an operation. Such qualification-only operations are usually used in a hierarchy, through a kind of inheritance, to add qualifications to other operations.

A Simple Operation

One of the simplest examples of an operation is Rede's () implementation of the classic "Hello World!" program:

Output Hello World :: 
    operation when initialized?
        evaluate "Hello World!" as Console Message.

In , Output Hello World :: operation when initialized?, there's the operation name, Output Hello World, and one qualification, when initialized. This qualification is referred to as a qualification. When applied in this way, a when initialized will qualify for execution when the application starts, so this operation called Output Hello World will execute immediately when the application begins to execute.

The third line, evaluate "Hello World!" as Console Message., is the operation logic. This is what will actually be executed when Output Hello World qualifies and executes. There's a lot going on in this line:

  • evaluate is a command to the . It tells the runtime to perform operations that are qualified by the context(s) that follows it. evaluate will require the runtime to perform any such operations before the current operation continues, unlike its counterpart \evaluate, which is not concerned about when the runtime will perform the operations. There are circumstances when \evaluate is more appropriate than evaluate, primarily when what is expected to be accomplished by \evaluate is of no importance to the current chain of logic or should be done entirely .

  • "Hello World!" is a string literal, which is to say it is an instance of a type. This is defining the text that will be presented to the user.

  • as Console Message is a command to the string "Hello World!" as a Console Message context type, which is a built-in context provided by the runtime. This will be done prior to the evaluate command being evaluated by the runtime.

There are a few runtime commands like evaluate in Rede. For any of them, prepending \ will make them run asynchronous of the current operation.

Altogether, evaluate "Hello World!" as Console Message. is telling the application runtime to "take the text, 'Hello World!', alias it as a Console Message, and execute any operations that qualify for that context". The standard functionality of the runtime includes an operation that will qualify for a single Console Message and will perform logic that will result in Hello World! being displayed to the user through a console.

While not much, this operation shows how to send messages to the user through the console while following the practices of Contextual Programming.

Requiring Context

Most operations will require at least one context, as the purpose of most operations is to progress the application's state. To specify the required contexts, the operation declaration changes some to look like :

"Operation Name" :: "operation description with [Context Types]" : operation 
    <"Context Names"> "Qualifications"? 
        'Operation Logic'.

The [Context Types] that appears in the operation's description defines the number of the operation's parameters (the "Context Names" above).

The parameters ("Context Names") of the operation can be anything. It is recommended that they describe the role of that parameter as it pertains to how its matching context type is described as being used in the operation's description.

Greeting the User

The Hello World example can be modified to greet the user. One way to accomplish this is with a new context and an operation to define its state. It's not necessary to do it this way, but this implementation is clearer and more reusable.

Input User Name :: the full name of the user as a String and a String : context
    first name, last name.

Next, the updated initial operation:

Output Hello User :: 
    operation when initialized?
        evaluate name is Input User Name,
        evaluate "Hello \(name (first name)) \(name (last name))!" 
            as Console Message.

There are a few things different here. The third line is noteworthy in that it is evaluating an operation (which is defined below) but is doing so while defining a new context. The context will be referred to as name and will be of the new Input User Name type, and it will be immediately evaluated.

The other difference is on the fourth line (which is wrapped to the fifth line for easier viewing). This line is similar to the previous evaluate "Hello World!" as Console Message but with some other code nested inside the string. In Rede \( ) denotes additional strings to be formatted within the encapsulating string. The values within the parentheses are basically injected into the string. In this case, if first name of name is "A" and last name of name is "B", then the resulting string will be formatted as "Hello A B!" which will then be output to the console.

Finally, the new operation that will populate the evaluated Input User Name:

Request Input User Name :: 
    asks the user their name to update an Input User Name : operation <input name>?
        evaluate "What is your first name?" as Console Message,
        evaluate first name is Console Response,
        
        evaluate "What is your last name?" as Console Message,
        evaluate last name is Console Response,
        
        input name (first name, last name) is {first name, last name}.

Note the punctuation ending each line in this example. Any time a construct is declared, it must end with a period (.), except when it is nested within another construct, in which it ends with a semi-colon (;). Any value, qualification, or logic statements within a set of such elements of a declaration, must end with a comma (,). This structure is intended to be closely related to the use of punctuation in English.

Punctuation is not required to stack in Rede, so . supersedes ; which supersedes ,.

Due to how punctuation defines the statements and declarations in Rede, the whitespace in the code (tabs and lines of code) is irrelevant. The entirety of Request Input User Name could be on one line, or it could be on the lines that it is on above but with no tabs for indentation, or any other method of formatting. The formatting of whitespace used is assumed for improved readability for most readers, but any formatting in practice is up to the programmer or team to decide.

Unlike the initial operation, the only qualification for this operation is that there is an Input User Name being evaluated, which will be named input name within the scope of this operation. There's a number of evaluates that are similar to what has been seen so far. Console Response is the simplest way in Rede to obtain an input through the console and is basically an alias for a String, so that is used to receive the user's first and last names.

The only particularly different part of this operation is the last line, where the responses from the user are assigned as the first name and last name values of the Input User Name. The assignment is performed stepping left-to-right in both the group of parameters for input name (to the left of is) and the collection composed of first name and last name (to the right of is). This line is what populates the Input User Name with the user's input first and last names.

Altogether, this new context and these operations will request the first and last name of the user and then output a greeting to them.

First, the new :

alias
context