Hacker News new | ask | show | jobs
by rocqua 1740 days ago
The 'require named argument' solution is less strong than the enum solution. (An enum is also available in python). Indeed re-use of the plain bool in Python is less clear, as is passing it on. This makes the enum the best solution.

However, enum is also a heavy-duty solution. It requires slightly more typing, but more importantly, it requires exporting an enum to all call-sites. Both in C++ and in python this is not desirable.

I'd say the enum should be in the toolbox, especially if the flag is important to the business logic of the code, and is likely to thread throughout it. But for quick work, a key-word only argument can work just as well. Especially if the flag is never to be passed on.

2 comments

It's worth noting that in Python, the enum will be slower than using a bool (how much slower? I don't know - I haven't measured it), if for no other reason than the repeated name lookups. Is it worth fretting over for something that's called occasionally? Probably not. If it's something that's going to be called a lot, e.g. in a tight loop, then it's something to be concerned about.
Another solution if you write fully-typed Python is to use typing.Literal:

    calc(x, y, mode="gain")
where the function is defined as

    def calc(
        x: float,
        y: float,
        *,
        mode: Literal["gain", "render"],
    ) -> float:
        ...
This is IMO one of the best things type annotations provide. Combined with Protocol you can write much better structured code with little or no runtime costs.
>... it requires exporting an enum to all call-sites. Both in C++ and in python this is not desirable.

Given the reasonable namespacing that C++ and python [modules] provide, and that you have to export the complete calling specification of the function to the caller anyway (whether it's an enum, a positional boolean or a keyword argument), what's the drawback of the enum option?

In Python, if you use ' import x from' now it becomes 'import x, y from'. Can especially make refactoring more work.

If you use namespaced imports then the call is going to become very long by having the package name included twice.

In C++ you are dealing with needing to drop the enum in a header file, requiring a two file change and making headers bigger. The call-side has the same potential namespace problem, but less badly.