if then else
As a solution to condtitional code execution plu-ts
exposes an if then else construct.
However, since everything in plu-ts
is an expression, the if then else construct does not allow stuff that in typescript would have been written as
if( my_condition )
{
doSomething();
}
because we don't really know what to do if the condtion is false.
So the if then else we have in plu-ts
is more similar to the typescript ? :
ternary operator, so at the end of the day, if then else is just a function.
Let's look at a simple if then else construct:
pif( int ).$( pBool( true ) )
.then( pInt(42) )
.else( pInt(69) )
This plu-ts
expression checks the condition (pBool(true)
) and if it is a Term<Bool>
equivalent to true
it returns pInt(42)
otherwhise it returns pInt(69)
.
Why pif
is a typescript function and not a constant like other plu-ts
funcitons?
Since the type of if then else is something like bool -> a -> a -> a
, we need to specify the type of a
prior to the actual expression.
This ensures type safety so that Typescript can warn you if one of the results is not of the type you expect it to be.
What happens if one of the two branches raises an error?
plu-ts
is a strict language as we saw while having a look at papp
; that means that arguments are evaluated prior being passed to a function.
what happens if one of the argument returns an error?
The answer is what you expect to happen. Or, to be more precise, if the error rose in the branch selected by the boolean, the computation results in an error; if not it returns the result.
This is because even if by default functions are strict, pif
is lazy; meaning that it evaluates only the argument it needs and not the others.
This is done using pforce
and pdelay
so the compiled funcion is a bit larger than the one you'd expect.
if you don't need lazyness you can use the
pstrictIf
function that emits slightly less code but evaluates both the arguments.so something like
pstrictIf( int ).$( pBool( true ) ) .$( pInt(42) ) .$( pInt(69) )
is just fine but something like
// this results in an error, even if the conditional is true pstrictIf( int ).$( pBool( true ) ) .then( pInt(42) ) .else( perror( int ) ) // KABOOM
generally speaking you should always prefer the plain
pif