Design decisions

Design decisions#

Nodes take only one unnamed (arg) argument#

By design Node callables take only one unnamed (arg) argument. While it is technically possible to handle multiple unnamed arguments, for clarity this use is not supported. Consider the following hypothetical case:

node_1 = Node(
    lambda *_: (123, "abc"),
    returns = Args[int, str] # Not supported
),

node_2 = Node(
    lambda *_: ("def", 456),
    returns = Args[str, int] # Not supported
),

node_3 = Node(
    lambda x, y: print(x, y) # '123 "abc"' or '"def" 456'
)

In the above example node_3 has no guarantees that the arguments passed as x and y have a consistent interpretation. To ensure consistency, the node would have to do type check the arguments, either inline, through a Connection’s where-clause, or using a to-be developed type validator. However, this creates additional overhead, limiting performance. Therefore, when returning more than one argument, a Node needs to name these arguments:

node_1 = Node(
    lambda *_: (123, "abc"),
    returns = Args[Param[int, "x"], Param[str, "y"]]
),

node_2 = Node(
    lambda *_: ("def", 456),
    returns = Args[Param[str, "y"], Param[int, "x"]]
),

node_3 = Node(
    lambda x, y: print(x, y) # '123 "abc"' or '456 "def"'
)