Всем привет.
Человек я здесь новый, так что строго не судите
Сам я пишу на Дельфи, поэтому на нее и ориентируюсь.
Понятно, что если в языках давно есть указатель на функцию/процедуру, то не мне первому эта идея в голову пришла. Мне неясно только, почему реализацию этой идеи я практически не встречаю. Может, плохо смотрю?
Сложную логику (вложенные if'ы), реузьтатом которых является присвоение чего-либо одной переменной, можно схлопнуть в const массив и обращаться к его элементам, используя как индекс само условие (благо, в Дельфи индекс массива пожет иметь любой перечислимый тип, в том числе и Boolean).
Возможно, что нужно будет использовать хеш-функцию для отображения "условий" на индекс массива.
Const-массив указателей на функции дает нам "дешевый" полиморфизм.
Вообще индексация схожих по смыслу вещей (ответов, действий, полей записи — пример поля TRect и TPoint...) дает основу для нехилого обобщения и уменьшения (!) кода, чем я сам регулярно пользуюсь.
Вот... вообще я это уже нашел в Code Complete под названием "Табличные методы", но там далеко не все, что у меня сейчас в голове роится.
Всем спасибо за внимание!
P.S. Наверное, это меня haskell испортил
Здравствуйте, Jandor, Вы писали:
J>Const-массив указателей на функции дает нам "дешевый" полиморфизм.
Я так (на Component Pascal) синтаксический анализатор писал. Массив из процедур, а индекс — номер буквы, на которую начинается слово. Дёшево и сердито.
Здравствуйте, Сергей Губанов, Вы писали:
J>>Const-массив указателей на функции дает нам "дешевый" полиморфизм.
СГ>Я так (на Component Pascal) синтаксический анализатор писал. Массив из процедур, а индекс — номер буквы, на которую начинается слово. Дёшево и сердито.
СГ>
ИМХО такие вещи должен оптимизатор делать
сам, а нам для него должно быть достаточно просто написать switch. Тогда будет меньше проблем с сопровождением. Что радует, бывает оптимизаторы так и делают.
Хотя не всегда. Не 64 мегабайта же таблицу делать для такого:
/// Конвертиреут знаки операций из ASCII во внутреннее представление.
Lexem static inline lexem(const tree_chars val)
{
const unsigned v = reinterpret_cast<unsigned>(val);
switch ( v )
{
case '*>-': return arrow_asterisk; // ->*
case '...': return dot_dot_dot; // ...
case '=>>': return greater_greater_equal; // >>=
case '=<<': return less_less_equal; // <<=
default: switch ( static_cast<two_chars>(v) )
{
case '&&': return ampersand_ampersand; // &&
case '=&': return ampersand_equal; // &=
case '>-': return arrow; // ->
case '=*': return asterisk_equal; // *=
case '=^': return caret_equal; // ^=
case '::': return colon_colon; // ::
case '*.': return dot_asterisk; // .*
case '==': return equal_equal; // ==
case '=>': return greater_equal; // >=
case '>>': return greater_greater; // >>
case '=<': return less_equal; // <=
case '<<': return less_less; // <<
case '=-': return minus_equal; // -=
case '--': return minus_minus; // --
case '=!': return non_equal; // !=
case '=%': return percent_equal; // %=
case '=+': return plus_equal; // +=
case '++': return plus_plus; // ++
case '=/': return slash_equal; // /=
case '=|': return vertical_equal; // |=
case '||': return vertical_vertical; // ||
default: return static_cast<Lexem>(static_cast<byte_t>(v));
} }
}
А вообще, этот "трюк с таблицами" давно известен на ассемблере. Забавно, что и на HLL его не забыли.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth