Существует ли связь между вызовом функции и созданием объекта на чисто функциональных языках? - PullRequest
6 голосов
/ 22 сентября 2010

Представьте себе простой (составленный) язык, в котором функции выглядят так:

function f(a, b) = c + 42
    where c = a * b

(скажем, это подмножество Lisp, которое включает в себя 'defun' и 'let'.)

Также представьте, что он включает в себя неизменяемые объекты, которые выглядят так:

struct s(a, b, c = a * b)

Снова аналогично Lisp (на этот раз надмножество), скажем, что определение структуры, подобное этому, сгенерирует функции для:

make-s(a, b)
s-a(s)
s-b(s)
s-c(s)

Теперь, учитывая простую настройку, кажется очевидным, что есть много общего между тем, что происходит за сценой, когда вы называете «f» или «make-s». Как только 'a' и 'b' предоставлены во время вызова / создания экземпляра, информации достаточно для вычисления 'c'.

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

Моя модель игрушки настолько упрощена, что бесполезна? Или это действительно полезный способ подумать о том, как работают настоящие языки? Существуют ли какие-либо реальные языки / реализации, о которых кто-то, не имеющий опыта работы с CS, но с интересом к языкам программирования (т.е. мне), должен узнать больше, чтобы изучить эту концепцию?

Спасибо.

РЕДАКТИРОВАТЬ: Спасибо за ответы до сих пор. Чтобы уточнить немного, я думаю, что мне интересно, есть ли какие-то реальные языки, когда люди, изучающие язык, говорят, например, «Вы должны думать об объектах как о замыканиях». Или, если есть какие-либо реализации на реальном языке, в которых экземпляр объекта и вызов функции фактически совместно используют какой-то общий (нетривиальный, то есть не просто вызов библиотеки) код или структуру данных.

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

Ответы [ 4 ]

3 голосов
/ 22 сентября 2010

Вы не можете получить намного чище, чем лямбда-исчисление: http://en.wikipedia.org/wiki/Lambda_calculus. Лямбда-исчисление на самом деле настолько чисто, оно имеет только функции!

Стандартный способ реализации пары в лямбда-исчислении выглядит так:

pair = fn a: fn b: fn x: x a b
first = fn a: fn b: a
second = fn a: fn b: b

Итак, pair a b, то, что вы могли бы назвать «структурой», на самом деле является функцией (fn x: x a b). Но это особый тип функции, называемый замыканием. Замыкание - это, по сути, функция (fn x: x a b) плюс значения для всех «свободных» переменных (в данном случае a и b).

Так что да, создание экземпляра "struct" похоже на вызов функции, но, что более важно, сама фактическая "struct" похожа на специальный тип функции (замыкание).

Если вы подумаете о том, как реализовать интерпретатор лямбда-исчисления, вы можете увидеть симметрию с другой стороны: вы можете реализовать замыкание как выражение плюс структуру, содержащую значения всех свободных переменных.

Извините, если это все очевидно, и вы просто хотели какой-то пример из реального мира ...

1 голос
/ 23 сентября 2010

Оба f и make-s являются функциями, но сходство не идет намного дальше.Применение f вызывает функцию и выполняет ее код;применение make-s создает структуру.

В большинстве языковых реализаций и моделей make-s - это объект другого типа, чем f: f - это замыкание, тогда как make-s - конструктор (в функциональных языках и логическом значении, которое близко к значению объектно-ориентированных языков).

Если вам нравится мыслить объектно-ориентированным образом, то и у 10101, и у 1014 есть метод apply,но у них есть совершенно разные реализации этого метода.

Если вы хотите думать в терминах базовой логики, f и make-s имеют построение типа на конструкторе типа samme (конструкторе типа функции), но они построены по-разному и имеют разные правила уничтожения (приложение-функция или приложение-конструктор).

Если вы хотите понять этот последний абзац, я рекомендую Типы и языки программирования Бенджамин С. Пирс.Структуры обсуждаются в §11.8.

1 голос
/ 22 сентября 2010

Моя модель игрушки настолько упрощена, что бесполезна?

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

1 голос
/ 22 сентября 2010

Существует связь между объектами и замыканиями.http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html

Следующее создает то, что некоторые могут вызывать функцию, а другие могут вызывать объект:
Взят из SICP (http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-21.html)

(define (make-account balance)
  (define (withdraw amount)
    (if (>= balance amount)
        (begin (set! balance (- balance amount))
               balance)
        "Insufficient funds"))
  (define (deposit amount)
    (set! balance (+ balance amount))
    balance)
  (define (dispatch m)
    (cond ((eq? m 'withdraw) withdraw)
          ((eq? m 'deposit) deposit)
          (else (error "Unknown request -- MAKE-ACCOUNT"
                       m))))
  dispatch)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...