LINUX.ORG.RU

ООП. Как представляете себе идеальную реализацию?

 , ,


2

3

Я знаю как минимум 4 слабо совместимых друг с другом понятия ООП:

  • С++: класс = неймспейc, вызов метода через точку,
  • CLOS: класс = идентификатор + наследование, тело метода определяется по классу всех параметров (а не только первого), методы доопределяются модификаторами :after :before :around.
  • Racket: класс = first-class object, как и функция, соответственно, может доопределяться по месту и не иметь имени.
  • Haskell: классы типов как наборы операций над типам (которые можно считать эквивалентными классам других языков)

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

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

Только потому, что твой собеседник некомпетентен в Java

Потому что я не помню в Java функции «сделать класс с именем ... и методом ..., который делает ...».

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

Называется UML

Как в UML нарисовать defgeneric? Как в нём же указать, что добавляется модификатор :around?

Или как описать Haskell'овские typeclass'ы?

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

Лол, кто сообщение анонимуса с безобидной шуткой удалил? В модерах появился лиспер? Посмотри, что за ник у него, посмеемся.

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

Как в UML нарисовать defgeneric?

Это еще что... Вот как в UML нарисовать кастомный комбинатор методов, вот это интересно узнать.

no-such-file ★★★★★
()
Ответ на: комментарий от monk

Потому что я не помню в Java функции «сделать класс с именем ... и методом ..., который делает ...».

Ничего, я напомню.

И да, разумеется, если тебе существенно необходимо создавать классы в рантайме — то у тебя проблемы с архитектурой. Естественное предназначение подобных механизмов — онлайн-инструментация кода.

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

Как в UML нарисовать defgeneric? Как в нём же указать, что добавляется модификатор :around? Или как описать Haskell'овские typeclass'ы?

Но ведь UML — промышленный инструмент проектирования, рассчитанный, что очевидно, на промышленные инструменты разработки.

LISP, Haskell, SmallTalk, BrainFuck и т.п. к таковым не относятся. Что не так?

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

Но ведь уже существует инструмент для «описания архитектуры программы до начала программирования». Называется UML.

Как в UML нарисовать defgeneric? Как в нём же указать, что добавляется модификатор :around?

А defgeneric и :around - это часть архитектуры?

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

Ничего, я напомню

А может сразу в байт-коде писать? Такие хаки как-то далеки от понятия first-class entity.

если тебе существенно необходимо создавать классы в рантайме — то у тебя проблемы с архитектурой

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

no-such-file ★★★★★
()
Ответ на: комментарий от anonymous

А сорри, не та тема, вопрос снимается.

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

Одно хорошо, он в основном сублимирует в толксах, а сюда захаживает редко.

anonymous
()
Ответ на: комментарий от no-such-file

А может сразу в байт-коде писать?

Зачем? Для определения класса в рантайме этого не требуется.

Такие хаки как-то далеки от понятия first-class entity.

Для тебя это — «хаки» и «далеки от понятия», потому что ты некомпетентен в Java.

Если ты не понимаешь для чего это нужно - то у тебя проблемы с кругозором.

Так объясни же, для чего это нужно, о великий гуру.

Кстати лямбды тоже не нужны, ведь в java их нет.

Но ведь это ложь. Ты не только некомпетентен в Java, ты ещё и лжец. Зачем же ты вступаешь в дискуссию? Надеешься, что тебя не раскусят? Так не надейся. Уже раскусили.

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

Для тебя это — «хаки» и «далеки от понятия», потому что ты некомпетентен в Java.

Ладно, компетентный анон, запили мне пример определения класса через ClassLoader, и чтоб там было 5 полей, 3 метода и вложенный анонимный класс с 3 полями и 2 методами.

Так объясни же, для чего это нужно, о великий гуру.

Тебе, шавка безымянная, все равно не понять.

Но ведь это ложь. Ты не только некомпетентен в Java, ты ещё и лжец

Нет ты.

no-such-file ★★★★★
()

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

Хз насколько эквивалентно:

Moreover, Haskell type classes support inheritance. Run-time polymorphism together with inheritance are often seen as OOP distinctive points, so during long time I considered type classes as a form of OOP implementation. But that's wrong! Haskell type classes build on a different basis, so they are like C++ templates with added inheritance and run-time polymorphism! And this means that the usage of type classes is different from using classes, with its own strong and weak points.

anonymous
()
Ответ на: комментарий от no-such-file

Ладно, компетентный анон, запили мне пример определения класса через ClassLoader, и чтоб там было 5 полей, 3 метода и вложенный анонимный класс с 3 полями и 2 методами.

Запилил. Как платить удобнее?

Тебе, шавка безымянная, все равно не понять.

Т.е. объяснить не можешь, и поэтому переходишь на оскорбления. Слив засчитан.

Нет ты.

Но ведь ты подтвердил некомпетентность в Java и был пойман на лжи. Так почему это я — лжец?

anonymous
()

идеальную реализацию?
Я знаю как минимум 4 слабо совместимых друг с другом понятия ООП:

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

anonymous
()

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

Сразу эксперта в Haskell видно.

В Haskell, вообще-то, «Не нужно» подход к ООП.

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

Тут ещё фишка в том, что каждый второй маргиналий норовит назвать своё поделие «ООП». При этом понятия «объектов» понимаются абсолютно по-разному, а классов и наследования может вообще не быть. Например, Smalltalk гордо называет свой message passing «объектно-ориентированным подходом». Лисперы со своим CLOS — тоже. Хотя ни первое, ни второе не имеют отношения к тому, что нормальные люди привыкли считать ООП (инкапсуляция-наследование-полиморфизм).

Похоже, маргинальщики услышав «модный» термин и, улюлюкая «мы — тоже ООП!!!111», неуклюже попытались запрыгнуть на поезд прогресса. Но не фартануло.

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

В Haskell, вообще-то, «Не нужно» подход к ООП.

При этом адепты Хацкеля, совершенно не стесняясь, впаривают нам следующее:

The advantages of using Haskell include: increased productivity, access to higher level of abstraction for better code reuse, reliability, and high performance on multicore processors.

Хотелось бы знать, за счёт чего достигается вышеперечисленное, а в особенности «higher level of abstraction for better code reuse». Это уж не зигохистоморфные ли препроморфизмы имеются в виду?

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

higher level of abstraction for better code reuse

Очевидно же: фвп, заворачивание в трансформеры, неприбитые к объекту «методы» (простое ограничение на тип все же зачастую гибче). А ооп не нужно, да.

зигохистоморфные ли препроморфизмы

все еще немного забавно, но уже не свежо

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

Параметрический полиморфизм и ленивость, в основном.

Докажи, что это способствует «increased productivity, access to higher level of abstraction for better code reuse».

Hint 1: например, приведи пример проекта на Haskell, по сложности эквивалентного Apache, или Octave, или OpenOffice, или Firefox, который бы при этом был создан меньшей командой, за меньшее время и был бы качественнее/функциональнее своего аналога на mainstream-языке.

Hint 2: XMonad таковым проектом не является.

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

Очевидно же: фвп, заворачивание в трансформеры, неприбитые к объекту «методы»

См. сообщение выше. Докажи, что это существенно повышает продуктивность разработки.

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

люди привыкли считать ООП (инкапсуляция-наследование-полиморфизм)

Вы так говорите, будто это адекватнее взгляда маргинальщиков. Инкапсуляция за счет пространств имен / модулей / etc - это опп? Полиморфизм (параметрический) средствами языка - тоже ооп? Наследование как хаскеле, больше похожее на compile-time диспетчеризацию, в рантайме классов (не считаем внестандартные расширения) уже нет - разве ооп?

Ну и «ООП» как термин недостаточно четкий.

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

Apache, или Octave, или OpenOffice, или Firefox

(полу)Естественные комбайны, которые успели много чем обрасти. А так веб-фреймворки есть: happstack, snap, yesod.. даже cas (был?) - docon.

А почему бы не оттолкнуться от хаскеле-поделок, разумеется, придется уменьшить масштаб:

назови «пример проекта на mainstream-языке, по сложности эквивалентного pandoc / gitit» и дальше по тексту (ну раз отрицение, строгие условия нужно заменить на нестрогие, но не принципиально).

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

Так объясни же, для чего это нужно, о великий гуру.

Простейший пример из Racket я приводил. Есть класc window.Есть пара десятков преобразователей decorared, top-level, 3-button, и т.д., которые к этому окну добавляют всякие кнопки/декораторы/поведение/... .

Если мне надо в Racket сделать окно с нужными предбразованиями я просто создаю экземпляр класса, например (decorated (top-level (3-button window%))). В java, насколько я знаю, приходится писать 2^20 классов с именами типа decoratedWindow, decoratedToplevelWindow, ... Если хак с байтлоадером позволяет этого избежать, то покажи как.

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

Straw man, извини. Попробуй еще раз.

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

А реюзабельность Хаскельного кода хорошо видна в гранулярности библиотек, можешь взглянуть на количество зависимостей у yesod или хотя бы lens.

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

конструктивнее было бы «реализация наследования»

Так речь как раз не столько про наследование, сколько про разбивку на классы объектов и операции над ними. В Haskell эти классы объектов будут типами. В JS — всё что создано от одного прототипа. Операции в C++ будут методами классов, в Haskell — методами инстанцов тайпклассов, в CLOS — generic'ами и т.д.

UML как раз и плох, что на нём можно выразить только Java/C++ ооп. Потому что упаковка методов внутрь классов уже сильно ограничивают гибкость решения.

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

Можно ссылку хотя бы на один движок на Java для Web, в котором можно писать наподобие

ну на Eclipse RWT/RAP примерно так можно.

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

UML как раз и плох, что на нём можно выразить только Java/C++ ооп.

В контексте UML можно рассматривать дженерик как отдельный класс, который содержит методы + интерфейс для их вызова.

no-such-file ★★★★★
()
Ответ на: комментарий от monk

в яве - навскидку соорудить фабрику своих окошек, передавать нужные варианты комбинацией флагов в конструкторе а-ля SWT (всяческие new Button(parent, SWT.ARROW | SWT.UP). Писанины больше, да.

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

количество зависимостей у yesod

A разве там много, там же отдельные модули? lens - специфичный, тут действительно в тему «препроморфизм». Еще pandoc и yi смотрятся солидно.

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

Так речь как раз не столько про наследование, сколько про разбивку на классы объектов и операции над ними.

Тогда «средства структурирования типов (+иерархия)». Ибо все равно определения класса у вас не видно, а для каждого языка подгоняете свое. Возникает вопрос, если в данном контексте «класс» - столь плавающее понятие, нафига от него отталкиваться?

Haskell эти классы объектов будут _типами_.

Хм, лучше что-нибудь вроде «ограничение на тип» / «идентификатор подмножества типов» (все же это другой абстракции).

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

соорудить фабрику своих окошек

А что фабрика будет возвращать? У каждой комбинации флагов будет своя функция Render в объекте. Реально варианта 2: или это на самом деле один класс, а всё поведение запихано в одну большую функцию. Или в зависимости от флажков выбирается один из 2^20 (по количеству флагов) классов и возвращается. Второй вариант явно ужасен при количетве флагов больше трёх, первый заставляет лезть внутрь класса, если пользователь библиотеки придумал свой декоратор и хочет его добавить.

monk ★★★★★
() автор топика
Ответ на: комментарий от no-such-file

В контексте UML можно рассматривать дженерик как отдельный класс,

То есть любая структура CLOS будет выглядеть как отдельное дерево без методов и россыпь дженериков-объектов. Очень «наглядно»...

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

Средства структурирования типов и операций.

Слово «типов» не хочу использовать, потому что в Lisp'ах, например, под типом подразумевается произвольное множество объектов. А меня интересуют только те множества объектов, которые являются доменом для каких-либо операций. То есть классы (множества объекто) и методы (операции над ними). Иерархия классов == уточнение операций на подмножестве объектов.

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

А что фабрика будет возвращать?

зависит от буйности фантазии писателя. Самый имхо простой - да, написать сразу все и в зависимости от флагов задействовать/не задействовать. Можно держать в классе массивы требуемых свойств и добавлять втуда реализацию необходимых интерфейсов снаружи по мере надобности; рендерить все, что есть в массивах. Можно поизвращаться со всякими DynamicProxy. Можно заняться рукоблудием с генерацией класса в рантайме. Про удобство всего этого хозяйства по сравнению с тем же ракетом умолчу) Но - можно.

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

В принципе аналог с выносом декорации в отдельный класс есть

Что-то типа

class Decorated: Window
{
   Button parent;
   Decorated(Window parent) {
      // здесь копируем все поля
   }
   void Render() { 
      parent.Render();
      makeDecoration();
   }      
}

и использовать как-то так:

  Window myWindow = new Decorated(new TopLevel(new Window()));

Если не считать кучи мусора на каждый декорированный объект и невозможности дать имя класса декорированному набору, то жить можно.

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

..произвольное множество объектов. А меня интересуют только те множества объектов,..

И в чем серьезная проблема, множество станет домен после того, как будет каким-то образом «встроено» в структуру типов (обявлена принадлежность к классу). Все же разнобоя в понятии «тип», как более базовом, мешьше чем в «класс», не-а?

Иерархия классов == _уточнение_ операций на подмножестве объектов

А вот не обязательно, где в том же хаскеле «перегрузка»? Здесь только для декларации «вложенности множеств»: в instance для определения операций класса, можно будет пользоваться операциями надкласса.

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

структура CLOS будет выглядеть как отдельное дерево без методов и россыпь дженериков-объектов

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

no-such-file ★★★★★
()
Ответ на: комментарий от monk

сколько видел явовских гуев, так не особо принято. Или «наследуйся от нужного и меняй», или чего-то вроде такого

public class FooWindow {
    private Decoration decor;
    ...
    public FooWindow(){
    ...
        this.decor=new SomeDefaultDecor();
    }

    public void setDecoration (Decoration newDecor) {
        this.decor=newDecor;
    }

    public void render(){
    ...
        decor.render();
    }
}
...
public interface Decoration {
    public void render();
}
....
FooWindow myWindow = new FooWindow();
myWindow.setDecoration(new Decoration(){
   public void render(){
        //рисуем чонить свое
}
...

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

где в том же хаскеле «перегрузка»

А разве там нельзя сделать что-то типа

newtype Age = Age Int { unAge :: Int }

instance Eq Age Where
  x == y = (unAge x < 100 && unage y < 100 && unAge x == unAge y)

?

Получили «перегрузку» операции == на подтипе.

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

Получили «перегрузку» операции == на подтипе

Во-первых что такое «подтип»?) Здесь объявление, что тип Age ∈ Eq , но Eq-то не тип и до этого не было определенной (==), откуда тогда «перегрузка»?

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

так не особо принято

Ну так в Java и комбинаторы использовать не принято. Хотя в таком стиле даже красивее будет и без мусора в полях.

Decoration decorate(Decoration parent)
  return new Decoration() {
     public void render() {
        ....
        parent.render();
     }
  }
}

FooWindow myWindow = new FooWindow()
myWindow.setDecoration = decorate(toplevel(threeButtons(new DefaultDecoration())));
monk ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Так любой тип в Haskell будет новый. Или там есть возможность описывать подтипы? Например «целые числа в диапазоне 0..100».

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

Так любой тип в Haskell будет новый.

И что, поэтому есть _уточнение_? Если проводить аналогию - то все методы _виртуальны_ (даже если вспомнить default, то «уточнением» это назвать не получится).

Или там есть возможность описывать подтипы?

Не понимаю, что такое «подтип» в контексте хаскеля. Здесь «классы» и «типы» не смешаны, а иерархия (вертикальная) определена на уровне первого.

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

Не понимаю, что такое «подтип» в контексте хаскеля.

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

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

Вот и я не понимаю.

Само-то понятие «подтип в хаскеле» откуда?

Если мне потребуется сделать тип Многоугольники, а потом тип Треугольники

Понятно, ну здесь default-метод можно: но смысловая-то нагрузка «если в instance ф-ия не определена, то будет использоваться default ф-ия из определения класса», можно с натяжкой назвать «уточнением», но звучит неидиоматично (само «default» намекает).

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