Так что Ваша задумка решается похоже одной лишь local(M=...). Правда не проверял.
Так проверьте
Если я правильно понимаю, то после local() все определённые в ней локальные переменные будут видны в любой функции, вызванной из данной.
Да, поэтому сперва мне предложили решение в виде комплекта из двух функций. Одна - рекурсивная, но использует внешнюю по отношению к ней переменную (массив накопленных решений) с конкретным именем (
М). А вторая - в которой определяется переменная
M с массивом накопленных значений как
local() и затем вызывается рекурсивная.
То есть, примерно так:
Вызываемая (рекурсивная) функция
Код:
memo_p(n,k)=
{
my(z); /* в z будет результат */
/* несколько строк пропущены */
if(mapisdefined(M,[n,k],&z),return(z)); /* проверка во _внешней_ по отношению к функции memo_p() переменной M */
z=memo_p(n,k-1)+memo_p(n-k); /* рекурсивный вызов */
mapput(M,[n,k],z); /* запоминание промежуточного результата */
return(z)
}
Вызывающая (нерекурсивная функция):
Код:
p(n,k)=
{
local(M=Map());
memo_p(n,k)
}
Но это "не чистое" решение, поскольку в этом комплекте рекурсивная функция
memo_p() должна использовать в теле конкретное имя "внешней" переменной
M. Упрятывание одной функции в другую разрешает эту несовершенность.
P.S. В версии 2.12 будет реализовано использование ссылок на аргументы, т.е. можно будет передавать в функцию не значение (копию) аргумента, а ссылку на него (и таким образом менять значение аргумента внутри вызываемой функции, чего сейчас делать нельзя в пользовательских функциях -- при вызове пользовательской функции туда передается копия аргумента, её можно менять, но при выходе из функции эта копия уничтожается). Правда, для указания на то что это ссылка, а не сама переменная, будет использоваться тильда, а не амперсанд (амперсанд используется сейчас для указания на то, что передается ссылка в некоторых "системных" функциях). Так что гибкость программирования увеличивается, что хорошо, но немного боязно.