2012-07-04 5 views
1

я обнаружил, что специальные формы не могут быть переданы в качестве аргументов или сохраняются в переменных, как в Clojure:Каковы будут последствия для того, чтобы особые формы могли рассматриваться как нормальные значения?

user=> (defn my-func 
     [op] 
     (op 1 2 3)) 
#'user/my-func 
user=> (my-func +) 
6 
user=> (my-func if) 
java.lang.Exception: Unable to resolve symbol: if in this context (NO_SOURCE_FILE:5) 
user=> (def my-if if) 
java.lang.Exception: Unable to resolve symbol: if in this context (NO_SOURCE_FILE:9) 

и Ракетка/Scheme:

> (define (my-func op) 
    (op 1 2 3)) 
> (my-func +) 
6 
> (my-func if) 
    if: bad syntax in: if 
> (define my-if if) 
    *if: bad syntax in: if 

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

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

ответ

4

Это делает оценку более сложной и сложной.

Если у вас есть форма (a b c), то вам нужно решить во время выполнения значение a, а затем применить его как-то к формам b и c.

Простая модель нескольких ограниченного числа специальных форм и в противном случае строгая оценка затем исчезает.

Смотрите также: FEXPR

+0

Спасибо за имя FEXPR! –

4

Специальные формы не являются функциями: функции принимают значения в качестве аргументов, тогда как специальные формы принимают формы. Например, посмотрите на свой пример if:

(if 1 2 3) 

Хорошо, что это легко, так как 2 и 3 уже значения. Но как насчет этого?

(define (modadd a b n) 
    (if (zero? n) #f (modulo (+ a b) n))) 

В этом случае, на самом деле if получения #f и (modulo (+ a b) n) как формы, а не в качестве значений. И это важно! (modulo x n) потерпит неудачу, если n 0: именно поэтому он оставил невычисленным, пока мы не знаем, что n не 0.

Проблемы в состоянии пройти специальные формы, как объекты первого класса является то, что функции высшего порядка не могут назвать тех, объекты с использованием предсказуемой семантики: это объект функции, так что вы передаете значения или это особая форма, чтобы вы проходили формы? Это становится огромным беспорядком.

Да, вы можете написать функцию обертки, например, мою modadd, которая инкапсулирует if. Тем не менее, вы не можете просто переопределить if как функцию, сохраняя при этом поведение только для оценки-одного-на-ветви.