Remix.run Logo
zahlman 3 months ago

A compromise version:

    def _f_part(item) -> str:
        match item:
            case str() as s:
                return s
            case Interpolation(value, _, conversion, format_spec):
                return format(convert(value, conversion), format_spec)

    def f(template: Template) -> str:
        return ''.join(map(_f_part, template))
The `match` part could still be written using Python's if-expression syntax, too. But this way avoids having very long lines like in the Ruby example, and also destructures `item` to avoid repeatedly writing `item.`.

I very frequently use this helper-function (or sometimes a generator) idiom in order to avoid building a temporary list to `.join` (or subject to other processing). It separates per-item processing from the overall algorithm, which suits my interpretation of the "functions should do one thing" maxim.

legobmw99 2 months ago | parent [-]

I still think it is a shame that `match` isn't valid as an expression, requiring things like the helper function here that could be a lambda or part of a comprehension otherwise

zahlman 2 months ago | parent [-]

The example absolutely can be done with conditional expressions (`x if y else z`). But each `case` of a `match` can execute arbitrary imperative logic (like `return`, `raise` etc.); a "match expression" syntax would have to support much less, and it's hard to imagine how it would gain any benefit over the existing conditional expression syntax.