-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchapter2.html
More file actions
57 lines (48 loc) · 61.2 KB
/
chapter2.html
File metadata and controls
57 lines (48 loc) · 61.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<!DOCTYPE html>
<html>
<head>
<title>L.B.Stanza</title>
<link type="text/css" rel="stylesheet" href="resources/mainstyle.css">
<link type="text/css" rel="stylesheet" href="resources/documentation.css">
</head>
<body>
<table class="wrap">
<tr><td colspan="3" class="banner">
<a href="index.html">Home</a><a href="stanzabyexample.html">Table of Contents</a><a href="chapter1.html">Previous Chapter</a><a href="chapter3.html">Next Chapter</a>
</td></tr>
<tr>
<td class="nav">
<h1>NAVIGATION</h1>
<h2><a href="#anchor132">The Very Basics</a></h2><h3><a href="#anchor2">Project Framework</a></h3><h4><a href="#anchor133">Create basics.stanza</a></h4><h4><a href="#anchor134">Compile and Run</a></h4><h4><a href="#anchor135">Indentation</a></h4><h3><a href="#anchor3">Printing Simple Messages</a></h3><h4><a href="#anchor136">Strings</a></h4><h4><a href="#anchor137">Printing Strings</a></h4><h4><a href="#anchor138">Print Without a New Line</a></h4><h4><a href="#anchor139">Ints</a></h4><h4><a href="#anchor140">Printing Integers</a></h4><h4><a href="#anchor141">Printing Multiple Things</a></h4><h4><a href="#anchor142">Formatted Printing</a></h4><h4><a href="#anchor143">Where's the Commas?</a></h4><h3><a href="#anchor4">Lexical Structure</a></h3><h4><a href="#anchor144">Lexemes</a></h4><h4><a href="#anchor145">Numbers</a></h4><h4><a href="#anchor146">Operators</a></h4><h4><a href="#anchor147">Identifiers</a></h4><h4><a href="#anchor148">Opening Brackets</a></h4><h3><a href="#anchor5">Comments</a></h3><h3><a href="#anchor6">Operators</a></h3><h4><a href="#anchor149">Basic Arithmetic</a></h4><h4><a href="#anchor150">Bitwise Arithmetic</a></h4><h4><a href="#anchor151">Operator Precedence</a></h4><h4><a href="#anchor152">Unary Operators</a></h4><h3><a href="#anchor7">Values</a></h3><h4><a href="#anchor153">Syntax</a></h4><h4><a href="#anchor154">Breaking up Complicated Expressions</a></h4><h4><a href="#anchor155">Types</a></h4><h4><a href="#anchor156">Type Inference</a></h4><h3><a href="#anchor8">Variables</a></h3><h4><a href="#anchor157">Types</a></h4><h4><a href="#anchor158">Type Inference</a></h4><h4><a href="#anchor159">Uninitialized Variables</a></h4><h3><a href="#anchor9">Functions</a></h3><h4><a href="#anchor160">Return Value</a></h4><h4><a href="#anchor161">Side Effects</a></h4><h4><a href="#anchor162">Return Type</a></h4><h4><a href="#anchor163">Argument Types</a></h4><h4><a href="#anchor164">Example: String Arguments</a></h4><h4><a href="#anchor165">Leaving off the Argument Type</a></h4><h4><a href="#anchor166">The Unknown Type</a></h4><h3><a href="#anchor10">Comparisons</a></h3><h4><a href="#anchor167">Comparison Operators</a></h4><h4><a href="#anchor168">Logical Operators</a></h4><h3><a href="#anchor11">If Expressions</a></h3><h4><a href="#anchor169">Result of an If Expression</a></h4><h4><a href="#anchor170">Default Else Branch</a></h4><h4><a href="#anchor171">Nested If Expressions</a></h4><h4><a href="#anchor172">True and False</a></h4><h3><a href="#anchor12">Expression Sequences</a></h3><h3><a href="#anchor13">Structure Through Indentation</a></h3><h3><a href="#anchor14">While Loops</a></h3><h3><a href="#anchor15">For "Loops"</a></h3><h4><a href="#anchor173">Counting Loops</a></h4><h4><a href="#anchor174">Range Expressions</a></h4><h3><a href="#anchor16">Labeled Scopes</a></h3><h4><a href="#anchor175">For Returning Early</a></h4><h4><a href="#anchor176">For Breaking From Loops</a></h4><h4><a href="#anchor177">General Form</a></h4><h4><a href="#anchor178">Well-Typed Labeled Scopes</a></h4><h3><a href="#anchor17">Scopes and the Let Expression</a></h3><h3><a href="#anchor18">Arrays</a></h3><h4><a href="#anchor179">Putting Things In</a></h4><h4><a href="#anchor180">Getting Things Out</a></h4><h4><a href="#anchor181">Asking For Its Length</a></h4><h4><a href="#anchor182">Arrays and Loops</a></h4><h3><a href="#anchor19">Tuples</a></h3><h4><a href="#anchor183">Returning Multiple Values</a></h4><h3><a href="#anchor20">Basic Types</a></h3><h3><a href="#anchor21">Structs</a></h3><h4><a href="#anchor184">Getter Functions</a></h4><h4><a href="#anchor185">Struct Type</a></h4><h3><a href="#anchor22">Exercises</a></h3>
</td>
<td class="main">
<h1 id="anchor132">The Very Basics</h1><p>This chapter introduces the basic programming constructs in Stanza. After this chapter, you'll be able to write basic programs that do simple things.</p><h2 id="anchor2">Project Framework</h2><p>Follow these steps to set up a project framework.</p><h3 id="anchor133">Create basics.stanza</h3><p>In your <code>stanzaprojects</code> directory, create a file called <code>basics.stanza</code> containing</p><pre><code>defpackage mypackage :<br> import core<br><br>defn main () :<br> println("Code goes here")<br><br>main()</code></pre><p>Again, make sure you do not forget the space between the <code>main</code> and the <code>()</code>. We'll explain why this is necessary when we discuss Stanza's lexical structure.</p><h3 id="anchor134">Compile and Run</h3><p>Compile and run the basic framework by typing the following in the terminal</p><pre><code>stanza basics.stanza -o basics<br>./basics</code></pre><p>The basic framework should print out</p><pre><code>Code goes here</code></pre><p>Follow the chapter and try out the examples by replacing the <code>println</code> command with the example code.</p><h3 id="anchor135">Indentation</h3><p>Try changing the basic framework to</p><pre><code>defpackage mypackage :<br>import core<br><br>defn main () :<br> println("Code goes here")<br><br>main()</code></pre><p>and try to compile it. It won't work. My Stanza installation says</p><pre><code>Syntax Error: Import clause expected here.</code></pre><p>Indentation is important in Stanza programs. Be careful when trying out the examples. </p><p>And don't use tabs. Stanza won't let you. We don't like tabs.</p><h2 id="anchor3">Printing Simple Messages</h2><p>Printing is important. It's the only way to observe what your program is doing.</p><h3 id="anchor136">Strings</h3><p>This is a <span style="font-style:italic;">string</span>. </p><pre><code>"Timon and Pumbaa"</code></pre><p>It's a bunch of characters surrounded in double quotes.</p><h3 id="anchor137">Printing Strings</h3><p>Use the <code>println</code> function to print strings.</p><pre><code>println("Timon")<br>println("and")<br>println("Pumbaa")</code></pre><p>prints out</p><pre><code>Timon<br>and<br>Pumbaa</code></pre><h3 id="anchor138">Print Without a New Line</h3><p>Use the <code>print</code> function to print strings without starting a new line at the end.</p><pre><code>print("Timon")<br>print(" and")<br>print(" Pumbaa")</code></pre><p>prints out</p><pre><code>Timon and Pumbaa</code></pre><h3 id="anchor139">Ints</h3><p>This is an <span style="font-style:italic;">integer</span>.</p><pre><code>42</code></pre><p>It's a bunch of digits, and represents the integers that you were taught in school.</p><h3 id="anchor140">Printing Integers</h3><p>The <code>print</code> and <code>println</code> function works on integers too.</p><pre><code>print(1)<br>print(" and a ")<br>print(2)<br>print(" and a ")<br>println(1)<br>println(2)<br>println(3)<br>println(4)</code></pre><p>prints out</p><pre><code>1 and a 2 and a 1<br>2<br>3<br>4</code></pre><p>Actually <code>print</code> and <code>println</code> works on a lot of things. We'll learn about that later.</p><h3 id="anchor141">Printing Multiple Things</h3><p>Calling <code>println</code> repeatedly to print multiple things is tedious. Use <code>println-all</code> to print out multiple things.</p><pre><code>println-all([1 " and a " 2 " and a "])<br>println-all([1 2 3 4 "."])</code></pre><p>prints out</p><pre><code>1 and a 2 and a <br>1234.</code></pre><p>If you don't want to start a new line at the end, use <code>print-all</code> instead.</p><pre><code>print-all([1 " and a " 2 " and a "])<br>println-all([1 2 3 4 "."])</code></pre><p>prints out</p><pre><code>1 and a 2 and a 1234.</code></pre><p>Don't fret about the <code>[]</code> brackets for now. They create <span style="font-style:italic;">tuples</span>. We'll learn about those later.</p><h3 id="anchor142">Formatted Printing</h3><p>Sometimes it's tedious to print multiple things even with <code>println-all</code>. Here's how to print things according to a <span style="font-style:italic;">format string</span>.</p><pre><code>println("%_ and a %_ and a %_, %_, %_, %_!" % [1 2 1 2 3 4])</code></pre><p>prints out</p><pre><code>1 and a 2 and a 1, 2, 3, 4!</code></pre><p>Notice that you're calling the same <code>println</code> function that you've already learned. The <code>%</code> operator is what's doing all the work. We'll learn other operators later.</p><h3 id="anchor143">Where's the Commas?</h3><p>Some of you may have noticed the lack of commas in the examples. Try adding them back in.</p><pre><code>println("%_ and a %_ and a %_, %_, %_, %_!" % [1, 2, 1, 2, 3, 4])</code></pre><p>still prints out</p><pre><code>1 and a 2 and a 1, 2, 3, 4!</code></pre><p>Commas are treated identically to spaces in Stanza. (Unless they are part of a string.) Try going crazy!</p><pre><code>println("%_ and a %_ and a %_, %_, %_, %_!" % [1 2,1,2,,,,3,,,,,4])</code></pre><p>The above still prints out what it used to. But don't do that. That was just an example.</p><h2 id="anchor4">Lexical Structure</h2><p>Before compilation, a Stanza program is <span style="font-style:italic;">lexed</span> into individual identifiers, numbers, and lists. Here are the rules that you'll need to know.</p><h3 id="anchor144">Lexemes</h3><p>The first thing that Stanza does is break down a program into a sequence of <span style="font-style:italic;">lexemes</span>, where each lexeme is separated by either whitespace or one of the following characters.</p><pre><code>, . : & | < > [ ] { } ( )</code></pre><h3 id="anchor145">Numbers</h3><p>A number is a lexeme that begins with a digit, or a hyphen followed by a digit. Here are some examples.</p><pre><code>3<br>50<br>-13<br>100L</code></pre><h3 id="anchor146">Operators</h3><p>An operator is any lexeme that is made up of the following characters.</p><pre><code>~ ! @ # $ % ^ * + - = / . : & | < ></code></pre><p>Here are some example operators.</p><pre><code>+<br>*<br>&<br>&&<br>+=<br>>>><br><+><br>::=<br><^.^></code></pre><h3 id="anchor147">Identifiers</h3><p>An identifier is any lexeme that is not a number or operator. Here are some examples.</p><pre><code>x<br>timon<br>timon_and_pumbaa<br>timon-and-pumbaa<br>#timon<br>$timon<br>timon?<br>x+one<br>x1<br>x+1-3</code></pre><h3 id="anchor148">Opening Brackets</h3><p>Syntactically, an identifier followed <span style="font-style:italic;">immediately</span> by a opening bracket character is treated <span style="font-style:italic;">differently</span> than if the two were separated by spaces. For example</p><pre><code>f(x)</code></pre><p>is syntactically different than</p><pre><code>f (x)</code></pre><p>The former calls the function <code>f</code> with <code>x</code>. The latter is simply the function <code>f</code> followed by the value <code>x</code>.</p><p>This is similar to how</p><pre><code>ab</code></pre><p>is syntactically different than</p><pre><code>a b</code></pre><p>The two mean different things. Please keep this in mind when following the examples in this book. For example, this is why it was stressed to you to remember the space after <code>main</code> in</p><pre><code>defn main () :<br> ...</code></pre><p>Additionally, </p><pre><code>f[x]</code></pre><p>is syntactically different than</p><pre><code>f [x]</code></pre><p>and</p><pre><code>f{x}</code></pre><p>is syntactically different than</p><pre><code>f {x}</code></pre><p>and</p><pre><code>f<x></code></pre><p>is syntactically different than</p><pre><code>f <x></code></pre><h2 id="anchor5">Comments</h2><p>Comments begin with the <code>;</code> character, and every following character in the line will be regarded as a comment and won't affect the behaviour of the code. Here's an example of using comments.</p><pre><code>;My favorite characters<br>println("Timon") ;The small one<br>println("and")<br>println("Pumbaa") ;and the smart one</code></pre><p>Code without comments is very difficult to understand. Use comments often.</p><h2 id="anchor6">Operators</h2><p></p><h3 id="anchor149">Basic Arithmetic</h3><p>To add two numbers together, use the <code>+</code> operator. </p><pre><code>println(10 + 32)</code></pre><p>prints out</p><pre><code>42</code></pre><p>That means the result of adding <code>32</code> to <code>10</code> is <code>42</code>. We say that the expression <code>10 + 32</code> <span style="font-style:italic;">returns</span> <code>42</code>. We'll learn later why we use the word <span style="font-style:italic;">returns</span>. </p><p>Here are examples of using the other arithmetic operators.</p><pre><code>68 + 32 ;Addition<br>68 - 32 ;Subtraction<br>68 * 32 ;Multiplication<br>68 / 32 ;Division<br>68 % 32 ;Modulus</code></pre><h3 id="anchor150">Bitwise Arithmetic</h3><p>Here are examples of using the bitwise operators.</p><pre><code>24 << 2 ;Left Bit Shift<br>24 >> 2 ;Right Bit Shift<br>24 >>> 2 ;Arithmetic Right Bit Shift<br>24 & 2 ;Bitwise And<br>24 | 2 ;Bitwise Or<br>24 ^ 2 ;Bitwise Xor</code></pre><h3 id="anchor151">Operator Precedence</h3><p>All the operators are <span style="font-style:italic;">left associative</span>. This means that in the following expression</p><pre><code>1 + 2 - 3 + 4 - 5 + 6</code></pre><p>the operators are applied left to right. The above is equivalent to</p><pre><code>((((1 + 2) - 3) + 4) - 5) + 6</code></pre><p>In expressions containing a mix of operators, the operators with highest precedence are grouped together first, followed by the operators with second highest precedence, until you reach the operators with lowest precedence. The shift operators (<code><<</code>, <code>>></code>, <code>>>></code>) have precedence 3. The multiply, divide, modulo, bitwise and, and bitwise xor operators (<code>*</code>, <code>/</code>, <code>%</code>, <code>&</code>, <code>^</code>) have precedence 2. Addition, subtraction, and bitwise or, (<code>+</code>, <code>-</code>, <code>|</code>), have precedence 1.</p><p>The following expression</p><pre><code>3 + 2 << 2 * 3 + 3 << 1</code></pre><p>first groups the precedence 3 operators</p><pre><code>3 + (2 << 2) * 3 + (3 << 1)</code></pre><p>followed by the precedence 2 operators</p><pre><code>3 + ((2 << 2) * 3) + (3 << 1)</code></pre><p>followed by the precedence 1 operators</p><pre><code>(3 + ((2 << 2) * 3)) + (3 << 1)</code></pre><h3 id="anchor152">Unary Operators</h3><p>Here's how to negate a number.</p><pre><code>(- 3)</code></pre><p>The parentheses are not optional! </p><p>Here's how to flip all the bits in a number.</p><pre><code>(~ 3)</code></pre><p>Again, the parentheses are not optional! This is different than most other languages. There's a good reason for this. But don't forget them! </p><h2 id="anchor7">Values</h2><p></p><h3 id="anchor153">Syntax</h3><p>The statement</p><pre><code>val a:Int = 3 * 71</code></pre><p>calculates the result of <code>3 * 71</code> and <span style="font-style:italic;">stores</span> the result in the <span style="font-style:italic;">value</span> <code>a</code>. </p><p>After the storing the result in <code>a</code>, you can then use that value afterwards by name.</p><pre><code>println(a)</code></pre><p>You cannot change what is stored in a value once it is initialized. </p><h3 id="anchor154">Breaking up Complicated Expressions</h3><p>You can use values to break up complicated expressions into smaller ones.</p><pre><code>println(1 + 30 * 2 * 3 - 30 / (3 << 1))</code></pre><p>can be rewritten as</p><pre><code>val a:Int = 30 * 2 * 3<br>val b:Int = 30 / (3 << 1)<br>println(1 + a - b)</code></pre><h3 id="anchor155">Types</h3><p>The <code>Int</code> in the previous example is called a <span style="font-style:italic;">type annotation</span>. It says that only an <span style="font-style:italic;">integer</span> can be stored in <code>a</code>. </p><p>Stanza won't let you store anything else into <code>a</code>. We can try to store a string</p><pre><code>val a:Int = "Timon"</code></pre><p>but attempting to compile it gives us this error.</p><pre><code>Cannot assign expression of type String to value a with declared type Int.</code></pre><p>If you want to store a string into <code>a</code>, then you have to declare it like this.</p><pre><code>val a:String = "Timon"</code></pre><p>Later, we will learn more about types and about types other than <code>Int</code> and <code>String</code>. </p><h3 id="anchor156">Type Inference</h3><p>If you leave off the type annotation</p><pre><code>val a = 3 * 71</code></pre><p>then Stanza figures out the type based on the expression it's initialized with.</p><p>Most Stanza programmers leave off type declarations for values.</p><h2 id="anchor8">Variables</h2><p>A variable is declared like a value, but using <code>var</code> instead of <code>val</code>.</p><pre><code>var a:Int = 10 + 30</code></pre><p>Just like a value, the result of calculating <code>10 + 30</code> is stored in the variable <code>a</code>. </p><p>And just like a value, you can refer to it by name afterwards.</p><pre><code>println(a)</code></pre><p>The difference is that, even after it is initialized, you can still store something <span style="font-style:italic;">else</span> into a variable. </p><pre><code>var a:Int = 3 * 71<br>println(a)<br>a = -10<br>println(a)</code></pre><p>prints out</p><pre><code>213<br>-10</code></pre><p>After we print out <code>a</code> for the first time, we use the <code>=</code> operator to store <code>-10</code> into <code>a</code>. The second time we print out <code>a</code>, it prints out <code>-10</code>.</p><h3 id="anchor157">Types</h3><p>Just like values, a variable's type annotation restricts what you can store inside it. Here's what happens when we attempt to store a string into <code>a</code>.</p><pre><code>var a:Int = 3 * 71<br>a = "Timon"</code></pre><p>Compiling the above gives us</p><pre><code>Cannot assign expression of type String to variable a with declared type Int.</code></pre><h3 id="anchor158">Type Inference</h3><p>Just like values, you can leave off the type annotation for a variable.</p><pre><code>var a = 3 * 71<br>println(a)<br>a = -10<br>println(a)</code></pre><p><span style="font-style:italic;">However</span>, the inferred type for a variable depends upon <span style="font-style:italic;">all</span> the values assigned to it, not just the initial one. </p><p>For various reasons, Stanza cannot always infer the type of a variable, as in this example. (Don't mind the functions you don't know. We'll learn them later.) </p><pre><code>var a = 3 * 71<br>a = cons(a, List())</code></pre><p>Attempting to compile the above gives us this error.</p><pre><code>Could not infer type of variable a.</code></pre><p>In these cases, you'll have to provide an explicit type annotation for the variable.</p><h3 id="anchor159">Uninitialized Variables</h3><p>Variables don't have to be declared with an initial value. Here's a variable, declared to only hold integers, but with no initial value.</p><pre><code>var x:Int</code></pre><p>Attempting to read from an uninitialized variable will crash the program. The following program</p><pre><code>var x:Int<br>println(x)</code></pre><p>when compiled and ran crashes with this error.</p><pre><code>FATAL ERROR: Variable is uninitialized.</code></pre><h2 id="anchor9">Functions</h2><p>Here's a function that subtracts forty two from its argument.</p><pre><code>defn subtract-forty-two (x:Int) -> Int :<br> x - 42 </code></pre><p>And here's how you <span style="font-style:italic;">call</span> the function.</p><pre><code>subtract-forty-two(43)</code></pre><p>Here's the complete program.</p><pre><code>defpackage mypackage :<br> import core<br><br>defn subtract-forty-two (x:Int) -> Int :<br> x - 42 <br><br>println(subtract-forty-two(43))</code></pre><p>It prints out:</p><pre><code>1</code></pre><p>This means that the result of calling <code>subtract-forty-two</code> with <code>43</code> is <code>1</code>. We say that <code>subtract-forty-two(43)</code> <span style="font-style:italic;">returned</span> <code>1</code>. </p><h3 id="anchor160">Return Value</h3><p>Here's a silly change we can make to <code>subtract-forty-two</code>. </p><pre><code>defn subtract-forty-two (x:Int) -> Int :<br> x + 43<br> x - 42 </code></pre><p><code>subtract-forty-two(43)</code> still returns <code>1</code> though. The result of the last expression in a function's body is the value returned by the function. </p><h3 id="anchor161">Side Effects</h3><p>Here's another change we can make to <code>subtract-forty-two</code>.</p><pre><code>defn subtract-forty-two (x:Int) -> Int :<br> println("Subtracting 42 from %_." % [x])<br> x - 42 </code></pre><p>Now the following code</p><pre><code>println(subtract-forty-two(43))</code></pre><p>prints</p><pre><code>Subtracting 42 from 43.<br>1</code></pre><p>The expressions in a function body are evaluated one at a time, but only the result of the last one is returned.</p><h3 id="anchor162">Return Type</h3><p>The <code>Int</code> following the <code>-></code> in <code>subtract-forty-two</code> is the function's <span style="font-style:italic;">return type</span>. It says that the function must return an integer. </p><p>Stanza won't let you return anything else. If we try to return a string</p><pre><code>defn subtract-forty-two (x:Int) -> Int :<br> println("Subtracting 42 from %_." % [x])<br> "Timon"</code></pre><p>then the Stanza compiler gives us this error.</p><pre><code>Cannot return an expression of type String for function <br>subtract-forty-two with declared return type Int.</code></pre><p>You can leave off the return type annotation</p><pre><code>defn subtract-forty-two (x:Int) :<br> println("Subtracting 42 from %_." % [x])<br> x - 42 </code></pre><p>in which case, Stanza will figure out the return type automatically based on the last expression in the function body. In certain cases, Stanza will not be able to figure it out and you'll have to provide it explicitly.</p><h3 id="anchor163">Argument Types</h3><p>The <code>:Int</code> following the <code>x</code> argument in <code>subtract-forty-two</code> is the type annotation for the argument. This type annotation does two things. The first is that it restricts what values you can call <code>subtract-forty-two</code> with. Compiling the following code</p><pre><code>subtract-forty-two("Hello")</code></pre><p>gives the error</p><pre><code>Cannot call function subtract-forty-two of type Int -> Int<br>with arguments of type (String).</code></pre><p>The second is that it restricts what you are allowed to do with <code>x</code>. Here is what happens if we try to use <code>x</code> as if it were a format string.</p><pre><code>defn subtract-forty-two (x:Int) :<br> println(x % [1, 2, 3])<br> x - 42 </code></pre><p>Compiling it gives us this error.</p><pre><code>No appropriate function modulo for arguments of type <br>(Int, [Int, Int, Int]). Possibilities are:<br> modulo: (String, Seqable) -> Printable at core/core.stanza:1982.12<br> modulo: (Byte, Byte) -> Byte at core/core.stanza:2444.21<br> modulo: (Int, Int) -> Int at core/core.stanza:2575.12<br> modulo: (Long, Long) -> Long at core/core.stanza:2644.21</code></pre><p>Roughly, that error message tells us that there are four different functions called <span style="font-style:italic;">modulo</span>, and none of them can called with <code>x</code> and <code>[1, 2, 3]</code>. We'll learn later how to interpret that error message more precisely.</p><h3 id="anchor164">Example: String Arguments</h3><p>Here is an example of a function that accepts a string as an argument.</p><pre><code>defn timon-and-pumbaa-says (format:String) :<br> println(format % ["Timon", "Pumbaa"])<br><br>timon-and-pumbaa-says(<br> "%_ says they're fireflies, while %_ says they're big balls of gas.")<br> <br>timon-and-pumbaa-says(<br> "When the world turns their back on %_, %_ turns their back on the world.")</code></pre><p>Compiling and running the above prints</p><pre><code>Timon says they're fireflies, while Pumbaa says they're big balls of gas.<br>When the world turns their back on Timon, Pumbaa turns their back on the world.</code></pre><p>We did not provide an explicit return type for <code>timon-and-pumbaa-says</code>. Thus Stanza figures it out automatically from the result of the last expression, the <code>println</code>. It turns out that <code>println</code> returns the value <code>false</code> which has type <code>False</code>. We could explicitly provide the return type as well.</p><pre><code>defn timon-and-pumbaa-says (format:String) -> False :<br> println(format % ["Timon", "Pumbaa"])</code></pre><h3 id="anchor165">Leaving off the Argument Type</h3><p><span style="font-style:italic;">Beware</span>. Argument types are <span style="font-style:italic;">not</span> inferred automatically. You can leave off the argument types</p><pre><code>defn subtract-forty-two (x) :<br> x - 42 </code></pre><p>but this is <span style="font-style:italic;">not</span> equivalent to declaring <code>x</code> as an <code>Int</code>.</p><p>If you leave off the type annotation for an argument, it means that the argument can be <span style="font-style:italic;">anything</span>. You can call the function with whatever you want, and within the body of the function Stanza will let you do whatever you wish with the argument. If you do something wrong then the program will crash when ran.</p><p>Here is an <span style="font-style:italic;">incorrect</span> program that compiles correctly.</p><pre><code>defn subtract-forty-two (x) :<br> println(x % ["Timon", "Pumbaa"])<br> x - 42<br><br>subtract-forty-two("%_ and %_ say Hakuna Matata!")</code></pre><p>But when the program is ran, it crashes with this error.</p><pre><code>Timon and Pumbaa say Hakuna Matata!<br>FATAL ERROR: Cannot cast value to type.<br> at core/core.stanza:2566.12<br> at stanzaprojects/basics.stanza:6.3<br> at stanzaprojects/basics.stanza:8.0</code></pre><p>The error message is saying that in the expression <code>x - 42</code> it could not convert <code>x</code> into the appropriate type needed by the <code>-</code> operator (<code>Int</code>). </p><h3 id="anchor166">The Unknown Type</h3><p>More precisely, leaving off the type annotation for an argument is equivalent to declaring the argument with the <code>?</code> type. So the above program can be written equivalently as</p><pre><code>defn subtract-forty-two (x:?) :<br> println(x % ["Timon", "Pumbaa"])<br> x - 42<br><br>subtract-forty-two("%_ and %_ say Hakuna Matata!")</code></pre><p>The <code>?</code> type is very special and forms the foundation of Stanza's optional type system. You can pass <span style="font-style:italic;">any</span> value to a location where a <code>?</code> is expected. <span style="font-style:italic;">And</span>, you can use a value of <code>?</code> type anywhere.</p><p>You can use the <code>?</code> type in variable and value declarations too. Here is an example of using them with variables.</p><pre><code>var x:? = "%_ says Hakuna."<br>println(x % ["Timon"])<br>x = 10 + 32<br>println("There are about %_ fireflies in the universe." % [x])</code></pre><p>It prints out</p><pre><code>Timon says Hakuna.<br>There are about 42 fireflies in the universe.</code></pre><p>Notice that we're using <code>x</code> as a format string in one case, and a number in the other case. The <code>?</code> type allows us to do this.</p><h2 id="anchor10">Comparisons</h2><p></p><h3 id="anchor167">Comparison Operators</h3><p>To test whether one integer is smaller than another number, you can use the <code><</code> operator. Here's an example.</p><pre><code>println(10 < 32)</code></pre><p>It prints out</p><pre><code>true</code></pre><p>This means that <code>10</code> is less than <code>32</code>. The expression <code>10 < 32</code> returned the value <code>true</code>. Conversely, </p><pre><code>println(10 > 32)</code></pre><p>prints out</p><pre><code>false</code></pre><p>This means that <code>10</code> is not greater than <code>32</code>. The expression <code>10 > 32</code> returned the value <code>false</code>. </p><p>Here's all the other comparison operators you can use.</p><pre><code>10 < 32 ;Less Than<br>10 <= 32 ;Less Than or Equal to<br>10 > 32 ;Greater Than<br>10 >= 32 ;Greater Than or Equal to<br>10 == 32 ;Equal<br>10 != 32 ;Not Equal</code></pre><h3 id="anchor168">Logical Operators</h3><p>You can use the <code>not</code>, <code>and</code>, and <code>or</code> operators to combine the results of multiple comparisons. Here is how to test whether <code>1</code> is less than <code>3</code> <span style="font-style:italic;">and</span> greater than <code>5</code>.</p><pre><code>println(1 < 3 and 1 > 5)</code></pre><p>Here is how to test whether <code>1</code> is less than <code>3</code> <span style="font-style:italic;">or</span> greater than <code>5</code>.</p><pre><code>println(1 < 3 or 1 > 5)</code></pre><p>Here is how to test whether <code>1</code> is <span style="font-style:italic;">not</span> less than <code>3</code>.</p><pre><code>println(not 1 < 3)</code></pre><h2 id="anchor11">If Expressions</h2><p>If expressions let you test whether a value is <code>true</code> or <code>false</code> and do different things depending on the result.</p><pre><code>val x = 10 < 32<br>if x :<br> println("Timon is better!")<br>else :<br> println("Pumbaa is better!")</code></pre><p>prints out</p><pre><code>Timon is better!</code></pre><p>The result of <code>10 < 32</code> (<code>true</code>) is stored in <code>x</code>. Then because <code>x</code> (the <span style="font-style:italic;">predicate</span>) is <code>true</code>, the <span style="font-style:italic;">consequent</span> branch of the if expression is evaluated instead of the <span style="font-style:italic;">alternate</span> branch.</p><p>Change the <code><</code> operator to a <code>></code> operator to root for Pumbaa instead.</p><h3 id="anchor169">Result of an If Expression</h3><p>If expressions evaluate to a result. The <span style="font-style:italic;">result</span> of an if expression is the result of the last expression in the consequent branch if the predicate is <code>true</code>. Otherwise it is the result of the last expression in the alternate branch.</p><p>Here's an example of using the result of an if expression.</p><pre><code>val x =<br> if 10 < 32 :<br> "Timon"<br> else :<br> "Pumbaa"<br>println("%_ is better!" % [x])</code></pre><p>It prints out the same message as the last example.</p><h3 id="anchor170">Default Else Branch</h3><p>If you leave off the <code>else</code> branch in an if expression, then the if expression simply evaluates to <code>false</code> if the predicate is not <code>true</code>. In the following code</p><pre><code>if 10 > 32 :<br> println("Timon is better!")</code></pre><p>nothing is ever printed. </p><h3 id="anchor171">Nested If Expressions</h3><p>You can nest if expressions inside other if expressions. The following code prints different messages when x falls in different ranges.</p><pre><code>val x = 32<br>if x < 0 :<br> println("x is negative!")<br>else :<br> if x < 10 :<br> println("x is between 0 and 10")<br> else :<br> if x < 30 :<br> println("x is between 20 and 30")<br> else :<br> println("x is really big!")</code></pre><p>It uses nested if expressions to test a series of conditions.</p><p>Because nested if expressions are so common, you are allowed to omit the colon after the <code>else</code> keyword if it is followed by an <code>if</code> expression. The above can be rewritten equivalently as</p><pre><code>val x = 32<br>if x < 0 :<br> println("x is negative!")<br>else if x < 10 :<br> println("x is between 0 and 10")<br>else if x < 30 :<br> println("x is between 20 and 30")<br>else :<br> println("x is really big!")</code></pre><p>Here's another example. <code>sign</code> is a function that computes the sign of its argument.</p><pre><code>defn sign (x:Int) :<br> if x < 0 :<br> -1<br> else if x == 0 :<br> 0<br> else :<br> 1</code></pre><h3 id="anchor172">True and False</h3><p>The <code>true</code> and <code>false</code> values can be created directly simply by referring to them by name. </p><p>The following</p><pre><code>val worries? = true<br>if worries? :<br> println("Chill out!")<br>else :<br> println("Hakuna Matata!")</code></pre><p>prints out</p><pre><code>Chill out!</code></pre><p>To print <code>Hakuna Matata!</code> instead, change the <code>true</code> to <code>false</code>. </p><p>The value <code>true</code> has type <code>True</code>, and the value <code>false</code> has type <code>False</code>. </p><h2 id="anchor12">Expression Sequences</h2><p>Multiple expressions can be grouped together as an <span style="font-style:italic;">expression sequence</span> by surrounding them with parentheses. </p><pre><code>val x = (println("A"), 42)<br>println(x)</code></pre><p>prints out</p><pre><code>A<br>42</code></pre><p>The expressions in an expression sequence are evaluated one at a a time, and the result of the last expression is the result of the expression sequence.</p><p>In the above example, the first expression in the sequence, <code>println("A")</code>, is evaluated, and then the last expression, <code>42</code>, is the result of the sequence and is stored in <code>x</code>. <code>x</code> is then printed to the screen.</p><h2 id="anchor13">Structure Through Indentation</h2><p>Some of you may be concerned about Stanza's use of structure through indentation due to how this system has been implemented in the past. Don't worry. Stanza's indentation structuring mechanism is very simple and <span style="font-style:italic;">predictable</span>.</p><p>The indentation structuring mechanism is governed by a single rule: a line ending colon automatically inserts parentheses around the following indented block.</p><p>Thus, after the implicit parentheses have been added, the previous <code>sign</code> example looks like this.</p><pre><code>defn sign (x:Int) : (<br> if x < 0 : (<br> -1)<br> else if x == 0 : (<br> 0)<br> else : (<br> 1))</code></pre><p>A program with no line ending colons can even be written on a single line if desired.</p><pre><code>defn sign (x:Int) : (if x < 0 : (-1) else if x == 0 : (0) else : (1))</code></pre><p>Here is one more example.</p><pre><code>defn hakuna () :<br> println("Timon")<br> println("Pumbaa")</code></pre><p>becomes the following after implicit parentheses are added.</p><pre><code>defn hakuna () : (<br> println("Timon")<br> println("Pumbaa"))</code></pre><p>Here is <code>hakuna</code> written out on a single line.</p><pre><code>defn hakuna () : (println("Timon") println("Pumbaa"))</code></pre><p>As you may have noticed, the indentation mechanism is simply used as a shorthand for creating expression sequences out of indented blocks.</p><h2 id="anchor14">While Loops</h2><p>The following</p><pre><code>var x = 1<br>while x < 1000 :<br> println("x is %_" % [x])<br> x = x * 2</code></pre><p>prints out</p><pre><code>x is 1<br>x is 2<br>x is 4<br>x is 8<br>x is 16<br>x is 32<br>x is 64<br>x is 128<br>x is 256<br>x is 512</code></pre><p>Here is the general form.</p><pre><code>while predicate : body </code></pre><p>A while loop repeatedly evaluates a block of code so long as the predicate expression evaluates to <code>true</code>. </p><p>Here is the order in which the while loop does things.</p><ol><li>Evaluate the predicate.
</li><li>If the predicate evaluates to <code>false</code>, then the loop is done.
</li><li>Otherwise, evaluate the body and then repeat from step 1.
</li></ol><h2 id="anchor15">For "Loops"</h2><p>Stanza's for construct is <span style="font-style:italic;">extremely</span> powerful. "Loops" is in double quotes because, strictly speaking, the for construct is not a looping mechanism. But it is often used as one, so we'll explain it here as if it were. Later, we'll learn the general form of the for construct.</p><h3 id="anchor173">Counting Loops</h3><p>The following</p><pre><code>for i in 0 to 4 do :<br> println("Pumbaa is Better!")</code></pre><p>prints out <code>Pumbaa is Better!</code> four times. </p><p>The following</p><pre><code>for i in 0 to 4 do :<br> println("i is %_" % [i])</code></pre><p>prints out</p><pre><code>i is 0<br>i is 1<br>i is 2<br>i is 3</code></pre><p>A counting loop has this general form.</p><pre><code>for x in start to end do : body</code></pre><p>For each integer between <code>start</code> (inclusive) and <code>end</code> (exclusive), the body is evaluated once with <code>x</code> <span style="font-style:italic;">bound</span> to that integer. </p><h3 id="anchor174">Range Expressions</h3><p>In the previous example, the expression <code>0 to 4</code> creates a <code>Range</code> object. A <code>Range</code> object represents a sequence of integers between some starting index and optional ending index.</p><p>Here's how to create a <code>Range</code> object that counts up in steps of 2.</p><pre><code>0 to 10 by 2</code></pre><p>It represents the numbers <code>0, 2, 4, 6, 8</code>.</p><p>The following</p><pre><code>for i in 0 to 10 by 2 do :<br> println("i is %_" % [i])</code></pre><p>prints out</p><pre><code>i is 0<br>i is 2<br>i is 4<br>i is 6<br>i is 8</code></pre><p>To make the ending index inclusive rather than exclusive, use the <code>through</code> keyword rather than the <code>to</code> keyword.</p><pre><code>0 through 10 by 2</code></pre><p>represents the numbers <code>0, 2, 4, 6, 8, 10</code>.</p><p>If you use <code>false</code> for the ending index, then the range represents an <span style="font-style:italic;">infinite</span> sequence of numbers.</p><pre><code>0 to false by 3</code></pre><p>represents the numbers <code>0, 3, 6, 9, ...</code>. </p><h2 id="anchor16">Labeled Scopes</h2><p></p><h3 id="anchor175">For Returning Early</h3><p>As you've learned so far, functions return the result of the last expression in its body. But what if you want to return earlier? </p><p>As an example, here's a function that computes the n'th fibonacci number. </p><pre><code>defn fibonacci (n:Int) -> Int :<br> var a:Int = 0<br> var b:Int = 1<br> var i = 0<br> while i < n :<br> val c = a + b<br> a = b<br> b = c<br> i = i + 1<br> b</code></pre><p>Let's use a labeled scope to change <code>fibonacci</code> to return <code>-1</code> immediately if the argument <code>n</code> is negative. </p><pre><code>defn fibonacci (n:Int) -> Int :<br> label<Int> myreturn :<br> if n < 0 : myreturn(-1)<br> var a:Int = 0<br> var b:Int = 1<br> var i = 0<br> while i < n :<br> val c = a + b<br> a = b<br> b = c<br> i = i + 1<br> b</code></pre><p>The first line within the labeled scope</p><pre><code>if n < 0 : myreturn(-1)</code></pre><p>checks to see whether <code>n</code> is negative, and if it is, it <span style="font-style:italic;">immediately</span> returns the value <code>-1</code> from the function by calling the <span style="font-style:italic;">exit function</span> <code>myreturn</code>. </p><h3 id="anchor176">For Breaking From Loops</h3><p>Labeled scopes are also useful for breaking early out of loops.</p><p>Here's how the while loop in <code>fibonacci</code> could have been written.</p><pre><code>defn fibonacci (n:Int) -> Int :<br> var a:Int = 0<br> var b:Int = 1<br> var i = 0<br> label<False> break :<br> while true :<br> if i == n : break(false)<br> val c = a + b<br> a = b<br> b = c<br> i = i + 1<br> b</code></pre><p>The code above starts an infinite loop, but breaks out of it when <code>i</code> is equal to <code>n</code>.</p><h3 id="anchor177">General Form</h3><p>The general form of a labeled scope is</p><pre><code>label<Type> exit :<br> body</code></pre><p><code>Type</code> is the type of the value returned by the labeled scope and <code>exit</code> is the name of the exit function. </p><p>You can name the exit function whatever you like. When used to return early from a function, <code>return</code> is a popular name for the exit function. When used to break early from a loop, <code>break</code> is a popular name.</p><p>The label construct simply executes the given body. If the exit function is never called then the result of the body expression is the result of the label construct. If the exit function is called, then we <span style="font-style:italic;">immediately</span> stop evaluation of the body, and the argument to the exit function is the result of the label construct.</p><h3 id="anchor178">Well-Typed Labeled Scopes</h3><p>The type annotation on the label construct enforces two properties.</p><ol><li>The argument to the exit function must be of the specified type.
</li><li>The result of the body itself must be of the specified type, as that is the value that is returned by the label construct if the exit function is never called.
</li></ol><p>The first restriction is fairly obvious. If you pass an argument of the wrong type to the exit function</p><pre><code>defn fibonacci (n:Int) -> Int :<br> label<Int> myreturn :<br> if n < 0 : myreturn("Timon")<br> var a:Int = 0<br> var b:Int = 1<br> var i = 0<br> while i < n :<br> val c = a + b<br> a = b<br> b = c<br> i = i + 1<br> b</code></pre><p>then Stanza will issue an error.</p><pre><code>Cannot call function myreturn of type Int -> Void with arguments of type (String).</code></pre><p>The second restriction sometimes arises in more subtle situations. The following function computes the first integer whose square is greater than 1000.</p><pre><code>defn first-big-square () :<br> label<Int> return :<br> for i in 0 to false do :<br> if i * i > 1000 :<br> return(i) </code></pre><p>But compiling it gives us this error.</p><pre><code>Cannot return an expression of type False for anonymous function<br>with declared return type Int.</code></pre><p>This message says that the body of the labeled scope returns <code>False</code> but it's declared to return <code>Int</code>. This arises because the for construct with the <code>do</code> operating function returns <code>false</code>, but the type annotation on the label construct was <code>Int</code>.</p><p>Since we <span style="font-style:italic;">know</span> that the <code>return</code> exit function is guaranteed to be called, we can explicitly handle this case by causing the program to fail if the loop ever finished without calling <code>return</code>. </p><pre><code>defn first-big-square () :<br> label<Int> return :<br> for i in 0 to false do :<br> if i * i > 1000 :<br> return(i)<br> fatal("Unreachable Statement") </code></pre><h2 id="anchor17">Scopes and the Let Expression</h2><p>We have now seen a number of expressions that introduce a new <span style="font-style:italic;">scope</span>: functions, while loops, for loops, if expressions, and labeled scopes. Values and variables defined within a scope are only visible within that scope. For example, in the following code</p><pre><code>val x = 3<br>if x < 5 :<br> val y = 10<br> println(y)<br>else :<br> val z = 12<br> println(z)</code></pre><p><code>y</code> is in the scope of the consequent branch of the if expression, and it is <span style="font-style:italic;">only</span> visible from within the consequent branch of the if expression. And <code>z</code> is only visible from within the alternate branch of the if expression. Referencing <code>y</code> and <code>z</code> from outside the scope in which they were declared</p><pre><code>val x = 3<br>if x < 5 :<br> val y = 10<br> println(y)<br>else :<br> val z = 12<br> println(z)<br> <br>println(y)<br>println(z)</code></pre><p>is illegal and would not pass the Stanza compiler. </p><p>Scopes may themselves contain other nested scopes. In the above example, <code>x</code>'s scope, contains both the scope of the consequent branch, and the scope of the alternate branch of the if statement. At any point in the program, you may only refer to a value or variable defined in a containing scope. The following <span style="font-style:italic;">is</span> legal.</p><pre><code>val x = 3<br>if x < 5 :<br> val y = 10<br> println(y)<br> println(x)<br>else :<br> val z = 12<br> println(z)<br> println(x)</code></pre><p>If there are multiple values with the same name that are visible, you automatically refer to the one in the nearest scope. Thus the following code prints <code>11</code>, not <code>3</code>. </p><pre><code>val x = 3<br>if x < 10 :<br> val x = 11<br> println(x)</code></pre><p>This feature is called <span style="font-style:italic;">shadowing</span>.</p><p>Sometimes it is useful to artificially introduce a new scope, simply because you will define a number of values that you only want visible within the scope. You can do this using the let expression.</p><pre><code>val x = 3<br>let :<br> val y = 4<br> println(y)</code></pre><p>In the above code, the let expression introduces a new scope where <code>y</code> is defined. After the let expression, <code>y</code> will no longer be visible. </p><h2 id="anchor18">Arrays</h2><p>Arrays are one of Stanza's most fundamental datastructures. The following</p><pre><code>val a = Array<Int>(10)</code></pre><p>creates an array of length 10 and gives it the name <code>a</code>. You can imagine an array to look like a row of boxes, into which you can put and retrieve objects. So <code>a</code> is a row of ten boxes, each capable of holding an integer.</p><h3 id="anchor179">Putting Things In</h3><p>You can put things into the boxes like this.</p><pre><code>a[0] = 42<br>a[1] = 13</code></pre><p>The first box is numbered box 0. The next box is numbered box 1. The last box in <code>a</code> is box 9 because <code>a</code> has only ten boxes in total. </p><h3 id="anchor180">Getting Things Out</h3><p>You can retrieve the contents of boxes like this.</p><pre><code>println(a[0])<br>println(a[1])</code></pre><p>prints out</p><pre><code>42<br>13</code></pre><h3 id="anchor181">Asking For Its Length</h3><p>You can call the <code>length</code> function to ask for the length of an array.</p><pre><code>val l = length(a)<br>println("a has %_ boxes." % [l])</code></pre><p>prints out</p><pre><code>a has 10 boxes.</code></pre><p>The type of <code>a</code> is <code>Array<Int></code> indicating that it is an array for holding integers. An array for holding strings would have type <code>Array<String></code>. And an array that can hold anything would have type <code>Array<?></code>. </p><h3 id="anchor182">Arrays and Loops</h3><p>Arrays are most powerful when combined with loops. This function</p><pre><code>defn array-sum (xs:Array<Int>) :<br> var sum = 0<br> for i in 0 to length(xs) do :<br> sum = sum + xs[i]<br> sum </code></pre><p>computes the sum of every integer in an array. Let's use it to compute the sum of 10, 11, 7, and 8. </p><pre><code>val a = Array<Int>(4)<br>a[0] = 10<br>a[1] = 11<br>a[2] = 7<br>a[3] = 8<br>println(array-sum(a))</code></pre><p>prints out</p><pre><code>36</code></pre><h2 id="anchor19">Tuples</h2><p>Tuples represent an immutable collection of items. The following creates a two-element type.</p><pre><code>val t:[Int, String] = [42, "Hello"]</code></pre><p>It contains an <code>Int</code> and a <code>String</code>. To extract the elements of a tuple, type</p><pre><code>val [x, y] = t</code></pre><p>The above code checks that <code>t</code> is a two-element tuple, and then puts the first element of <code>t</code> in <code>x</code> and the second element of <code>t</code> in <code>y</code>.</p><p>Notice that the type of the expression <code>[42, "Hello"]</code> is <code>[Int, String]</code>. That type says its a two-element tuple containing an <code>Int</code> and a <code>String</code>. </p><h3 id="anchor183">Returning Multiple Values</h3><p>Tuples are often used to return multiple values from a function. The following function takes an argument, <code>n</code>, and a distance, <code>d</code>, and returns both <code>n - d</code> and <code>n + d</code>.</p><pre><code>defn bracket (n:Int, d:Int) :<br> [n - d, n + d]</code></pre><p>We can call and receive both return values from <code>bracket</code> like this.</p><pre><code>val [lo, hi] = bracket(5, 3)<br>println("Bracket around %_ and %_" % [lo, hi])</code></pre><h2 id="anchor20">Basic Types</h2><p>At this point, we have seen a couple of different types now. Here is a listing of the other basic types in Stanza.</p><pre><code>Byte : e.g. 1Y, 42Y, 255Y<br>Int : e.g. 10, 42<br>Long : e.g. 10L, 420020020L<br>Float : e.g. 1.0f, 42.0f<br>Double : e.g. 1.0, 42.0<br>String : e.g. "Timon", "Pumbaa"<br>Char : e.g. 'a', 'Z'<br>True : e.g. true<br>False : e.g. false</code></pre><p>As we've said already, the <code>?</code> type is special and any value can be passed to a place expecting a <code>?</code>.</p><p>All of the types listed in the previous table are examples of <span style="font-style:italic;">ground</span> types. It means that you refer to them simply by their name and they don't take any parameters. With the introduction of arrays, you have now also been introduced to your first <span style="font-style:italic;">parametric</span> type. </p><pre><code>Array<Int> : Arrays of Ints<br>Array<String> : Arrays of Strings<br>Array<Array<Int>> : Arrays of Arrays of Ints<br>Array<?> : Arrays of anything</code></pre><p>Unlike ground types, parametric types take additional <span style="font-style:italic;">type parameters</span>. An array needs to know what type of objects it holds, so it has one type parameter for specifying that. </p><p>Note that for parametric types, if you leave off its parameters, then it is equivalent to specifying <code>?</code> for all of its type parameters. Thus</p><pre><code>Array</code></pre><p>is equivalent to</p><pre><code>Array<?></code></pre><p>And</p><pre><code>Array<Array></code></pre><p>is equivalent to</p><pre><code>Array<Array<?>></code></pre><p>Tuple types have their own syntax, and consists of surrounding the types of all of its elements with the <code>[]</code> brackets. Here is a tuple containing an integer and a string.</p><pre><code>[Int, String]</code></pre><p>Here is a tuple containing an integer, a string, and a tuple of a single integer.</p><pre><code>[Int, String, [Int]]</code></pre><h2 id="anchor21">Structs</h2><p>For convenience, Stanza provides a simple way to create compound types out of existing types using structs. Here is how to define a new <code>Dog</code> type with two fields, a name, and a breed.</p><pre><code>defstruct Dog :<br> name: String<br> breed: String</code></pre><p>Once <code>Dog</code> is defined, you can create new <code>Dog</code> objects by calling the <code>Dog</code> function.</p><pre><code>val d1 = Dog("Chance", "Pitbull")<br>val d2 = Dog("Shadow", "Golden Retriever")</code></pre><h3 id="anchor184">Getter Functions</h3><p>To retrieve the values of the fields it was constructed from, you may call the <code>name</code> and <code>breed</code> getter functions.</p><pre><code>println("%_ is a %_." % [name(d1), breed(d1)])</code></pre><p>prints out</p><pre><code>Chance is a Pitbull.</code></pre><h3 id="anchor185">Struct Type</h3><p>Additionally, once a struct is defined, you may now also use it as the name of a type. Here is a function that prints out the contents of an array of <code>Dog</code> objects.</p><pre><code>defn kennel-contents (dogs:Array<Dog>) :<br> println("There are %_ dogs in the kennel." % [length(dogs)])<br> for i in 0 to length(dogs) do :<br> println("%_ the %_" % [name(dogs[i]), breed(dogs[i])])</code></pre><p>Let's try calling <code>kennel-contents</code>.</p><pre><code>val kennel = Array<Dog>(3)<br>kennel[0] = Dog("Chance", "Pitbull")<br>kennel[1] = Dog("Shadow", "Golden Retriever")<br>kennel[2] = Dog("Bud", "Basketball Player")<br>kennel-contents(kennel)</code></pre><p>prints out</p><pre><code>There are 3 dogs in the kennel.<br>Chance the Pitbull<br>Shadow the Golden Retriever<br>Bud the Basketball Player</code></pre><p>Structs are just a convenient form for quickly declaring a new type, constructor function, and getter functions. Later we'll learn the general method for creating new types.</p><h2 id="anchor22">Exercises</h2><ol><li>Write a function called <code>nearest-pow-2</code> that takes a single positive integer <code>n</code> and returns the closest number to <code>n</code> that can be represented as a power of 2.
</li><li>Write a program that prints out different messages depending on a value called <code>temperature</code>. If <code>temperature</code> is below 20, then print <code>Too Cold!</code>. If it is between 20 and 40 then print <code>Getting There!</code>, and print <code>Pumbaa Approves!</code> if it is over 40.
</li><li>Use a for loop and a variable to compute the sum of all the integers between 100 (inclusive) to 500 (also inclusive).
</li><li>Use a labeled scope and for loops to compute the minimum number, n, for which the sum of the integers between 0 and n (inclusive) is above 10000.
</li><li>Use a while loop and variables to calculate the great common divisor of two variables, <code>x</code> and <code>y</code>. The Euclidean algorithm is the simplest one to use. Look online for a description about how the algorithm works.
</li><li>Write a function to print out the following pattern of stars. Allow the width and height of the rectangle to be indicated by the arguments <code>width</code> and <code>height</code> respectively.
<pre><code>*************<br>* *<br>* *<br>* *<br>* *<br>* *<br>* *<br>*************</code></pre>
</li><li>Write a program to print out the following pattern of stars. Allow the height of the triangle to be indicated by an argument named <code>height</code>.
<pre><code> * <br> *** <br> ***** <br> ******* <br> ********* <br> *********** <br> ************* <br> *************** <br>***************** </code></pre>
</li><li>For the following code, predict what will be printed out and then test your prediction.
<pre><code>val x = 42<br>println(x)<br>let :<br> println(x)<br> val x = "Hi"<br> println(x)<br> let :<br> val x = 42<br> println(x)<br> let :<br> val x = "There"<br> println(x)<br>println(x)<br>let :<br> val x = x + 1<br> println(x)<br>println(x)</code></pre>
</li><li>For the following code, write it out completely on a single line, grouping expressions with parentheses where necessary. Run both versions and ensure that they behave identically.
<pre><code>val x = (42 10)<br>for i in 0 to 10 do :<br> println(x)<br> println("B")<br>println("C")<br>for i in 0 to 10 do : println("D")<br> println("E")</code></pre>
</li></ol>
</td>
<td class="rest">
<img url="resources/spacer.gif"></img>
</td>
</tr>
<tr><td colspan="3" class="footer">
Site design by Luca Li. Copyright 2015.
</td></tr>
</table>
</body>
</html>