Опыты с Фактором
Aug. 12th, 2021 05:14 amВот, допустим, команда dup
dup ( x -- x x )
она удваивает последний элемент в стеке. А вот команда drop
drop ( x -- )
она удаляет последний элемент стека. Если сделать подряд drop dup, стековый эффект будет такой
( x y -- x x )
Определяем новую функцию fff, которая делает drop dup, для неё надо указать стековый эффект
: fff ( x y -- x x ) drop dup ;
и компилятор его проверит (это такая рудиментарная проверка типов, очень помогает от грубых ошибок). Теперь определяем функцию, которая вызывает сама себя, а эффект указываем какой угодно
: fff ( x -- ) fff ;
компилятор не возражает (при вызове эта функция зациклится). Теперь определяем такую функцию
: fff ( x -- ) fff fff ;
компилятор выдаёт ошибку "неправильно указан стековый эффект, должно быть
( x x -- )". Действительно, если fff ( x -- ) выбрасывает один элемент, то fff fff должно выбрасывать два. Теперь пишем комбинацию dup call, она удваивает последний элемент
dup ( x -- x x )
и применяет его сам к себе вызовом call. Применим эту комбинацию саму к себе
[ dup call ] dup call
и зациклимся. Попробуем вычислить для неё стековый эффект (для этого есть специальная команда), компилятор выдаёт ошибку "штуковина применяется сама к себе, нехорошо". Тут мне становится смешно на хитроумие некоторых программистов, которые так пытаются бороться с зацикливанием. В общем, я разобрался, как компилятор Фактора проверяет стековый эффект и сейчас буду думать, нельзя ли улучшить (в том виде, как есть, там дыра на дыре).
dup ( x -- x x )
она удваивает последний элемент в стеке. А вот команда drop
drop ( x -- )
она удаляет последний элемент стека. Если сделать подряд drop dup, стековый эффект будет такой
( x y -- x x )
Определяем новую функцию fff, которая делает drop dup, для неё надо указать стековый эффект
: fff ( x y -- x x ) drop dup ;
и компилятор его проверит (это такая рудиментарная проверка типов, очень помогает от грубых ошибок). Теперь определяем функцию, которая вызывает сама себя, а эффект указываем какой угодно
: fff ( x -- ) fff ;
компилятор не возражает (при вызове эта функция зациклится). Теперь определяем такую функцию
: fff ( x -- ) fff fff ;
компилятор выдаёт ошибку "неправильно указан стековый эффект, должно быть
( x x -- )". Действительно, если fff ( x -- ) выбрасывает один элемент, то fff fff должно выбрасывать два. Теперь пишем комбинацию dup call, она удваивает последний элемент
dup ( x -- x x )
и применяет его сам к себе вызовом call. Применим эту комбинацию саму к себе
[ dup call ] dup call
и зациклимся. Попробуем вычислить для неё стековый эффект (для этого есть специальная команда), компилятор выдаёт ошибку "штуковина применяется сама к себе, нехорошо". Тут мне становится смешно на хитроумие некоторых программистов, которые так пытаются бороться с зацикливанием. В общем, я разобрался, как компилятор Фактора проверяет стековый эффект и сейчас буду думать, нельзя ли улучшить (в том виде, как есть, там дыра на дыре).