Right now there are a few ways we can create UDF:
- With standalone function:
This allows for full control flow, including exception handling, but duplicates variables.
- With `lambda` expression:
No variable duplication but only pure expressions.
- Using nested functions with immediate call:
Quite verbose but enables full control flow and clearly indicates expected number of arguments.
- Using `udf` functions as a decorator:
Possible but only with default `returnType` (or curried `@partial(udf, returnType=IntegerType())`).
Add `udf` decorator which can be used as follows: