@haskellru

Страница 384 из 1551
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
В питоне есть метапрограмминг, делегацию можно автоматизировать. А встраивать именно в язык не очень хорошо, да

В расте хотят расширяемые рекорды запилить, еяпп. Но когда запилят, не знаю

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
ООП и наследование об этом

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
В питоне я могу сделать так: class Foo( compose(bar=Bar, delegate=['write', 'read', 'size']), compose(qux=Qux, delegate=ALL)): ...
о, а это откуда? либа какая-то для делегирования? или пример абстрактный?

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
нуу не знаю, мне кажется что вариант с полями-методами какой-то менее структурированный может я и не прав конечно

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
думаю без ооп классов
Какая-то тухлая шутка, все давно уже пишут на JS, там классов нету

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 где ссылки друг на друга ссылаются

Страница 384 из 1551