История изменений
Исправление quasimoto, (текущая версия) :
Я там говорил, что замыкание это всегда одна функция:
(funcall (lambda (a) (lambda (b) (+ a b))) 1)
; #<CLOSURE (LAMBDA (B)) {10048430CB}>
Кортеж замыканий это уже не замыкание :)
Тогда как с объектом связано несколько (>= 0) функций:
Class obj(...); // obj is a "closure" now
obj(...); // so its callable, nevertheless has state and behaves like a first-class value
// ^ sugar for:
obj.operator()(...);
// or:
std::mem_fun_ref(&Class::operator())(obj, ...);
// ^ *this
// another method:
obj.foo(...);
std::mem_fun_ref(&Class::foo)(obj, ...);
// ...
Но если считать, что первое более примитивно, то, конечно, можно и объекты на замыканиях сделать (как в SICP).
Плюс отсутствие приписанного конкретного типа
Динамический тип (который вычисляется глубоким type-of) должен быть чем-то вроде (list closure), то есть не тип конкретных данных на которых работает интерфейс, и не тип самого интерфейса, так как всё смешано.
в Ocaml'е класс не является типом и тип определяется как раз по интерфейсу объекта.
Слышал, что сами камльщики не особо жалуют тамошнее ООП.
Вот в хаскеле если t :: *
(тип) и I :: * -> Constraint
(интерфейс), то
f :: I t => t -> ...
при вызове
f (obj :: SomeType)
работает как
f {instanceOf obj :: I SomeType} (obj :: SomeType)
с разрешением во время компиляции или выполнения. То есть метод это суть
f :: I t -> t -> ...
где на место I t
передаётся реализация someInstance :: I SomeType
(которая единственна в случае классов типов, хотя при явной передаче может быть не единственна), на место t — obj :: SomeType
, I
представляет собой data I t = MkI { _i1 :: sig...; ... }
, someInstance :: I SomeType
— someInstance = MkI { _i1 = impl...; ... }
.
Исходная версия quasimoto, :
Я там говорил, что замыкание это всегда одна функция:
(funcall (lambda (a) (lambda (b) (+ a b))) 1)
; #<CLOSURE (LAMBDA (B)) {10048430CB}>
Кортеж замыканий это уже не замыкание :)
Тогда как с объектом связано несколько (>= 0) функций:
Class obj(...); // obj is a "closure" now
obj(...); // so its callable, nevertheless has state and behaves like a first-class value
// ^ sugar for:
obj.operator()(...);
// or:
std::mem_fun_ref(&A::operator())(obj, ...);
// ^ *this
// another method:
obj.foo(...);
std::mem_fun_ref(&A::foo)(obj, ...);
// ...
Но если считать, что первое более примитивно, то, конечно, можно и объекты на замыканиях сделать (как в SICP).
Плюс отсутствие приписанного конкретного типа
Динамический тип (который вычисляется глубоким type-of) должен быть чем-то вроде (list closure), то есть не тип конкретных данных на которых работает интерфейс, и не тип самого интерфейса, так как всё смешано.
в Ocaml'е класс не является типом и тип определяется как раз по интерфейсу объекта.
Слышал, что сами камльщики не особо жалуют тамошнее ООП.
Вот в хаскеле если t :: * (тип) и I :: * -> Constraint (интерфейс), то
f :: I t => t -> ...
при вызове
f (obj :: SomeType)
работает как
f {instanceOf obj :: I SomeType} (obj :: SomeType)
с разрешением во время компиляции или выполнения. То есть метод это суть
f :: I t -> t -> ...
где на место I t передаётся реализация someInstance :: I SomeType (которая единственна в случае классов типов, хотя при явной передаче может быть не единственна), на место t — obj :: SomeType, I представляет собой data I t = MkI { _i1 :: sig...; ... }, someInstance :: I SomeType — someInstance = MkI { _i1 = impl...; ... }.