List Compehension

seen from Germany

seen from Germany
seen from Germany
seen from Germany

seen from United Kingdom
seen from United States
seen from Sweden
seen from United Kingdom

seen from Netherlands

seen from United States
seen from Malaysia
seen from Türkiye

seen from United Kingdom
seen from Germany
seen from United States

seen from Malaysia

seen from Malaysia
seen from Germany
seen from China
seen from Yemen
List Compehension
Wednesday December 26, 2012
watched teekyuu ep1-12, man that is some crazy stuff
worked on compilers pretty much all day. Got pointer arithmetic working for ints and pointers (though not for multi-dimensional arrays), got some basic IF branching done (assuming no short-circuit operators in the check), started evaluating conditional expressions outside of control flow context, and trying to use that inside the control flow things also instead of the usual
Conditional Expressions In Python
The Python syntax for conditional expressions (introduced in Python 2.5) is
trueval if cond else falseval
I think this is bloody awful. Why couldn’t they have adopted the standard C syntax, as used in a whole bunch of other C-derivative languages?
cond ? trueval : falseval
On the bright side, there are some alternative constructs that allow you to avoid that horrible syntax. Here’s one I have used a few times:
(falseval, trueval)[cond]
For example:
NrRows = (3, 5)[LargeTable]
The main disadvantage with this is that it doesn’t do short-circuit evaluation: both falseval and trueval are always evaluated, regardless of the value of cond. For example, this will crash with a “TypeError: 'NoneType' object is not subscriptable” if Dict happens to be None:
Value = (None, Dict[Key])[Dict != None]
It also requires that cond evaluate to 0, 1, True or False, not allowing other types of values like standard Python conditionals, but I don’t see this as a disadvantage.
Here is another form I have seen suggested:
cond and trueval or falseval
For example (rewriting the crashing example above):
Value = Dict != None and Dict[Key] or None
This one correctly short-circuits the evaluation of the arms of the conditional, provided that trueval does not return a value that can be interpreted as false. In other words, it can malfunction in mysterious ways if you’re not careful.
Finally, here’s an idea I came up with, which introduces short-circuit evaluation into the first alternative I mentioned above:
(lambda : falseval, lambda : trueval)[cond]()
For example:
Value = (lambda : None, lambda : Dict[Key])[Dict != None]()
Don’t you just love lambda-expressions?
But Wait, There’s More
This idea can be carried further. Some languages have case-expressions, which are the expression equivalent of switch/case statements. The above lambda-using template can be extended to implement these, either as simple indexing into an array of alternatives:
( lambda : case_0_expr, lambda : case_1_expr, lambda : case_2_expr, ... )[index]()
which evaluates to case_0_expr if index equals 0, case_1_expr if index equals 1 and so on; or by a more general table lookup:
{ key1 : lambda : case_key1_expr, key2 : lambda : case_key2_expr key3 : lambda : case_key3_expr, ... }[selector]()
which evaluates to case_key1_expr if selector equals key1, case_key2_expr if selector equals key2 and so on. This last form can also be extended to include a default case, if selector matches none of the keyed alternatives:
{ key1 : lambda : case_key1_expr, key2 : lambda : case_key2_expr key3 : lambda : case_key3_expr, ... }.get(selector, lambda : default_expr)()