А в исходном-то языке какая стратегия вычислений? (Забыл. Пару процедур на PL/SQL составлял когда-то, но этой детали не помню.) Если call by value, то он, разумеется, не сможет написать ничего того, о чём вам стоило бы беспокоиться. Возможно, опять же, что-то недопонимаю.
PL/SQL - обычный императивный язык с энергичной стратегией вычисления. Хотя там есть ленивые встроенные
coalesce и
decode, но это - исключение, а заставить клиента писать формулы через них не представляется возможным + это даже проблемы не решит.
Я руками пишу ленивый расчет. Т.е. мне на вход приходит строка, я ее парсю как хочу, в частности теоретически могу ленивый расчет сделать.
Не понял, что значит «вычислять величину только при условии» — если побочных эффектов нет, или если величине можно в противном случае присвоить произвольное значение (по идее, если условие не выполняется, должно же быть не важно, какое у неё тогда значение?), вычисление которого не имеет их (скажем, константы 0).
Присвоить
могу, но для этого придется разбираться в формуле и определять, можно или не можно, а это выглядит сложнее даже, чем исходная задача.
И стратегия call by need всё равно не спасёт от зацикливания при вычислении A с определением A = if(false, …, A). Раз уж уже имеется определение порядка вычислений, циклические ссылки при этом должны определяться, и надо сообщать клиенту, что он неправ, когда они есть.
Да, безусловно. В данном случае нас должен спасать здравый смысл. Т.е. если клиент что-то такое написал, то его мы должны обругать, на уровне программиста, а еще лучше, на уровне вычислителя.
в общем случае от той величины, которую иногда может быть «не надо» вычислять, могут зависеть другие. Что тогда делать с ними?
У меня такой проблемы пока нет
К сожалению, даже на на анализ уже нет времени.
Кстати, ленивые вычисления придумали для оптимизации производительности вроде, да? Просто в PL/SQL execute immediate, coalesce и decode - это прямо противоположные производительности вещи.
Последние два лучше на CASE заменить...
Мне надо не для оптимизации (какая м.б. у меня оптимизация, если я для расчета
строки парсю). Мне надо для расчета
A=dbase.iif(P,F,A)Но я тоже пробовал писать трансляторы на PL/SQL.
Грубо говоря, после парсинга у вас получается дерево, а раз уж там все равно Oracle, то это дерево складываем в таблицу вида (id, parent_id, <все остальное>), а потом рекурсивный WITH:
Спасибо, я запишу себе, если понадобится - применю. "Ленивость" парсера неважна, важна стратегия вычисления "снаружи внутрь" в том языке, в котором работает клиент - именно для расчета штук вида
A=dbase.iif(P,F,A).
Вообще, я поспал, и сейчас мне кажется самым простым написать аппликативный расчет только для внешнего
dbase.iif.
Ввести в язык
Если было бы хорошо, но тогда даже то, что сейчас вычисляет
execute immediate, придется считать руками.
До чего я докатился