Использование цитаты, вычисленной по другому слову, приводит к ошибке компиляции

Фон

Загрузка фрагмента ниже приводит к сообщению об ошибке Невозможно применить "вызов" к вычисляемому значению во время выполнения:

: subtract-sum ( seq -- quot: ( n -- n ) ) sum '[ _ - ] ;
: subtract-sum-seq ( seq -- x ) dup subtract-sum map ;

Насколько я понимаю, это ожидаемое поведение, поскольку внутренний вызов для вызова в карте требует, чтобы входные и выходные данные обработанной цитаты присутствовали во время компиляции.

проблема

Однако я проверял в слушателе, что я считаю двумя эквивалентными выражениями, и они работали просто отлично.

Пример 1:

# : subtract-sum ( seq -- quot: ( n -- n ) ) sum '[ _ - ] ;
# : subtract-sum-seq ( seq -- seq call ) dup subtract-sum ;
# { 1 2 3 4 } subtract-sum-seq
{ 1 2 3 4 }
[ 10 - ]
# map
{ -9 -8 -7 -6 }

Пример 2:

# : subtract-sum-seq ( seq -- x ) dup '[ _ - ] map ;
# { 1 2 3 4 } subtract-sum-seq
{ -9 -8 -7 -6 }

Вопрос

В чем разница между исходным кодом и рабочими примерами, который вызывает ошибку в первом, а не в двух других? Ясно, что в цитатах что-то не так.

Дополнительная информация

Интересно, что я попытался обернуть свой вызов map внутри слушателя из первого примера в слово, и это привело к той же ошибке, что и исходный код:

# { 1 2 3 4 } subtract-avg-seq map
{ -9 -8 -7 -6 }
# : apply ( -- seq ) { 1 2 3 4 } subtract-avg-seq map ; ! error: Cannot apply "call" to a run-time computed value

0 ответов

В этом примере есть две разные проблемы.

Во-первых, в интерактивном коде слушатель не будет проверять влияние цитат на стек, но он проверяется, когда код компилируется в определении. Это причина того, что ручное расширение слов в Слушателе сработало.

Вторая проблема заключается в том, что вложенные эффекты, объявленные для цитат, игнорируются в большинстве слов. Вы могли бы заменить ( n -- quot: ( n -- n ) ) с ( n -- q ) и это будет работать так же.

В этом случае объявление кавычки в первом слове не относится ко второму слову. Это причина того, что даже если это все теоретически правильно, компилятор не может доказать это; он просто не знает эффектов цитаты.

Решение состоит в том, чтобы объявить эффект цитаты на сайте вызова:

: subtract-sum ( seq -- quot: ( n -- n ) ) sum '[ _ - ] ;
: subtract-sum-seq ( seq -- x ) dup subtract-sum [ call( n -- n ) ] curry map ;
{ 1 2 3 4 } subtract-sum-seq .

! -> { -9 -8 -7 -6 }

https://docs.factorcode.org/content/article-effects.html

https://docs.factorcode.org/content/article-inference-escape.html

Другие вопросы по тегам