The Readable Programming Language - Handbook



A procedure in Lisilogic is defined in a "to" sentence made up of:

To cleanup: - save, - clear the user's current_submission.

To validate an address: * set its validated to true; * if its street is empty, issue the warning "Street empty!" next to its street; * if its zipcode is empty: - set its validated to false, - issue the error "Zip code must not be empty" next to its zip code.

It is possible to define several procedures with the same name if they have different parameter types. Note that a procedure that handles null as a parameter is not the same as a procedure without a parameter.

It is not possible in Lisilogic to define a procedure with several parameters. This is a typical use case for session attributes, see Structures: session.

In the statements, the parameter passed to the procedure is accessed using the expressions "the given ..." "it" and "its ...", see Expressions: Contextual Constants.


A procedure gets started by a button click, see User Interface: Procedure Calls.

Note that the procedure to start is chosen after the value of the parameter passed to it: calling a procedure on an attribute that happens to be null (unreachable, not yet initialized, or set to null) will execute the version of this procedure defined with null as a parameter type, not the one defined for the type of the attribute.


A Lisilogic procedure may include user interaction by navigating to pages of the application using the go to and open statements, see below.
The page shown inbetween must display a continue or skip button to let the procedure go on. It may display a cancel button to terminate it prematurely. See User Interface: Simple Actions.

To validate a profile: * if its address is null: - create an address as its address, - go to the "Edit Profile" page for it; * if its address's zip_code is empty: - issue the error "Zip Code must not be empty" next to its zip_code, - open the "Edit Profile" page for it; * ... On the "Edit Profile" page, the user can: * edit the given profile's address's zip_code; * click "Next step" to continue; * click "Cancel profile check" to cancel.

Any button that navigates to another page of the application (navigation action, see User Interface: Navigation Actions) or that starts a new procedure (see User Interface: Procedures Calls and Anonymous Procedures) will automatically cancel the current procedure if there's one.

For now, it is not possible in Lisilogic to start a procedure from inside another one. One difficulty is to decide how continue, skip and cancel buttons should behave in nested procedures: the non-specialist reader must still understand what the code does. A solution could be to provide the name of the procedure to be skipped or canceled, but to ensure clarity, it would probably require a possibility to test explicitely if the procedure has been called directly or inside another one... This is still a research topic.

Another research topic is a possibility to go back one step.



The save statement stores the contents of any editors that appeared on the last displayed page, just like a save button action (see User Interface: Simple Actions). It takes no parameters.


The terminate statement ends the current procedure. It takes no parameters.


The issue statement displays a notification. It is made up of

  • The verb issue
  • The kind of notification to issue: success notification, warning, error, or plain notification
  • The text of the notification between quotes (""), eventually containing calculated parts in braces ({}),
  • An eventual placement, which can be at the top or bottom of the page or next to an UI element (displayer, editor or button, see User Interface).

issue the error "{the given address's zip_code} is not a correct postal code" next to the given address's zip_code

Notifications without a placement and notifications whose placement can't be found on the next displayed page will appear at the bottom of the page, after the UI elements placed at this location.

The issued notifications can be tested in an "if" clause ("if" statement of a procedure, see below, or condition in a page or widget definition, see User Interface: Conditions) using a there are expression.
if there are no errors, issue the success notification "saved!" next to the "Save" button

send an email

The send an email statement takes:

  • An expression resulting in an email address or a list of email addresses preceded by the word to,
  • The word with,
  • The subject of the email, between quotes (""), with eventual calculated parts in braces ({}), followed by the words as subject,
  • The word and,
  • The body of the email, between quotes (""), with eventual calculated parts in braces ({}), followed by the word as body.

send an email to the application's last_created_user's email address with "Registration complete!" as a subject and "Welcome! Your login is: Username: {the application's last_created_user's username} Password: {the application's last_created_user's password}" as a body

Eventual error notifications are displayed next to the button that started the current procedure, or at the bottom of the page if it isn't visible any more.

See also Basic Syntax: Character Strings.

The possibility to send attachments (images and files) is in development.

go to / open

The go to or open statement displays a page of the application. The word for allows to pass an eventual parameter to the page (it will correspond to the variables "the given ...", "it" and "its ..." in the page definition, see Expressions: Contextual Constants).

go to the "Edit Profile" page

open the "Edit Gallery" page for the user's current_gallery

Due to limitations of the HTTP protocol, unlike with a navigation action (see User Interface: Navigation Actions, it is not possible to open a new tab or window from a procedure.


The create statement creates a new instance of a structure (see Structures). It is made up of

  • The verb create,
  • The name of the structure to create, preceded by a, an or a new
  • If whished, as or into followed by the path where the newly created structure instance will be stored or added,
  • An eventual list of initializers introduced by the word with.

An initializer is an expression (see Expressions) followed by as its and the name of an attribute of the structure being created.
Note that the possessive "its" will have a different meaning in the path to the attribute to initialize than in the expression that gives its value. It is recommended to use "the given..." in the value expression. See also Expressions: Pronouns

create a new address as the user's address

create a new gallery into the user's galleries with now as its creation_time

Creating an instance of a structure whose name is identical with a role (a role object) means creating a new user with this role, see Roles: Role Objects.

Note that creating an object doesn't change the meaning of the variables "it" and "its ...", even if the create statement contains initializers (with "its ..." refering to the attributes of the newly created structure instance). In expressions, "it" and "its ..." still refer to the parameter passed to the procedure, page or widget. For clarity, you may prefer using "the given ..." instead. See Expressions: Pronouns.


The delete statement takes an expression resulting in a structure instance or a list of structure instances as a parameter, and deletes them.

delete the given image

Any structures owned by the ones to be deleted are deleted too, including files, images and role objects.

The structures to be deleted are removed from any list or attribute that contained them. Single attributes in this case are set to null.

See Structures: Relationships and Roles: Role Objects.


The clear statement takes a path to an attribute as a parameter. If this attribute is a list, all its elements are removed; if it is a single value attribute, it is set to null.

clear the user's address's zip_code

clear the given gallery's images

If the given attribute owned its contents (elements or value), these contents are deleted (recursively, with everything they own themself), and removed also from any other lists or attributes that contained them. See Structures: Relationships.


The set statement takes a path to an attribute and an expression to store into it (see Expressions), separated by the word to.

set the user's address's city to the text "Berlin"

set the user's address's validated to true

If the expression's value is a structure instance and the attribute owns its content, the value is removed from its eventual previous owner attribute. See Structures: Relationships.

add, append, move, remove, subtract, copy

The following statements take an expression as first parameter (see Expressions) and the path to an attribute as second parameter:

  • add ... to ...
  • append ... to ...
  • move ... to ...
  • remove ... from ...
  • subtract ... from ...
  • copy ... into ...

add 10 points to the user's score

remove the user's avatar from the user's pictures

Note that the set statement (see above) requires its parameters to be in opposite order: first the destination path, then the value.

Adding or moving a structure instance to an attribute that owns its content will remove the structure from its eventual previous owner attribute.
Removing or subtracting a structure instance from an attribute that owns it will delete it: use move if you don't want this to happen.
See Structures: Relationships.

if, else if, otherwise

The if, else if and otherwise statements drive the execution of the procedure. "If" and "else if" are followed by an expression resulting in a boolean (see Expressions); all three are followed by one or more statements to execute according to their meaning.

* if the user's address's zip_code is empty, issue the error "Zip code must not be empty"; * else if the user's address's zip_code starts with the text "10": - set the user's address's city to "Berlin", - issue the success notification "City found!"; * otherwise: - clear the user's address's city, - issue the warning "Please type in your city".

See also Basic Syntax: Lists about writing lists and lists in lists.

while, for each

Loop statements are in development.