Комментарии 14
А какой практический смысл изучать лямба-исчисление?
Чтобы развивать мозги, вдохновляться идеями и просто потому, что это интересно.
Некоторые вещи, которые я здесь использовал, имеют названия среди паттернов проектирования. Все сложное строится на чем-то простом.
P.S. ну и еще обратите внимание на хаб
Мы, по сути, создали язык программирования (!), используя только лишь чистое ООП
Мы создали Java :)
Хоть я и люблю нападки в сторону Java, но, к сожалению, вынужден не согласиться :)
Моя самая главная претензия к Java — наличие настоящих примитивов (int, char, etc). Джава довольно "грязный" язык в плане ООП.
В комментариях на реддите люди сказали, что некоторая часть того, что я нагородил, из коробки именно так и работает в Smalltalk. Довольно интересное совпадение, на мой взгляд. Поэтому и стоит изучать разные языки и парадигмы :)
P.S. я понимаю, что Вы пошутили, просто не мог не ответить ;)
Но парадигма именно ООП, только классы и больше ничего, а int и т.д. это больше похоже на legacy.
Но java подкупает своим ООП при первом изучении (но c++ мне нравится больше)
Я думаю, что Ruby будет ближе по духу к ООП, чем Java и C++ вместе взятые. Но они все-таки слишком уж разные, чтобы сравнивать.
Вместо джавы я бы лучше обратил внимание на Kotlin. На первый взгляд он выглядит как чистый ООП язык со статической типизацией. Условно говоря, джава, только лучше.
ИМХО, разумеется
В комментариях на реддите люди сказали, что некоторая часть того, что я нагородил, из коробки именно так и работает в Smalltalk. Довольно интересное совпадение, на мой взгляд.
Банда четырех свой справочник создавала на основе Smalltalk. В первом издании книги он часто упоминается, а современный ООП был взрощен на этом труде, так что не такое уж и совпадение
Ну так руби — идейный наследник смолтока.
Поддерживаю комментаторов с реддита. Именно так всё и устроено.
а пост-то Вам понравился?
Поскольку я и в Пеано с Чёрчем, и в потроха смолтока очень давно играл, то для меня новизны тут нет, но вообще, почему бы и да!
Так как ООП — это ФП для бедных (и наоборот), то идея "давайте всё выразим через диспетчеризацию виртуальных вызовов" естественно ложится на комбинаторную логику / лямбда-исчисление.
Так, ветвление если X то Y() иначе Z()
можно представить, как X(Y, Z)()
— ну, или если это объектное/структурное программирование, то добавим селектор поля/метода: X.then_else(Y, Z)()
— подчеркнём ленивость через позднее применение ().
То есть, булево значение — это двуместная функция. (Виртуальная, определённая для классов True и False; или являющаяся значением полей объектов-синглетонов).
Отсюда, чёрчевские комбинаторы
True = λt.λe. t = K — если говорить про SKI
False = λt.λe. e = SK — соответственно
а логический базис
And = λx.λy. (λt.λe. (x (y t e) e)) = λx.λy. (x x y)
Or = λx.λy. (λt.λe. (x t (y t) e)) = λx.λy. (x y x)
Not = λx. (λt.λe. (x e t)) = λx. (x False True)
Нумералы Чёрча по мотивам чисел Пеано (Zero, Succ).
Нумерал — одноместная функция над моноидом одноместных функций, значение нумерала — это возведение функции в соответствующую степень.
id = λx. x — нейтральный элемент моноида, — функция, которая ничего не делает
P = λf.λg. (λx. f (g x)) — умножение в моноиде, — композиция функций
Нумералы:
N0 = λf. id = λf. (λx. x)
N1 = λf. f = λf. (λx. f x)
N2 = λf. (P f f) = λf. (λx. f (f x))
N3 = λf. (P f (P f f)) = λf. (λx. f (f (f x)))
и т.д.
Операции над нумералами:
Succ = λN. (λf. P f (N f)) = λN. (λf. P (N f) f) — что так, что этак, умножение ассоциативно
Plus = λM.λN. (λf. P (M f) (N f))
ну и так далее.
Списки на лямбда-исчислении тоже строятся довольно просто (оставлю интригу читателям).
То есть, зная теоретические основы, перепереть эту полечку на ООП — милое дело.
Егор Бугаенко присоединился в чат
Программирование только классами