Changes between Version 2 and Version 3 of CoalesceExpression
- Timestamp:
- 07/07/13 13:27:14 (11 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
CoalesceExpression
v2 v3 1 = Coalesce Expression = 1 = Coalesce Expressions = 2 There are two forms of this - nil-coalesce and nonNil-coalesce. 3 In both cases they evaluate the first expression and if it is nil (nonNil) return the second expression otherwise return the first expression. 2 4 3 The '''coalesce''' binary expression evaluates to the first non-nil value. There is an augmented assignment version of it as well. 5 They are convenient shorthand for respectively testing an expression against nil and returning a default or 6 testing against nonNil and returning something else (usually a deref of the first expression) 7 8 = Nil Coalesce = 9 10 The '''nil coalesce''' binary expression evaluates to the first non-nil value. There is an augmented assignment version of it as well. 4 11 5 12 === Grammar === … … 10 17 The expression evaluates to a unless that value is '''nil''', in which case, it evaluates to '''b'''. 11 18 12 Although uncommon, nothing prevents b itself from also being '''nil'''. Neither expression will be evaluated more than once and if a is non-nil then b will not be evaluated at all. 19 Although uncommon, nothing prevents b itself from also being '''nil'''. 20 Neither expression will be evaluated more than once and if a is non-nil then b will not be evaluated at all. 13 21 14 22 The type of the coalesce expression is the greatest common denominator between the type of '''a''' and the type of '''b'''. … … 19 27 }}} 20 28 21 In the augmented assignment version, the result is assigned back to a. This requires that b is type compatible with a or a compilation error will occur. 29 In the augmented assignment version, the result is assigned back to a. 30 This requires that b is type compatible with a or a compilation error will occur. 22 31 32 === Examples === 23 33 {{{ 24 34 #!cobra 25 35 # Example 1 26 36 print name ? 'NONAME' 37 27 38 28 39 # Example 2 … … 32 43 33 44 # Example 3 34 get name as String35 return _name ? .getType.name36 37 # Example 438 45 # this: 39 46 name = if(employee.manager.name<>nil, employee.manager.name, 'NONAME') 40 47 # can evaluate the key expression twice and is less succinct than: 41 48 name = employee.manager.name ? 'NONAME' 49 42 50 }}} 51 52 53 = !NonNil Coalesce = 54 55 The '''nonNil coalesce''' binary expression evaluates the second expression if the first is a non-nil value. 56 If the first expression is nil it just returns it. 57 There is an augmented assignment version of it as well. 58 59 === Grammar === 60 {{{ 61 <a> ! <b> 62 }}} 63 64 The expression evaluates to a if that value is '''nil''', otherwise it evaluates to '''b'''. 65 66 Although uncommon, nothing prevents b itself from also being '''nil'''. 67 Neither expression will be evaluated more than once and if a is nil then b will not be evaluated at all. 68 69 The type of the coalesce expression is the greatest common denominator between the type 'nil' and the type of '''b'''. 70 (Nilable Type of '''b''') 71 72 === Grammar === 73 {{{ 74 <a> != <b> 75 }}} 76 77 In the augmented assignment version, the result is assigned back to a. 78 This requires that b is type compatible with a or a compilation error will occur. 79 80 Note: this looks like a boolean comparison (not equals) in other languages. 81 82 {{{ 83 #!cobra 84 # Example 1 85 print x ! x.name # if x is not nil return its member name else nil 86 87 # name or default regardless of x or x.name nil 88 print x ! x.name ? 'NONAME' 89 90 # Example 2 91 current = list 92 current != current.head # (not a comparison) nil if list nil or list.head nil 93 if current 94 # process 95 96 # Example 3 97 name = if(employee and employee.manager and employee.manager.name, employee.manager.name, 'NONAME') 98 # is less succinct than: 99 name = employee ! employee.manager ! employee.manager.name ? 'NONAME' 100 # assumes derefs are idempotent (same returns on each call or deref) 101 102 # Example 4 103 #if calls are NOT idempotent need to capture each deref and use it subsequently 104 # assuming employee.manager returns nil or a different value on each visit as in some places 105 mgrName = employee ! (m = employee.manager) ! m.name ? 'NONAME' 106 }}}