| HomeTable of ContentsPrevious ChapterNext Chapter | ||
NAVIGATIONThe Very BasicsProject FrameworkCreate basics.stanzaCompile and RunIndentationPrinting Simple MessagesStringsPrinting StringsPrint Without a New LineIntsPrinting IntegersPrinting Multiple ThingsFormatted PrintingWhere's the Commas?Lexical StructureLexemesNumbersOperatorsIdentifiersOpening BracketsCommentsOperatorsBasic ArithmeticBitwise ArithmeticOperator PrecedenceUnary OperatorsValuesSyntaxBreaking up Complicated ExpressionsTypesType InferenceVariablesTypesType InferenceUninitialized VariablesFunctionsReturn ValueSide EffectsReturn TypeArgument TypesExample: String ArgumentsLeaving off the Argument TypeThe Unknown TypeComparisonsComparison OperatorsLogical OperatorsIf ExpressionsResult of an If ExpressionDefault Else BranchNested If ExpressionsTrue and FalseExpression SequencesStructure Through IndentationWhile LoopsFor "Loops"Counting LoopsRange ExpressionsLabeled ScopesFor Returning EarlyFor Breaking From LoopsGeneral FormWell-Typed Labeled ScopesScopes and the Let ExpressionArraysPutting Things InGetting Things OutAsking For Its LengthArrays and LoopsTuplesReturning Multiple ValuesBasic TypesStructsGetter FunctionsStruct TypeExercises |
The Very BasicsThis chapter introduces the basic programming constructs in Stanza. After this chapter, you'll be able to write basic programs that do simple things. Project FrameworkFollow these steps to set up a project framework. Create basics.stanzaIn your Again, make sure you do not forget the space between the Compile and RunCompile and run the basic framework by typing the following in the terminal The basic framework should print out Follow the chapter and try out the examples by replacing the IndentationTry changing the basic framework to and try to compile it. It won't work. My Stanza installation says Indentation is important in Stanza programs. Be careful when trying out the examples. And don't use tabs. Stanza won't let you. We don't like tabs. Printing Simple MessagesPrinting is important. It's the only way to observe what your program is doing. StringsThis is a string. It's a bunch of characters surrounded in double quotes. Printing StringsUse the prints out Print Without a New LineUse the prints out IntsThis is an integer. It's a bunch of digits, and represents the integers that you were taught in school. Printing IntegersThe prints out Actually Printing Multiple ThingsCalling prints out If you don't want to start a new line at the end, use prints out Don't fret about the Formatted PrintingSometimes it's tedious to print multiple things even with prints out Notice that you're calling the same Where's the Commas?Some of you may have noticed the lack of commas in the examples. Try adding them back in. still prints out Commas are treated identically to spaces in Stanza. (Unless they are part of a string.) Try going crazy! The above still prints out what it used to. But don't do that. That was just an example. Lexical StructureBefore compilation, a Stanza program is lexed into individual identifiers, numbers, and lists. Here are the rules that you'll need to know. LexemesThe first thing that Stanza does is break down a program into a sequence of lexemes, where each lexeme is separated by either whitespace or one of the following characters. NumbersA number is a lexeme that begins with a digit, or a hyphen followed by a digit. Here are some examples. OperatorsAn operator is any lexeme that is made up of the following characters. Here are some example operators. IdentifiersAn identifier is any lexeme that is not a number or operator. Here are some examples. Opening BracketsSyntactically, an identifier followed immediately by a opening bracket character is treated differently than if the two were separated by spaces. For example is syntactically different than The former calls the function This is similar to how is syntactically different than 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 Additionally, is syntactically different than and is syntactically different than and is syntactically different than CommentsComments begin with the Code without comments is very difficult to understand. Use comments often. OperatorsBasic ArithmeticTo add two numbers together, use the prints out That means the result of adding Here are examples of using the other arithmetic operators. Bitwise ArithmeticHere are examples of using the bitwise operators. Operator PrecedenceAll the operators are left associative. This means that in the following expression the operators are applied left to right. The above is equivalent to 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 ( The following expression first groups the precedence 3 operators followed by the precedence 2 operators followed by the precedence 1 operators Unary OperatorsHere's how to negate a number. The parentheses are not optional! Here's how to flip all the bits in a number. 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! ValuesSyntaxThe statement calculates the result of After the storing the result in You cannot change what is stored in a value once it is initialized. Breaking up Complicated ExpressionsYou can use values to break up complicated expressions into smaller ones. can be rewritten as TypesThe Stanza won't let you store anything else into but attempting to compile it gives us this error. If you want to store a string into Later, we will learn more about types and about types other than Type InferenceIf you leave off the type annotation then Stanza figures out the type based on the expression it's initialized with. Most Stanza programmers leave off type declarations for values. VariablesA variable is declared like a value, but using Just like a value, the result of calculating And just like a value, you can refer to it by name afterwards. The difference is that, even after it is initialized, you can still store something else into a variable. prints out After we print out TypesJust 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 Compiling the above gives us Type InferenceJust like values, you can leave off the type annotation for a variable. However, the inferred type for a variable depends upon all the values assigned to it, not just the initial one. 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.) Attempting to compile the above gives us this error. In these cases, you'll have to provide an explicit type annotation for the variable. Uninitialized VariablesVariables don't have to be declared with an initial value. Here's a variable, declared to only hold integers, but with no initial value. Attempting to read from an uninitialized variable will crash the program. The following program when compiled and ran crashes with this error. FunctionsHere's a function that subtracts forty two from its argument. And here's how you call the function. Here's the complete program. It prints out: This means that the result of calling Return ValueHere's a silly change we can make to
Side EffectsHere's another change we can make to Now the following code prints The expressions in a function body are evaluated one at a time, but only the result of the last one is returned. Return TypeThe Stanza won't let you return anything else. If we try to return a string then the Stanza compiler gives us this error. You can leave off the return type annotation 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. Argument TypesThe gives the error The second is that it restricts what you are allowed to do with Compiling it gives us this error. Roughly, that error message tells us that there are four different functions called modulo, and none of them can called with Example: String ArgumentsHere is an example of a function that accepts a string as an argument. Compiling and running the above prints We did not provide an explicit return type for Leaving off the Argument TypeBeware. Argument types are not inferred automatically. You can leave off the argument types but this is not equivalent to declaring If you leave off the type annotation for an argument, it means that the argument can be anything. 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. Here is an incorrect program that compiles correctly. But when the program is ran, it crashes with this error. The error message is saying that in the expression The Unknown TypeMore precisely, leaving off the type annotation for an argument is equivalent to declaring the argument with the The You can use the It prints out Notice that we're using ComparisonsComparison OperatorsTo test whether one integer is smaller than another number, you can use the It prints out This means that prints out This means that Here's all the other comparison operators you can use. Logical OperatorsYou can use the Here is how to test whether Here is how to test whether If ExpressionsIf expressions let you test whether a value is prints out The result of Change the Result of an If ExpressionIf expressions evaluate to a result. The result of an if expression is the result of the last expression in the consequent branch if the predicate is Here's an example of using the result of an if expression. It prints out the same message as the last example. Default Else BranchIf you leave off the nothing is ever printed. Nested If ExpressionsYou can nest if expressions inside other if expressions. The following code prints different messages when x falls in different ranges. It uses nested if expressions to test a series of conditions. Because nested if expressions are so common, you are allowed to omit the colon after the Here's another example. True and FalseThe The following prints out To print The value Expression SequencesMultiple expressions can be grouped together as an expression sequence by surrounding them with parentheses. prints out 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. In the above example, the first expression in the sequence, Structure Through IndentationSome 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 predictable. The indentation structuring mechanism is governed by a single rule: a line ending colon automatically inserts parentheses around the following indented block. Thus, after the implicit parentheses have been added, the previous A program with no line ending colons can even be written on a single line if desired. Here is one more example. becomes the following after implicit parentheses are added. Here is As you may have noticed, the indentation mechanism is simply used as a shorthand for creating expression sequences out of indented blocks. While LoopsThe following prints out Here is the general form. A while loop repeatedly evaluates a block of code so long as the predicate expression evaluates to Here is the order in which the while loop does things.
For "Loops"Stanza's for construct is extremely 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. Counting LoopsThe following prints out The following prints out A counting loop has this general form. For each integer between Range ExpressionsIn the previous example, the expression Here's how to create a It represents the numbers The following prints out To make the ending index inclusive rather than exclusive, use the represents the numbers If you use represents the numbers Labeled ScopesFor Returning EarlyAs you've learned so far, functions return the result of the last expression in its body. But what if you want to return earlier? As an example, here's a function that computes the n'th fibonacci number. Let's use a labeled scope to change The first line within the labeled scope checks to see whether For Breaking From LoopsLabeled scopes are also useful for breaking early out of loops. Here's how the while loop in The code above starts an infinite loop, but breaks out of it when General FormThe general form of a labeled scope is
You can name the exit function whatever you like. When used to return early from a function, 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 immediately stop evaluation of the body, and the argument to the exit function is the result of the label construct. Well-Typed Labeled ScopesThe type annotation on the label construct enforces two properties.
The first restriction is fairly obvious. If you pass an argument of the wrong type to the exit function then Stanza will issue an error. The second restriction sometimes arises in more subtle situations. The following function computes the first integer whose square is greater than 1000. But compiling it gives us this error. This message says that the body of the labeled scope returns Since we know that the Scopes and the Let ExpressionWe have now seen a number of expressions that introduce a new scope: 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
is illegal and would not pass the Stanza compiler. Scopes may themselves contain other nested scopes. In the above example, 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 This feature is called shadowing. 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. In the above code, the let expression introduces a new scope where ArraysArrays are one of Stanza's most fundamental datastructures. The following creates an array of length 10 and gives it the name Putting Things InYou can put things into the boxes like this. The first box is numbered box 0. The next box is numbered box 1. The last box in Getting Things OutYou can retrieve the contents of boxes like this. prints out Asking For Its LengthYou can call the prints out The type of Arrays and LoopsArrays are most powerful when combined with loops. This function computes the sum of every integer in an array. Let's use it to compute the sum of 10, 11, 7, and 8. prints out TuplesTuples represent an immutable collection of items. The following creates a two-element type. It contains an The above code checks that Notice that the type of the expression Returning Multiple ValuesTuples are often used to return multiple values from a function. The following function takes an argument, We can call and receive both return values from Basic TypesAt this point, we have seen a couple of different types now. Here is a listing of the other basic types in Stanza. As we've said already, the All of the types listed in the previous table are examples of ground 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 parametric type. Unlike ground types, parametric types take additional type parameters. An array needs to know what type of objects it holds, so it has one type parameter for specifying that. Note that for parametric types, if you leave off its parameters, then it is equivalent to specifying is equivalent to And is equivalent to Tuple types have their own syntax, and consists of surrounding the types of all of its elements with the Here is a tuple containing an integer, a string, and a tuple of a single integer. StructsFor convenience, Stanza provides a simple way to create compound types out of existing types using structs. Here is how to define a new Once Getter FunctionsTo retrieve the values of the fields it was constructed from, you may call the prints out Struct TypeAdditionally, 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 Let's try calling prints out 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. Exercises
|
|
| Site design by Luca Li. Copyright 2015. | ||