3 ms·
Author of the article here. The Python solution using lists-as-options is actually even simpler: def values_in(keys, d): return [x for key in keys
by rntz 12y ago
Author of the article here. The Python solution using lists-as-options is actually even simpler:
def values_in(keys, d):
return [x for key in keys for x in getOpt(d,key)]
Using lists as options is a neat trick I hadn't thought of when writing the article. Unfortunately, no dynamic language uses this idiom (or really any other non-exception option-like patterns) natively.
- dragonwriter 12y ago> The Python solution using lists-as-options is actually even simpler: Good point. For some reason, I have this giant python blind spot for comprehensions where the sources aren't orthogonal -- I miss them in the first pass all the time; I normally notice it fairly quickly in code I'm not posting on a discussion forum... > Unfortunately, no dynamic language uses this idiom (or really any other non-exception option-like patterns) natively. Yeah, to use it in your own code in most popular dynamic languages, you have to wrap library code that works differently. The good thing is that most popular dynamic libraries have good (largely functionally-inspired) tools for working with lists and other iterables that the payoff is pretty good. (Of course, with duck typing in most popular dynamic languages, one thing you could do to be more explicit is to combine the Option-as-class and Option-as-list approach, and make Option a class that implemented the interface used by immutable collections.)
- chriswarbo 12y agoActually, at least in PHP, I find myself using arrays and other iterables as pseudo-Options quite a lot; eg. when checking the existence of a DB value, xpath element, etc. // Using if/then/else function foo($x) { $results = look_up_something($x); if (count($results) > 0) { $val = $results[0]; return do_something($val); } } // Same as above, but with a foreach loop function foo($x) { foreach (look_up_something($x) as $val) { return do_something($val); } } Of course, the nice thing about Options (other than being able to distinguish between "None", "Some None", "Some (Some None)", etc.) is the availability of combinators to lift and compose non-Option functions with optional functions. Sometimes we can map and fold ("reduce"), but sometimes we can't (eg. PHP's "array_map" doesn't work on iterable objects, which many APIs use in lieu of arrays).
- wylee 12y agoThat version (and the one in the article) are somewhat confusing to parse and detract from the point of the article. This seems more "Pythonic": def lookup(d, key): return Just(d[key]) if key in d else None def values_in(keys, d): values = [] for k in keys: x = lookup(d, k) if x: values.append(x.value) return values If you really want a one-liner, I think this is easier to understand: def values_in(keys, d): return [x.value for x in (lookup(d, k) for k in keys) if x]
- falcolas 12y agoWell, considering that this is an indirection on top of the `in` operator which will slow the whole thing down, of course they're not typically implemented in idiomatic solutions in Python. The obvious being said, you can also use functions and lambdas to get around having to create custom classes or abuse lists. def value(x): return lambda: x def values_in(keys, d): return [x() for x in (value(d[key]) if key in d else None for key in keys) if x] def get_maybe(d, k): return value(d[k]) if k in d else None def values_maybe(keys, d): """ If you want the caller to be responsible for handling the maybe case """ return [get_maybe(d, k) for k in keys]