Closed ivan-pi closed 3 years ago
Here's an example of adding multiple elements:
#:def base_add(a,b)
(${a}$ + ${b}$)
#:enddef
#:def add(a,b,*pos)
#:set res = base_add(a,b)
#:if len(pos) > 0
#:set res = add(res,*pos)
$:res
#:else
$:res
#:endif
#:enddef
res = @{add(1,2,3,4)}@
@ivan-pi The variable number of arguments was actually documented, but the word variadic was not used, indeed. And the recursive call was not mentioned at all in the docs. I've fixed it now (cd222e2), thanks a lot for making me aware of it, and also for the nice example with the Horner scheme, which is now included (in a simplified form) in the docs.
Thanks for documenting this. I must say the recursion can be tricky to get right in some cases. Inspired by the functional-fortran package I attempted to produce left and right "fold" macros that would work for arbitrary binary operators:
#:def binary_op(op,a,b)
(${a}$ ${op}$ ${b}$)
#:enddef
#:def foldl(op,start,*pos)
#:if len(pos) > 0
#:set res = foldl(op,binary_op(op,start,pos[0]),*pos[1:])
$:res
#:else
$:start
#:endif
#:enddef
#:def foldr(op,start,*pos)
#:if len(pos) > 0
#:set res = binary_op(op,start,&
foldr(op,pos[0],*pos[1:]))
$:res
#:else
$:start
#:endif
#:enddef
@{foldl(.and.,a)}@
@{foldl(.and.,a,b)}@
@{foldl(.and.,a,b,c)}@
@{foldl(.and.,a,b,c,d)}@
@{foldl(.and.,a,b,c,d,e)}@
@{foldr(+,a)}@
@{foldr(+,a,b)}@
@{foldr(+,a,b,c)}@
@{foldr(+,a,b,c,d)}@
@{foldr(+,a,b,c,d,e)}@
For the right-fold I exceeded the maximal recursion depth dozens of times before finally succeeding by copying the code functional-fortran uses verbatim.
Cool example! However, one really has to decide, where to stop with preprocessing and let the compiler do the work instead. Unfortunately, fold
-like operations are not necessary very efficient in imperative languages without lazy evaluation...
Yes, I don't have actual use cases for these, but it's interesting to probe what can be done via preprocessing.
I attended a C++ course recently, where I learned about variadic templates. Here's an example of using C++17 to compute the maximum value:
Today, I finally had time to try this with fypp:
The input
gets expanded as
I was really impressed when this just worked straight out the box! Now of course the Fortran
max
intrinsic is already variadic and can be used directly asmax(a,b,c,d)
, so this example makes only little sense.The website fypp.readthedocs.io doesn't appear to contain the keywords recursive or variadic anywhere, so I thought I'd open an issue.