[ /b/ /u/ /rf/ /dt/ /vg/ /r/ /cr/ /lor/ /mu/ /oe/ /s/ /w/ /hr/ ] [ /a/ /ma/ /sw/ /hau/ /azu/ ] [ /tv/ /cp/ /gf/ /bo/ /di/ /vn/ /ve/ /wh/ /fur/ /to/ /bg/ /wn/ /slow/ /mad/ ] [ /d/ /news/ ] [ Главная | Настройки | Закладки | Плеер ]

Ответ в тред 48832. [Назад]
 [ Скрыть форму ]
Имя
Не поднимать тред 
Тема
Сообщение
Капча Капча
Пароль
Файл
Вернуться к
  • Публикация сообщения означает согласие с условиями предоставления сервиса
  • В сообщениях можно использовать разметку wakabamark
  • На данной доске отображаются исходные имена файлов!
  • Разрешенные типы файлов: music, vector, image, code, pdf, flash, archive, text, video
  • Тред перестает подниматься после 500 сообщений.
  • Треды с числом ответов более 100 не могут быть удалены.
  • Старые треды перемещаются в архив после 40 страницы.

No.48832 Ответ
Файл: pg087.png
Png, 23.35 KB, 475×349
edit Find source with google Find source with iqdb
pg087.png
Файл: pg072.png
Png, 56.58 KB, 515×709
edit Find source with google Find source with iqdb
pg072.png
Файл: 14686072547160.png
Png, 44.08 KB, 1024×450
edit Find source with google Find source with iqdb
14686072547160.png

Как понять ООП? Я просто вот не понимаю, зачем это нужно. Безотносительно языка программирования

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

Вот допустим есть public private protected модификаторы доступа т.е. ограничения на то, откуда какой метод можно вызывать. public можно вызывать отовсюду, private только для методов из числа public, а protected ... protected становится private при наследовании, притом наследований может быть 3 вида - тоже public, private, protected... Зачем всё это? Чем это лучше просто кучи функций, которые могут просто вызывать другие функции и работать с какими-то структурами?

Или вот методы, методы это функции, которые привязаны к конкретной структуре, но что если мне нужны методы, которые связывают два разных класса? Например это может код, переводящий из вектора в растровую картинку. Этот код должен быть методом класса для растровой или векторной картинки?
>> No.48833 Ответ
>>48832
> Как понять ООП? Я просто вот не понимаю, зачем это нужно.
Это еще один уровень абстракции. В императивном языке ты думаешь как работать непосредственно с данными, а в объектом - как работать с объектами. В этом плане ООП больше похоже на сборку лего, где у каждой детали свои характеристики, и у тебя уже не получится использовать шестеренку как кирпичик. Или как сборку ПК, где тебя уже не волнует, как и какие там чипы, транзисторы и резисторы на платах припаяны, тебе главное чтоб разъемы совпадали и по спецификациям друг к другу подходили.

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

> Вот допустим есть public private protected модификаторы доступа т.е. ограничения на то, откуда какой метод можно вызывать. public можно вызывать отовсюду, private только для методов из числа public, а protected ... protected становится private при наследовании, притом наследований может быть 3 вида - тоже public, private, protected... Зачем всё это? Чем это лучше просто кучи функций, которые могут просто вызывать другие функции и работать с какими-то структурами?
Во-первых, все эти мутации public private protected друг в друга - просто особенность C++. Прими как данное. В других языках тоже свои заморочки есть. Во-вторых, эти модификаторы позволяют четко определить, какие переменные можно изменять, а какие нет. Как и в случае с методами, это еще одна защита от ошибки программиста. Ты же не всегда на 100% внимателен и трезв умом. Сегодня у тебя голова болит, завтра тебя отвлекли разговором, послезавтра тебя девушка бросила, а через неделю тебе просто лень вычитывать код на ошибки. Раз в год и палка стреляет, так что лучше сразу технически пресечь такую возможность.

> Или вот методы, методы это функции, которые привязаны к конкретной структуре, но что если мне нужны методы, которые связывают два разных класса? Например это может код, переводящий из вектора в растровую картинку. Этот код должен быть методом класса для растровой или векторной картинки?
Четкого ответа дать не могу, я бы лично написал отдельную функцию, не привязанную к какому-либо классу. На мой взгляд это зависит от архитектуры кода. Можно представить растровый класс, который постоянно жрет векторные данные, и реализовать код конвертации как метод растрового класса. А можно запариться и для каждого класса реализовать метод конвертации в противоположный формат.
>> No.48834 Ответ
>>48833
> Это еще один уровень абстракции. В императивном языке ты думаешь как работать непосредственно с данными, а в объектом - как работать с объектами. В этом плане ООП больше похоже на сборку лего, где у каждой детали свои характеристики, и у тебя уже не получится использовать шестеренку как кирпичик.
> В случае с методами и функциями, у тебя, например, больше шансов случайно засунуть векторную структуру в функцию для растровой и в результате получить баг.
Ну если взять чистый C и противопоставить его C++, то в C есть структуры (struct), и если у меня функция принимает в качестве аргумента структуру, то передать в эту функцию другую структуру просто так не выйдет, будет как минимум warning. Класс в C++ это когда насильно привязывают некоторые функции к некоторым структурам и создают некие правила, что вот есть такие функции-привязанные-к-структуре, которые можно вызывать кому угодно, а есть еще какие-то особые функции-привязанные-к-структуре, которые можно вызывать только из других функций-привязанных-к-структуре (private методы можно вызывать только из других методов класса). Каким образом это увеличивает уровень абстракции? Это просто добавляет способ задать некие ограничения. Например модификатор const для переменных, он тоже никаких абстракций не добавляет, а просто позволяет указать что переменная не может быть изменена, и чтобы компилятор еще ругался при попытке эту переменную изменить.
На абстракцию похоже разве что наследования с виртуальными методами, когда C++ компилятор создает таблицу виртуальных методов т.е. массив из указателей на функции (не нужно рукам эти массивы из указателей на функции писать). Да и есть альтернативы для vtable в других языках, например через хеш-таблицы имен методов.
В самой же идее связать структуру и некоторые функции я никакого нового уровня абстракции не вижу.
> Во-вторых, эти модификаторы позволяют четко определить, какие переменные можно изменять, а какие нет. Как и в случае с методами, это еще одна защита от ошибки программиста.
Для этого больше бы подошли какие-нибудь контракты. Например, в каком-нибудь гипотетическом ЯП сделать так, чтобы можно было объявить особый неймспейс №1, перечислив в нем некоторое множество функций. И потом объявить другой неймспейс №2, перечислив в нем другое множество функций, при этом у этого неймспейса задать особый атрибут, что функции из этого неймспейса №2 могут быть вызваны только из функций, объявленных в неймспейсе №1. Но при этом может быть и так, что функции из неймспейса №2 не могут быть вызваны из неймспейса №1. Сама идея создания подобных контрактов к ООП отношения не имеет
С плюсовыми методами класса такое кстати не работает, т.е. public методы могут вызывать private, private могут вызывать public и private, нельзя ввести запрет для private вызывать public, как и нельзя объявить какой-нибудь свой уникальный модификатор, типа public_2 и вручную выставить для него правила, что и как ему можно делать.
> Четкого ответа дать не могу, я бы лично написал отдельную функцию, не привязанную к какому-либо классу.
А еще было б неплохо, если бы такой отдельной функции можно было бы дать разрешение вызывать private методы этих двух классов и читать-писать private переменные из этих двух классов. #define private public
>> No.48835 Ответ
>>48834
Очевидно, ты не понимаешь самой идеи (инкапсуляция, полиморфизм, наследование, вот это все) и смотришь только на синтаксис.
> и если у меня функция принимает в качестве аргумента структуру, то передать в эту функцию другую структуру просто так не выйдет, будет как минимум warning.
Классический пример: у тебя есть функция copulate. В сишке ты будешь сам трахаться, плодя бесчисленные copulate(Bat), copulate(Tiger) и т.д., тогда как ООП позволяет тебе выделить общую базу и сделать единый copulate(Animal), где наследники Animal будут перенимать поведение базового класса.
> Каким образом это увеличивает уровень абстракции?
Ты не задаешь функции, функции хуйня. Ты задаешь поведение объектов класса. Ты берешь класс и говоришь, что у него есть такие-то методы, и в public методы может тыкнуться любой желающий, а в private только он сам и т.д.
> Например модификатор const для переменных, он тоже никаких абстракций не добавляет, а просто позволяет указать что переменная не может быть изменена, и чтобы компилятор еще ругался при попытке эту переменную изменить.
Замечательная вещь: позволяет отсеять часть ошибок в логике еще на этапе компиляции. Точно так же часть ошибок можно отсеять с помощью правильной установки прав доступа (public-protected-private).
> С плюсовыми методами класса такое кстати не работает, т.е. public методы могут вызывать private, private могут вызывать public и private, нельзя ввести запрет для private вызывать public, как и нельзя объявить какой-нибудь свой уникальный модификатор, типа public_2 и вручную выставить для него правила, что и как ему можно делать.
Все просто: public_2 костыль и НИНУЖНО. Имеющихся прав доступа достаточно: это не непонятно какие неймспейсы с потолка, а именно что классы и описание того, кому и что с ними можно делать. По определению public - то, что доступно любому, а потому "запрет private вызывать public" - абсурд.
Не привязывайся к функциям, а пойми саму парадигму: ты описываешь не функции, а классы. Собственно, поэтому годные программисты пишут код на уровне взаимодействия интерфейсов, а не говнокодят с реализациями.
>> No.48836 Ответ
Да говно это, учи Haskell
>> No.48837 Ответ
>>48836
Да тоже фигня, лучше учиться на перспективу - учить языки для квантового программирования.
>> No.48838 Ответ
Файл: Cylinder_Head_Sector_ru.svg.png
Png, 260.88 KB, 1200×1293 - Нажмите на картинку для увеличения
edit Find source with google Find source with iqdb
Cylinder_Head_Sector_ru.svg.png
>>48835
> Классический пример: у тебя есть функция copulate. В сишке ты будешь сам трахаться, плодя бесчисленные copulate(Bat), copulate(Tiger) и т.д., тогда как ООП позволяет тебе выделить общую базу и сделать единый copulate(Animal), где наследники Animal будут перенимать поведение базового класса.
Т.е. смысл ООП в том, чтоб не копипастить? И это новый уровень абстракции?
Новый уровень абстракции это например переход ASM -> C, когда уже не нужно оперировать регистрами и инструкциями процессора. ООП это скорее некий способ организации кода (теперь функции мы привязали к структурам, пишите вот так!), а не новый уровень абстракции.
> Ты не задаешь функции, функции хуйня. Ты задаешь поведение объектов класса. Ты берешь класс и говоришь, что у него есть такие-то методы, и в public методы может тыкнуться любой желающий, а в private только он сам и т.д.
А зачем ограничивать себя только таким дефолтным набором public-private-protected? Может ООП является частным случаем более общей парадигмы, т.е. идеи выставлять на что-то какие-то разрешения? Ну вот я приводил пример с контрактами, что одни функции могут там что-то вызывать, а другие не могут, но никакие объекты для этого не требуются, это просто выделение некоторого неймспейса функций и создание для них каких-то запретов/разрешений. Такие же запреты/разрешения можно определять относительно каких-нибудь структур, и это можно сделать намного более гибко, типа вот только функции из этого неймспейса могут работать вот с этими структурами, а вот функции из этого неймспейса могут работать с другими структурами, а еще какие-то функции могут и с теми и с теми структурами работать.
> Замечательная вещь: позволяет отсеять часть ошибок в логике еще на этапе компиляции. Точно так же часть ошибок можно отсеять с помощью правильной установки прав доступа (public-protected-private).
Я и не спорю, но на новую парадигму это не тянет. Это просто возможность ставить самому себе какие-то ограничения. И систему прав доступа можно сделать значительно более гибкой, чем это реализовано в ООП.
> Все просто: public_2 костыль и НИНУЖНО. Имеющихся прав доступа достаточно: это не непонятно какие неймспейсы с потолка, а именно что классы и описание того, кому и что с ними можно делать. По определению public - то, что доступно любому, а потому "запрет private вызывать public" - абсурд.
Ну почему же, вполне можно представить ситуацию, когда полезно сделать ограничения вида "функции из неймспейса №1 могут вызывать только функции из неймспейса №1 и №2, функции из неймспейса №2 могут вызывать только функции из неймспейса №2 и №3, функции №3 вызывают только №3 и №4 и.т.д."
Например представим, что у нас есть гипотетический компьютер с жестким диском с магнитными блинами, и жесткий диск своего контроллера не имеет (управление осуществляется центральным процессором). Есть ОС на этом компьютере, и нам надо создать файл и записать в него такие-то данные. Вот тут можно вводить некие слои с разделением прав. Когда некая программа из юзерспейса просит ОС создать такой-то файл и записать в него такие-то байтики, ядро передает драйверу файловой системы указание "создай такой-то файл и запиши в него то-то", драйвер ФС передает драйверу жесткого диска "запиши вот эти байтики вот туда-то, и вот эти байтики вот туда", при этом драйвер ФС ничего не знает про геометрию диска(дорожки, количество пластин), т.е. с точки зрения драйвера ФС, жесткий диск это просто большой массив из некоторых секторов, например секторов по 512 байт. Т.е. драйвер ФС общается с драйвером жесткого диска на уровне "запиши в тот сектор размером в 512 байт вот это" и "прочитай из того сектора размером в 512 байт и дай мне". В драйвере жесткого диска обращение на чтение/запись такого-то сектора транслируется по каким-то формулам, учитывающим скорость вращения блинов, угол поворота коромысла с магнитными головками, и напрямую управляет всем этим. Так вот, тут имеет смысл запретить обычной программе из юзерспейса обращаться к драйверу жесткого диска напрямую и говорить, в какие секторы что писать. Обычная программа не должна управлять поворотом коромысла с магнитными головками, менять скорость вращения двигателя и прочего (то, что делает драйвер ЖД). Драйвер файловой системы тоже не должен управлять напрямую поворотом коромысла, а только лишь просить у драйвера ЖД, чтобы он туда-то записал/прочитал. А сам драйвер жесткого диска совершенно точно не должен обращаться к каким-нибудь вышележащим функциям, например драйверу ЖД незачем обращаться к драйверу ФС типа "драйвер ФС, давай удали вот этот файл". Т.е. из более низкого уровня нет смысла вызывать более высокий уровень. В ООП private имеет право вызывать и private и public, там нельзя строить такие правила.
Такое можно без всякого ООП делать в чистом Си, разбив реализацию на несколько файлов и используя static функции.
>> No.48839 Ответ
Давайте сделаем поправку, что ООП в том виде, в котором его задумывал Алан Кей, мало где реализован. Так что да, ООП в мейнстримовых языках больше влияет на организацию кода, чем претендует на новую парадигму.
Собственно говоря, ООП в C++ не реализует ничего такого, чего нельзя было бы написать в C. Да только делается это в плюсах удобнее и безопаснее.
>> No.48840 Ответ
>>48839
> Давайте сделаем поправку, что ООП в том виде, в котором его задумывал Алан Кей, мало где реализован.
Это связано с тем, что каноничное ООП оказалось никому не нужным? Или оно было слишком сложным в реализации? Или почему?
>> No.48841 Ответ
>>48840
Без понятия. Наверное, все как всегда - теория столкнулась с практикой и изменилась.
Вот есть хорошая статья про историю идеи - https://medium.com/@atherlangga/retracing-original-object-oriented-programming-f8b689c4ce50
>> No.48847 Ответ
>>48840
Каноничное ПО никому не нужно. Тебе же пофиг, как это работает. Вот и всем тоже пофиг. А когда всем пофиг, можно "хуяк-хуяк - и в продакшон". При такой бизнес-парадигме популярными становятся языки, на которых "хуяк-хуяк" можно безопаснее и удобнее.
Если тебе действительно интересно, чем может быть полезна объектно-ориентированная парадигма, а не как её подобием обмазали наиболее популярные языки, почитай про CLOS. Если понравится, можешь ещё MOP навернуть и изучить понятие интроспекция в контексте ЯП. Если всё ещё не обретёшь понимания, что такое ООП, ну значит не готов, не нужно оно тебе.
>> No.48849 Ответ
>>48838
> Т.е. смысл ООП в том, чтоб не копипастить? И это новый уровень абстракции?
Ты опять смотришь на функции вместо того, чтобы смотреть на классы. Отсутствие тупого копипаста - лишь вытекающее из мышления на объектном уровне плюшка.
> Новый уровень абстракции это например переход ASM -> C, когда уже не нужно оперировать регистрами и инструкциями процессора. ООП это скорее некий способ организации кода (теперь функции мы привязали к структурам, пишите вот так!), а не новый уровень абстракции.
А здесь не нужно оперировать лоу-левел функциями, а нужно оперировать интерфейсами.
> А зачем ограничивать себя только таким дефолтным набором public-private-protected?
Потому что этого достаточно. Снова, не смотри на какие-то дурацкие неймспейсы как приложение к функциям. Мысли на уровне классов и интерфейсов. Есть только интерфейсы, доступные всем, недоступные никому кроме себя и недоступные никому кроме себя и потомков.
> Ну вот я приводил пример с контрактами, что одни функции могут там что-то вызывать, а другие не могут, но никакие объекты для этого не требуются, это просто выделение некоторого неймспейса функций и создание для них каких-то запретов/разрешений.
Мерзкие сишные костыли. Это называется методы работы одних объектов с другими объектами, и делается через public-protected-private, наследование и иногда friendование.
> И систему прав доступа можно сделать значительно более гибкой, чем это реализовано в ООП.
Нельзя. Есть объект, который не знает ничего об окружающем мире кроме того, что от него могут унаследоваться. Все возможные виды доступа к его интерфейсам - public, protected, private.
> Ну почему же, вполне можно представить ситуацию, когда полезно сделать ограничения вида "функции из неймспейса №1 могут вызывать только функции из неймспейса №1 и №2, функции из неймспейса №2 могут вызывать только функции из неймспейса №2 и №3, функции №3 вызывают только №3 и №4 и.т.д."
Костыли. Используй классы, Люк.
> драйвер ФС передает драйверу жесткого диска "запиши вот эти байтики вот туда-то, и вот эти байтики вот туда", при этом драйвер ФС ничего не знает про геометрию диска(дорожки, количество пластин), т.е. с точки зрения драйвера ФС, жесткий диск это просто большой массив из некоторых секторов, например секторов по 512 байт. Т.е. драйвер ФС общается с драйвером жесткого диска на уровне "запиши в тот сектор размером в 512 байт вот это" и "прочитай из того сектора размером в 512 байт и дай мне".
Быдлокод с магическими числами. ФС дергает общий интерфейс всех драйверов ЖД "Записать N-байт". Реализация этого интерфейса, представляющая конкретный HAL для конкретного диска, разбивает файл на куски в зависимости от параметров диска, формирует блок метаданных с последовательностью адресов этих блоков, записывает это все и возвращает драйверу ФС файловый дескриптор блока метаданных. Вуаля, все работает на интерфейсах ООП-стайл.
> Так вот, тут имеет смысл запретить обычной программе из юзерспейса обращаться к драйверу жесткого диска напрямую и говорить, в какие секторы что писать.
Вообще не задача программы или ЯП. Это задача ОС заделать разделение на юзерспейс и кернелспейс. В юзерспейсе доступны интерфейсы для записи и чтения файлов, опять же ООП-стайл.
> Такое можно без всякого ООП делать в чистом Си, разбив реализацию на несколько файлов и используя static функции.
Разбивать на файлы все равно придется, очевидно. А всего-то нужно - использовать нужные интерфейсы, которые можно реализовывать для любого устройства. Твою же идею ждет инстант пиздец, стоит только подключить какой-нибудь ССД ил рамдиск или дискетку вместо ЖД, лол.
>> No.48850 Ответ
>>48849
Спор слепого с глухим.
Как ООП избавляет от копипасты и при чём тут она вообще? Решения типа copulate(Bat), copulate(Tiger) можно сгенерировать независимо от парадигмы. Ни ООП, ни декларативное, ни какое-либое другое программирование не может запретить писать говнокод или копипастить.
Раньше программы писали просто перечислением команд, потом стали выделять куски кода в подпрограммы, процедуры, функции - это уже начала инкапсуляции и полиморфизма. Затем стали объединять разные встроенные типы в структуры, а функционал, работающий с такими комбинированными типами данных - всё так же в процедуры. Почему так стали делать? Потому что программы становились больше, сложнее, возникла необходимость структурировать код, чтобы его было легко анализировать, допиливать. Разные подходы к организации кода были вызваны сильно различающимися типами задач, костылей мышления погромистов и породили необходимость в расслоении на языки с разными парадигмами. Но такого чтобы парадигма лишала возможности говнокодить не было никогда. Ну разве что вот нейронные сети, практически исключив человека из, собственно, процесса формирования итоговой системы, могут как-то помочь с этим, но это уже не о парадигмах речь.
В плюсах ничего принципиально нового не вводится, никаких волшебных механизмов, исключающих говнокод. Классы - всё те же супер-типы на стероидах. Для каждой лексемы найдётся оправдание, каждая нужна для чего-то, иначе её не впилили бы. И это всё, конечно, работает, ты, конечно, можешь думать классами, наследованиями, разграничением прав для членов класса, пояснять за виртуальные функции и считать шаблоны - венцом программистской мысли. Раньше был молоток, пила, рубанок, теперь - молоток с выдвижной пилой и возможностью прикрутить сколько угодно рубанков, причём у всего этого одна ручка (удобно), и теперь ты не можешь пораниться, потому что везде наклейки "ОСТОРОЖНО!". В нормальном мире ручной инструмент уходит в прошлое, совершенствуются и материалы, и технологии строительства, и вообще автоматизация процесса даёт человеку больше свободного времени на осмысление происходящего.
>> No.48852 Ответ
>>48849
> Потому что этого достаточно. Снова, не смотри на какие-то дурацкие неймспейсы как приложение к функциям. Мысли на уровне классов и интерфейсов. Есть только интерфейсы, доступные всем, недоступные никому кроме себя и недоступные никому кроме себя и потомков.
Достаточно для чего? Если говорить о том, чего достаточно, то и обычных функций + структур вполне достаточно, а все эти public-private-protected ничего кардинально не меняют. Если же public-private-protected это что-то нужное, то почему именно на этом остановились, почему б не вводить какие-то новые права доступа?
> Мерзкие сишные костыли. Это называется методы работы одних объектов с другими объектами, и делается через public-protected-private, наследование и иногда friendование.
> Нельзя. Есть объект, который не знает ничего об окружающем мире кроме того, что от него могут унаследоваться. Все возможные виды доступа к его интерфейсам - public, protected, private.
Зачем ты говоришь догмами? Язык программирования и предоставляемые им абстракции это не какие-то незыблемые законы физики, вроде закона сохранения энергии, это просто придуманная людьми хрень, которая при желании может быть улучшена/переделана.
> > Ну почему же, вполне можно представить ситуацию, когда полезно сделать ограничения вида "функции из неймспейса №1 могут вызывать только функции из неймспейса №1 и №2, функции из неймспейса №2 могут вызывать только функции из неймспейса №2 и №3, функции №3 вызывают только №3 и №4 и.т.д."
> Костыли. Используй классы, Люк.
Я через классы не могу создавать сложный набор правил доступа, там только public, protected, private.
> Быдлокод с магическими числами. ФС дергает общий интерфейс всех драйверов ЖД "Записать N-байт".
Винчестер тебе 1 байт записать не может, там не побайтная адресация (ты б еще попросил его один бит записать, лол). Он прочитает 512 байт (или сколько у него там размер кластера) в буфер, изменит там 1 байт и потом обратно запишет 512 байт. Если ты вот так побайтно будешь писать в некий файл данные по одному байту, это будет нерационально. Лучше пусть это буферизуется, но буферизоваться это может на разных уровнях, и желательно чтобы ФС знала о том, какого размера кластер винчестера, и чтобы ФС была отформатирована соответствующим образом. Абстракция "записать N байт" протекает.
> Вуаля, все работает на интерфейсах ООП-стайл.
> В юзерспейсе доступны интерфейсы для записи и чтения файлов, опять же ООП-стайл.
ООП-стайл, ООП-стайл, ООП-стайл... идея разделения чего-либо на интерфейс и реализацию возникла ДО появления т.н. ООП. Что ты называешь ООП-стайлом?
> Твою же идею ждет инстант пиздец, стоит только подключить какой-нибудь ССД ил рамдиск или дискетку вместо ЖД, лол.
Дискеты и современная флеш-память тоже читается-пишется кусками в сколько-то байт, лол.

>>48850
> В плюсах ничего принципиально нового не вводится, никаких волшебных механизмов, исключающих говнокод. Классы - всё те же супер-типы на стероидах. Для каждой лексемы найдётся оправдание, каждая нужна для чего-то, иначе её не впилили бы. И это всё, конечно, работает, ты, конечно, можешь думать классами, наследованиями, разграничением прав для членов класса, пояснять за виртуальные функции и считать шаблоны - венцом программистской мысли. Раньше был молоток, пила, рубанок, теперь - молоток с выдвижной пилой и возможностью прикрутить сколько угодно рубанков, причём у всего этого одна ручка (удобно), и теперь ты не можешь пораниться, потому что везде наклейки "ОСТОРОЖНО!".
Ну так вот я и говорю, плюсовые классы это такие недоконтракты, типа "public можно вызывать, а вот private можно только из public". Когда я говорю "а зачем только public-private-protected, почему б не сделать более общий механизм", мне он отвечает "так неположено, неканонично, костыли".
Наследование это просто такой инструмент для борьбы с копипастой, недокодогенерации (намного лучше с этим делом обстоит в лиспе, где код = данные).
Зачем использовать более узкие (вероятно, намеренно суженные) механизмы, и почему более общие методы это что-то плохое.
>> No.48853 Ответ
>>48852
> Достаточно для чего?
Для реализации ООП-подхода. В пределе все есть объект какого-то класса.
> Зачем ты говоришь догмами? Язык программирования и предоставляемые им абстракции это не какие-то незыблемые законы физики, вроде закона сохранения энергии, это просто придуманная людьми хрень, которая при желании может быть улучшена/переделана.
Придумай другой тип доступа, кроме public, protected и private. Не неймспейсики, а именно тип доступа к классу, про который известно только то, что есть еще и другие классы, и что от него можно наследоваться.
> Я через классы не могу создавать сложный набор правил доступа, там только public, protected, private.
Значит, ты не умеешь программировать в ООП. Гугли, как делать интерфейсы.
> Винчестер тебе 1 байт записать не может, там не побайтная адресация (ты б еще попросил его один бит записать, лол). Он прочитает 512 байт (или сколько у него там размер кластера) в буфер, изменит там 1 байт и потом обратно запишет 512 байт. Если ты вот так побайтно будешь писать в некий файл данные по одному байту, это будет нерационально. Лучше пусть это буферизуется, но буферизоваться это может на разных уровнях, и желательно чтобы ФС знала о том, какого размера кластер винчестера, и чтобы ФС была отформатирована соответствующим образом. Абстракция "записать N байт" протекает.
Наоборот, именно абстракция и решает.
Мне плевать, как там внутри все устроено, какой размер кластера и т.д. Я хочу создать файл в 1 байт и сохранить его на диск. Ты будешь лихорадочно искать подходящую функцию, вручную создавать буфер и наполнять его нулями? Это жопорукость. Ты вызовешь метод и передашь файл в 1 байт, а как там внутри реализовано, что он там прочитает и запишет, не важно. Ты дернешь интерфейс записи N байт, а проверки на N < размера кластера должны быть скрыты внутри и как-то там магически решаться, вплоть до буферизаций и дрочки вприсядку.
> идея разделения чего-либо на интерфейс и реализацию возникла ДО появления т.н. ООП.
Интересно, как ты ее реализуешь на голом С. Без указателей на void.
> Дискеты и современная флеш-память тоже читается-пишется кусками в сколько-то байт, лол.
Все пишется кусками минимум в 1 байт, лол.
>> No.48863 Ответ
>>48832

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

> > вот допустим есть public private protected модификаторы доступа
> > наследований может быть 3 вида - тоже public, private, protected...
> > Зачем всё это?
Тебе не за чем. А если бы ты кодил хотя бы вдвоем, то быстро бы понял, что некоторые вещи другой человек видеть, наследовать и тд не должен.

> > Этот код должен быть методом класса для растровой или векторной картинки?
Не, это должно быть что-то третье.
>> No.48915 Ответ
>>48853
> Для реализации ООП-подхода. В пределе все есть объект какого-то класса.
Этот ООП подход не работает в чистом виде. Я уже приводил пример с растровой и векторной картинкой. Если надо сделать код, переводящий вектор в растр, этот код нельзя отнести ни к методу векторной, ни к методу растровой картинки. Это должен быть некий ОБЩИЙ метод для двух структур данных, который имеет доступ к внутренностями (деталям реализации) и того и другого класса (структуры).
> Придумай другой тип доступа, кроме public, protected и private. Не неймспейсики, а именно тип доступа к классу, про который известно только то, что есть еще и другие классы, и что от него можно наследоваться.
Я уже придумал в своем описании, про разделения на слои доступа. Что из слоя 1 можно вызывать код и получать доступ к данным из слоя 1 и слоя 2, из слоя 2 можно вызывать код и получать доступ к данным из слоя 2 и слоя 3 и так далее. Это тебе не подходит?

Или опять таки идея с векторной и растровой картинкой, можно ввести особый модификатор доступа, и если я объявляю с этим модификатором доступа некую функцию, то она имеет доступ к внутренностям и для векторной, и для растровой картинки.
> Значит, ты не умеешь программировать в ООП. Гугли, как делать интерфейсы.
Я умею делать интерфейсы, но к ООП это прямого отношения не имеет. Интерфейсы и до ООП успешно делали.
> Мне плевать, как там внутри все устроено, какой размер кластера и т.д. Я хочу создать файл в 1 байт и сохранить его на диск. Ты будешь лихорадочно искать подходящую функцию, вручную создавать буфер и наполнять его нулями? Это жопорукость.
А где я писал что я буду что-то лихорадочно искать и что-то вручную создавать?
> Интересно, как ты ее реализуешь на голом С. Без указателей на void.
Меня указатели на void не пугают
> Все пишется кусками минимум в 1 байт, лол.
Байты бывают и 7-битными. И вообще, что если я хочу не 1 байт, а всего лишь 1 бит записать, и при этом физический интерфейс флеш-памяти мне позволяет адресовать даже отдельные биты?
>> No.48916 Ответ
>>48863
> Тебе не за чем. А если бы ты кодил хотя бы вдвоем, то быстро бы понял, что некоторые вещи другой человек видеть, наследовать и тд не должен.
Вдвоем я уже кодил, описанных проблем не испытывал. Можно просто договориться об особом нейминге, если это вдруг становится проблемой. Или static функции в отдельном файле.
>> No.48918 Ответ
>>48915
> Если надо сделать код, переводящий вектор в растр, этот код нельзя отнести ни к методу векторной, ни к методу растровой картинки. Это должен быть некий ОБЩИЙ метод для двух структур данных, который имеет доступ к внутренностями (деталям реализации) и того и другого класса (структуры).
Лолнет, ты предлагаешь говнокод. Должен быть либо конструктор, либо статик метод from(), принимающий аргументом объект-исходник. И конечно же архитектурно там будут использоваться только public методв исходника и никаких, упаси боже, деталей реализации.
> Я уже придумал в своем описании, про разделения на слои доступа. Что из слоя 1 можно вызывать код и получать доступ к данным из слоя 1 и слоя 2, из слоя 2 можно вызывать код и получать доступ к данным из слоя 2 и слоя 3 и так далее. Это тебе не подходит?
Звучит странно. Если ты хочешь замутить охуенный N-уровневый контроль привилегий (мсье знает толк), то для этого требуется больше одного класса, это целая подсистема получается.
> Или опять таки идея с векторной и растровой картинкой, можно ввести особый модификатор доступа, и если я объявляю с этим модификатором доступа некую функцию, то она имеет доступ к внутренностям и для векторной, и для растровой картинки.
Bad design. Или даже ugly.
> Я умею делать интерфейсы, но к ООП это прямого отношения не имеет. Интерфейсы и до ООП успешно делали.
Лолнет, интерфейсы - суть ООП. То, что кто-то костылил это раньше доступными средствами... ну так и лямбды частично костылили через функторы.
> А где я писал что я буду что-то лихорадочно искать и что-то вручную создавать?
А куда ты денешься без ООП? В итоге так и будет какая-нибудь срань типа iowrite8, iowrite16, iowrite32.
> Меня указатели на void не пугают
Да можно вообще макросы MAX(a, b) ((a > b) ? a : b) использовать. Почему это небезопасно и не один нежопорукий программист так не делает, интересно.
> Байты бывают и 7-битными. И вообще, что если я хочу не 1 байт, а всего лишь 1 бит записать, и при этом физический интерфейс флеш-памяти мне позволяет адресовать даже отдельные биты?
А еще можно three-state использовать и вообще дрочить вприсядку. Приложению плевать, и все грязные делишки твоей железяки должны быть инкапсулированы внутрь, а снаружи предоставлять только общий, оперирующий общепринятыми вещами (типа 8 битных байтов) интерфейс.
>> No.48919 Ответ
Предлагаю заставить ОПа выучить жабу.
>> No.48925 Ответ
Файл: 1530364206116.png
Png, 0.99 KB, 300×20 - Нажмите на картинку для увеличения
edit Find source with google Find source with iqdb
1530364206116.png
>>48919
Или написать большой и серьезный проект на чистом C. При этом мониторить качество кода и наказывать за косяки.
>> No.48937 Ответ
Может ли быть полноценное ООП без friend классов?
>> No.48940 Ответ
>>48937
Нет, конечно. Ведь пророк наш Алан Кей ничего не говорил про friend-классы.
PS. Ищи не Истину в Идеях, а Инструмент.
>> No.48978 Ответ
Файл: 1528302888273.jpg
Jpg, 293.45 KB, 1500×1954 - Нажмите на картинку для увеличения
edit Find source with google Find source with iqdb
1528302888273.jpg
Чтобы понять ООП надо писать код который его требует.

Вот я например долго не понимал паттерна Factory. Нахуя он нужен? А когда встречал его в чужом коде непонимал как люди такой то код надумывают.

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

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

Я все еще плохо владею абстракциями, но я верю что втянусь по мере работы. Не верю что книги тут сильно помогут, я их много в свое время перечитал и мало что с этого осело в памяти. Я вот сейчас думаю перечитать Clean Code и думаю что взгляну на нее совершенно другими глазами.
>> No.49021 Ответ
>>48978
> Чтобы понять ООП надо писать код который его требует.
Какой именно код его требует? Есть вообще в природе код, который без ООП написать невозможно?
И где конкретно кончается ООП и начинается не-ООП? Если в чистом Си писать функции, которые принимают указатели на структуры и что-то с ними делают, ну там аллоцируют память, меняют какие-то значения полей структур, это уже ООП или еще нет?
Или вот если просто использовать классы, но не использовать наследования и полиморфизмов, это ООП?
>> No.49022 Ответ
>>49021
> > Какой именно код его требует?
Тот, который его требует.
В общем виде эта задача не решается. Но так или иначе иногда удобно использовать ООП. Когда - сердце подскажет.

> > это уже ООП или еще нет?
> > Или вот если просто использовать классы, но не использовать наследования и полиморфизмов, это ООП?
Ты задаешь пустые вопросы уровня курица или яйцо.
Ну допустим ООП.
>> No.49042 Ответ
>>49022
> В общем виде эта задача не решается. Но так или иначе иногда удобно использовать ООП. Когда - сердце подскажет.
У меня сердце (и другие органы) пока ничего подсказать не может т.к. я не совсем понимаю это ООП.
> Ты задаешь пустые вопросы уровня курица или яйцо.
> Ну допустим ООП.
Допустим. Но такой код может написать человек, который вообше ничего про ООП не слышал. Как-то это слишком размыто

Давайте вот лучше наследование подробно разберем. На примере аналитической геометрии на плоскости.
Вот например точка. Точку можно записывать в декартовых координатах (y, x) и в полярных (r-радиус, f-угол). Т.е. если без ООП то можно объявить две структуры, в одной координаты x, y, в другой радиус r, угол f.
Мы хотим иметь функцию, которой передаем две точки, и она возвращает true если точки в одном месте находятся (накладываются друг на друга) и false если нет. Методом какого класса такая функция должна быть?
Ок, допустим мы ходим сделать еще и отрезки, прямые и лучи при этом надо чтоб отрезок можно было задавать двумя точками, при этом одна точка может быть в полярных координатах, другая в декартовых, или обе в декартовых или обе в полярных, а еще прямые и лучи могут задаваться через одну единственную точку (хоть в полярных, хоть в декартовых координатах) и угол, и должны быть функции, которые бы позволяли находить точки пересечения луча с прямой, луча с лучом, прямой с прямой, отрезка с отрезком, независимо от того, каким образом какую прямую мы задали, проверять параллельность, проверять принадлежность какой-то точки какому-то отрезку... А еще можно добавить векторов, и им там проверять коллениарность... Пока остановимся на этом.

Так вот, как это все будет выглядеть в ООП, что из чего унаследуется, методами каких классов будут функции, сравнивающие отрезки/прямые и пр. и возвращающие точку пересечения, проверяющие параллельность?
>> No.49050 Ответ
>>49042
> Так вот, как это все будет выглядеть в ООП, что из чего унаследуется, методами каких классов будут функции, сравнивающие отрезки/прямые и пр. и возвращающие точку пересечения, проверяющие параллельность?
Начнем с начала. Имеются классы "координаты в декартовой системе" и "координаты в полярной системе", плюс в них методы конверсии друг в/из друга.
Иметь одновременно две системы координат и хуячить каждому классу дублирующие методы - слишком криво. Так что берется опорная система координат, и кому надо, юзает функции конверсии классов "координата". Пусть опорной будет декартова, так как полярные - хуета.
Класс точка хранит в себе один объект класса "декартовы координаты". Этот класс также имеет операторы == и !=, внутри одного из них сравниваются координаты этой точки и параметра. Это дает приятный сахар if (pointA != pointB) вместо сишного аутизма !isEqual(pointA, pointB).
Отрезок - еще один класс, имеет внутри два объекта класса "декартовы координаты" - концы отрезка. Прямые и лучи точно также имеют две координаты внутри, плюс для особо извращенных имеют конструкторы не только из двух точек, но и точки и угла - внутри этих конструкторов попросту высчитывается вторая dummy точка исходя из параметра угла.
Так как ты хочешь найти параллельности и прочая, то имеет смысл унаследовать отрезок, прямую и луч от базового класса. Это будет класс с двумя координатами, для каждой координаты булевый флаг "конец", скажем, с методом пересчета угла в dummy-точку, методами проверки на параллельность и т.д. Профит: вместо аутичного сишного копипаста функций ты сразу имеешь универсальные методы проверки на принадлежность точки и прочая.
Для добавления векторов достаточно унаследовать его от класса отрезка (с добавлением какой-нибудь ссылки, указывающей на одну из двух координат как на начальную).
>> No.49059 Ответ
>>49050
> Иметь одновременно две системы координат и хуячить каждому классу дублирующие методы - слишком криво. Так что берется опорная система координат, и кому надо, юзает функции конверсии классов "координата". Пусть опорной будет декартова, так как полярные - хуета.
> Отрезок - еще один класс, имеет внутри два объекта класса "декартовы координаты" - концы отрезка.
Нет, это плохо. Если мы задаем координаты двух точек отрезка в полярных координатах, и нам надо повернуть этот отрезок на угол X относительно начала координат, мы просто этот угол прибавляем или отнимаем (в зависимости от того, по или против часовой) от углов тех двух точек, ну и если угол измеряется в обычных градусах, то если он перевалил за 360 или ушел в минуса, сделать соответствующую коррекцию. Ну и аналогично для других единиц измерения угла (радианы, грады).
Если то же самое мы захотим сделать с отрезком, точки которого заданы в декартовых координатах, работы у нас будет уже значительно больше.
> Класс точка хранит в себе один объект класса "декартовы координаты". Этот класс также имеет операторы == и !=, внутри одного из них сравниваются координаты этой точки и параметра. Это дает приятный сахар if (pointA != pointB) вместо сишного аутизма !isEqual(pointA, pointB).
Да это вообще не важно. К ООП это не имеет никакого отношения. Можно конечно отдельно обсудить проблемы всех этих перегрузок операторов в контексте языка C++, например невозможность для перегруженных операторов менять приоритеты, ассоциативность и коммутативность, невозможность сделать short-circuit evaluation для && и || при их перегрузке, невозможность вводить свои новые операторы. Притом в том же хаскеле можно вводить свои операторы, и задавать им приоритет и ассоциативность https://progra-lang.blogspot.com/2016/02/Operatory-v-yazyke-programmirovaniya-Haskell.html
> Прямые и лучи точно также имеют две координаты внутри, плюс для особо извращенных имеют конструкторы не только из двух точек, но и точки и угла - внутри этих конструкторов попросту высчитывается вторая dummy точка исходя из параметра угла.
> Так как ты хочешь найти параллельности и прочая, то имеет смысл унаследовать отрезок, прямую и луч от базового класса. Это будет класс с двумя координатами, для каждой координаты булевый флаг "конец", скажем, с методом пересчета угла в dummy-точку, методами проверки на параллельность и т.д. Профит: вместо аутичного сишного копипаста функций ты сразу имеешь универсальные методы проверки на принадлежность точки и прочая.
Представь что тебе надо проверить параллельность двух прямых или двух лучей, или прямой и луча. У тебя есть точка и угол. Если угол и там и там одинаков (или одинаков если развернуть на 180 градусов) то эти прямые/лучи или лежат на одной прямой, или параллельны. Осталось только проверить, лежат ли прямые/лучи на одной прямой (накладываются ли).
Если же у тебя прямые и лучи хранят две точки, тебе нужно будет выполнять дополнительную работу по определению угла, что неэффективно.

А еще если у тебя две прямые заданы одной точкой и углом, будет очень легко находить угол в точке пересечения
> Для добавления векторов достаточно унаследовать его от класса отрезка (с добавлением какой-нибудь ссылки, указывающей на одну из двух координат как на начальную).
Может быть проще договориться, что первая точка это всегда начальная, вторая - всегда конечная?
>> No.49063 Ответ
Файл: co.jpg
Jpg, 66.25 KB, 751×499 - Нажмите на картинку для увеличения
edit Find source with google Find source with iqdb
co.jpg
>>49059
> Нет, это плохо. Если мы задаем координаты двух точек отрезка в полярных координатах, и нам надо повернуть этот отрезок на угол X относительно начала координат, мы просто этот угол прибавляем или отнимаем (в зависимости от того, по или против часовой) от углов тех двух точек
Нет, это хорошо. Хоть ты и про повороты ничего не говорил, но это элементарно добавляется одним методом, в котором координаты концов конвертятся в полярные, поворачиваются и конвертятся обратно в декартовы.
А вообще это надо по задаче смотреть, что выгоднее: хранить декартовы или полярные.
> Если то же самое мы захотим сделать с отрезком, точки которого заданы в декартовых координатах, работы у нас будет уже значительно больше.
Лолнет, вся дополнительная работа - конвертация туда и обратно.
> Да это вообще не важно. К ООП это не имеет никакого отношения.
Имеет. Это в сишке есть только тупые структуры без операторов, а в ООП есть классы, которые могут инкапсулировать в себе что угодно и предоставлять API, в том числе и Foo::operator ==. То, что у класса могут быть кастомные операторы, вытекает из парадигмы класса.
> например невозможность для перегруженных операторов менять приоритеты
Да оно и не надо в реальной жизни. Если ты пишешь код сразу с кучей разных операторов в одну строку да еще и с нестандартными приоритетами, то ты пишешь говнокод, и любой поддерживающий его потом программист будет заслуженно проклинать себя самыми нехорошими словами.
> невозможность сделать short-circuit evaluation для && и || при их перегрузке
Чо? (пикрелейтед)
> невозможность вводить свои новые операторы
Нинужно
> Притом в том же хаскеле можно вводить свои операторы, и задавать им приоритет и ассоциативность
Вот поэтому хачкелем кроме полутора отмороженных никто не пользуется. Играются в свои игрушки, а нахрена - непонятно.
> Если же у тебя прямые и лучи хранят две точки, тебе нужно будет выполнять дополнительную работу по определению угла, что неэффективно.
Это несущественно, в каких координатах хранить - определяется по задачам. Если на сотню задач с декартовыми координатами придется одна задача по высчитыванию угла, то и хрен бы с ним. Да и подсчитать угловой коэффициент - раз плюнуть.
> Может быть проще договориться, что первая точка это всегда начальная, вторая - всегда конечная?
Можно и так, но это может быть не удобно при некоторых гуях, например.
>> No.49064 Ответ
>>49063
> Чо? (пикрелейтед)
> (a1 && a2) && (a3 && a4)

Лол, ты продемонстрировал короткозамкнутость bool && bool, а не A && A.

>>48918

> Да можно вообще макросы MAX(a, b) ((a > b) ? a : b) использовать. Почему это небезопасно и не один нежопорукий программист так не делает, интересно.

Oh really?

https://github.com/mpv-player/mpv/blob/7dd69ef77c6aa80067c13f76aa0b78d63fbc4eda/common/common.h#L36
>> No.49065 Ответ
>>48832
> Вот допустим есть public private protected модификаторы доступа т.е. ограничения на то, откуда какой метод можно вызывать. public можно вызывать отовсюду, private только для методов из числа public, а protected ... protected становится private при наследовании, притом наследований может быть 3 вида - тоже public, private, protected... Зачем всё это? Чем это лучше просто кучи функций, которые могут просто вызывать другие функции и работать с какими-то структурами?
>

Модификаторы доступа нужны для удобства. Когда у тебя в проекте будет сотня классов с тысячами переменных и методов ты поймешь
>> No.49067 Ответ
>>49063
> Нет, это хорошо. Хоть ты и про повороты ничего не говорил, но это элементарно добавляется одним методом, в котором координаты концов конвертятся в полярные, поворачиваются и конвертятся обратно в декартовы.
Если я сказал что нужны декартовы и полярные, это значит что нужны декартовы и полярные. Если ты говоришь "нет, полярные ненужны, будем все делать в декартовых. Пусть опорной будет декартова, так как полярные - хуета." то ты провалил задание.
> Лолнет, вся дополнительная работа - конвертация туда и обратно.
Иногда эта дополнительная работа может очень много времени занимать, если надо повернуть кучу точек относительно начала координат.
> Имеет. Это в сишке есть только тупые структуры без операторов, а в ООП есть классы, которые могут инкапсулировать в себе что угодно и предоставлять API, в том числе и Foo::operator ==. То, что у класса могут быть кастомные операторы, вытекает из парадигмы класса.
Причем тут сишка и плюсы вообще? Я говорю об ООП. Если очень хочется поговорить о сишке и плюсах, могу создать новый тред. Вон в хаскеле можно вообще свои новые операторы добавлять и выставлять им приоритеты, где там ООП?
> > невозможность сделать short-circuit evaluation для && и || при их перегрузке
> Чо? (пикрелейтед)
https://stackoverflow.com/questions/25913237/is-there-actually-a-reason-why-overloaded-and-dont-short-circuit
> > невозможность вводить свои новые операторы
> Нинужно
Очень аргументированно. Я так тоже могу, смотри: ООП - нинужно.
> Вот поэтому хачкелем кроме полутора отмороженных никто не пользуется. Играются в свои игрушки, а нахрена - непонятно.
Вообще-то у хаскеля и прочих ФП языков есть своя ниша, в которой они востребованы.
> > Если же у тебя прямые и лучи хранят две точки, тебе нужно будет выполнять дополнительную работу по определению угла, что неэффективно.
> Это несущественно, в каких координатах хранить - определяется по задачам. Если на сотню задач с декартовыми координатами придется одна задача по высчитыванию угла, то и хрен бы с ним. Да и подсчитать угловой коэффициент - раз плюнуть.
Это существенно. Я написал что нужны декартовы и полярные координаты. Я ж не написал "нужны декартовы, а полярные там как-нибудь через декартовы можно сделать, типа инициализировать их как порярные, но хранить как декартовы". А еще кроме полярных и декартовых есть много чего еще, например биполярные, параболические, эллиптические... И определенный способ представления координат может быть выгоден для проведения определенных преобразований над точками, заданными в такой системе координат, так что тупо хранить все в декартовых и потом каждый раз конвертить туда-сюда может быть просто глупо.
>> No.49069 Ответ
>>49064
> Лол, ты продемонстрировал короткозамкнутость bool && bool, а не A && A.
Это ты серьезно сейчас предлагаешь писать говнокодище, где && возвращает не bool?
> Oh really?
Собственно, сразу видно сишный говнокод. За одно только
#define CONTROL_OK 1
#define CONTROL_TRUE 1
#define CONTROL_FALSE 0
#define CONTROL_UNKNOWN -1
#define CONTROL_ERROR -2
#define CONTROL_NA -3
автора надо выебать шваброй. Так даже на сях пишут только джуны.
>> No.49127 Ответ
>>49069
> автора надо выебать шваброй. Так даже на сях пишут только джуны.
А что тебе не так? Энумы хочешь? Скажи это разработчикам Linux ядра
https://elixir.bootlin.com/linux/v4.1/source/include/linux/brcmphy.h
>> No.49142 Ответ
>>49127
Как будто в линухе не полно говнокода.
>> No.49143 Ответ
>>49142
А где его не полно?
>> No.49150 Ответ
>>49143
Везде и нигде, но не важно. Точка. Уже в третий раз точка. Да что такое!
>> No.49155 Ответ
>>49143
В nginx и instead. Мне понравилось читать из коды.
>> No.49156 Ответ
>>49155
> nginx
https://github.com/nginx/nginx/blob/master/src/os/unix/ngx_process.c#L215-L250 что-то не очень. Выразительных средств Си явно недостаточно
>> No.49157 Ответ
>>49156
И что там не так? По моему так очень хорошо (для C, разумеется).
>> No.49159 Ответ
>>49157
> По моему так очень хорошо (для C, разумеется).

В том-то и дело, что в Си это нормально не делается. Ну вот например есть у нас структура
typedef struct
{
int a;
int b;
int c;
int d;
} mystr;

Допустим что у нас
mystr str_val;

str_val.a = 123;

Дальше идет много кода, и потом нам надо доинициализировать элементы структуры таким образом, чтоб `.b = 1, .c = 2, .d = 3`

Ну, в си начиная с C99 есть designated struct initializers, можно сделать так
strval = (mystr){.a = strval.a, .b = 1, .c = 2, .d = 3};
Н тут пришлось переприсвоить `.a = str_val.a` иначе б оно тупо занулилось. Это опять таки недостаток Си. Хотелось бы тупо через запятую перечислять то, что мы хотим ПЕРЕназначить, а не копипастить фигню.
Кстати, в плюсах-то кстати этот самый designated struct initializers только в C++20 сделают (21 год отставания от сишечки, лол) так что и в плюсах это не сделать по-нормальному.
>> No.49160 Ответ
>>49159
А еще тут на доброчане серьезно косячит разметка. Подчеркивания _ срабатывают внутри кусков, обрамленных ` скобками
>> No.49161 Ответ
>>49159
Вообще не вижу никакой проблемы в написании банального
str_val.b = 1;
str_val.c = 2;
str_val.d = 3;

Тот же самый смысл (можно еще в начале для полной ясности написать strval.a = strval.a). Единственная проблема может возникнуть в копипасте когда, где есть вероятность не заменил одно букву и получить баг.
>> No.49162 Ответ
>>49161
> вероятность не заменил одно букву
О хоспаде.
*вероятность не заменить одну бувку
>> No.49163 Ответ
>>49161
> Вообще не вижу никакой проблемы в написании банального
Плохо быть говнокодером. Вначале у тебя инициализируются все поля начальным значением, затем ты по одному начинаешь их переназначать.
В плюсах для этого есть инициализация полей до тела конструктора. В сях, как правильно говорит >>49159б есть списки, но это довольно убогая замена ООП-шным конструкторам, где можно сделать множество вариантов инициализации и инициализировать только то, что надо. Ну и еще в сях есть этот отвратный "выстрели себе в ногу" мемсет.
>> No.49164 Ответ
>>49163
Не вижу говнокода. Да, такой вариант длиннее будет. Да, там есть вероятность забыть изменить значение при копипасте. Более существенных недостатков разглядеть не могу.
>> No.49165 Ответ
>>49163
Не вижу говнокода. Да, такой вариант длиннее будет. Да, там есть вероятность забыть изменить значение при копипасте. Более существенных недостатков разглядеть не могу.
>> No.49166 Ответ
>>49163
Не вижу говнокода. Да, такой вариант длиннее будет. Да, там есть вероятность забыть изменить значение при копипасте. Более существенных недостатков разглядеть не могу.
>> No.49168 Ответ
>>49166
> Да, такой вариант длиннее будет. Да, там есть вероятность забыть изменить значение при копипасте.

В этом и заключается говнокод
>> No.49170 Ответ
>>49168
Для меня говнокод, это когда все настолько запутанно, как наушники в кармане. В создании такой мешанины временами помогают и всякие "короткие, красивые и эффективные" синтаксические конструкции языков.
>> No.49172 Ответ
>>49164
>>49165
>>49166
> Не вижу говнокода. Да, такой вариант длиннее будет.
Я и говорю, плохо быть говнокодером.
А должен бы видеть, что сперва будет инициализация скорее всего нулями (но вообще undefined), а потом инициализация еще раз нужными значениями (на самом деле не инициализация, а присваивание, но так нагляднее).
>> No.49177 Ответ
>>49172
И? В чем проблема?
>> No.49180 Ответ
>>49177
В удвоенном потреблении ресурсов, очевидно.
>> No.49183 Ответ
>>49180
И как в других языках решается эта проблема? В переменной сразу нужные значения находятся? Откуда? Кто их заранее в память закинул?
>> No.49214 Ответ
>>49163
> Вначале у тебя инициализируются все поля начальным значением, затем
Я что-то пропустил? С каких пор сишка стала инициализировать переменные какими либо значениями вообще?
Насколько я помню, даже плюсы этого не делали, для полей классов разве что.
>> No.49217 Ответ
Файл: 1544280718843.png
Png, 0.97 KB, 300×20 - Нажмите на картинку для увеличения
edit Find source with google Find source with iqdb
1544280718843.png
>>49214
Он указал, что
> > (но вообще undefined),
но все равно бред. Нулями инициализирует не C, а ОС (в случае линукса это так). Другой вариант, это ОС выделяет память переменной, а в этой области памяти могу быть какие угодно значения, оставшиеся после выполнения другой программы.
>> No.49221 Ответ
>>49183
> И как в других языках решается эта проблема? В переменной сразу нужные значения находятся? Откуда? Кто их заранее в память закинул?
Constructor, motherfucker, do you write it?
>>49214
>>49217
> Я что-то пропустил? С каких пор сишка стала инициализировать переменные какими либо значениями вообще?
Насколько я помню, даже плюсы этого не делали, для полей классов разве что.
> Другой вариант, это ОС выделяет память переменной, а в этой области памяти могу быть какие угодно значения, оставшиеся после выполнения другой программы.
Джуниоров полон тред. При создании объекта, что в динамике что в статике, память выделяется сразу на весь объект (это в обычном случае, пляски с собственными менеджерами памяти не рассматриваем). И если ты объявляешь какой-нибудь int i, то он уже на стеке и имеет значение, и ты можешь его cout или printf. Но если ты криворук и не проинициализировал сразу, то значение все равно есть, но undefined. В большинстве случаев это будет 0 просто по дефолту ОС и компилятора, но это не гарантировано. Таким образом работает что С, что кресты.
Проверяется легко: возьми
struct A
{
int i;
char j;
double k;
};
std::cout << i << std::endl; // etc.
И то же самое в сях.
>> No.49222 Ответ
>>49221
Я знаю это и написал то же самое.
>> No.49412 Ответ
>>48918
> А еще можно three-state использовать и вообще дрочить вприсядку. Приложению плевать, и все грязные делишки твоей железяки должны быть инкапсулированы внутрь, а снаружи предоставлять только общий, оперирующий общепринятыми вещами (типа 8 битных байтов) интерфейс.
Это работает только если у тебя есть возможность жертвовать производительностью и функциональностью ради унификации. Если у тебя есть разработанный инопланетянами флеш-накопитель с тритами, то если ты будешь костылить поверх тритов обычные биты (ну т.е. вместо 0 1 2 ты наинкаспулируешь использовать трит как бит 0 1) то ты сможешь меньше записать на такой накопитель, не раскроешь весь его потенциал.
>> No.49414 Ответ
Ну и еще немного по ООП вброшу.
Допустим, есть у нас некая компьютерная игра, там есть объект "Костер" и есть у него некое состояние, типа температуры, количества непрогоревшего материала и прочего. Ну и какие-то методы. И нам скажем надо костер уметь тушить. У костра должен быть метод "быть потушенным" и например у нас есть объект "ведро с водой" и мы хотим тушить костер. Надо чтоб костер имел метод для его тушения чем-то?
костер.тушим-его(Ведро-с-водой);
Или у ведра с водой должны быть метод тушения чего-либо?
ведро-с-водой.тушим-им(костер);
Или может и то и другое? Типа будет особая функция "тушить(что, чем)"
тушить(костер, ведро-с-водой);
А членом какого метода будет эта функция? Ну т.е. если мы описываем взаимодействие двух неких объектов, обладающих некими характерными особенности(горящий может быть чем-то потушен, а тушащий предмет может что-то тушить), каким вообще образом это должно быть огранизовано? Гореть может не только костер, но и например мебель какая-то, и у мебели, если она горит, будет такое вот свойство, что его можно будет тушить. У мебели (в т.ч. горящей!) могут быть еще свойства/методы, для костра совершенно нехарактерные, типа "сесть на стул", можно еще придумать что на горящий стул вы можете сесть только если у вас огнеупорность и так далее... как это решается в рамках ООП?
>> No.49415 Ответ
>>49414
Кто инициализирует действие? Костер или ведро? Человек, все это использующий! Объекты должны представлять какую-то идею и ничего кроме. Костер не должен знать, что его может потушить ведро, дождик, отсутсвие воздуха - костер может потухнуть. Так и ведро, не важно, кому на голову ты его выльешь, важны только состояния, которые могут измениться при использовании ведра.
Иначе, если тебе где-нибудь захочется переиспользовать это ведро, оно обязательно должно будет уметь тушить костры.
>> No.49416 Ответ
Тогда и я поспрашиваю.
Когда стоит использовать наследовние? Я прочитал много различных статей и ответов о том, когда наследование использовать не надо: SOLID принципы, квадраты, бла, прямоугольники, бла-бла. Но ничего лучше гайдлайна "is a"/"has a" для разделения композиций и наследования не было.
Допустим у меня есть класс сокет. Я хочу его разделить на блокирующие и нет подклассы. Мне для этого можно сделать одно приватное поле, определяющее данное свойство сокета с соответсвующими ему геттером и сеттером, а можно от одного абстрактного сокета, задавшего реализацию, унаследоваться два раза и получить блокирующую и нет реализации. Еще одним вариантом можно принять за стандартный класс блокирующий сокет, а от него уже один раз унаследоваться и получить неблокирующий.
Где эта граница, отделяющая каждый из трех подходов?
Также отсутствие интерфейсов в С++ неблагоприятно влияет на изменения к "public-интерфейсной" части наследования - новые открытые поля через абстрактный-класс-почти-интерфейс я вызывать не смогу. Поэтому и смысла в наследовании глубже чем на один уровень от абстрактного класса я не вижу. Но ведь он есть?
>> No.49417 Ответ
>>49415
> Кто инициализирует действие? Костер или ведро? Человек, все это использующий!
И? У костра должен быть метод "потушиться"? Или где этот метод должен быть? У человека? Объект костра вообще должен знать, что его можно тушить?
Класс (объект) в тех же плюсах это структура, к которой приделали некие функции, которые что-то осмысленное делают с состоянием этой структуры внутри класса. Т.е. все построено так, что якобы этот класс это некая сущность, которую мы просим что-то сделать с собой или с чем-то еще, и она что-то делает. По-моему это ерунда какая-то. Вместо того чтобы описывать некие свойства, взаимосвязь разных "штук", мы описываем то, что именно какая-то "штука" умеет делать.
По-моему надо рассматривать свойства объектов. Вот есть ведро с водой - у него есть такое свойство, что им можно что-то тушить. А вот есть горящий костер - у него есть свойство, что его можно чем-то потушить. Ну и пусть будет человек, у которого есть такое свойство, что он может использовать всякие предметы, в т.ч. и ведро с водой для тушения чего-либо. Никаких т.н. методов в привычном виде тут нет. Можно хранить некие свойства предмета в каком-нибудь списке или хэш-таблице, и когда мы в игре применяем ведро с водой на костер (т.е. просто перетаскиваем мышкой например) то в коде игры происходит следующее - мы смотрим на ведро, какие у него свойства - им можно тушить. А какие свойства у костра - его можно тушить. И где-то в коде игры описано, что вещи, которыми можно тушить - их можно применять на вещи, которые можно тушить. Отлично - мы пишем игроку "хотите ли вы использовать ведро с водой для тушения костра?". И если у ведра будет еще какой-то способ провзаимодействовать с костром, то можно вывести соответствующее меню с выдобром. Т.е. не нужны никому никакие методы, надо просто прицепить некие свойства к некоторым сущностям и потом сверять эти свойства на сочетаемость. Искать совместимые свойства. Как вот у ключа есть свойство, что он открывает конкретный замок, а у замка есть свойство что его можно открыть каким-то конкретным ключом.
>> No.49418 Ответ
>>49417
> Вместо того чтобы описывать некие свойства, взаимосвязь разных "штук", мы описываем то, что именно какая-то "штука" умеет делать.
Вот тут и проблема. В основе ООП лежат не взаимодействия предметов, а сами предметы. И все методы этих объектов направлены на работу только с самим собой (какие эгоистичные). Иначе нарушается инкапсуляция, иначе эти объекты не могут существовать друг без друга. Еще раз, каждый объект должен быть маленьким закрытым мирком, к которому тебе можно обращаться только через публичные методы или интерфейсы.
> По-моему надо рассматривать свойства объектов
Изначально речь шла о методах. Со свойствами же целая поляна открыта: можно попытаться узнать класс объекта в рантайме, а для этого есть различные решения, можно добавить базовому классу методы, проверящие тушибельность каждого из объектов, предоставляя соответствующий интерфейс, правда тогда не получиться добавлять новые свойства, да и старых будет огромное количество.
Решений есть много, я хорошо не знаю ни одного, постораюсь за парочку ночей разобраться хотя бы в нескольких.
>> No.49419 Ответ
Файл: 28880.jpg
Jpg, 288.94 KB, 800×406 - Нажмите на картинку для увеличения
edit Find source with google Find source with iqdb
28880.jpg
Пока вы разбирались в ООП, он уже признан нимодным и всё ровные пасаны начинают его обоссывать и доказывать, что нинужен.
>> No.49420 Ответ
>>49417
В целом можно выделить новый класс "Поливание" с методом, принимающим в себя объекты класса костер и ведро. В результате оба этих класса будут не связаны, и при желании метод можно будет перегружать и поливать землю, небеса, Аллаха.
Правда с этим главное не переборщить:
http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html
Также на размышление тред, половина которого посвящена обсуждению подобного "Игрок-Ударить-Монстр" вопроса, саму статью также можно прочитать:
https://news.ycombinator.com/item?id=18526490
>> No.49421 Ответ
>>49419
Функциональщина?
>> No.49434 Ответ
>>49419
Как раз таки ООП никто не признал ненужным. Единственная реализация ООП в продакшене - Erlang, а все эти ваши C++ и Java не являются реализацией ООП, специально для адептов "классы-ооп головного мозга" процитирую Алана Кэя:

> I invented the term object-oriented, and I can tell you, that C++ wasn't what I had in mind
> OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late binding of all things.

Разумеется, эксперты из треда начнут заочно спорить с автором ООП парадигмы и доказывать почему он не тру и в ООП ничего не понимает.
>> No.49439 Ответ
>>49434
> с автором ООП парадигмы
Симулу писал не Кей.
>> No.49440 Ответ
>>49434
Он молодец конечно, но настоящее ООП оказалось бесполезным и никому не нужным. Тогда как его "модификации" (я без понятия, каким ООП был изначально) широко используются везде, ведь они позволяют писать сложное и расширяемое ПО. Тот же самый пример с регулярными выражениями: большинство современных языков подобавляли в них различные способы хранения памяти, различные предпросмотры и подобное. И сейчас регулярные выражения могут описывать различные рекурсивные строки, а это далеко за гранью обычных регулярных языков. Только HTML не надо ими парсить, да.
>> No.49441 Ответ
>>49440
> я без понятия, каким ООП был изначально
Эрланго-образный обмен сообщениями это был.
> но настоящее ООП оказалось бесполезным и никому не нужным
Один только сраный WhatsApp на нём и работает, ага.
>> No.49443 Ответ
>>49441
> Эрланго-образный обмен сообщениями это был.
Нет, не был: https://habr.com/ru/post/455638/
Изобрести мем «объектно-ориентированный» ≠ изобрести объекты.
>> No.49522 Ответ
Файл: afwXT.jpg
Jpg, 350.83 KB, 1131×707 - Нажмите на картинку для увеличения
edit Find source with google Find source with iqdb
afwXT.jpg
>>49418
> Вот тут и проблема. В основе ООП лежат не взаимодействия предметов, а сами предметы. И все методы этих объектов направлены на работу только с самим собой (какие эгоистичные). Иначе нарушается инкапсуляция, иначе эти объекты не могут существовать друг без друга. Еще раз, каждый объект должен быть маленьким закрытым мирком, к которому тебе можно обращаться только через публичные методы или интерфейсы.
А зачем так надо делать? Откуда эти постулаты взялись? Почему именно так, а не иначе?
Мне порой кажется, что сторонники ООП это как нейросеть, которая везде псов распознает: какую задачу ООПшнику не дай - он там увидит что это хорошо ложится на ООП парадигму, и что вот так вот можно это реализовать, вот та фигня - базовый класс, вот так будет эта фигня наследоваться от той фигни... но если посмотреть на проблему незашоренным взглядом (с головой, не забитой всем этим теоретическим бредом, паттернами от банды четырех и прочей такой хренью) то нет там ничего особо связанного с ООП, и ООП по-сути вообще не нужно. Любую задачу можно решать через ООП, или через ФП, или в процедурном или вообще хрензнает каком стиле. ООП похоже на какие-то костыли для мышления, что якобы есть некие объекты, что они что-то могут с собой(и только с собой) делать и что они могут как-то наследоваться т.е. на основе одних объектов можно сделать новые, добавив всяких полей и методов. Почему именно так надо, почему не сделать какие-то другие штуки (назовем эту парадигму штуко-ориентированное программирование или ШОП) в которых мы описываем, что вот какая-то штука может под воздействием другой штуки становиться третьей штукой. Например, есть у нас штука "ведро с водой" и есть штука "горячий костер". Мы где-то описываем, что можно штуку "что-то-чем-можно-тушить" применять на штуку "что-то-что-горит" и получается в итоге штука "что-то-негорящее". Ну по-сути это можно реализовать как функцию, которая принимает два аргумента, что тушим и чем тушим, и возвращает потушенное что-то. Ну и если в эту функцию передать костер и ведро с водой, она вернет потушенный костер. Ну и еще она может вернуть пустое ведро без воды. Никаких объектов с жестко привязанными к ним методами нет, да они и не нужны
>> No.49524 Ответ
>>49522
А вот чем абстрактные типы того же Хаскеля отличаются от ООП принципиально?
>> No.49525 Ответ
Файл: 1568146639231.jpg
Jpg, 42.03 KB, 218×300 - Нажмите на картинку для увеличения
edit Find source with google Find source with iqdb
1568146639231.jpg
>>49524
Я не очень понимаю, как ты хочешь сравнивать ADT с ООП, но в целом система типов в Хаскеле работает совершенно иначе по сравнению с популярными сейчас ООП языками: C#, Java. В плюсах есть классы, но нет ООП.
В основе ADT лежит параметрический полиморфизм, в основе ООП лежит подтиповый полиморфизм.
Параметрический получил свое название из-за схожести передачи параметров в функцию, только вместо функций у нас конструкторы типа. В шарпах и джаве подобное есть, но обрезан их функционал до нуля: больше параметризованных листов ничего сделать не получится, в плюсах ситуация лучше, но, чтобы начать понимать шаблоны, надо быть магом и убить годы жизни на изучение уродливого синтаксиса.

К примеру, ты можешь создать такой свой уютненький полиморфный тип в Хаскеле:
`data Bla f1 f2 a b c = Bla (f1 a) (f2 c b)`
Первый Bla - конструктор типа, второй - конструктор самого значения, они живут в разных пространствах имен и друг с другом не ругаются
Если мы посмотрим на его сигнатуру (kind)..
`Bla :: ( -> ) -> ( -> -> ) -> -> -> -> *`
То будет видно, что для создания элемента данного типа нам необходимы 2 полиморфных типа и 3 обычных. Это одна строка кода, компилятор определил тип сам, и получить такое в ООП языках не получится.

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

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

Не очень хороший пример, но все что надо в нем понять, что две функции высшего порядка fmap тут различны и перегружены для двух совершенно различных типов: Maybe и List.

`mxs :: Maybe [Int]`
`f :: Int -> Int`
`mys = (fmap . fmap) f mxs`

Еще построено это все по совершенно другим принципам - по теории категорий, но это так явно и быстро не показать.
>> No.49526 Ответ
>>49525
Все сломалось, все сломалось. Я ничего не вижу.
>> No.49527 Ответ
>>49525
> В основе ADT лежит параметрический полиморфизм, в основе ООП лежит подтиповый полиморфизм.
Оба утверждения спорны. Во-первых параметрический полиморфизм в ООП сегодня применяют чаще чем подтиповый, который якобы более "лежит в основе". Во-вторых в Хаскеле классы типов по сути -- это подтиповый полиморфизм.
> больше параметризованных листов ничего сделать не получится
Почему? Прикручиваешь дженерики и обычные параметры, куда взбредёт в голову.
> получить такое в ООП языках не получится
Ну делаешь 2 класса. А потом третий, у которого объекты первых двух и ещё поле в полях. Ну да, в Хаскеле система типов круче, но всё равно не так это принципиально.

Всё как бы круче и гибче, но всё то же самое. Если я создам модуль, а в него помещу типы и определю на них несколько функций, то на выходе это будет тупо класс. На каких-то высосанный из пальца примерах это выглядит иначе, но когда я в голове пытаюсь обуть типичный CRUD с квитанциями и сметами, то выходит такое же точно ООП. Big picture, архитектура в общем и целом, вот что не отличается. Я не вижу, где сам подход другой.
>> No.49528 Ответ
>>49527
> Во-первых параметрический полиморфизм в ООП сегодня применяют чаще чем подтиповый, который якобы более "лежит в основе"
Наследование - основа ООП, а из наследования следует подтиповый полиморфизм. Параметрический не имеет ничего общего с этими концепциями. И пришел он в ООП из функционального программирования.

> Во-вторых в Хаскеле классы типов по сути -- это подтиповый полиморфизм.
Классы в Хаскеле реализуют ad-hoc полиморфизм, он не требует никакой структруры, тогда как подтиповый даже своим именем подразумевает общего наследника. Ничего общего между ними нет.

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

> выходе это будет тупо класс
> Я не вижу, где сам подход другой.
Функциональное программирование не заканчивается системой типов. Чистые функции, монады, отсутствие состояния, отсутствие указателей, отсутствие null'a, высокоуровневые функции, отстутсвие while и for циклов и другие производные от этих идей. С такими высокоуровневыми концепциями подход к написанию того же CRUD'a просто не может не измениться. Другое дело ты можешь после перехода продолжать пытаться написать код в своей уютной парадигме и фрустрировать, что ничего нормально не получается.
>> No.49529 Ответ
>>49528
> Наследование - основа ООП
Основа, ни основа -- пофигу. На практике от него часто отказываются в пользу композиции.
> подтиповый даже своим именем подразумевает общего наследника
Класс типов подразумевает общий класс у типов у Хаскеля. Ну и что?
> Сопоставлять паттерны дженериков у тебя не получится.
Я могу в разные классы воткнуть разные реализации метода интерфейса. Будет работать почти так же.
> написанный с ними код выглядит нечитабельно.
Примерно так же выглядят типы с параметрами в Хаскеле. Это почти те же дженерики.
> Чистые функции, монады, отсутствие состояния, отсутствие указателей, отсутствие null'a, высокоуровневые функции, отстутсвие while и for циклов и другие производные от этих идей
Всё это конструкции нижнего уровня архитектуры программы. Мелочи. А вот как программа будет дробиться на большие куски? Так же. Или это будет куча разрозненных функций, которые не объединены ни в какие модули?
>> No.49530 Ответ
>>49529
> подтиповый, который якобы более "лежит в основе"
> Основа, ни основа -- пофигу
Ну-ну. Чаще чем в ООП наследование нигде больше не используется.

> Класс типов подразумевает общий класс у типов у Хаскеля. Ну и что?
Никто ничего не подразумевает. Еще раз, в Хаскеле нет типов как таковых. Если ты желаешь, в Хаскеле есть разнородные интерфейсы, которые твой тип может реализовать. При этом реализованы они могут быть когда угодно.

> Примерно так же выглядят типы с параметрами в Хаскеле. Это почти те же дженерики.
Из головы..
data Either a b = Left a | Right b
data Maybe a = Just a | Nothing

f :: (Num a) => Either [a] (a, a) -> Maybe a
f (Right (x, y)) = Just (x + y)
f (Left (x:y:_)) = Just (x + y)
f _ = Nothing
Осталось тебе реализовать подобное своими дженериками, а потом можно будет и сравнить "почти же"-сть.

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


Пароль:

[ /b/ /u/ /rf/ /dt/ /vg/ /r/ /cr/ /lor/ /mu/ /oe/ /s/ /w/ /hr/ ] [ /a/ /ma/ /sw/ /hau/ /azu/ ] [ /tv/ /cp/ /gf/ /bo/ /di/ /vn/ /ve/ /wh/ /fur/ /to/ /bg/ /wn/ /slow/ /mad/ ] [ /d/ /news/ ] [ Главная | Настройки | Закладки | Плеер ]