Walnut/Ordinary Programming/Data Types and Control Flow
From Erights
Contents |
Simple data types, simple control flow
Here are some of the basics of the language:
# E sample # Comment on this piece of code def a := 3 var b := a + 2 b += 1 if (a < b) { println("a is less than b") } else { println("Wow, the arithmetic logic unit in this processor is confused") }
Variable declarations in E are made with the var statement. Variables that are only assigned a value once at creation (i.e., constants, or variables declared final) are created with the def statement. In E as in Java, "+=" is shorthand for adding the righthand value to the lefthand variable.
Single-line comments have a "#" at the beginning, and terminate with the end of line. The /**...*/ comment style is used only for writing javadoc-style E comments, discussed later. link here
Assignment uses the ":=" operator. The single equal sign "=" is never legal in E, use ":=" for assignment and "==" for testing equality. The function "println" prints to the console. The "if" statement looks identical to its Java equivalent, but the braces are required.
What is the end-of-statement delineator in E? In Java, you terminate a statement with a semi-colon. In E, the end-of-line is also the end-of-statement unless there is an open operation at the end of the line. In the example, the "if" statement's first line ends with an open brace; E knows the next line must be a continuation line. Some quick examples
This works ? def a := 1 + 2 + 3 + 4 # value: 10 And this works ? def b := 1 + 2 + > 3 + 4 # value: 10 But this does not work, because the first line can and does evaluate without a continuation, so the second line is a syntax error: ? def c := 1 + 2 ? + 3 + 4 # example syntax error: # + 3 + 4 # ^
The end-of-line statement termination of E makes it easy to use E for command lines, as in rune.
If your organization uses a line continuation convention that puts the operator at the beginning of the second line, you can use the explicit continuation character "\" as here:
This also works ? def c := 1 + 2 \ > + 3 + 4 # value: 10
Basic Types and Operators
The basic types in E are int, float, string, char, and boolean. All integer arithmetic is unlimited precision, as if all integers were BigIntegers.
Floats are represented as 64-bit IEEE floating point numbers. The operators +, -, * have their traditional meanings for integers and floats. The normal division operator "/" always gives you a floating point result. The floor divide operator "//" always gives you an integer, truncated towards negative infinity. So (-3.5 // 1) == -4.
E has 2 modulo operations: "%", like the Java modulo operator, returns the remainder of division that truncates towards zero. E also supplies "%%", which returns a remainder of division that truncates towards negative infinity.
Operator precedence is generally the same as in Java. In a few cases E will throw a syntax error and require the use of parentheses.
E's quasi-literals enable the easy processing of complex strings as described in detail later; here is a very simple example:
# E sample def printString := `Value of x is: $x`
wherein the back-ticks denote a quasi-literal, and the dollar sign denotes a variable whose value is to be embedded in the string.
"+" when used with strings is a concatenation operator as in Java. It automatically coerces other types on the right-hand if the left-hand operand is a string, but prints a warning as it does so.
&& and || and ! have their traditional meanings for booleans; true and false are boolean constants.
Strings are enclosed in double quotes. Characters are enclosed in single quotes, and the backslash acts as an escape character as in Java: '\n' is the newline character, and '\\' is the backslash character. Strings in E are so similar to strings in Java, it is easy to conclude they are identical when they are not. The protocol for E strings is detailed in the E javadoc.
== and != are the boolean tests for equality and inequality respectively. When the equality test is used between appropriately designated link to selfless here transparent immutables, such as integers, the values are compared to see if the values are equal; for other objects the references are compared to see if both the left and right sides of the operator refer to the same object. Chars, booleans, integers, and floating point numbers are all compared by value, as in Java. In addition, Strings, ConstLists, and ConstMaps link here are also compared by value, which makes it different from, and more natural than, Java.
Other transparent immutables (notably ConstLists and ConstMaps) will be introduced later. Additional useful features of transparent immutables are discussed under Distributed Computing.
There are some special rules about the behavior of the basic operators because of E's distributed security. These rules are described in the Under the Covers section later in this chapter.
Additional flow of control
We have already seen the if/then/else structure. Other traditional structures include:
- while (booleanExpression) {...}
- try{...} catch errorVariable {...} finally{...}
- throw (ExceptionExpressionThatCanBeAString)
- break (which jumps out of a while or for loop; if the break keyword is followed by an expression, that expression is returned as the value of the loop)
- continue (which jumps to the end of a while or for, and starts the next cycle)
- switch (expression) {match==v1{...} match==v2{...} ... match _{defaultAction}}
One structure that is more powerful than its Java counterpart is the for loop.
# E sample for i in 1..3 { println(i) } for j in ["a", 1, true] {println(j)}
In this simple example, i becomes 1, 2, 3 in succession. In the second, j becomes each of the elements of the list.
The for loop operates not only with number ranges, but also with lists, maps (i.e. hashtables), text files, directories, and other structures discussed later in this book. The expanded version of the for loop that is needed to get both keys and values out of maps is:
# E syntax for key => value in theMap { println(`Key: $key Value: $value`) } # You can get the index and the value from a list at the same time the same way for i => each in ["a", "b"] { println(`Index: $i Value: $each`) }
You can create your own data structures over which the for loop can iterate. An example of such a structure, and a brief explanation of the iterate(function) method you need to implement, can be found in the Library Packages: emakers section later in this chapter, where we build a simple queue object.
The Secret Lives of Flow Control Structures
Flow control structures actually return values. For example, the if-else returns the last value in the executed clause:
# E sample def a := 3 def b := 4 def max := if (a > b) {a} else {b}
This behavior is most useful when used with the when-catch construct described in the chapter on Distributed Computing.
The break statement, when used in a for or a while loop, can be followed by an expression, in which case the loop returns the value of that expression.
(Note: the following patch of code is used by updoc.e, the E testing tool, to enable execution of all the upcoming code that depends on Swing)
?? in new vat awtVat.e-awt ? pragma.syntax("0.9")