LINUX.ORG.RU

[philosophy] В чем заключается революционность перехода от функциональщины к ООП?


1

0

Так уж повелось, что первый язык, который я изучал, был делфи. Потом всякие сишарпики, С++, лисп, и т.п. В итоге, как мне кажется, у меня ООП головного мозга. Когда возникала задача писать на С, я начал реализовавывать обьектную модель в этом языке.

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

Почему появились языки, которые взяли ООП за главенствующую идею (java, c#, етц)?

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

Сухой остаток. ООП представляет из себя еще один уровень абстракции, который позволяет оперировать про проектировании не функциями, а обьектами. А неужели это так меняет дело и делает разработку более удобной?

Было бы интересно без срачей услышать компетентное мнение.

★★
Ответ на: комментарий от Love5an

> вообще, дебильное словосочетание, для обозначения дебильной хреноты

из убогих скриптоязыков, навроде питона


Нормальное словосочетание для обозначений очень мощной и полезной концепции.

archimag ★★★
()
Ответ на: комментарий от Love5an

> Типизация в CL сильная, говно вроде сложения строки

с числом там невозможно.


Ага, а в Python значит возможно? Ты вообще в каких языках хорошо разбираешься?

archimag ★★★
()
Ответ на: комментарий от Miguel

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

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

зачем этой функции знать о типах элементов, если она работает только со структурой — списком?

как же в хаскелле организуется типобезопасность? компилятор генерит кучу функций на «[a] -> [a] -> [a]» для каждого типа «a»?

korvin_ ★★★★★
()
Ответ на: комментарий от archimag

> Ещё раз: почему шаблоны в C++ не являются примером параметричекого полиморфизма?

мигель хочет сказать, что параметрический полиморфизм в случае

template<class T> void f(T x) {...}

при условии что типов T много (неизвестное на этапе компиляции число, или допустим даже 4 000 000 000) потребует дополнительных паттернов (или костылей :-), типа того, что я подставил в случае mapcar

неизвестное их число может быть в случае

template<class T> void f(T x) { if(...) { f(Cons<T>(x,...);} ... }

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от oh

Да почему?

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

В хаскеле, например, чтобы хоть как-то приблизиться к возможностям д.т. в данном аспекте, придумали такую кривую жопу, как Data.Dynamic

Love5an
()
Ответ на: комментарий от archimag

Абстракция всегда протекает, просто потому, что компьютер конечен и имеет ограниченные ресурсы.

Понимаете, есть разница между «это возможно, если поставить побольше памяти» и «это невозможно».

Ещё раз: почему шаблоны в C++ не являются примером параметричекого полиморфизма?

Потому, что для разных типов возможны различные реализации. Даже если они текстуально совпадают (а могут и не совпадать - см. частичную специализацию).

qsort?

Опять-таки, с одним. «Список».

Так зачем про список рассказываете?

Ну, как бы, чтобы вы что-нибудь поняли.

Нет, в С++ это делает компилятор, а не препроцессор.

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

Поймите, наконец, меня как раз конкретные реализации не волнуют совершенно. Меня интересует принцип. А принцип именно таков, C++-ные шаблоны ведут себя ровно так, как если бы мы разворачивали их целиком, а потом отдельно компилировали.

В стандарте C++, кстати, предусмотрена возможность раздельной компиляции шаблонов (так что это точно не препроцессор).

Это, увы, невозможно. Виной тому - та самая клятая Тьюринг-полнота.

Это как-то противоречит определению полиморфизма?

Угу, мы используем один тип, а не разные.

Miguel ★★★★★
()
Ответ на: комментарий от Love5an

Типизация в CL сильная, говно вроде сложения строки с числом там невозможно.

Угу, мы получим ошибку типизации. В рантайме. Это и значит «хреновая».

Miguel ★★★★★
()
Ответ на: комментарий от korvin_

зачем этой функции знать о типах элементов, если она работает только со структурой — списком?

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

как же в хаскелле организуется типобезопасность? компилятор генерит кучу функций на "[a] -> [a] -> [a]" для каждого типа «a»?

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

Miguel ★★★★★
()
Ответ на: комментарий от archimag

да нихрена:

In essence, the problem is that, «if it walks like a duck and quacks like a duck», it could be a dragon doing a duck impersonation. You may not always want to let dragons into a pond, even if they can impersonate a duck.

Love5an
()
Ответ на: комментарий от Miguel

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

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

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

т.е. ты согласен, что даже в строгом хаскелле подобным функциям совершенно пофиг, что «список целых» и «список строк» — разные типы, они об этом даже не знают?

korvin_ ★★★★★
()
Ответ на: комментарий от korvin_

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

Да. А вообще он есть.

даже в строгом хаскелле подобным функциям совершенно пофиг, что «список целых» и «список строк» — разные типы, они об этом даже не знают?

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

Вообще, я не понимаю, ты задался целью доказать мне, что в Хаскеле есть параметрический полиморфизм?

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

> Понимаете, есть разница между «это возможно, если поставить

побольше памяти» и «это невозможно».


Какое это имеет отношение к предмету разговора? И да, не совсем понимаю, ибо у меня в материнку больше 3 Гб не впихнуть.

Опять-таки, с одним. «Список».


И что? Как это влияет на результат?

Меня интересует принцип. А принцип именно таков


Меня интересует как это отражается на практическом использовании. Пока вижу, что никак. Так что о принципах то рассуждать?

Это, увы, невозможно. Виной тому - та самая клятая Тьюринг-полнота.


Странно, а реализация есть. Чудеса...

Это как-то противоречит определению полиморфизма?

Угу, мы используем один тип, а не разные.


Не вижу противоречия, в Python вообще нет такого типа, как список целых. Разве концепция от этого становится не применимой?

archimag ★★★
()
Ответ на: комментарий от Miguel

> Вообще, я не понимаю, ты задался целью доказать мне, что в Хаскеле есть параметрический полиморфизм?

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

korvin_ ★★★★★
()
Ответ на: комментарий от Miguel

> Что не отменяет того, что эти типы существуют, совершенно отличны,

и другие функции это различие видят


Важно примечание: в Haskell, а не вообще в программировании.

Вообще, я не понимаю, ты задался целью доказать мне,

что в Хаскеле есть параметрический полиморфизм?



Вы взяли терминологию, специфичную для Haskell, и начали натягивать её за уши вообще на все языки. Такого полиморфизма как в Haskell нет нигде, ибо это Haskell. В других языках есть другие виды полиморфизма. И везде всё по разному. Вот и всё. Нефиг всех под одну гребёнку грести.

archimag ★★★
()
Ответ на: комментарий от archimag

Какое это имеет отношение к предмету разговора?

Самое прямое. Бесконечное развёртывание шаблонов не может быть сделано за конечное время.

Как это влияет на результат?

А должно?

Меня интересует как это отражается на практическом использовании. Пока вижу, что никак.

Ещё раз: бесконечное развёртывание шаблонов. Его не я придумал. И оно для настоящего ПП не имеет смысла, так как там нет никакого развёртывания вообще.

Странно, а реализация есть. Чудеса...

Нету.

Не вижу противоречия, в Python вообще нет такого типа, как список целых. Разве концепция от этого становится не применимой?

Какая концепция? ПП? А какой ПП, если мы работаем с одним типом?

Miguel ★★★★★
()
Ответ на: комментарий от korvin_

я просто не понимаю зачем нужно твоё утверждение, что список целых чисел и список строк — разные типы, в контексте обсуждения функций, которым это не важно, которые оперируют только «контейнерами» — списками в данном случае.

Какая разница, кому что важно в каком контексте. Эти типы - объективно разные в Хаскеле (C++) и объективно одинаковые в Python. Что там кому важно - не влияет.

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

> Какая разница, кому что важно в каком контексте. Эти типы - объективно разные в Хаскеле (C++) и объективно одинаковые в Python. Что там кому важно - не влияет.

это никому не важно, кроме тебя.

korvin_ ★★★★★
()
Ответ на: комментарий от archimag

Важно примечание: в Haskell, а не вообще в программировании.

Естественно.

терминологию, специфичную для Haskell

Терминология - 1967 года, если верить википедии. Хаскель - в крайнем случае 1990.

Такого полиморфизма как в Haskell нет нигде, ибо это Haskell.

А в OCaml, простите, что?

Хотя частично я согласен, статического ad-hoc нет нигде, тайпклассы есть только в Хаскеле (ну, из более-менее известных языков).

И везде всё по разному.

Ну, то есть, скажем, классификация на животных/растения/грибы/бактерии бессмысленна? Ведь все живые существа разные.

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

> Отвлекись уже от персоналий, они никому не важны, кроме тебя.

Извини, но утверждение, что «список целых чисел» и «список строк» — разные типы, твоё. Видимо тебе это важно.

korvin_ ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

> Но если мы выкинем строку с if, то код станет неверным, и компилятор тихо промолчит, а он ДОЛЖЕН давать варнинг или лучше ошибку. Поэтому нихрена ваш компилятор не знает.

Я сказал, что есть способ дать компилятору знать, какое значение ввел пользователь. Я _не_ говорил, способен ли какой-нибудь существующий компилятор использовать это знание.

естественно, определять надо int foo(Int<0,15>) и т.д.

Ты не сможешь определить Int<0, 15>, проверяемый на этапе компиляции, так что твое «нихрена компилятор не знает» просто нелепо.

tailgunner ★★★★★
()
Ответ на: комментарий от archimag

Гугли по словам export и Comeau C/C++.

Экспорт шаблонов? Не, не пойдёт. При компиляции шаблона Comeau просто пишет в специальный .et-файл, где искать исходники реализации. Это никоим образом не раздельная компиляция.

Miguel ★★★★★
()
Ответ на: комментарий от korvin_

Извини, но утверждение, что «список целых чисел» и «список строк» — разные типы, твоё. Видимо тебе это важно.

Ты тупой. Вопрос не в том, что мне важно. Вопрос в том, что на самом деле.

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

> Ты тупой. Вопрос не в том, что мне важно. Вопрос в том, что на самом деле.

ответ в том, что это «на самом деле» никому не важно

korvin_ ★★★★★
()
Ответ на: комментарий от korvin_

ответ в том, что это «на самом деле» никому не важно

Ответ на что? Никто не спрашивал, важно ли это.

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

>> Важно примечание: в Haskell, а не вообще в программировании.

Естественно.


А в других языках с хорошей сильной статической типизацией?

oh
()
Ответ на: комментарий от korvin_

Ты упоротый чтоли?
Есть тип «Список чисел». Операция длинна_списка работает без различий для типов и «Список чисел», и «Список строк». А операция приписать_к_каждой_строке_в_списке_букву работает только для «Список строк».

oh
()
Ответ на: комментарий от oh

> А в других языках с хорошей сильной статической типизацией?

Речь изначально шла об ООП вообще, а не об ООП в языках с статической проверкой типов.

Есть тип «Список чисел».


А если такого типа нет?

archimag ★★★
()
Ответ на: комментарий от oh

>операция приписать_к_каждой_строке_в_списке_букву
Нет для [a] конкретно такой операции. Есть map. И ей тоже не важен конкретный тип данных.

Love5an
()
Ответ на: комментарий от archimag

> Речь изначально шла об ООП вообще, а не об ООП в языках с статической проверкой типов.

Да, но сейчас идет дискуссия про ПП.

А если такого типа нет?

Это был условный пример. Еще раз. Есть языки с статической типизацией. Там может быть ПП, может не быть. Есть языки с дин. типизацией. Тут можно говорить про существование искаробочного ПП, либо можно говорить о бессмысленности термина в данном контексте. В динамич. типизированных языкых дискуссия про ПП переходит в простую демагогию и ИМХО.

oh
()
Ответ на: комментарий от Love5an

Ну я как раз и привел пример функции, где нет ПП

oh
()
Ответ на: комментарий от oh

А в других языках с хорошей сильной статической типизацией?

Тоже. Но, как верно было замечено, не вообще в программировании.

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

Ээ.. ты только что подтвердил слова оппонента, есличе.
Он говорил, что операция добавить_букву_к_каждой_строке имеет тип НЕ [a].
Ты это подтвердил показав тип функции f: [String] -> [String]

oh
()
Ответ на: комментарий от archimag

> Или что такое по вашему препроцессор?

Я с вас фигею...

LamerOk ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

> это все-таки не препроцессор

Весь вечер выяснять совершенно элементарную вещь.

Перпроцессор это, обычный препроцессор, так как конечным результатом является _исходный код_ (пусть даже в форме АСТ, а не текста) для собственно компилятора.

LamerOk ★★★★★
()
Ответ на: комментарий от oh

Ээ.. ты только что подтвердил слова оппонента, есличе.

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

Мне померещилось, что он отрицал существование такой операции для массивов вообще - он же тебе возражал, вроде как.

Miguel ★★★★★
()
Ответ на: комментарий от korvin_

> это «на самом деле» никому не важно

Учись говорить за себя.

LamerOk ★★★★★
()
Ответ на: комментарий от oh

Так, давайте, чтоб первое место занять, надо еще 7 страниц.

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

oh
()
Ответ на: комментарий от oh

Да подожи ты.

Мы ждем от влора шаблон-телепат, предсказывающий ввод пользователя.

Кроме того у нас повисло два хвоста дисскусий:

LamerOk ★★★★★
()
Ответ на: комментарий от Miguel

>> Не вижу противоречия, в Python вообще нет такого типа, как список целых. Разве концепция от этого становится не применимой?

Какая концепция? ПП? А какой ПП, если мы работаем с одним типом?

LamerOk ★★★★★
()
Ответ на: комментарий от tailgunner

>> естественно, определять надо int foo(Int<0,15>) и т.д.

Ты не сможешь определить Int<0, 15>, проверяемый на этапе компиляции, так что твое «нихрена компилятор не знает» просто нелепо.


P.S. Я всё еще жду реализации вот этого:

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

LamerOk ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.