Формальное определение термина «чистый ОО язык»?

13

Я не могу придумать лучшего места среди SO братьев и сестер, чтобы поставить такой вопрос. Изначально я хотел спросить "Является ли python чистым языком OO?" но, учитывая проблемы и некоторый дискомфорт, которые испытывают люди, пытаясь определить термин, я решил начать с получения четкого определения самого термина.

Было бы довольно справедливо начать с переписки доктора Алана Кея, который придумал этот термин (обратите внимание на вдохновение в биологической аналогии с клетками или другими живыми объектами).

Есть следующие способы решения этой задачи:

  1. Проведите сравнительный анализ, перечислив языки программирования, которые могут демонстрировать (или не демонстрировать) определенные свойства, уникальные и достаточные для определения термина (хотя Smalltalk, Scala, Java и т. Д. - являются возможными примерами, но IMO этот способ кажется не совсем полным. ни плодотворный )
  2. Дайте формальное определение (или близкое к нему, например, в более академическом или математическом стиле).
  3. Дайте философское определение, которое бы полностью опиралось на семантический контекст конкретного языка или априорный опыт программирования (у сообщества должен быть некоторый шанс на успешное объяснение).

Моя текущая версия: «Если определенный язык программирования ( формальный ), который может ( грамматически ) различать операции и операнды, а также делать вывод о типе каждого операнда, является ли этот тип объектом (в смысле ООП) или нет, тогда мы вызываем такой язык - ОО-язык, если в этом языке есть хотя бы один тип, который является объектом. Наконец, если все типы языка также являются объектами, мы определяем такой язык как чистый (сильный) ОО-язык ».

Был бы признателен за любое возможное улучшение этого. Как видите, я только что сделал определение зависимым от термина «объект» (часто полностью упоминается как класс объектов).

[РЕДАКТИРОВАТЬ]

Кроме того, я использую (к счастью хорошо понятое) понятие типа, как в типизированных языках. Программирование типов данных или программирование на основе типов - это не только синтаксическая интерпретация (текста программы, т. Е. Как обрабатывать определенные значения литералов и переменных данных - то, что эволюционирует в безопасность типов), но ее можно отнести к грамматике языка и изучать формально. (используя математическую логику) как так называемые системы типов . Обратите внимание, что требование, чтобы конкретная система типов имела так называемый универсальный тип, является одним из способов определения чистоты языка ОО (есть способы расширить это семантически).

NB

как ответить :

  • это помогает, если вы указываете книгу или справочник, которые поддерживают / объясняют ваше понимание терминологии и понятий (обычно хорошее определение охватывает или ссылается на все зависимые понятия, кроме элементарных).
  • если возможно, укажите категорию вашего ответа / определения с отступом, если неясно иначе (см. выше: 1 - на примере языка, 2 - математическая логика, 3 - техническое описание и философия программирования)
  • классификация важна (а также потому, что термин «чистый ОО» включен в термин «ОО») при ответе попытаться размешать элементы парадигмы ОО из других хорошо известных методологий (и ни в коем случае не путать / не перекрывать их, например, как правило, элементы модульного программирования могут быть охвачены / воплощено в ОО-программировании): попытаться отличить ООП от (включая или являться частью) функционального программирования, логического программирования (особенно сильно специализированного), типов данных Abstarct (ADT), модульного, метапрограммирования (обобщений и времени макро-расширения LISP), Контракты (например, Eiffel), Аспектно-ориентированные (AO), (разница между декларативной и функциональной классификацией, а также историческими определениями структурированной Дейкстры ясна)

при затруднении дать формальное определение : как ни удивительно, очень легко дать математическое описание ООП в форме определенной логической (формальной) системы (наиболее вероятной основанной на типах) и определяющей одно понятие за другим. Можно даже попробовать сделать чтото более практичное, применяя этот формализм для проверки безопасности типа или новых аспектов дизайна языка , чем просто абстрактное развлечения или упражнение (также поиск состав ЛСГА в интуиционистской теории типов , зависимые типы , независимо другдруга, в FOL формализме как лямбдаисчисление и просто с помощью теории категорий). Главное здесь то, что неудивительнотакие формулировки ИМО сильно предвзяты (ошибочны), скорее всего, изначально изначально не полностью понимают ООП (в компьютерной инженерии), и в конечном итоге оказываются почти недоступными (таким образом, едва ли способствуют обратному развитию мира программирования - возможно, за исключением того, что определенный процент находит приложения назад из формального мира, будучи интегрированы в популярные языки ).

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

Евгений Якимович
источник
2
Ну, вы сами ответили за Python. «Нет».
PSR
2
+1 за хороший вопрос, но ваша версия немного испорчена проблемой, что тип и объект - это разные вещи.
Фрэнк
5
@JoachimSauer: он сказал в другом письме в списке рассылки Squeak, что «большая идея - это обмен сообщениями» и что он сожалеет, что когда-либо назвал его «объектно-ориентированным», и вместо этого ему следовало бы назвать его «ориентированным на сообщения». Эрланг, например, является полностью объектно-ориентированным языком, который отвечает всем критериям доктора Кея, не имея никакого понятия обо всех «объектах», «методах», «наследовании», «классах», «прототипах» или чем-то подобном ,
Йорг Миттаг
1
Это может быть хорошей иллюстрацией того, что синтаксисов недостаточно для определения языка ОО. Если кто-то может показать, что ООП (например, как инструмент) является только семантическим (независимым от синтаксиса), это полностью меняет (инвертирует) мой вопрос!
Евгений Якимович
2
@YauhenYakimovich Это одна из основных проблем при обсуждении ООП, каждый и его собака имеют свое представление о том, что это такое. Напротив, структурное программирование и функциональное программирование могут быть определены очень просто. Это приводит меня к вопросу о том, обладает ли ОО подобными свойствами религии, а не науке.
Рикки Кларксон

Ответы:

19

ОО, по словам Алана Кея, это все о передаче сообщений, и все. Вы увидите, что такие качества, как полиморфизм и инкапсуляция, на самом деле происходят от передачи сообщений.

Теперь эта позиция на самом деле очень экстремальная, потому что в основном это означает, что квалифицируются только Smalltalk и языки.

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

  • объявить открытые поля
  • объявлять переменные, которые могут содержать только экземпляры определенного класса и его подклассов (т. е. переменные должны быть напечатаны на интерфейсах, через которые биологические объекты общаются в анологии Кея), что представляется еще более узким, если рассматриваемый класс является окончательным, как что оставляет еще меньше места для полиморфизма
  • объявлять примитивы

Опять же, ИМХО чистота языка - это скорее слабость, чем сила. ОО это не серебряная пуля. Нет единой парадигмы.

back2dos
источник
2
+1 за "ОО не серебряная пуля".
Андрес Ф.
1
@AndresF. Обратите внимание, что практическая ценность ООП, а также других теоретических знаний, связанных с программированием, на самом деле не является частью вопроса. Совершенно очевидно, что можно писать код довольно успешно без какого-либо глубокого понимания методов программирования или теорий (и наоборот). Также не обсуждаются свойства приложений для ОО-языков и т. Д.
Евгений Якимович,
@YauhenYakimovich О, я знаю. Я бы не проголосовал за ответ, если бы он был не по теме. Тем не менее, мне понравилось утверждение, с которым я согласен.
Андрес Ф.
@AndresF. Конечно :-) «Оо не серебряная пуля», скорее всего, верно, так как нам не хватает идеального языка программирования. Но что именно делает ООП не серебряной пулей? Как хороший отчет об ошибке, я думаю, что точная и точная терминология - способ ответить на этот вопрос. Я потратил столько времени на работу с ним, что мне чертовски любопытно вывести его на новый уровень. ООП - это просто набор идей, скопированных из одной книги по программированию в другую?
Евгений Якимович
@ back2dos +1 за явное указание на роль «передачи сообщений» по Кей (Smalltalk, Objective-C). Очевидно, он никогда не собирался видеть, что ООП развивается в направлении, которое оно имеет сегодня. Но мне очень понравилось, что у Кея были идеи сделать объекты НЕ данными (типами). Он действительно стремился приписать им биологические качества, но в итоге оказался в «обмене сообщениями».
Евгений Якимович
6

Я хотел бы подойти к этому, определив его как язык, который использует конструкции ООП и ничего больше (так же, как чистый язык FP использует чистые функции с неизменяемыми данными и ничем иным).

Особенно:

  • Каждая сущность, над которой работает ваша программа, является объектом первого класса - т.е. без примитивов, без указателей, без массивов и т. Д.
  • Единственное, что вы можете сделать с объектом, - это вызвать (потенциально полиморфный) метод (== отправка сообщения). Никаких других операций не существует.
  • Все данные инкапсулированы - т.е. нет доступа к общедоступным полям, вы должны пройти через методы для объекта
  • Если у вас есть функции первого класса, то они также должны быть объектами - так что вам нужно сделать что-то вродеfunctionObject.call(param1,param2)
  • Нет глобальных переменных - если вы хотите что-то подобное, вам нужно использовать объект для представления текущей глобальной среды, например, environment.getValue("myThing")или поместить переменную в объект класса

Обратите внимание, что это все еще оставляет довольно много открытых вариантов:

  • Объектные модели на основе классов и прототипов
  • Как реализуется наследование (если вообще)
  • Независимо от того, есть ли у вас одна или несколько отправок по методам
  • Являются ли ваши объекты статически или динамически типизированными
  • Точный синтаксис, используемый для вызовов методов (например, у вас может быть синтаксический сахар для методов получения / установки и т. Д.)
mikera
источник
1
это хорошие определения, но не путайте объектную реальность с простым синтаксисом. Просто потому, что функции и глобальные переменные имеют дружественный синтаксис, они могут быть объектами в глубине души.
ddyer
@ddyer - это правильно, если это действительно просто синтаксис, но я думаю, что если синтаксис также вводит другую семантику, то это может нарушить «чистоту». Например, для глобальных переменных, используемых globalVariableNameдля доступа к глобальной переменной, семантика отличается от вызова метода для объекта, который был бы единственным способом доступа к нелокальному значению в чистом ООП.
Микера
Я думаю, что «Все» должно быть квалифицированным. Если язык вообще не имеет отражательной способности (например, он не может ссылаться на метод объекта по абстрактному имени или сохранять его в переменной), то должны ли методы также быть объектами? Являются ли ссылки объектами? Ссылки и объекты - это даже разные вещи?
Иоахим Зауэр
@ Иоахим - хорошая мысль. Я определил его как «каждую сущность, над которой работает ваша программа», чтобы отличать объекты от мета-объектов в языке, таких как имена переменных и синтаксические конструкции. Очевидно, что если ваша программа на самом деле оперирует такими вещами посредством отражения, то их нужно будет реализовать как реальные объекты, но это не всегда будет требованием. В любом случае, если вы можете придумать лучшую квалификацию, не стесняйтесь редактировать ее!
Микера
«Объектные модели на основе классов и прототипов»: но я бы сказал, что в обоих случаях у вас есть какая-то классификация, то есть вы группируете объекты с общей структурой и поведением.
Джорджио
4

Дискуссия о так называемых ОО-языках всегда была немного размытой. То есть:

«Кто-то сказал мне, что язык X - это OO, поэтому язык X равен OO, и тогда каждый язык, в котором отсутствуют возможности языка X, не может быть OO. И поскольку я пишу свой код на языке X, все, что я делаю, это OO». "

Термин объектно-ориентированный дизайн сводится к 3 вещам:

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

1) это чистый программный дизайн, его можно достичь на любом языке программирования. Тем не менее, некоторые языки имеют полезные функции, такие как класс / структура и частные ключевые слова.

2) В основном это программный дизайн, хотя он не может быть полностью реализован без языковой поддержки, так как вам нужны языковые механизмы, такие как private / static, для защиты от случайного использования.

3) в основном дизайн программы. Как правило, существует три различных зависимости: «объект X содержит объект Y», «объект X является своего рода Y» и «объект X взаимодействует с объектом Y». Существует множество языковых возможностей, помогающих справиться с этими зависимостями: наследование / полиморфизм, абстрактные базовые классы и так далее.

Теперь, если мы посмотрим на вышесказанное, то увидим, что для написания ОО-программ вам практически не нужны языковые функции. Функции просто делают это намного проще.

Вышеперечисленные цели не могут быть достигнуты с помощью некоторой грязной обратной логики: просто потому, что вы используете ключевое слово class, ваша программа не получает автоматически модульный дизайн. То, что вы используете наследование, не означает, что ваши объектные зависимости имеют смысл. Язык с ОО-функциями по-прежнему допускает такие вещи, как class TheWholeBloodyProgram«Животное наследует кота».

К сожалению, тема хорошего объектно-ориентированного проектирования программ редко упоминается в подобных дискуссиях. Программисты с промытыми мозгами смотрят только на синтаксис и трепетные вещи, такие как, например, «C ++ имеет примитивные типы данных, поэтому ваша программа C ++ не является OO», а затем они начинают писать совершенно ужасную программу на своем любимом языке, не используя никаких намеков на дизайн программы какой-то-никогда.

Чтобы ответить на вопрос: очень мало, если какие-либо языки поддерживают правильную разработку ОО программы. Узнать, какие языки имеют определенные функции, связанные с ОО, не имеет значения, если программист не знает, что означает объектно-ориентированное проектирование. Программист, утверждающий, что некоторые языки являются объектно-ориентированными, скорее всего, не понял концепцию ОО в целом. Спросите потенциального ОО-программиста, как они проектируют ОО-программы. Если первое, что они делают, это начинают выкрикивать языковые ключевые слова, то можно смело предположить, что они не знают ОО-дизайна.

Возможно, существует какой-то причудливый высокоуровневый инструмент UML, выходящий далеко за исходный код, который заставляет программиста писать только программы с хорошим объектно-ориентированным дизайном, но я сомневаюсь в этом. Лучшими инструментами проектирования для ОО-программирования, скорее всего, по-прежнему остаются человеческий мозг и здравый смысл.


источник
Можете ли вы уточнить, чем ваше определение отличается, например, от модульного программирования с абстрактными типами данных? Я думаю, что вы на правильном пути, но я пока не вижу поезд!
Йорг Миттаг,
@ JörgWMittag Это не обязательно отличается, традиционные ADT: могут быть написаны с использованием объектно-ориентированного проектирования, с надлежащей инкапсуляцией, сеттерами / получателями, способами наследования и т. Д. И т. Д. Но они также могут быть написаны безотносительно к ОО-дизайну. ->
2
@ JörgWMittag Если у вас есть такой язык, как, например, C, с ограниченной языковой поддержкой для ОО, то сложно написать ADT: s объектно-ориентированным способом. Самая распространенная ошибка - оставить выделение ADT вызывающей стороне, то есть дать им открытую структуру со всеми открытыми внутренними компонентами, нарушая инкапсуляцию. Правильный способ сделать это в C - это так называемые «непрозрачные типы» (неполные типы), хотя не многие программисты на C знают, как их использовать.
@Lundin: В статье, опубликованной JörgWMittag в качестве комментария к другому ответу, есть (IMO) интересное сравнение между ADT и OO.
Джорджио
Я помню из некоторых книг по UML (вероятно) дополнительный пункт 0. Абстрактность (подчеркивающая важность абстрактной формулировки, существенной для межобъектных отношений, таких как полиморфизм, наследование, агрегация и т. Д.).
Евгений Якимович
2

Нет, формального или даже полезного определения нет и никогда не будет. Для некоторых людей ООП означает «Универсальный базовый класс» и «Необходимо использовать ссылочную семантику, лучше всего с сборщиком мусора» - и вы даже можете получить споры о синтаксисе, одной из наименее актуальных вещей, когда-либо изобретенных.

В конечном итоге, во-первых, вы должны ответить на вопрос «Что такое объект?». Более ограниченный будет настаивать на наследовании от какого-то бессмысленного универсального базового класса и без необходимости размещаться на сборщике мусора для квалификации. Но я предпочитаю гораздо более полезное определение. Цель ООП состоит в том, чтобы иметь некоторые данные и некоторые функции, которые вы можете вызывать из этих данных. Так

  • Объект содержит некоторое состояние и предлагает некоторые функции для этого состояния.

В этом случае даже intквалифицируется. В конце концов, когда вы пишете шаблонный код на C ++, который может принимать либо примитивы, либо объекты, становится трудно утверждать, что примитивы отличаются каким-либо существенным образом. Vector v1, v2; v1 + v2;Вместо этого нет ничего особенного int v1, v2; v1 + v2;(за исключением дрянной семантики инициализации, надо признать). Кроме того, это позволяет лямбдам и подобным вещам быть объектами, поскольку они хранят состояние - их захваты - и предлагают функцию в этом состоянии для вызова лямбды.

К счастью, мы также можем классифицировать указатели на свободные функции как объекты, так как они оба содержат состояние (адрес) и функцию в этом состоянии (для ее вызова). Поэтому должна быть разрешена свободная функция, даже если вы скажете, что все свободные функции на самом деле являются глобальными указателями на функции.

DeadMG
источник
2
Я не вижу необходимости в таком различии. Но, во-вторых, они имеют ту же идентичность, что и любой другой объект - сравнение адресов и ссылок. Тот факт, что вы не можете различить два объекта с одинаковым состоянием, кроме как путем сравнения адресов, далеко не нов и применим ко всем объектам.
DeadMG
5
-1. Начинается с бесполезной и ненужной напыщенной речи, вскоре переключается на атаку ad hominem, и единственное, даже отдаленно фактическое (определение ООП ), неверно. Пожалуйста, прочитайте « О понимании абстракции данных», вновь рассмотренном Уильямом Куком, чтобы узнать разницу между абстрактным типом данных и объектом.
Йорг Миттаг,
1
«Я не вижу необходимости в таком различии». Но это различие относится к общепринятым признакам объектов. Конечно, вы можете выработать собственное представление об объекте, которое отличается от общепринятого. Вы абсолютно свободны сделать это.
Джорджио
2
@ Йорг, я позволю себе не согласиться. Я не совсем согласен с этим постом, но называть предостережение в первом абзаце «бесполезным» или «напыщенной» неискренне. Не существует универсально согласованного определения для ООП. Это простой и широко признанный факт. Остальная часть поста является определение ООП. Конечно, не самый широко используемый, ни тот, который я бы дал, но, как сказал DeadMG, на самом деле довольно полезный.
Конрад Рудольф
2
@KonradRudolph: этот абзац читался очень по-разному, когда я писал свой комментарий, включая сравнение программистов, которые заботятся о синтаксисе, с расистами, даже упоминая конкретного пользователя этого сайта по имени.
Йорг Миттаг,
0

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

Существует также вопрос о том, какая часть языка закрыта для модификации, даже в рамках объектной структуры. В Java вы не можете определить новые подклассы для некоторых классов, таких как String или Class.

Какие языки чистые? Единственный кандидат, который приходит на ум, это Smalltalk.

ddyer
источник
Разве Ruby не является чистым языком OO?
zxcdw
2
@zxcdw (и ddyer): в этом и заключается проблема: никто не имеет формального определения «чистого ОО», поэтому никто не может дать однозначный ответ на этот вопрос.
Иоахим Зауэр