Подтвердить что ты не робот

"Закрытие - это плохие человеческие объекты и наоборот". Что это значит?

Закрытие - это плохие человеческие объекты и наоборот.

Я видел это утверждение в many места в Интернете (включая SO), но я не совсем понимаю, что это значит. Может кто-нибудь объяснить, что это значит?

Если возможно, укажите примеры в своем ответе.

4b9b3361

Ответ 1

Объекты - это плохие замыкания человека.

Рассмотрим Java. Java - это объектно-ориентированный язык программирования без поддержки языкового уровня для реальных лексических замыканий. Как программисты Java используют анонимные внутренние классы, которые могут закрывать переменные, доступные в лексической области (при условии, что они final). В этом смысле объекты - это плохие замыкания человека.

Закрытие - это плохие человеческие объекты.

Рассмотрим Haskell. Haskell - это функциональный язык без поддержки уровня языка для реальных объектов. Однако они могут быть смоделированы с использованием закрытий, как описано в этой отличной статье Олега Киселева и Ральфа Ламмеля. В этом смысле закрытие - это плохие человеческие объекты.


Если вы исходите из фона OO, вы, вероятно, найдете мышление с точки зрения объектов более естественным, и поэтому можете думать о них как о более фундаментальной концепции, чем о закрытии. Если вы исходите из фона FP, вы можете найти мышление с точки зрения более естественных замыканий и, следовательно, подумать о них как о более фундаментальной концепции, чем о объектах.

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

В философии это называется реализацией, зависящей от модели.

Ответ 2

Дело в том, что замыкания и объекты выполняют одну и ту же цель: инкапсуляция данных и/или функциональных возможностей в единую логическую единицу.

Например, вы можете создать класс Python, который представляет такую ​​собаку:

class Dog(object):
    def __init__(self):
        self.breed = "Beagle"
        self.height = 12
        self.weight = 15
        self.age = 1
    def feed(self, amount):
        self.weight += amount / 5.0
    def grow(self):
        self.weight += 2
        self.height += .25
    def bark(self):
        print "Bark!"

И затем я создаю экземпляр класса как объект

>>> Shaggy = Dog()

Объект Shaggy имеет встроенные данные и функциональные возможности. Когда я звоню Shaggy.feed(5), он получает фунт. Этот фунт хранится в переменной, которая хранится как атрибут объекта, который более или менее означает, что он находится во внутренней области объектов.

Если бы я кодировал некоторый Javascript, я бы сделал нечто подобное:

var Shaggy = function() {
    var breed = "Beagle";
    var height = 12;
    var weight = 15;
    var age = 1;
    return {
        feed : function(){
            weight += amount / 5.0;
        },
        grow : function(){
            weight += 2;
            height += .25;
        },
        bark : function(){
            window.alert("Bark!");
        },
        stats : function(){
            window.alert(breed "," height "," weight "," age);
        }
    }
}();

Здесь вместо создания области внутри объекта я создал область внутри функции, а затем вызвал эту функцию. Функция возвращает объект JavaScript, состоящий из некоторых функций. Поскольку эти функции получают доступ к данным, которые были выделены в локальной области, память не восстанавливается, что позволяет вам продолжать использовать их через интерфейс, предоставляемый закрытием.

Ответ 3

Объект, в его самом простом виде, представляет собой просто набор состояний и функций, которые работают в этом состоянии. Закрытие также представляет собой совокупность состояний и функцию, которая работает в этом состоянии.

Скажем, я вызываю функцию, которая выполняет обратный вызов. В этом обратном вызове мне нужно оперировать некоторым состоянием, известным перед вызовом функции. Я могу создать объект, который воплощает это состояние ( "поля" ) и содержит функцию-член ( "метод" ), которая выполняет функцию обратного вызова. Или, я мог бы взять быстрый и легкий ( "бедный человек" ) маршрут и создать закрытие.

Как объект:

class CallbackState{
    object state;

    public CallbackState(object state){this.state = state;}

    public void Callback(){
        // do something with state
    }
}

void Foo(){
    object state = GenerateState();
    CallbackState callback = new CallbackState(state);
    PerformOperation(callback.Callback);
}

Это псевдо-С#, но по-другому аналогично другим языкам OO. Как вы можете видеть, существует достаточное количество шаблонов, связанных с классом обратного вызова для управления состоянием. Это было бы намного проще с помощью закрытия:

void Foo(){
    object state = GenerateState();
    PerformOperation(()=>{/*do something with state*/});
}

Это лямбда (опять же, в синтаксисе С#, но концепция похожа на другие языки, поддерживающие закрытие), которая дает нам все возможности класса без необходимости писать, использовать и поддерживать отдельный класс.

Вы также услышите следствие: "объекты - это бедные люди". Если я не могу или не буду использовать закрытие, то я вынужден выполнять свою работу с использованием объектов, как в моем первом примере. Хотя объекты обеспечивают большую функциональность, закрытие часто является лучшим выбором, когда закрытие будет работать по причинам, уже заявленным.

Следовательно, бедный человек без предметов может часто выполнять работу с закрытием, а бедный человек без закрытия может выполнить свою работу с использованием объектов. Богатый человек имеет и то, и другое использует для каждого задания правильный.

Ответ 4

EDITED: название вопроса не включает "наоборот", поэтому я постараюсь не предполагать намерения афера.

Два общих лагеря являются функциональными и императивными языками. Оба являются инструментами, которые могут выполнять аналогичные задачи по-разному с различными проблемами.

Закрытие - это плохие человеческие объекты.

Объекты - это плохие замыкания человека.

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

Закрытие - это плохие человеческие объекты. Объекты - плохие замыкания человека.

Автор этого "прагматика", а также довольно умный. Это означает, что автор ценит обе точки зрения и ценит, что они концептуально одно и то же. Это мой товарищ.

Ответ 5

"Объекты - закрытые люди" - это не просто утверждение некоторой теоретической эквивалентности - это общая идиома Java. Очень часто используют анонимные классы для завершения функции, которая фиксирует текущее состояние. Вот как это используется:

public void foo() {
    final String message = "Hey ma, I'm closed over!";
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            System.out.println(message);
        }
    });
}

Это даже очень похоже на эквивалентный код, используя закрытие на другом языке. Например, использование Objective-C блоков (поскольку Objective-C достаточно похож на Java):

void foo() {
    NSString *message = @"Hey ma, I'm closed over!";
    [[NSOperationQueue currentQueue] addOperationWithBlock:^{
        printf("%s\n", [message UTF8String]);
    }];
}

Единственное реальное отличие заключается в том, что функциональность завершена в экземпляре анонимного класса new Runnable() в версии Java.

Ответ 6

Просто так много сахара, поскольку закрытие скрывает анонимные объекты под юбками.