У «кода» другая семантика...
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 не имеет смысла. :)
- Поведение is junction, G_Z [M] 24.10.2015 04:11
- Ответ, MoKo 24.10.2015 20:47
- Ну так мы про это и говорим..., Sumo [M] 24.10.2015 21:57
- Ответ, G_Z [M] 24.10.2015 20:58
- Ответ, MoKo 25.10.2015 02:41
- Ответ, G_Z [M] 25.10.2015 02:55 / 25.10.2015 02:59
- Ответ, MoKo 25.10.2015 03:29
- Ответ, G_Z [M] 25.10.2015 03:33
- Ответ, MoKo 25.10.2015 13:15
- Ответ, G_Z [M] 25.10.2015 14:15
- Ответ, MoKo 25.10.2015 14:26
- Ответ, MoKo 25.10.2015 14:45
- Ответ, G_Z [M] 25.10.2015 15:05
- Ответ, MoKo 26.10.2015 02:55
- Ответ, G_Z [M] 26.10.2015 03:11
- Я понимаю, G_Z [M] 25.10.2015 14:31 / 25.10.2015 14:33
- Ответ, MoKo 25.10.2015 03:03
- Ответ, G_Z [M] 25.10.2015 03:17
- Ответ, MoKo 25.10.2015 03:24
- Есть одна ситуация..., Sumo [M] 24.10.2015 11:30 / 24.10.2015 11:31
- У «кода» другая семантика..., Sumo [M] 24.10.2015 10:37 / 24.10.2015 10:42
- Ответ, G_Z [M] 24.10.2015 16:13 / 24.10.2015 16:17
- Ответ, Sumo [M] 24.10.2015 17:09