может, если быть надлежащей функцией, а не специальной формой

Я наконец начал учить функциональные языки (emacs шепелявость), и она делает явное различие между функциями и специальными формами, такими как управление потоком, например, если.

Существует ли фундаментальная/теоретическая причина, почему специальные формы отличны от функций? сделайте любые языки обеспечивают функциональный if?

Спасибо

14
задан Anycorn 10 February 2010 в 22:15
поделиться

7 ответов

Как насчет :

Это достаточное условие может быть ослаблено, как обсуждалось ниже в разделе Выборка сигналов без основной полосы частот.

Более поздние утверждения теоремы иногда осторожны, чтобы исключить условие равенства; то есть условие заключается в том, что x (t) не содержит частот, превышающих или равных В; это условие эквивалентно условию Шеннона, за исключением тех случаев, когда функция включает в себя устойчивую синусоидальную составляющую с точной частотой B.

-121-3702229-

У меня есть веб-страница с парой многоагентных имитаций netlogo . Я использую netlogo для преподавания, и я обнаружил, что, как только вы преодолеваете кривую обучения, вы можете разрабатывать симуляции удивительно быстро. То, что займет 80 человеко-часов в других так называемых агентских средах (Jade, Repast, которые действительно в основном являются просто библиотеками программирования), может быть сделано за 2 часов.

С другой стороны, netlogo на самом деле не подходит для моделирования, которое требует огромного количества деталей, например, имитация сети на всем пути от TCP/IP до HTTP. Это просто потребует большого количества кода, независимо от языка программирования, и netlogo в настоящее время отстой, если ваша программа в конечном итоге больше, чем 10 страниц. Сказав это, большинство людей были бы поражены тем, что можно сделать на 10 страницах кода netlogo.

-121--2774053-

При жаждущей оценке требуется различение языков с ленивой оценкой (т.е. Haskell), если et al. могут быть функциями.

Жаждущая оценка: Аргументы функции вычисляются перед вызовом функции, и функции передаются только результаты.

Lazy evaluation: Аргументы функции оцениваются тогда и только тогда, когда они доступны.

12
ответ дан 1 December 2019 в 11:59
поделиться

Если , если была нормальной функцией, то оба ее аргумента - then форма и else форма - были бы оба вычислено перед вызовом функции if , потому что это правило оценки функции : оцените все аргументы для получения значений, затем предоставьте эту последовательность значений в качестве аргументов функции, обозначенной первым символом в списке.

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

8
ответ дан 1 December 2019 в 11:59
поделиться

Для полноты: в языке Pico, например, нет специальных форм, а if - это примитивная функция, в то время как Pico вдохновлен Scheme и по умолчанию имеет ускоренную оценку.

В Scheme вы могли бы написать

(define (true t f)
  (t))

(define (false t f)
  (f))

(define (function_if c t e)
  (c t e))

а затем

(function_if true (lambda () 'true) (lambda () 'false))
==> true

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

Так, в синтаксисе Scheme с функциональными параметрами вы можете кодировать булевы как:

(define (true (t) (f))
  (t))

(define (false (t) (f))
  (f))

Тогда функция if становится:

(define (function_if c (t) (e))
  (c (t) (e)))

и

(function_if true 'true 'false)
==> true

В качестве другого примера, определение функции и - это (define (and p (q)) (p (q) false)).

Аналогично можно определить or, not, while, for, ... как функции, используя приведенную выше кодировку булевых чисел.

1
ответ дан 1 December 2019 в 11:59
поделиться

Короткий ответ: Нет.

Длинный(эр) ответ: (if ...) требует, чтобы вы контролировали порядок оценки аргументов. Лисп, будучи нетерпеливым языком, не может сделать это в функции.

Обходной путь: сделать это в макросе:

(defmacro _if (cnd true false)
    (let (  (gcond (gensym))
            (gresp (gensym)))
        `(let ( (,gcond ,cnd) ;`#quotes
                (,gresp nil))        
            (and ,gcond       (setf ,gresp (multiple-value-list ,true)))
            (and (not ,gcond) (setf ,gresp (multiple-value-list ,false)))
            (values-list ,gresp))))

Например:

[dsm@localhost:~]$ clisp -q
[1]> (defmacro _if (cnd true false)
    (let (  (gcond (gensym))
            (gresp (gensym)))
        `(let ( (,gcond ,cnd) ;`#quotes
                (,gresp nil))        
            (and ,gcond       (setf ,gresp (multiple-value-list ,true)))
            (and (not ,gcond) (setf ,gresp (multiple-value-list ,false)))
            (values-list ,gresp))))
_IF
[2]> (_if (= 1 1) (+ 2 3) "bar")
5
[3]> (_if (= 1 2) (+ 2 3) "bar")
"bar"
[4]> 
1
ответ дан 1 December 2019 в 11:59
поделиться

В таких языках, как Emacs Lisp и Common Lisp, специальные формы являются встроенными языковыми конструкциями. У них разные правила оценки, которые вызывают обычные функции. Для обычных вызовов функций оцениваются все аргументы. Итак, вы не можете написать IF как обычную функцию - условие определяет, какое предложение будет оценено. Также обычно вы не можете писать свои собственные специальные формы - в Common Lisp нет языковой конструкции для определения специальной формы (хотя отдельные реализации должны каким-то образом реализовывать существующие. Это приводит к макросам. С помощью макросов вы можете написать синтаксическое преобразование который преобразует одно выражение в другое. Чтобы иметь возможность писать IF как макрос, вам нужна другая условная форма, которую вы можете использовать для преобразованного кода. Lisp предоставляет условные выражения в качестве базовых конструкций. Предположим, COND является такой базовой конструкцией , тогда вы можете расширить IF до использования COND.

MY-IF в качестве макроса в Common Lisp:

(defmacro my-if (condition true-clause false-clause)
   `(cond (,condition ,true-clause)
          (t ,false-clause)))

Итак,

(my-if (foo-p) 'one 'two)

расширяется до

(cond ((foo-p) 'one)
      (t 'two))
3
ответ дан 1 December 2019 в 11:59
поделиться

В Scala можно смоделировать if с правильной оценкой побочных эффектов с использованием аргументов вызова по имени.

def If[A](cond : Boolean, truePart : => A, falsePart : => A) = if (cond) truePart else falsePart

Эту функцию также можно использовать для моделирования множества новых управляющих структур .

0
ответ дан 1 December 2019 в 11:59
поделиться

IF может быть функцией в функциональном языке с семантикой вызова по имени (ленивая оценка), как в Lambda Calculus или Algol. Фактически это, я думаю, лежит в основе отношений между машинами Тьюринга и Lambda Calculus как эквивалентными основами для вычислений. Однако в языках, имеющих побочные эффекты (например, присваивания переменным), это не слишком полезно, потому что важно когда все происходит.

0
ответ дан 1 December 2019 в 11:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: