Почему отсутствие явного объявления типа в параметре работает, когда функция используется напрямую, а не когда она передается другой функции?
Определите эту функцию в вашем модуле:
module Data
int inc(x) = x + 1;
Введите это в консоли:
rascal> import Data;
rascal> import List;
Это работает:
rascal> inc(1);
int: 2
Но это не так:
rascal> list[int] y = [1,2,3];
rascal> mapper(y, inc);
|rascal://<path>|: insert into collection not supported on value and int
☞ Advice
Но это работает, если inc(...)
Тип параметра 's объявлен:
int inc(int x) = x + 1;
Так почему же не работает это объявление типа для использования inc(...)
функция напрямую, но не для передачи этой функции mapper(...)
?
1 ответ
Поскольку средство проверки типов в Rascal все еще находится в стадии разработки, вы не будете предупреждены, если допустите небольшую ошибку, например, забудете предоставить тип для параметра функции. Это может все же работать, случайно, в некоторых обстоятельствах, но вы гарантированно столкнетесь с проблемами где-то, как вы заметили. Причина в том, что вывод типа для параметров функции просто не реализован как функция. Это решение по разработке языка с целью обеспечения понятности сообщений об ошибках.
Итак, это не разрешено:
int f(a) = a + 1;
И это должно быть написано так:
int f(int a) = a + 1;
Я считаю ошибкой то, что интерпретатор не жалуется на нетипизированный параметр. Это связано с тем, что мы повторно используем код сопоставления с образцом как для параметров функции, так и для встроенных шаблонов. [править: проблема была зарегистрирована на https://github.com/cwi-swat/rascal/issues/763]
В вашем случае пример работает, потому что динамически тип значения int
и дополнение не проверяет типы параметров. Разбитый пример ломается, потому что интерпретатор проверяет тип параметра функции на сайте вызова (по умолчанию value
для нетипизированного параметра).