Contents

Searching...

Statements

And so we begin...

A statement is a basic unit of execution in Kal. It performs an operation. You have seen
stdout
in the previous chapter. It simply prints information to the screen. Any information passed to a statement is its argument. A statement can have multiple arguments.

Take
stdout
for example.
stdout "Hello" " Kal! " "\n".

hello.kal

As you may have noticed, all Kal statements, except for preprocessor statements, beginning and ending of blocks end with a period (
.
).

You can also split statements across multiple lines as long as they end with a period.
stdout "Hello"
"Kal!"
"\n".

hello.kal

You don't always need to create and pass values immediately. You may want to store them beforehand, process them and use them later. You can store values inside variables. Use
var
statements to create variables.
var planet = "Earth".

variables.kal

Variables can directly be used wherever needed.
var planet = "Earth".
stdout "From " planet "\n".

variables.kal

You can have as many
var
statements as needed. When declaring a large number of variables together, the
var
statement can be extended using commas (
,
).
var name = "Kal", planet = "Earth".
stdout name " is from " planet "\n".

variables.kal

Variables are called “variables” for a reason. Their values can be changed. You can reassign a value to a variable directly without using the
var
statement again.
var g = 10.
stdout "g = " g "\n".
;; Variable reassignment g = 9.8. stdout "g = " g "\n".

reassignVar.kal

Kal is dynamically typed. A variable can be reassigned to a value to different type.
var pi = "pi". ;; string
pi = 3.14. ;; float

dynamicReassign.kal

Wait, what were those semi-colons? Semi-colons in Kal are used to write comments. Comments are ignored by the Kal interpreter and are used to write instructions for the programmers. Another use case is to comment out code which you don't wish to execute.

Kal supports both single-line and multi-line comments. Single-line comments start with
;;
and comment out everything till the end of the line. On the other hand, multi-line comments start and end with
;
and can be used to comment as many lines as needed.
;; single line comment
;
multi
line
comment
;

stdout "Not a comment".

comments.kal

Kal offers 5 data types: Numbers, Strings, Lists, Dictionaries and Nulls.

Numbers support integers and floats together.
var pi = 3.14.
var value = 123.

numbers.kal

Strings represent textual data. They start and end with a double quote symbol (
"
).
var planet = "Earth".

strings.kal

Have you noticed that
\n
character before? That's an escape character. An escape character has a special meaning. In this case,
\n
represents a new line. Every escape character starts with a backslash,
\
.

Kal supports the following escape characters.

NameCharacter
New Line\n
Tab\t
Backspace\b
Backslash\\
Double Quote\"
Carriage Return\r


Lists are collections of multiple values in a single container. Lists start and end with
[
and
]
respectively with values separated by a comma (
,
).
var celestialBodies = ["Sun", "Earth", "Moon"].

lists.kal

If a list grows large, it can be split into multiple lines.
var celestialBodies = [
    "Sun",
    "Earth",
    "Moon"
].

lists.kal

Lists in Kal are heterogenous. This means, you can have values of different types inside the same list.
var data = ["Pi", 3.14].

heterogenousList.kal

As the complexity of your data grows, you can nest one list into another.
;; a 3x3 matrix
var matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
].

nestedList.kal

You can use
[]
symbols to access values from the list via an index. Index is the position of the item in the list. Indexes start from 0 in Kal.
var data = [1, 2, 3].
stdout "Value = " data[1] "\n".

listAccess.kal

Elements inside the list can also be reassigned in a similar fashion.
var data = [1, 2, 3].
stdout "Before = " data "\n".
data[1] = 20. stdout "After = " data "\n".

listElementReassign.kal

A negative index can be used to access a list from the end. Negative indexes start with -1.
var data = [1, 2, 3].
stdout "Last = " data[-1] "\n".
data[-1] = 4. stdout "Final = " data "\n".

negativeIndex.kal

Symbols
[]
can be chained together to get/reassign elements from/to a nested list.
;; 2x2 matrix
var matrix = [
    [4, 5],
    [6, 7]
].
stdout "--- Before ---\n". stdout "Matrix = " matrix "\n". stdout "Diagonal = " matrix[0][0] ", " matrix[1][1] "\n".
stdout "--- After ---\n". matrix[0][0] = 10. matrix[1][1] = 20.
stdout "Matrix = " matrix "\n". stdout "Diagonal = " matrix[0][0] ", " matrix[1][1] "\n".

nestedListReassign.kal

Similarly, Dictionaries are also heterogenous collections of elements in a key-value pair. A Dictionary starts with
#(
and ends with
)
.
var data = #(
    planet -> "Earth",
    species -> "Humans"
).

dict.kal

Keys and values are separated by
->
whereas key-value pairs are separated by commas (
,
). Keys are stored as strings, whereas values can be of any type. If keys contain spaces, surround them with double quotation marks (
""
).
var data = #(
    planet -> "Earth",
    species -> "Humans",
    "total hours" -> 24
).

dict.kal

Access symbols (
[]
) can be used to access a specific value using its key.
var data = #(
    planet -> "Earth",
    species -> "Humans",
).
stdout "Species = " data["species"] "\n".

dictAccess.kal

Similarly, values can be reassigned.
var data = #(
    planet -> "Earth",
    species -> "Humans",
).
stdout "Before:\n". stdout data "\n".
stdout "After:\n". data["species"] = "Trees". stdout data "\n".

reassignValues.kal

You can add new key-value pairs in the same fashion.
var data = #(
    planet -> "Earth",
    species -> "Humans",
).
data["total hours"] = 24. stdout data "\n".

newPair.kal

Dictionaries can be nested.
[]
symbols can be chained together to access or reassign values.
var data = #(
    planet -> "Earth",
    resources -> #(
        trees -> "Wood",
        ores -> "Metals",
        oceans -> "Water"
    )
).
stdout data["resources"]["oceans"] "\n".
data["resources"]["oceans"] = "Salt".
stdout data["resources"]["oceans"] "\n".

nestedDict.kal

Lists and Dictionaries can be nested within each other.
;; dict
var data = #(
    planet -> "Earth",
;; nested list resources -> ["Wood", "Metal", "Water"],
;; list biomes -> [ ;; nested dict #( land -> ["forest", "desert"], ), #( water -> ["ocean", "river"] ) ] ).
stdout data["resources"][2] " comes from the " data["biomes"][1]["water"][0] ".\n".

nestedDictList.kal

Null represents absence of value. Variables set to
null
can be reassigned to actual values later.
var data = null.
stdout "Data = " data "\n".
data = 100. stdout "Data = " data "\n".

null.kal

Uninitialized variables are set to
null
.
var data.
stdout "Data = " data "\n"

nullInitialize.kal

If you are unsure of the type of the variable you are dealing with, you can confirm it using the type statement.

So far you have seen statements that perform operations. Oftentimes that is not enough. You’ll also be requiring the end result of a statement. Kal statements return values wherever appropriate.

type
is one of those statements.
var name = "Kal".
type name -> t.
stdout "Type = " t "\n".

type.kal

Observe the syntax of the
type
statement:
  • type
    is the name of the statement.
  • name
    is the argument passed to it.
  • ->
    is the target operator.
  • t
    is the variable that holds the return value.
The target operator assigns the return value to the provided variable. If the variable already exists, it's reassigned to hold the return value. If not, a new variable is declared and the return value is assigned.

Alternatively, you can convert a statement into an expression by wrapping it into
$(
and
)
. Doing so removed the need to use a target operator. The return value also becomes part of a larger expression.
var name = "Kal".
var t = $(type name).
stdout "Type = " t "\n".

typeExpr.kal

Conversion of types between numerical and string data is possible using the
as
operator. The
as
operator takes the value to be converted as the first operand and the type to be converted to as the second operand.
var data = "123" as int.
stdout $(type data) "\n".

strToInt.kal

var data = 456 as str.
stdout $(type data) "\n".

intToStr.kal

var data = "3.14" as float.
stdout $(type data) "\n".

strToFloat.kal

Number is an umbrella term for both integers and floats. Conversion of a float to integer removes the fractional part.
var data = 3.14 as int.
stdout data "\n".
stdout $(type data) "\n".

floatToInt.kal



Complicated data involving string literals and variables can be easily composed together. Formatted strings start with f( and end with ). Values encompassed inside these symbols are separated by commas.

The very first value is the template string which defines dynamic parts using
{}
as a place holder. Rest of the values are positionally placed inside the template string replacing their respective placeholders.
var string = f("Formatted {}!", "String").
stdout string "\n".

fstr.kal

Variables can also be embedded dynamically.
var data = "String".
var string = f("Formatted {}!", data).
stdout string "\n".

dynFstr.kal

Expressions are evaluated and used as values.
var string = f("5 + 8 = {}", (5 + 8)).
stdout string "\n".

exprFstr.kal

There can be multiple placeholders and values to embed.
var string = f("{} + {} = {}", 5, 8, (5 + 8)).
stdout string "\n".

multiFstr.kal

You can nest formatted strings together.
var string = f(
    "For{} {}",
    "matted",
    f(
        "Str{}{}",
        "ing",
        "!"
    )
).
stdout string "\n".

nestedFstr.kal

You may need to extract values from lists and dictionaries into distinct variables. This is called unpacking.

Use the list's
[
and
]
syntax to unpack variables from a list.

First, let's see how values are extracted without unpacking.
var data = [1, 2, 3].
var x = data[0], y = data[1], z = data[2].
stdout x " " y " " z "\n".

extractValues.kal

Compact this using unpacking.
var data = [1, 2, 3].
var [x, y, z] = data.
stdout x " " y " " z "\n".

unpack.kal

You are not required to unpack all values. Consider unpacking 2 values from a list of 3 values.
var data = [1, 2, 3].
var [x, y] = data.
stdout x " " y "\n".

partialUnpack.kal

Values are unpacked sequentially. The placeholder symbol,
_
is used to maintain the sequence without unpacking a value from that position.

Consider unpacking the first and third value from a list.
var data = [1, 2, 3].
var [x, _, z] = data.
stdout x " " z "\n".

placeholderUnpack.kal

The syntax can be nested to unpack more complex structures.
var data = [1, 2, [3, 4]].
var [_, x, [_, y]] = data.
stdout x " " y "\n".

nestedUnpack.kal

Here, data contains a nested list. The unpack syntax matches the same structure to extract 2 and 4.

Similarly, values can be unpacked from dictionaries.
var data = #(
    planet -> "Earth",
    species -> "Human"
).
var #(species) = data. stdout "Hi " species "\n".

dictUnpack.kal

List and Dictionary unpacking syntaxes can be combined together in case of nested structure.
var data = [
    "Hi",
    "Hello",
    #(
        name -> "Kal",
        runsOn -> "Interpreter"
    )
].
var [_, greet, #(name)] = data.
stdout greet " " name "\n".

combinedUnpack.kal

Variables in Kal are evaluated as soon as they are initialized. It's possible to delay the evaluation to the point where the variable is actually used.

Similar to a
var
statement, the
inert
statement declares a lazy variable.
inert data = 5 + 8.
stdout data "\n".

inert.kal

In this case, the
data
variable was defined but its value was not evaluated immediately. It's evaluated when it is used on the next line.

Let's look at another example which makes more sense.
var a = 20.
inert x = a + 10. a = 90.
stdout x "\n".

lazyEval.kal

Let's break this down line by line.
  • A variable
    a
    is initialized to value 20.
  • An inert variable
    x
    is lazily initialized to expression
    a + 10
    . However, it's not evaluated immediately, so the final value 30 is never obtained.
  • a
    is reassigned to 90.
  • x
    is used by
    stdout
    and thus the expression
    a + 10
    is revisited and evaluated at this point. The value of a has changed to 90, therefore the final evaluated value of
    x
    becomes 90 + 10 =
    100
    .
Inert variables may cause unintended side-effects and must be used with caution.
Since the evaluation is delayed for inert variables, you may use it in cases where regular variables may not work.
inert data = x + y. ;; no error
var x = 200, y = 100.
stdout data "\n".

noErrInert.kal

So far you have used
stdout
which is used to write to the terminal.
stdin
allows you to read data from user input into a variable.
stdin "Name? " -> name.
stdout "Hello " name "\n".

stdin.kal