parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

У «кода» другая семантика...

Sumo 24.10.2015 10:37 / 24.10.2015 10:42

Код в переменной означает одно — значение переменной будет вычислено не сразу, а при обращении к переменной. Т.е. это механизм отложенного вычисления, а не хранилища текста программы. Поэтому любую переменную с кодом надо рассматривать как обычную переменную с известным значением. Если мы не хотим вычислять значение сразу, а хотим передать переменную с кодом дальше, то используем фигурные скобки, т.е. мы таким образом оттягиваем непосредственное вычисление значений.

Junction-code хранит не только код для вычисления значения, но и контекст той функции, в которой код был написан. Без контекста вычислить значение кода попросту невозможно. Отсюда еще одно следствие — контекст «живет» очень не долго. Как только мы вышли из функции, то контекста больше не существует (локальные переменные потеряны) и вычислить значение кода нельзя. Поэтому передавать код можно только вглубь стека вызовов и вычислить значение надо как можно быстрее. Сохранять код во внешних переменных смысла не имеет.

Из этого следует, что при проверке переменной с кодом на тип (is) сначала должно быть вычислено значение, а потом уже взят тип этого значения.

Если сделать как ты предлагаешь, то мы можем получить фигню:
@func[value]
# Функция ожидает число или строку
  ^if($value is double){
    ^value.format[%08d]
  }{
     $value
   }

# А мы вызываем ее с кодом
^func{^eval(2+3)}

# И получаем в результате, потому что is doublе не сработал:
5
# А предполагали, что получим 00000005.
Таким образом получается, что алгоритм работы функции зависит от метода ее вызова, а такого быть не должно никогда.

Совершенно другая ситуация, когда мы храним в переменной ссылку на функцию. Тут и с контекстом и с логикой все хорошо. Контекст долгоживущий — это объект, а не локальный контекст функции. Для вызова функции есть отдельный механизм. И проверка на тип вполне имеет смысл, потому что для функции нужен другой механизм:
@func[value;callback][locals]
  ^if($value is double){
    ^value.format[%08d]
  }{
     $value
   }
  ^if($callback is junction){
    ^callback[$value]
  }

@log[value]
  $result[]
  ^value.append[/../logs/values.log]

# Вызываем функцию и логируем значение
^func{^eval(2+3)}[$log]

# Тоже самое без логирования
^func[5]
Я бы предпочел переименовать is junction в is function, чтобы избежать проблемы с терминами и не требовалось объяснять почему проверка на junction-code не имеет смысла. :)