Ментальные модели или метафоры реального мира для функционального программирования

16

У кого-нибудь есть хорошая ментальная модель или метафора для функционального программирования, которая ссылается на что-то в реальном мире?

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

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

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

Гвидо Ансельми
источник
На какой конкретный смысл «функционального программирования» вы ссылаетесь, «без побочных эффектов / декларативных» или «первоклассных функций / составов функций»? Или оба?
отлично
Интересный вопрос. С моими нынешними небольшими знаниями и небольшим опытом программирования в области «функционального программирования» я не могу осмысленно ответить на этот вопрос. Если бы я рисковал предположением, я бы сказал, что оба.
Гвидо Ансельми
13
Модель «реального мира» часто приводится как мотивация для объектно-ориентированного программирования. Я думаю, что это подход, который вы должны в конечном итоге перерасти, потому что объекты в ООП не всегда должны соответствовать объектам реального мира, и даже когда они это делают, соответствие часто бывает неполным; например, отношения "is-a" не всегда одинаковы. С другой стороны, когда вы говорите, что вам нужна модель или метафора для языка программирования, основанного на чем-то в «реальном мире», я думаю, что вы по сути ограничились этой ограниченной формой ООП.
Дэвид К
Действительно хорошая ментальная модель, если у вас есть опыт использования Unix-подобных систем (или PowerShell в современной Windows), это оболочка с одной линией. Они не совсем одинаковые, так как каналы оболочки - это технически основанное на потоке программирование, а не функциональное, но они имеют то же «чувство», что и программист.
Slebetman
1
Кроме того, по мере изучения функциональных языков вы обнаружите, что в функциональном программировании объектно-ориентированный интерфейс рассматривается как инструмент, например, регулярные выражения. То, что вы можете использовать, если хотите, но не обязаны. В некоторых языках, таких как lisp, tcl и далее, OO - это не встроенная в язык функция, а библиотека, которую вы можете использовать (или вы даже можете написать свой собственный OO, если вы чувствуете себя смелым). Таким образом, проблемы, которые естественно имеют ОО-решение, могут быть решены с помощью ОО на большинстве функциональных языков. Люди просто не относятся к ОО как к религии.
Slebetman

Ответы:

32

Функциональное программирование - это объединение небольших функций для достижения ваших результатов. Приличная ментальная модель (по крайней мере для меня) - это сборочная линия. Каждая составная функция - это еще один шаг в процессе сборки. Рассмотрим эту функцию здесь:

smallest  = head . sort

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

smallestEven = head . sort . filter even

Это просто еще один шаг на конвейерной ленте.

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

bstamour
источник
2
В чистом функциональном языке без глобальных переменных одна сборочная линия не может влиять на другую (если она не питает другой ввод строки). Теоретически любые сборочные строки, которые не зависят друг от друга, могут выполняться параллельно, но я не уверен, если какие-либо компиляторы делают это.
bstamour
3
@GuidoAnselmi Один способ думать об этом - то, что сборочная линия в функциональном программировании создает новые выходные данные, оставляя входные данные нетронутыми, тогда как сборочная линия в традиционном ООП преобразует входные данные.
Довал
2
Эта метафора имеет смысл только в «первоклассных функциях / композициях функций», означающих «программирование функций», а не в «отсутствие побочных эффектов / декларативных». Кроме того, объектно-ориентированное программирование не обязательно имеет побочные эффекты, поэтому вы можете реализовать либо деструктивную, либо конструктивную сборочную линию, используя либо ООП, либо это значение FP. ООП больше касается инкапсуляции, передачи сообщений и полиморфизма, чем побочных эффектов, это зависит от того, как вы моделируете вещи. Например, вы требуете ссылочной идентичности от начала до конца?
апреля
3
@bstamour: Чтобы быть точным, нужно написать, что (f . g) (x)означает f(g(x))или f . gозначает \x -> f (g (x)).
Джорджио
3
@MarjanVenema В этом примере все осталось только потому, что .это так; это не то, как работает Haskell в целом . С таким же успехом вы можете определить оператор прямого канала F # ( |>) в Haskell и записать, smallest x = (sort x) |> headи данные будут течь правильно. Просто подумал, что укажу на это.
Довал
18

У кого-нибудь есть хорошая ментальная модель для функционального программирования?

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

Калеб
источник
1
Благодарю. Однако мне нужна метафора из реального мира (например, не из компьютеров или математики).
Гвидо Ансельми
3
@GuidoAnselmi: функция - это черный ящик. Вы кладете что-то в одну сторону, а затем что-то новое выходит на другую сторону. Если вы добавляете одни и те же вещи, вы всегда получаете одни и те же вещи. Вы можете взять много этих маленьких коробочек и объединить их в разных порядках, чтобы построить завод, который мог бы брать сырые металлы и выпускать машину. Внутри процесс разбит на множество кусочков, но снаружи это просто еще одна функция.
Дейнит
16

Как насчет флип книги ?

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

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

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

Марио Т. Ланца
источник
3

Отношения.

Друг: Учитывая двух человек, дружеские отношения следуют этим общим законам

  1. Имейте добрую волю друг к другу
  2. Думает, что друг друг для них друг (поэтому законы должны соблюдаться обоими участниками в этих отношениях)
  3. Любит проводить время друг с другом

Моноид: учитывая несколько элементов и функцию, которая принимает 2 элемента и возвращает 1, моноидальное отношение следует этим общим законам

  1. Существует один из этих элементов (только один, называемый идентификатором), который передается функции с любым другим элементом, гарантирует, что функция всегда возвращает другой элемент (0 + 1 = 1, таким образом, 0 - это идентификатор, когда элементы являются числами и функция сложение)
  2. Функция не может работать или возвращать элементы, не входящие в набор, с которым она имеет моноидальное отношение
  3. Функция является ассоциативной и может использоваться с элементами в некотором порядке, не зависящем от порядка, это означает a * (b * c) = (a * b) * c, что говорит о том, что вы можете умножить a на результат b * c или c в результате a * b и результат будет таким же, что вы делаете в первую очередь.

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

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

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

Джимми Хоффа
источник
2

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

Doval
источник
Благодарю. К сожалению, это больше похоже на описание, чем на ментальную модель или метафору. Мне нужна метафора из реального мира (не из компьютеров).
Гвидо Ансельми
1
Как указывает Калеб , функциональное программирование моделирует математику, а не реальный мир. Он может моделировать реальный мир через призму математики, но вы, вероятно, не найдете метафору, которая вас устраивает, потому что FP избегает концепции вещей с постоянной идентичностью и изменчивым состоянием. Если хотите, я могу указать, как ООП конструирует карту в FP, но это не тот ответ, который вам нужен.
Довал
Но математика основана на реальном мире. 1 солнце, 9 планет. 2 яблока плюс 2 яблока делают четыре яблока.
Гвидо Ансельми
А в функциональном программировании вы также можете иметь тип для солнц, планет и яблок, затем создать одно значение типа солнца, 9 значений типа планеты и определить дополнение для типа яблока.
Довал
3
@GuidoAnselmi, у вас это совершенно задом наперед, люди анализируют реальный мир с помощью математики, он не имеет никакого отношения к реальному миру. Математика используется для анализа и определения отношений между всевозможными вещами, реальными и нет. 9 планет - это применение математической конструкции (набора натуральных чисел) к конструкции реального мира (планетам) с функцией математического анализа (счет). Реальный мир не имеет 9 планет, он имеет то, что имеет, математика просто говорит о символических представлениях вещей, где символы имеют отношения друг с другом.
Джимми Хоффа
1

Главное, что нужно понять о функциональном программировании, это то, что все является ценностью, даже сам код является «ценностями».

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

Когда один перемещается на функциональных языки, а не декартова сетка из A1и B42функции имеют имена. Это все, что есть на самом деле.

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

Это оно. Функциональное программирование - это электронная таблица с именами, а не сеткой.


источник
0

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

В ООП объект кода предназначен для того, чтобы быть состоянием объекта в проблемной области; он изменяется со временем, чтобы отразить изменения в этом доменном объекте. В FP значение представляет состояние объекта домена; оно никогда не меняется, вы просто создаете разные значения для представления разных состояний.

Я нахожу функциональную модель более честной в том, что на самом деле делают компьютеры - представляют. В конце концов, я не могу просто вызвать new Tesla()из воздуха. :)

Джон Перди
источник
-5

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

The brown cow is in the meadow across the deep river.

Таким образом, нам нужно найти ключевые фразы, а затем остальные:

The cow (brown)
the meadow (across)
the river (deep)

За один присест:

sentence: The cow ((the meadow (the river (deep)) (across)) brown)

Разобрать дерево:

|                     sentence
|                      /         
|                  The cow
|                 /       \
|            the meadow   brown
|            /         \
|      the river      across
|              \
|              deep

Скупость поражает функциональное мышление;

Снимаю шляпу перед Готлибом Фреге, 1890-е годы, Аланом Тьюрингом (entschiedungsprobleme), 1930-е годы, Ноамом Хомским (1960-е годы).

KTys
источник
4
Это запутанное объяснение, и я знаком с FP с самого начала.
Дениф
Похоже, имитируя форму Лисп, не понимая смысла
Izkata