The Indu Programming Language

The Basics

Indu variables can be strings, integers (whole numbers), integers with printing units, or booleans (true or false). Variables don’t need to be pre-declared, just name one and start using it.

set a-string-variable to "Hello"
set an-integer-variable to 10
set a-measured-integer to 120pt
set a-flag to true

There are a few things to notice here. Variable names can contain letters, numbers and the dash (-). The only things that can’t appear in a name are “, (, ), =, <, >, #, :, ;, [ and ]. Variable names can’t start with a number.

You assign a value to a variable with set ... to .... You can assign a value to a variable at any point.

Measured integers can have the units in (inch), cm (centimetre), mm (millimetre), em (m-width), ex (x-height), pt (point), pc (pica) and px (pixel). If you’ve done any graphic design or CSS development those are probably familiar to you.

Finally, yes: Indu does not yet have non-integers (floating points, reals, etc.) Everything is whole numbers only. So far. That obviously needs to be fixed.

Loops and the like

Doing things repeatedly is pretty useful. There are three ways you can loop, all start with repeat. Loop while some expression is true:

set counter to 0
repeat while counter < 10
  ...
  set counter to counter + 1
end repeat

Loop until some expression is true:

set counter to 10
repeat until counter = 0
  ...
  set counter to counter - 1
end repeat

Both of those cases are quite long-winded so it is also possible to loop a number of times:

repeat 10 times
  ...
end repeat

Doing things based on an expression is pretty useful to:

if i < 10
  ...
end if

if i < 10
  ...
else
  ...
end if

Adding up, subtracting away, etc.

There are the usual mathematical operators: + (add), - (subtract), * (multiply), / (divide). These behave how’d you expect from what you’ve learnt of maths. That is, 10 + 5 * 3 works out to 80.

If you want to compare values, you can use = (equals), != (not equals), > (greater than), >= (greater than or equal to), < (less than) and <= (less than or equal to). As a shorthand, remember the = sign always appears last.

To combine together comparisons, you can use and and or.

Using other people’s programs

If someone else (or you) have written some handy functions or objects, you can include them into your program with include from. Pandita supports this by letting you refer to any author’s app:

include from /gga/hello-world
include from /indu/standard-library

Lists

You can create lists of values. To create a list use set a-list to list with 10; 20; "hello". That will create a list with the values 10, 20 and “hello”. Lists don’t all need to contain the same type. To update the value in a list, use set:

set item 2 of a-list to 30

That same list will now contain 10, 30 and “hello”. To add a new item to the end of a list use append:

append "world" to a-list

And now that list will contain 10, 30, “hello” and “world”.

XPath

When your Indu program is running in the browser, you’ll probably want to be able to read things out of the HTML, for example, what a user typed into a form field. Indu supports XPath to query the HTML:

set user-name to /input of me

Functions

Start a function with the keyword when:

when ten-square
  10 * 10
end ten-square

A function returns the value of the last expression. And a function is just a list of expressions. What’s an expression? Everything you’ve seen up until this point, including loops. If your function is short, then there is a shorthand: when ten-square => 10 * 10. Each function can access anything named when the function is defined. Functions can take arguments by name:

when square(number)
  number * number
end square

Calling those functions

To call just any function: call ten-square. To call a function with named arguments: call square with (number: 10).

JavaScript!

Sometimes you’ll find there’s something that Indu doesn’t let you do. Typically around accessing something new and cool in the browser. But that’s ok, you can write an Indu function in JavaScript:

when square [javascript] (number)
  return number * number;
end square

Every line in that function must be JavaScript. Any arguments and other variables are available inside the function. You can’t call back into Indu yet. Have a look at the log function in the Indu Standard Library for an example.

Objects

Pretty much everything you use is an object. An object is a way of structuring some variables and keeping them together, and then also the structure of your program. The way you structure your objects builds up to the structure of your program.

begin <object-name>
end <object-name>

Objects can contain attributes, functions, events, styles, mixins, and other objects. To create your application, begin an object called site, and then start including objects inside it.

Attributes

Attributes are single values, with a name. Like so, for an attribute called text:

begin label
  text is "Hello, world!"
end label

Once an attribute is set, it can be updated elsewhere. Attributes can also be initialised by more complex expressions, such as ten-square is 10 * 10. And by the way, names can include - characters.

To call a function on an object, say label above: call ten-square of label. This is how all attributes of objects are accessed: text of label

To set an attribute: set text of label to "Hello".

Events

Events (event click) are used to declare that an object responds to a browser event, such as a click. The event is handled by calling a function in the object called click, in this case.

Styling

Styles are how you define what an object looks like in the browser:

style
  font-size is 10pt
end style

There can be many of these inside an object. Each line is an attribute, where the name of the attribute becomes a CSS style. The value of each attribute becomes the value of the CSS style.

Creating objects from other objects

Objects can be created from any other object available. To create a name label based on a label object:

begin name using label
end name

In this case, every attribute, function, event and style of label will be copied into name. This is a copy, if an attribute in label is changed after name is created (by begin) then that change will not be reflected in name.

Creating an object with begin defines a variable with the name of the object. If the object is created inside another object, then this becomes another attribute with that name. If you don’t need to name the object when using another object, then you can leave the begin ... out: using label.

When using another object, you can also override any attributes from that object:

begin name using label(text: "Giles")
end name

If you want to add more than one object into your object, mix those in:

begin name using label(text: "Giles")
  with font(family: "Gill Sans")
end name

There can be as many mixins in an object as you want. There is no difference between using and with.

The UI in the browser

Finally, as well as other objects, an object can contain fragments of HTML:

begin label
  <p>Some text</p>
end label

And this is where things can get dynamic:

begin label
  <p>#{ text }</p>
end label
using label(text: "Giles")
end label

Just as you can change an attribute (with set as mentioned above) you can change the list of objects within an object that has already been defined using append name to site. The same as appending to a list.

Back on the server

For persistence across users, and sessions with your application, define a resource. This is another kind of object that has a couple of extra things it can include. Firstly, you can include a database as a named place to put things.

resource posts
  database posts
end posts

Database

A database is just somewhere you can put values under keys. A value under a key is a bit like a variable, so you set it and refer to is just like that.

set key "latest-post" of posts to "Hello, world"
...
key "latest-post" of posts

HTTP

A resource is an object that becomes accessible over the uniform HTTP interface of verbs, headers and documents. To handle an HTTP verb, such as GET against a resource, define a function in the resource with the appropriate name.

resource posts
  database posts
  when get => ...
  when post => ...
  when put => ...
  when delete => ...
end posts

Documents

A document to be exchanged with a resource is another kind of object. A document is also defined within a resource.

resource posts
  database posts
  
  document new-post
    title is "New post"
    date is call today
  end new-post
end posts

A document defined here also becomes an attribute of the resource that contains it.

Also like all other objects, a resource and a document can inherit from other objects with using, and can mixin other object through with. The parent of mixin does not need to be a resource or document, any kind of object will do. A document can also contain a headers object. By default, every document contains one, defining default values for certain required HTTP headers. If a headers object is defined within a document, this object will be merged into the default set – overriding any default values.

Submitting

To interact with a resource requires filling and then submitting a document.

fill new-post of posts from browser
  set title of new-post to "Hello, world!"
  post new-post to posts receiving into created
    ...
  end post
end new-post

fill takes a reference to the document within a resource to fill. This will make a copy of the document for the purposes of the block. The new document can then be manipulated within the block safely.

Information is submitted to the resource over HTTP with either post, get, put' or delete`.

Receiving

The receiving into part is optional and is there to handle any response. It takes two things: the name to attach to the response document (created in this case) and a function to process the response.

Indu will look at the response that it gets back and attach everything as the body of the variable you received into (created in the example above.)