The Basics


In this tutorial I'll cover the basics of Aetherlang, which includes:

WARNING: I DO NOT RECOMMEND ANYONE NOT FAMILIAR WITH PROGRAMMING TO START WITH THIS LANGUAGE. IT IS OBSCURE, DEMONSTRATIONAL AND WILL CERTAINLY RUIN YOUR FURTHER CAREER.

"Hello, World!"

Once you have your Aetherlang interpreter installed properly, try running this simple program on it by saving it into a ".aeth" file and executing.

Any tutorial starts with a simple program printing "Hello, World" to console. This one is no exception. And since you are probably already dying from excitement, let me show it to you:

  @ WE NEED THESE TWO LIBRARIES: "BASE" AND "IO"
  USE :BASE
  USE :IO
  @ ACTUALLY PRINTING TEXT
  PRINTLN "HELLO WORLD"

Aetherlang code is not case-sensitive, so you can rewrite the same code in lowercase and try to run it. As you can guess from the example above, any text after @ ("at" symbol) is not evaluated.

Constants and Variables

Now we're ready for some serious stuff. Let us define some constant names in the main namespace and some variables in ether.

  USE :BASE
  USE :IO
  @ MAKE A & B AND CALCULATE THEIR SUM
  A = 5
  B = 10
  PRINTLN (+ A B)

The above code will output 15. You may have noticed that to compute A+B we need to put parentheses and place the operation (+) first. That is how you do it in Aetherlang. If you don't put parentheses, you are likely to get messy output because the interpreter will see the "println" function and three other names (including "+") that it will consider function's arguments:

  @ BAD CODE
  USE :BASE
  USE :IO
  A = 5
  B = 10
  PRINTLN + A B @ prints "AE_add 5 10" on my version

Now, because of EDPP style, neither of these A and B is variable. In fact, not only they are both immutable but also constant:

  @ BAD CODE
  USE :BASE
  USE :IO
  A = 5
  B = 10
  A = + A B @ ERROR: CONSTANT "A" OF TYPE "NUMBER" CANNOT BE REDEFINED
  PRINTLN A

Aetherlang does provide a separate namespace for variables, though. It is called ether or aether. For name to be defined there, you need to explicitly put "aether." prefix to it:

  USE :BASE
  USE :IO
  AETHER.A = 5
  B = 10
  AETHER.A = + AETHER.A B
  PRINTLN AETHER.A

Arrays

Of course, you can assign names other types of values besides numbers. More on basic Aetherlang types can be found here. Let us see how arrays work, for instance.

  USE :BASE
  USE :IO
  A = COLLECT 1 2 3 4 5
  PRINTLN "A is" A
  PRINTLN "first of A is" (FIRST A)

Note that "collect" can be replaced with "array" or "arr" as these are synonyms in Aetherlang. All of them can be used to allocate arrays (sequences) of data.

Functions

These may come in handy when you need to perform a compund operation multiple times.

  use :base
  use :io
  function f x y = / (* x y) (+ x y)
  println f @ printing the function itself
  println (f 5 6) @ printing the result of the function called with 5 and 6 as its arguments
  println (f 1.2 3.4)

Here we've created a function "F" that takes two arguments "x" and "y" and computes "(x*y)/(x+y)". "F" can be used exactly the same way we used "println" and "collect".

Let us now create our implementation of "collect":

  use :base
  use :io
  function ar! = oargs @ you can use any characters unused in Aetherlang's syntax to define names, including "!"
  a = ar! 1 2 3 4 5
  println "array: " a

Seems like "collect" is a very simple function to rewrite ourselves. And it is! Because we can use a certain trick from Aetherlang's Core: when you call a function and give it too many arguments, Aetherlang allocates an array under the name "oargs" which stands for "optional arguments" and puts all the extra arguments in it. Thus, we can create a function that takes no arguments at all and simply set its return value to "oargs".

It is important to notice that in Aetherlang you CANNOT call a function with no arguments. Built-in functions that require no data declare "dummy" arguments. Typically, you would call such functions by passing "void" as an argument:

  ...
  f void
  ...

Where "void" is a predefined constant you should use to resemble the absence of value or logical fallacy.

Quotes and Symbols

Now, in a nutshell this all works very simple: You can quote pieces of code to create what is known as symbols. These symbols are like strings (strings of characters created with quotation marks "..."), but they're used to quote programming languages rather than natural ones:
  USE :BASE
  USE :IO
  PRINTLN "HELLO WORLD" @ A STRING
  PRINTLN :(HELLO WORLD) @ A SYMBOL

This is a way of doing meta-coding in Aetherlang. Or rather, it is THE way of doing it. There are no macros here, you can only define functions that operate with symbols instead. One of such functions is "USE" that we've already met. It takes the name of the library to import as a symbol, however, if you pass it the name of the library as string, it will be fine.

You will see that blending macros and functions can get a bit uncomfortable, though, but I plan to change it by introducing a new way of dealing with them in v0.3.

Condition Function (IF)

Aetherlang has a very simple tool for condition statements. It is implemented as a function called "IF" and is available in base.

  use :base
  use :io
  use :math
  a = intinput "Enter a number: "
  if (eq 0 (% A 2)) :(println A "is divisible by 2") :(println A "is not divisible by 2")

If (eq 0 (% A 2)) evaluates to void, then "if" evaluates the third argument (which is :(println A "is not divisible by 2") in this case). However, when the first argument is not void, the second one gets evaluated. You can skip the third argument entirely and then "if" will assume there is :void given.

Next tutorial: Dimensions and Rituals