«Закрытие – это объекты бедного человека и наоборот». Что это значит?

Закрытие – это объекты бедного человека и наоборот.

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

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

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

Например, вы можете сделать class 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!" 

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

 >>> 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, состоящий из некоторых функций. Поскольку эти функции получают доступ к данным, которые были выделены в локальной области, память не восстанавливается, что позволяет вам продолжать использовать их через интерфейс, предоставляемый закрытием.

Объекты – закрытые люди.

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

Закрытие – это объекты бедного человека.

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


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

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

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

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

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

В качестве объекта:

 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); } 

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

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

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

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

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

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

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

Закрытие – это объекты бедного человека.

Объекты – закрытые люди.

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

Закрытие – это объекты бедного человека. Объекты – закрытые люди.

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

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

 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() экземпляре анонимного classа new Runnable() в версии Java.

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

  • Отменить в начале складки
  • Поток Zipping с использованием JDK8 с lambda (java.util.stream.Streams.zip)
  • Последствия foldr vs foldl (или foldl ')
  • Что такое «n + k patterns» и почему они запрещены в Haskell 2010?
  • Каков способ Scala для реализации повторного вызова, подобного этому?
  • Вычисление функции, которая принимает бесконечные аргументы
  • Почему нет дженериков в Go?
  • Какую задачу лучше всего выполнять в стиле функционального программирования?
  • Группировать путем подсчета в Java 8 stream API
  • Обработка инкрементного моделирования данных Изменения в функциональном программировании
  • почему функции lambda в c ++ 11 не имеют функции типов?
  • Давайте будем гением компьютера.