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.
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
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
.
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
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”.
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
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
To call just any function: call ten-square
. To call a function with named arguments: call square with (number: 10)
.
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.
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 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 (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.
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.
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
.
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.
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
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
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
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.
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`.
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.)