Skip to content

evincarofautumn/Hap

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hap

Hap is a dynamically typed, asynchronous, imperative programming language.

This is the original C++ prototype, which is no longer maintained; it’s superseded by the new Haskell implementation of Hap, which has an improved performance model and a graphical mode.

Here is a simple example of Hap’s syntax and semantics:

var health = 100;

when (health <= 0) {
  print("Goodbye, cruel world!");
  exit;
}

print("Hello, sweet world!");

while (true)
  health = health - 1;

Hap code reads much like code in other imperative languages. Its syntax is reminiscent of JavaScript. However, note the use of when: this is an asynchronous conditional. The above code prints:

Hello, sweet world!
Goodbye, cruel world!

Synchronous flow control statements such as if, while, and for are evaluated immediately. If the condition is true when the statement is reached, then the body is evaluated immediately, before proceeding to subsequent statements.

Asynchronous flow control statements such as when are evaluated concurrently. The flow of control proceeds to subsequent statements immediately; only when the conditional actually becomes true is the body evaluated.

This allows programs to be structured implicitly in terms of events and time-based constraints. You are not forced to subscribe to event handlers for predefined conditions—rather, you can create ad-hoc conditions as needed, and this is syntactically lightweight.

Types

TypeExamples
int
0
1234
bool
false
true
text
""
"scare"
list
[]

[1, 2, 3, 4, 5]

[ "this", "that", "and", "the", "other", "thing", ]

[ [ +cos(x), -sin(x) ], [ +sin(x), +cos(x) ] ]

[0, false, ""]

map
{}

{ "one": 1, "two": 2, "three": 3 }

[ { en: "one", fr: "un", }, { en: "two", fr: "deux", }, { en: "three", fr: "trois", }, ]

Statements

General

StatementDescription
var NAME;
var NAME = EXPR;
Creates a lexically scoped variable named NAME. Initializes it to EXPR, or gives it an initial value of undef if EXPR is not specified.
fun NAME(PARAM, PARAM, ...) STAT
Creates a lexically scoped function named NAME with a body given by STAT using the given parameters.
EXPR;
Synchronous. Evaluates EXPR and discards the result.
{ STAT... }
Synchronous. Evaluates a block of statements as a unit. Introduces a new lexical scope.
exit
Exits the program entirely.
last
Exits the current loop.
next
Jumps to the next iteration of the current loop, re-evaluating the loop condition.
redo
Redoes the current iteration of the current loop, without re-evaluating the loop condition (or step, in the case of for).

Flow Control

Statement Synchronicity How many times STAT is evaluated When STAT is evaluated
if EXPR STAT
Synchronous Once If EXPR is true when the statement is reached.
when EXPR STAT
Asynchronous Once The first time EXPR becomes true; immediately if EXPR is already true.
whenever EXPR STAT
Asynchronous Once Every time EXPR becomes true; immediately if EXPR is already true.
while EXPR STAT
Synchronous Repeatedly As long as EXPR remains true; never if EXPR is already false.
for (INIT; COND; STEP) STAT
Synchronous Repeatedly

Equivalent to:

INIT;
while (COND) {
  STAT;
  STEP;
}

Except that variables declared in INIT are local to the loop, and STEP is evaluated even when the next statement is used.