= Expression Tour = This is a "tour" of various kinds of expressions in Cobra. It is intended to help you learn Cobra by quickly highlighting some interesting expressions you can write. It is neither a reference nor an exhaustive list of features. It assumes that the reader has basic familiarity with programming. == Displaying Expression Values == One of the best ways is to display an expression's value is to use the [wiki:Trace] statement which will show the source code of the expression, its value and the location of the trace in the source code (filename, line number, etc.): {{{ #!cobra trace p.x, p.y }}} {{{ trace: p.x=5; p.y=6; at Foo.cobra:6; in Foo.main }}} You can, of course, use a [wiki:Print] statement. On a related note, you can validate the value of an expression with an [wiki:Assert] statement. {{{ #!python print 'My name is', name assert x > 0 }}} == Arithmetic == Arithmetic has the usual infix operators and parentheses for grouping. Note that division with a single slash (/) gives a fractional value. Use a double slash (//) for "integer" division. {{{ #!cobra assert 4 / 5 = 0.8 assert 4 // 5 == 0 assert 6 / 5 == 1.2 assert 6 // 5 == 1 }}} Augmented assignment operators can be used to change values: {{{ #!cobra i += 1 p.x *= 2 }}} Underscores can be put in numbers to separate groups of digits for easier reading: {{{ #!python big = 10_000_000 }}} == Bitwise == Standard bit operations. - & = bitwise 'and' - | = bitwise 'or' - ~ = bitwise not (flip) - !^ = bitwise Xor - << = left shift - >> = right shift == Boolean == Boolean expressions include the literals `true` and `false` as well as logical operations such as `and`, `or`, `not`, comparisons and other tests. {{{ #!cobra obj.isActive = true if obj.isActive, .doSomething }}} Note: You dont need to compare booleans against true or false ( dont say == true or ==false).[[BR]] Most expressions can determine a natural truth or not. See ConditionalExpr. to-do (all, any) == Strings == to-do (literals, immutable, common methods, stringbuilder, msdn reference) == Calling Methods == to-do (don't need empty parens, calling on "this", calling base) == Instantiating Types == to-do (use parens, keyword args for properties, combining enums, works on System.Type and dynamic) == Comparing Values == to-do (<>, is & is not vs. == & <>, 0<= i < 10, overriding .equals (and .getHashCode) and .compareTo) == Collections == to-do (list, array, set, dict, explicit creation, indexing, .get, membership(in and not in for lists, arrays, sets, dict.keys, dict.values) ) == Slicing == to-do == Type Membership == to-do (inherits, implements, if-inherits, alternative is virtual method) == Casting to Type or Nilability == Cast an expression to a particular Type (nilable or not). Cast to or away from nilability. EXPR to TYPE - cast the expression to the given TYPE, cast failing throws an Exception. - ("cast or throw Exception") EXPR to? TYPE - cast the expression to the given TYPE, if the cast fails return nil - ("cast or return nil") - Note: single token 'to?' no spaces EXPR to ? - cast the type of EXPR to the nilable version of same type (EXPR.typeOf?) - Note space between 'to' and '?' EXPR to ! - cast the type of EXPR to the non-nilable version of same type( EXPR.typeOf!) {{{ #!cobra s = 'String' sObj = s to Object assert sObj.typeof is Object ds as dynamic = 'xyzzy' s = ds to String i = 99 s = i to? String assert s is nil s = 'xyzzy' # nonnilable sNil = s to ? #cast to nilable s as String? = 'xyzzy' sNotNil = s to ! # non nilable }}} == If Expression == Trinary operator on an expression. If the conditional expression evaluates to true give the first Expr otherwise give the second. Note: no space between the if and the '(' - single token 'if(' === Grammar === if( COND-EXPR, EXPR1, EXPR2 ) {{{ #!cobra i=22 z = if( i>10, 100, 0) assert z == 100 name = if( s.length, s, 'empty') o = if(o, o, default) # set o to 'default' if it is nil - but see nil coalesce below }}} == For Expression == Apply an expression across a collection or range or a filtered subset thereof. === Grammar === for VAR in EXPR [where EXPR ] get EXPR for VAR in EXPR where EXPR - same as for VAR in EXPR where EXPR get VAR for VAR in START-EXPR : STOP-EXPR [: STEP_EXPR] [where EXPR] get EXPR {{{ #!cobra a = for i in 1:4 get i*2 assert a == [2,4,6] a = for i in [1, 2, 3] get i*10 assert a == [10, 20, 30] a = for i in 10 where i>5 get i assert a == [6, 7, 8, 9] c = ['how', 'now', 'brown', 'cow'] d = for k in c where k.endsWith('ow') get k assert d == ['how', 'now', 'cow'] tmpFiles = for fileName in Directory.getFiles('.') where '.tmp' in fileName }}} == Try-Catch-Get Expression == This is a shorthand for a try-catch statement wrapping a single statement assigning an expression.[[BR]] The value of the expression is the value of the expr following 'try' or if an exception is thrown the value of the expression after the 'get'. If an Exception-Type is not given it will catch all Exceptions. === Grammar === try EXPR catch [ EXCEPTION-TYPE ] get EXPR {{{ #!cobra inVal = '..' #an int string presumably x = try int.parse(inVal) catch FormatException get 0 # return 0 if inVal not an int String # Catch all exceptions dflt = '---' s1 = try String.format('{1:P}', 0.123) catch get dflt assert s1 == '---' }}} == Nil == Operations and literals around nil/null values.[[BR]] '''nil''' is the nil/null literal EXPR to ? - cast the type of EXPR to the nilable form of the same type (EXPR.typeOf?, nilable EXPR.typeof) EXPR to ! - cast the type of EXPR to the the non-nilable form of same type( EXPR.typeOf!) EXPR ? EXPR1 - nil coalesce - if EXPR is nil return EXPR1 EXPR ! EXPR - non-nil coalesce - if EXPR is non nil return EXPR1 EXPR1 ?= EXPR1 - nil coalesce EXPR1 to itself or EXPR2 - same as EXPR1 = EXPR1 ? EXPR2 EXPR1 != EXPR1 - non-nil coalesce EXPR1 to itself or EXPR2 - same as EXPR = EXPR1 ! EXPR2 - Note: gotcha Warning b != a This is NOT 'b not equals (<>) a' - is same as b = b ! a OR b = if( b <> nil, a, nil) {{{ #!cobra if a is nil, print 'Bad a' y = a ? b # coalesce nil : y gets a if a non nil, b otherwise #same as y = if(a, a, b) except a evaluated only once a = a ? default # a if a nonnil, default otherwise # above is same as a ?= default y = b ! a # coalesce non nil : y gets b if b is nil, a otherwise # same as y = if(b <> nil, a, nil) OR y = if(not b, a, nil) i as int? = input ! int.parse(input) #( equiv to i = if(input <> nil ? int.parse(input), nil) }}} == Method References == to-do (ref obj.method) == Expressions in Contracts == to-do (old expr, a implies b, breakout to a method) == See Also == * LanguageTopics * HowToPrograms * LibraryTopics