350 likes | 494 Views
CS 152, Programming Paradigms Fall 2012, SJSU. Jeff Smith. Expressions and statements. Ideally the meaning of an expression will depend only on the values of the subexpressions, and the meaning of the operator that is used to combine these values.
E N D
CS 152, Programming ParadigmsFall 2012, SJSU Jeff Smith
Expressions and statements • Ideally the meaning of an expression will depend only on • the values of the subexpressions, and • the meaning of the operator that is used to combine these values. • In this case, the semantics is said to be compositional.
Order of evaluation • With compositional semantics, syntax trees can be evaluated bottom up. • Can subexpressions can be evaluated in any order without affecting the value? • this issue is important for compiler optimization. • The answer is "yes", in the absence of side effects. • note that side effects can include throwing an exception, or simply failing.
Short-circuit evaluation • With short-circuit evaluation of Boolean expressions, the order of evaluation of the subexpressions can determine whether the overall evaluation succeeds or fails.. • Some languages offer a choice between short-circuit operators and those that aren't short circuit.
Modifying a function argument • Another special kind of side effect arises if a function can modify its argument. • In this case the order of evaluation can be important in an expression like • f(x) + g(x) • Functions that don't behave the way mathematical functions do make programs hard to reason about.
Conditionals and ambiguity • Conditionals can be ambiguous, e.g. • if X then if Y then Z else W • Ambiguity is usually resolved here by associating each else with the nearest if.
Disambiguating conditionals • A different interpretation can be forced by a requirement of explicit delimiters, e.g. • if X then {if Y then Z} else W
Disambiguating conditionals • Or explicit bracketing keywords can be required for all conditionals, e.g. • if X then • if Y then Z endif • else W • endif • This is a different string of tokens than • if X then • if Y then Z else W endif • endif
Explicit bracketing keywords • are used by Ada (cf. L&L, p 413) • recall the Ada BNF solution from the syntax slides • may include an elsif construction to avoid multiple closing endifs, e.g. • if --- then --- • elsif --- then --- • elsif --- then --- • else --- • end if
Tests as boolean expressions • A language designer needs to decide whether the tests in conditional statements need to have boolean values. • If not, then a policy is needed to determine which nonboolean values correspond to a successful test.
Conditional evaluation • Don't confuse conditional execution with conditional evaluation • the latter returns a value • In C the latter looks like • A ? B : C • When considered as ternary functions, such functions do not evaluate all of their arguments.
Case and switch statements • Many languages offer multiway conditional statements based on the value of a single expression • e.g., switch statements in C • e.g., casestatements in Fortran
Issues for case and switch statements • which types are allowed for the expression? any discrete type? • can cases be combined for two or more different values? • is there a default case? • what if the actual value is not among the specified alternatives?
Indefinite iteration • Languages may allow a block of statements may be executed while some condition remains true • or until some condition becomes true • In the first case the condition is tested before the block; in the second case it's tested afterwards. • C and Java have a while statement for case 1, and a do-until statement for case 2.
For loops • Some special cases of iteration are handled with for loops, which use a loop control variable (LCV). • Loop control variable issues: • what types of LCVs are ok? any ordinal type? any discrete type? • must an LCV be explicitly declared? • must it be local to the loop?
Values of loop control variables (LCVs) • Must integer LCVs begin at 0? at 1? • Can an LCV be assigned a value inside a loop? if so, is the assignment effective? • How can LCVs be incremented? decremented? • by successor or predecessor only? • Are loop bounds evaluated just once, or at every iteration?
Control and for loops • Can control be transferred into a loop? • if so, what's the LCV's initial value? • Can control be transferred out of a loop? • Can control be transferred out of the current iteration? • if so, where does control go? • can a programmer decide? • Outside of the loop, do LCVs have a value? • if so, what is it?
Collections and iteration • One common use of for loops is to process each element of a collection. • For this sort of traversal, languages sometimes provide a specialized for loop known as a for-each loop. • Another possibility is an iterator data type.
Transferring control out of a loop • The ability to transfer control out of a loop is useful enough that some languages provide special mechanisms for doing so. • Java has a break construction for this purpose. • and a related continue construction • One advantage of such constructions is that they can replace a goto statement of the sort found in assembly languages.
Programming using goto • Using goto often leads to bugs and hard-to-read programs. • It's common for languages not to providing a goto statement at all. • Arguably, using break and continue avoids these problems of goto. • So languages that do not provide a goto statement often provide versions of these constructions.
Detecting and handling errors • Many languages have a special mechanism for detecting and handling errors. • The alternative to a special mechanism would be to test for every possible error in the program code. • But some errors (out of memory, corrupt file) don't result from program code.
Errors in functions • could be reported by a special return type • cf. L&L, p. 424 • but the function may already have a conflicting return type. • could be reported by a special value of an existing return type • cf. the indexOf method for ArrayLists • but all values of the return type might be needed for nonerroneous cases.
Errors in functions, part 2 • could be dealt with by passing an error handling function as a parameter • cf. L&L, p. 425 • but not all languages allow function parameters. • could be reported by creating an extra return type, or passing an extra pointer (or reference) parameter. • but not all languages allow this.
Detecting and reporting errors • All of these alternate mechanisms are arguably overly complicated, compared to an exception mechanism as in Java. • Errors that are found can sometimes be handled locally. • But the program segment that detects the error is not always the best segment to handle the error.
Issues for exceptions • Are they types, or instances of types? • What types may be exception types? • Which such types are predefined? • How can users define their own exception types? • Are exceptions basic, or composite? • What is the scope of an exception (name)?
Raising and handling exceptions • How are exceptions raised (or thrown)? • How are handlers defined? • i.e., where does handler code go? • How are handlers bound to exceptions? • by name? by type name?
Binding handlers to exceptions • Scoping issues may arise if handlers are bound to exceptions by name (or type name) • If a block f defines an exception type name, but no handler for that type, then • an exception of that type raised inside f may fail to find a handler inside f, • the chain of callers can extend outside f, • and outside f the type name is out of scope and can’t be matched
What if exception (type) names are out of scope? • Exceptions whose (type) names are out of scope are effectively anonymous. • Languages may have a policy for such cases. • In Java, handlers may be available for supertypes. • In Ada, the others keyword may be used as in its case keyword statement (cf. L&L, p. 428).
Issues for exception handlers • what is the scope of a handler? • what predefined handlers are available? • can they be redefined? • are there default handlers? • can handling be disabled? • If there's no local handler, • where is a nonlocal handler sought? • must it be sought explicitly? • how does the handler get control?
Issues for continuation • after handling, is the exception reraised? • where exactly does control resume? • in what environment? • can the programmer decide either issue? • can handlers raise exceptions? • can a value be returned? if so, how? • what if there's cleanup to do? • (e.g., a file to close)
Issues regarding functions • what is the syntax of a call? a definition? • what if there are no arguments? • can a function have side effects? • can a function have side effects only • i.e., no return value? • can function definitions be nested?
Function overloading • can predefined functions be overloaded? • how can overloaded functions be distinguished? • is it enough to have distinct return types?
Operator overloading • (Infix) operators • can they be user-defined? • if so, how are they distinguished from ordinary (prefix) functions? • Can predefined operators be overloaded? • if so, must the precedence and associativity stay the same?
Parameters • Is an evaluation order specified? • How are parameters & arguments matched? • by position? by name? • Are default parameters possible? • if so, must they come last? • Are extra arguments just ignored? • or treated as an error? • Is a variable number of parameters possible? • if so, can their types be checked?
Returns and return values • Can a return value be of any type? • an aggregate? a function? • If a function, what environment is used? • How is the type of the return value specified? • What is the syntax for a return? • assignment to a special variable? • an explicit return statement? • Can the return value be ignored by the caller?