
Alexander
02.09.2017
09:15:25
м?

Abbath
02.09.2017
09:15:54

Anton
02.09.2017
09:16:17

Aleksey
02.09.2017
09:16:47
Можно просто не наследоваться :) Только копмозить

Google

Alexander
02.09.2017
09:17:27
тогда это уже не классическое ООП
про которое обычно говорят апологеты этого стиля
и прекрасно выражается в не-ООП языках

Aleksey
02.09.2017
09:18:09
Только преподы ООП, разве что
Практики знают, что композиция лучше наследования!

Alexander
02.09.2017
09:19:08
я видел интырпрайз явакод

Aleksey
02.09.2017
09:19:09
Все книжки про паттерны об этом говорят

Alexander
02.09.2017
09:19:30
при этом 3/4 паттернов полагаются на наследование?

Aleksey
02.09.2017
09:20:02
Нет, композиции хватает

Anton
02.09.2017
09:22:42
Ну вот типы-суммы и типы-произведения — очень простые вещи, которые можно комбинировать как угодно. Интерфейсы/трейты тоже — их можно как при статической, так и при динамической диспетчеризации использовать. А наследование включает в себя слишком много всего сразу, поэтому очень легко получить кашу, которую потом сложно зарефакторить
Нет, композиции хватает
Композиции не хватает, когда в базовом типе 20 методов, а в наследнике добавляется один, и приходится все 20 пробрасывать руками

Aleksey
02.09.2017
09:25:28
Это уже должен решать язык, аннотациями, или ещё чем

Anton
02.09.2017
09:26:50
Ну я считаю, что такое пробрасывание надо делать явной отдельной концепцией в языке

Google

Anton
02.09.2017
09:27:03
В расте не хватает такого
Но я глупенький) Может быть есть лучше решения

Aleksey
02.09.2017
09:29:12
В питоне есть метапрограмминг, делегацию можно автоматизировать. А встраивать именно в язык не очень хорошо, да
В расте хотят расширяемые рекорды запилить, еяпп. Но когда запилят, не знаю

Anton
02.09.2017
09:33:48

Aleksey
02.09.2017
09:36:32
"OOP as a Library", лучше, чем некая всегда чем-то неполоноценная версия ООП, намертво встроенная в синтаксис

Anton
02.09.2017
09:37:26
Ну это не ООП, я именно за то, чтобы делегацию сделать отдельно от остального
По сути просто бойлерплейт убрать
delegate to base {
fn1, fn2, fn3
}
Что-нибудь типа такого

Aleksey
02.09.2017
09:39:09
В питоне я могу сделать так:
class Foo(
compose(bar=Bar,
delegate=['write', 'read', 'size']),
compose(qux=Qux, delegate=ALL)):
...

Anton
02.09.2017
09:39:34
Ага

Aleksey
02.09.2017
09:40:56
Тут хотя бы не будет той же проблемы с множественным наследованием, от которого в питоне одна боль
А вообще в питоне или том же Ruby я могу неизвестные методы пробрасывать во все вложенные объекты по порядку, пока кто-то из них не обработает. Так что можно даже особо не делегировать. Правда и интроспекции не будет тогда

Alexander
02.09.2017
09:43:05
тут надо чтобы тот кому делегировали мог вызвать асирактный метод, который будет выполнен тем, кто делегировал
абстрактный

Aleksey
02.09.2017
09:43:32
Ну да, получится двойная диспетчеризация

Alexander
02.09.2017
09:43:35
ООП и наследование об этом

Abbath
02.09.2017
09:44:00

Aleksey
02.09.2017
09:44:27
При композиции вложенный объект не должен знать ничего об оборачивающем - это утечка абстракции
Разве что передать при вызове колбэк можно, если это соответствуте API вкладываемого объекта

Google

Anton
02.09.2017
09:46:03
Короче очень неортогональная штука это наследование)

Aleksey
02.09.2017
09:46:32
Наследование сначала смотрится неплохо, а потом начинается адище
Иерархии сущностей адекватные написать нелегко, часто - невозможно. А ещё чаще - просто не нужно, но "все привыкли уже"

Denis
02.09.2017
10:07:31
Ох и развели вы тут)

Alexander
02.09.2017
10:22:29
и не особо нужная :)
зачастую вложенный объект все же должен знать какой-то интерфейс
ну или по другому выкручиваться, а вот с иерархиями согласен
там наверху пример с Боингом был
я там не как птиц наследовать и что делать с самолётами двойного назначения
меняют ли они класс в военное время


Даниил
02.09.2017
12:36:15
и не особо нужная :)
да ладно, вот простейший пример
есть какая-нибудь ORM, надо шоб она могла подключаться к разным БД
плохой способ: хардкодить подключение к каждому типу БД в одной структуре
тоже плохой способ: наследоваться от общей структуры и в наследниках перегружать метод подключения к БД
чёткий способ: выделить подключение к БД в отдельный интерфейс Connection и хранить ссылку на Connection в качестве поля структуры ORM
таким образом ORM знает только об универсальном интерфейсе предоставляемым структурами, реализующими Connection
и можно в пользовательском коде реализовать подключение к какой-нибудь БД о которой разработчик ORM не знает

Alexander
02.09.2017
12:41:54
какое отношение это имеет к наследованию или композиции?

Даниил
02.09.2017
12:42:07
прямое
второй способ - наследование, третий - композиция
(простите за мой Rust):
type ConnectionResult = ...;
trait Connection {
fn connect(&mut self) -> ConnectionResult;
// more methods
}
struct ORM {
connection: Box<Connection>;
// more fields
}

Alexander
02.09.2017
12:46:27
в данном случае data Connection = Connection { method1, method2 } хватит
что правда тоже самое, но в профиль

Даниил
02.09.2017
12:49:03
нуу или так
хотя мне-таки больше нравится вариант где Connection - интерфейс/трейт/тайпкласс

Google

Даниил
02.09.2017
12:51:23

Aleksey
02.09.2017
12:52:47
абстрактный, но реализуемый :)

Alexander
02.09.2017
12:53:22
ну с Haskell можно подобное
data Connection; class HasConnection ; class AsORM a where default .. :: HasConnection a => a -> ...

Даниил
02.09.2017
12:54:47
абстрактный, но реализуемый :)
ну так-то реализовать достаточно просто)
проблема только в том что одно дело когда популярная либа, другое - когда используешь свой костыль
костыль не в том плане что плохо реализован, а в том что никто больше этим подходом не пользуется и рандомный человек заглянув в твой код будет учить чуть ли не новый язык, привыкая использовать кастомный механизм делегирования вместо встроенного в питон наследования

Alexander
02.09.2017
12:54:48
HasConnection через Generic

Даниил
02.09.2017
12:55:47
@qnikst можно ж через экзистенциальную квантификацию, а то с дженериками немного громоздко

Alexander
02.09.2017
12:56:03
не, это совсем разные вещи :)

Даниил
02.09.2017
13:02:46
я имел ввиду что-то типа
{-# LANGUAGE ExistentialQuantification #-}
class Connection c where
connect :: c -> IO ()
data ORM = forall c. Connection c => ORM { connection :: c }
(сигнатура connect не особо осмысленная, но не суть)

Alexander
02.09.2017
13:04:10
здесь тогда класс такой вообще не нужен
взять структуры данных и все
в которой поля это методы

kana
02.09.2017
13:04:35
Я, как новичок, просто использовал бы ReaderT для передачи коннекшона, а код, который работает с базой, требовал бы тот самый тайпкласс для енва в ридере, что позволит один и тот же код запускать с разными коннекшонами (чтобы замокать для тестов, например).
Я пока не писал ни одного продакшенового кода на хаскеле, если что, могу нести хрень

Alexander
02.09.2017
13:04:53
а это уже совсем другое

Даниил
02.09.2017
13:09:14
нуу не знаю, мне кажется что вариант с полями-методами какой-то менее структурированный
может я и не прав конечно
Я, как новичок, просто использовал бы ReaderT для передачи коннекшона, а код, который работает с базой, требовал бы тот самый тайпкласс для енва в ридере, что позволит один и тот же код запускать с разными коннекшонами (чтобы замокать для тестов, например).
Я пока не писал ни одного продакшенового кода на хаскеле, если что, могу нести хрень
хм, а это получается можно сказать Reader тут выступает в роли такого функционального IoC-контейнера?

kana
02.09.2017
13:13:47
Ну как я понимаю ридер, он для этого и нужен, чтобы упростить передачу одной и той же зависимости куче кода без кучи лишних аргументов

Denis
02.09.2017
13:16:52
https://twitter.com/mokevnin/status/903909806901166080
https://gist.github.com/mbbx6spp/899e7813ada901c9ffea4ac157bc361a

Google

Евгений
02.09.2017
13:48:38

Denis
02.09.2017
13:48:55
думаю без ооп классов

Aragaer
02.09.2017
13:49:07
я нормально программирую без классов

Евгений
02.09.2017
13:51:01

Denis
02.09.2017
13:51:16
есть)
в жс классы

Евгений
02.09.2017
13:57:27
Может ты с метаобъектами путаешь?

Даниил
02.09.2017
13:58:20
class Foo {
constructor() {
console.log("wow! classes in js");
}
}

Denis
02.09.2017
14:02:19
Ну и extends тоже есть и это уже не просто сахар над прототайп

Дмитрий
02.09.2017
16:32:47
Существует лишь крайне узкий ряд кейсов в которых можно отличить сущность созданную через прототипы от сущности созданной через классы. И те можно убрать через Proxy или другие приёмы
Просто это долго и неудобно, так как к прототипному наследованию относятся все проблемы наследования обычного

Евгений
03.09.2017
19:22:13
Как нету IDE-срача, так тишина. Так что сделаю вброс не менее классический, но похитрее.
Вопрос промышленным хаскель-программистам: @qnikst, @voidlizard, @weonn, вы вообще видете продакшон профит от call-by-need? Или вы юзаете хаскель из-за разросшейся инфраструктуры, являющейся побочным эффектом ленивых вычислений: развитой системы типов, тайп-классов монад-трансформеров и прочего; а лень вызывает у вас только грусть, ощущение пустоты и постоянную борьбу с граф-редукцией?

Alexander
03.09.2017
19:27:08
а профита от call-by-need не видно пока он под капотом, но об этом обычно не думаешь, чтобы его увидеть можно взять идрис и начать пытаться писать в привычном стиле
т.к. чаще возникает лень - грусть, а про то что это хорошо, только в дискуссиях вроде "какого черта это работает за O(1) по памяти, хотя причин не видно"

? animufag ?
03.09.2017
19:49:37
а что возникнет в идрисе?
ну то есть где проявление привычного стиля?

Валерий
03.09.2017
19:51:28
Емнип, он активный

? animufag ?
03.09.2017
19:51:30
кстати интересно стало можно ли там сделать какой-нибудь 2связный или кольцевой список так же через let где ссылки друг на друга ссылаются