* Bruno Le Floch <[log in to unmask]> [2012-02-05 13:01:41 -0500]: Hello Bruno, : It's an expansion issue. Everything that appears within an integer : expression must be fully expandable, and x-type expansion is not : expandable (I think that's documented in l3expan, otherwise, it should : be added). You can use f-expansion instead, which expands from the : left, stopping at the first expandable macro; it will expand any : expandable function, but not restricted expandable functions (hollow : stars in the doc, I believe), such as \tl_map_function:NN. So to : expand an integer argument, use Thanks very much. I'll have a look at this this evening/tomorrow. (I did have a quick glance, and I think I understand all your comments.) : \exp_args:Nf \recurrence_f_0:n { \int_eval:n {#1} } : : Also, we normally denote the arguments by "n", unless they explicitly : perform expansion on top of their normal action. For instance, : \int_eval:n expands everything until finding integers, but it is : called \int_eval:n, not \int_eval:x. Thanks. It's something that wasn't clear from the documentation, which suggested (to me) that adding the x made the macros magically expand everything. (As you can see, I had to explicitly evaluate some arguments so that made me wonder how it really worked.) So, am I right in understanding that the macro signature is for documentation only? If yes, then that makes a lot more sense to me. : Putting all that together, your macros could be : : \f macro:#1->\int_eval:n { \f:n {#1} } : \f:n macro:#1->\exp_args:Nf \recurrence_f_0:n {\int_eval:n {#1}} : \recurrence_f_0:n macro:#1->\int_compare:nTF {#1=0}{1}{\recurrence_f_1:n {#1}} : \recurrence_f_1:n macro:#1->\int_compare:nTF {#1=1}{1}{\recurrence_f_2:n {#1}} : \recurrence_f_2:n macro:#1->\bool_if:nTF {\int_compare_p:n{1=1}} : {\f:n{#1-1}+\f:n{#1-2}} {\recurrence_f_3:n {#1}} : \recurrence_f_3:n \long macro:#1->0\msg_expandable_error:n {f[ #1 ] undefined.} : : (1) Notice that I've used \int_eval:n in the definition of \f. : Otherwise, you would end up with an expansion of the form 1+1+1+1+1, : not evaluated to give 5. I had already noticed it:-) : (2) Also, the function _3 should use \msg_expandable_error:n, which : gives a nicer log output than just \error, and expands to nothing. : Since it expands to nothing, but we're within an \int_eval:n, we must : insert a default value, here 0. I know. It was a quick hack. I still had to look up the name of the macro. : (3) I changed the signature to "n" instead of "x", since the functions : do not perform any special expansion of their arguments before using : them. : : (4) As it is, the code will un forever on negative input. You should : probably use \int_compare_p:n {#1>0} or something like that in the _2 : function. : : (5) Of course you know it, this code will run exponentially slowly for : large input. That is difficult to solve (but doable; I can give : details) if you want an expandable function which expands to the value : of your recursion. For a non-expandable function of the form : \recursion_get_value_f:nN { <index> } <int var> (dunno how the : function should be called), getting a linear-time solution should be : easier: it involves storing the intermediate results as you get them. : : > The current code I have is packaged as a .tex and a .sty file. If you have : > any comments on the problem, or indeed, the source files, then that'd be : > much appreciated. : [ more comments ] I'll study this later but I may be back about it. Thanks very much for your help. Regards, Marc