Какой следующий уровень абстракции? [закрыто]

15

Поскольку языки программирования изначально использовали только строки кода, выполняемые последовательно, и он превратился в функции, которые были одним из первых уровней абстракции, а затем были созданы классы и объекты, чтобы абстрагировать его еще дальше; какой следующий уровень абстракции?

Что может быть более абстрактным, чем классы или есть еще?

Джордан Медлок
источник
17
Вы, кажется, думаете, что это линейная прогрессия с упорядочением («X более абстрактен, чем Y, более абстрактен, чем Z»). Позволю себе не согласиться.
2
Было бы неплохо сказать, почему вы стали отличаться. ;) (читай: мне интересно!)
sergserg
3
Я предлагаю окончательную «абстракцию»: делай то, что я думаю, а не то, что я печатаю. ;)
Изката
1
@Delnan: Абстракция не вводит полный порядок, но можно сказать «более абстрактный», «менее абстрактный». Например, общая реализация сортировки слиянием является более абстрактной, чем реализация сортировки слиянием, которая работает только для целых чисел.
Джорджио
2
Братья, выучите некоторую теорию категорий. Затем мы можем обсудить, что на самом деле означает абстракция, как цивилизованные люди.
davidk01

Ответы:

32

Я думаю, у вас есть некоторые неправильные представления об истории вычислений.

Первой абстракцией (в 1936 г.) была Лямбда-исчисление Алонзо Черча, которое является основой для концепции функций высокого порядка и всех последующих функциональных языков. Это напрямую вдохновило Lisp (второй старейший язык программирования высокого уровня, созданный в 1959 году), который, в свою очередь, вдохновил все от ML до Haskell и Clojure.

Второй абстракцией было процедурное программирование. Он возник из компьютерной архитектуры фон Неймана, где были написаны последовательные программы, по одной инструкции за раз. FORTRAN (самый старый язык программирования высокого уровня, 1958) был первым языком высокого уровня, который вышел из процедурной парадигмы.

Третья абстракция была, вероятно, фактически декларативным программированием, сначала иллюстрированным Absys (1967), а затем Прологом (1972). Это основа логического программирования, где выражения оцениваются путем сопоставления серии объявлений или правил, а не выполнения серии инструкций.

Тогда четвертой абстракцией было объектно-ориентированное программирование, которое впервые появилось в программах на Лиспе в 60-х годах, но позднее было продемонстрировано на Smalltalk в 1972 году. (Хотя, похоже, существуют некоторые споры относительно того, является ли стиль передачи сообщений Smalltalk Единственная Истинная объектно-ориентированная абстракция. Я не буду касаться этого.)

Все остальные абстракции, особенно в традиционной компьютерной архитектуре фон Неймана, являются вариациями этих четырех тем. Я не уверен, что есть еще одна абстракция, кроме этих четырех, которая не является просто вариацией или их комбинацией.

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

Однако существует модель квантовых вычислений. В квантовых вычислениях новые абстракции необходимы для моделирования квантовых алгоритмов. Будучи новичком в этой области, я не могу это комментировать.

greyfade
источник
4
Можно ли считать аспектно-ориентированное программирование еще одной формой абстракции?
Шиван Дракон
Объектно-ориентированное программирование появилось в Лиспе в 60-х годах? [цитата нужна], большое время. Все, что я слышал, говорит о том, что это произошло от Simula в 60-х годах, который был прямым потомком ALGOL, императивного языка, который не имел ничего общего с Lisp. Smalltalk появился, взяв концепции, представленные Симулой, и повернув их вокруг, чтобы чувствовать себя более «шустрым».
Мейсон Уилер
3
@MasonWheeler: Это в руководствах по Lisp 1 и 1.5, и Лисперс часто говорит о выполнении объектно-ориентированных программ, особенно старых парней. В то время ребята из ИИ были хороши в создании объектных систем на Лиспе.
Greyfade
2
@ShivanDragon: я бы сказал нет. Это просто способ оснастить процедурную программу с дополнительными возможностями. На самом деле он не моделирует алгоритмы и не влияет на структуру данных.
Greyfade
4
На самом деле, исчисление комбинатора SKI предшествует как лямбда-исчислению, так и машине Тьюринга.
Йорг Миттаг
4

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

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

Функции высшего порядка теперь также являются основой многих императивных языков; Лямбда-операторы .NET в основном допускают «анонимный» функциональный ввод в другую «функцию» (реализована обязательно, но теоретически не обязательно), что позволяет легко настраивать «цепочку» «универсальных» функций для достижения желаемый результат.

Другая абстракция, обычно встречающаяся в последнем раунде языков программирования, - это типизация динамических переменных, основанная на концепции «типизирования по типу утки»; если это похоже на утку, плавает как утка, летит как утка и крякает как утка, вы можете назвать это уткой. Неважно, если это на самом деле кряква или холст. Это может иметь значение, если это на самом деле гусь или лебедь, но с другой стороны, это может не иметь значения, если все, что вас волнует, это то, что он плавает и летает, и вроде как утка. Это считается окончательным в наследовании объекта; Вам не все равно , что это будет , за исключением того, чтобы дать ему имя; что важнее то, что он делает, В таких языках есть в основном только два типа; «атом», отдельный элемент информации (одно «значение»; число, символ, функция и т. д.) и «кортеж», состоящий из атома и «указателя» на все остальное в кортеже. То, как эти типы реализованы в двоичном виде во время выполнения, не имеет значения; используя их, вы можете достичь функциональности практически всех типов, которые вы можете себе представить, от простых типов значений до строк и коллекций (которые, поскольку значения могут быть разных «типов», допускают «сложные типы», то есть «объекты»).

Keiths
источник
1
«Duck typing» (по крайней мере, как вы описываете) не является чем-то новым или ограниченным динамически типизированными языками; это было вокруг в течение долгого времени в статически типизированных языках , как «структурного субтипирование», лучше всего видно на OCaml.
Тихон Джелвис
2

Можно рассматривать предметно-ориентированные языки, такие как SQL, как более высокий порядок абстракции. SQL - это очень целевой язык, который абстрагирует удаленные операции, такие как хранилище, и предоставляет функции более высокого уровня, основанные на теории множеств. Также обратите внимание на то, что многие основные языки сегодня ориентированы не на конкретную архитектуру, а на виртуальную машину (например, JVM или .NET CLR). Например, C # компилируется в IL, который интерпретируется (или чаще JIT'd - Just In Time Compiled - в собственную реализацию) собственным механизмом выполнения.

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

Некоторые из них существуют сегодня, такие как JetBrains MPS (набор инструментов для описания DSL или генератора языка). У Microsoft был небольшой набег (и очень многообещающий, я мог бы добавить) в это пространство с ее языком M (язык M был настолько полным, что язык был определен в M).

Критики концепции указывают на предыдущие неудачные попытки отстранить программистов от работы по разработке программ. Разница с инструментами DSL (как их называет Фаулер) заключается в том, что разработчики все равно будут вовлечены в кодификацию концепций, которые эксперты домена могли бы использовать для выражения потребности своего домена. Так же, как поставщики ОС и языков создают инструменты, которые мы используем для программирования, мы будем использовать DSL для предоставления инструментов для бизнес-пользователей. Можно представить DSL, которые описывают данные и логику, в то время как разработчики создают интерпретаторы, которые хранят и извлекают данные и применяют логику, выраженную в DSL.

Майкл Браун
источник
1

Я бы сказал, что мета-структуры, модули, платформы, платформы и сервисы являются группами объектов более высокого уровня, чем классы. Моя иерархия систем программирования абстракций:

  • Сервисы
  • платформы, стеки решений
  • рамки
  • модули, пакеты
  • мета-структуры: метаклассы, функции высшего порядка, дженерики, шаблоны, черты, аспекты, декораторы
  • объекты, классы, типы данных
  • функции, процедуры, подпрограммы
  • управляющие структуры
  • строки кода

Метаструктуры, такие как метаклассы , функции высшего порядка и универсальные шаблоны, явно добавляют абстракцию к базовым классам, функциям, типам данных и экземплярам данных. Черты, аспекты и декораторы являются новыми механизмами для объединения функций кода и аналогичным образом «ускоряют» другие классы и функции.

Даже предобъектные языки имеют модули и пакеты, поэтому их размещение над классами может быть спорным. Но они содержат эти классы и мета-структуры, поэтому я оцениваю их выше.

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

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

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

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

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

Джонатан Юнис
источник
1

Следующая абстракция после классов - мета-классы . Это так просто ;)

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

Себастьян Бауэр
источник
1
Метаклассы являются корневыми объектами иерархии наследования языка. .NET - это объект. Вы также можете думать об интерфейсах как о метаклассах; они определяют интерфейс своих наследников независимо от фактического «родительского» класса наследника.
KeithS
1
@KeithS - это не то, что означает это слово в любом контексте, который я видел - от CLOS до UML и до C #. Метакласс - это класс, экземплярами которого являются классы - слабая реализация - это C #, Typeкоторая дает отражающие возможности, но не мутацию (вы не можете добавить новый метод MyType, сказав, typeof(MyType).Methods += new Method ( "Foo", (int x)=>x*x )как можете в CLOS)
Пит Киркхэм
1

Я удивлен, что никто не упомянул теорию категорий.

Наиболее фундаментальной единицей программирования является функция, основанная на типах. Функции обычно обозначаются как f: A -> B, где A и B - типы. Если вы соберете все эти вещи, которые я называю типами и функциями, в правильную форму, вы получите нечто, называемое категорией. Вам не нужно останавливаться на этом.

Возьмите эти вещи, категории и спросите себя, как правильно связать их друг с другом. Если вы все сделаете правильно, вы получите нечто, называемое функтором, которое идет между двумя категориями и обычно обозначается как F: C -> B. Еще раз вам не нужно останавливаться.

Вы можете взять все функторы и соединить их правильно, и если вы все сделаете правильно, вы начнете задумываться, как связать два функтора друг с другом. В этот момент вы получите нечто, называемое естественным преобразованием, mu: F -> G, где F и G - функторы.

Мои знания на этом этапе становятся нечеткими, но вы можете продолжать делать это и продолжать подниматься по лестнице абстракции. Объекты и классы даже близко не описывают, как высоко вы можете подняться по лестнице абстракции. Есть много языков, которые могут выразить вышеупомянутые понятия в вычислительном отношении, и наиболее выдающимся из этих языков является Haskell. Так что, если вы действительно хотите узнать, что такое абстракция, изучите Haskell, Agda, HOL или ML.

davidk01
источник
1

Я думаю, что актерская модель отсутствует в списке кандидатов.

Вот что я имею в виду под актерами:

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

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

Краткое обсуждение / введение: http://youtube.com/watch?v=7erJ1DV_Tlo

Кристофер Кройциг
источник
Ваш пост довольно трудно читать (текстовая стена). Не могли бы вы изменить его в лучшую форму?
комнат
0

Если я вас правильно понимаю, ваши «восходящие абстракции» можно рассматривать как все более крупные инкапсуляции логики, в основном связанные с повторным использованием кода.

От конкретных инструкций, выполняемых одна за другой, мы переходим к функциям / подпрограммам , которые инкапсулируют или абстрагируют логическую группу инструкций в один элемент. Затем у нас есть объекты или модули , которые инкапсулируют подпрограммы, относящиеся к определенной логической сущности или категории, так что я могу сгруппировать все строковые операции в Stringклассе или все общие математические операции в Mathмодуле (или статический класс в таких языках, как C #). ,

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

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

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

Авнер Шахар-Каштан
источник
0

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

Я бы предположил, что следующий уровень практических абстракций, которые скрывают низкоуровневую рутинную работу от вас, - это функциональное реактивное программирование . Посмотрите на «сигналы» в чем-то вроде http://elm-lang.org/, которые скрывают обратные вызовы и обновляют зависимости, которые вы должны явно управлять в javascript. FRP может скрыть большую сложность межпроцессного и межмашинного взаимодействия, которое необходимо в крупномасштабных интернет-приложениях, а также высокопроизводительный параллелизм.

Я уверен, что это то, чем мы все будем рады в ближайшие 5 лет или около того.

Interstar
источник
1
FRP великолепен, но имеет дело с довольно специфическим видом программирования (а именно с реактивным программированием). Это не очень хорошо для моделирования других видов программ. Тем не менее, более общий вид программирования, который он представляет - написание вашего кода в терминах алгебр - является хорошим кандидатом на новый уровень абстракции.
Тихон Джелвис
0

Теория множеств - частично реализованная в реляционных базах данных, а также в языках статистики, таких как SAS и R, обеспечивает другой, но, возможно, более высокий уровень абстракции, чем ОО.

Джеймс Андерсон
источник