Getting Started - maxkatzmann/hydra GitHub Wiki
Welcome to the Hydra wiki!
In the following we explain how to use Hydra to create drawings in the hyperbolic plane.
Getting Started with Hydra
Hydra interprets code line by line. You are allowed to have at most one statement in each line. Consequently, there is no need for an indicator (like ;
) to separate statements. For example, the following Hydra code defines a variable a and assigns a value of 5.0 to it.
var a = 5
On the other hand, the following statements would be invalid and can not be interpreted:
var = 5 var b = 0 // Invalid assignment. There must only be one assignment per statement.
var a // Invalid assignment. Use 'a = 10.0' or 'var a = 10.0' to assign a variable.
Variables
As we have seen above, variables are defined using the keyword var
. Once a variable is defined, the value it contains can be accessed or new values can be assigned to it:
var a = 5 // a = 5
var b = a + 2 // b = 7
a = 2 * b // a = 14
Numerical values are internally represented as Doubles. Note that you cannot assign a value to an undefined variable, which means you always need to define a variable using the var
keyword, and assign an initial value to it, before further usage. It is, however, not allowed to define the same variable twice. Meaning the following code would lead to an error:
var a = 5
var a = 5 // Error in line 2: Redefinition of: 'a'.
Variables can be any combination of letters and numbers. Additionally, variables names can contain '_' but not at the beginning! This pattern is reserved for so called hidden variables, which will be introduced later.
Expressions
Hydra supports mathematical expressions containing the operators +
(addition), -
(subtraction), *
(multiplication), and /
(division). Multiplication and division operators are interpreted before addition and subtraction operators. Parentheses can be used to change the order of interpretation.
var a = 5 * 3 + 2 // a = 17
a = 5 * (3 + 2) // a = 25
Currently, Hydra supports one mathematical constant M_PI
, which is internally represented with C++'s M_PI
. Additionally, there is no support for the unary minus operator at the moment. However, 0 - x
works just fine.
Functions
In the following we explain how built-in functions work. Hydra supports a collection of mathematical functions like exp(x:)
which evaluates the exponential function at the passed parameter x
:
var a = exp(x: 3.4) // a = e^3.4 = 29.964100
All functions that take parameters have the following form: function(parameter1: value1, parameter2: value2, ...)
. The parameter names must not be omitted. An example of a built-in function that takes two parameters is random(from:to:)
which returns a number that is uniformly distributed within the passed bounds:
var a = random(from: 0.0, to: 2.0 * M_PI)
For a list of built-in functions, see Built-In Functions.
Additionally, Hydra supports the definition of custom functions using the following syntax.
func functionName(parameter1, parameter2) {
...
}
This function is then called as
functionName(parameter1: value1, parameter2: value2)
A custom function automatically returns the result of the last statement in the function. For example the code
func printAndReturnRandom() {
var r = random(from: 0, to: 5)
print(message: "The number is: \(r)\n")
r
}
var s = printAndReturnRandom()
print(message: "Can confirm: \(s)\n")
May lead to an output like
The number is: 0.164877
Can confirm: 0.164877
Note, that it is important to define the function before calling it for the first time. As can be seen above, strings can contain the contents of variables using the escape sequence \()
, i.e., the string "My number is \(1.5)"
is the same as "My number is 1.5"
.
Initializations
Besides primitive numbers, Hydra has a built-in type called Pol
that represents a polar coordinate. A Pol
object is defined by its radius r
and angular coordinate phi
. The initialization of a Pol
object looks just like a function call: Pol(r:phi:)
:
var origin = Pol(r: 0.0, phi: 0.0)
Property Access
The properties of a non-primitive object are accessed using .
-notation.
var point = Pol(r: random(from: 0.0, to: 10.0), phi: M_PI / 4.0) // A point with a random radius
var radius = point.r // The radius of the point
Loops
Hydra supports range-based for-loops using the following notation:
for i in [L, S, U] {
...
}
There i
is the loop variable , L
is the lower bound, S
is the step size and U
is the upper bound. The range includes the lower bound. The range only includes the upper bound, if i
= U
at some point during the execution. The loop variable i
may be manipulated in the loop. Hydra also supports nested loops.
for i in [0, 1, 3] {
print(message: "\(2.0 * i)\n")
}
// 0
// 2
// 4
// 6
for i in [0, 2, 5] {
print(message: "\(i * i)\n")
}
// 0
// 4
// 16
for i in [0, 1, 2] {
for j in [0, 1, i] {
print(message: "\(i + j)\n")
}
}
// 0
// 1
// 2
// 2
// 3
// 4