Обновить
102
Роман Смирнов@Source

Head of Elixir at Ecom.tech

0,2
Рейтинг
51
Подписчики
Отправить сообщение
Вот, кстати, я и на первые грабли Smalltalk наступил:
«Take care that addAll: also returns its argument, and not the receiver!»
С чего это вдруг?

Исправленная версия:
|a b c d|
a := 1.
b := 2.
d := a.
c := a + b.
c. "-> 3"
d. "-> 1"

|a b c d|
a := OrderedCollection newFrom: #(1).
b := OrderedCollection newFrom: #(2).
d := a.
c := a addAll: b; yourself.
c. "-> an OrderedCollection(1 2)"
d. "-> an OrderedCollection(1 2)"
Но не в обоих случаях d равно первоначальному значению a.

|a b c d|
a := 1.
b := 2.
d := a.
c := a + b.
d. "-> 1"

|a b c d|
a := OrderedCollection newFrom: #(1).
b := OrderedCollection newFrom: #(2).
d := a.
c := a addAll: b.
d. "-> an OrderedCollection(1 2)"

Не, погодите, что значит «как везде»? Далеко не везде можно переопределить любой метод/функцию из чужой библиотеки, не прибегая к форкам и пулл-реквестам )
Тесты — ok, допустим у нас 200% покрытия и они даже упали:
1) Как быстро понять, что дело именно в переопределении? Вы ведь не пишете тесты на стандартную библиотеку и на все зависимости.
2) Как быстро найти какая из зависимостей в этом виновата?
А почему дошло? В ООП изначально понятие операции (над значением определенного типа) заменили на сообщение (посылаемое объекту).
Потому что это тонкий стёб над мейнстрим-реализациями ООП.
Дело не в распределении часов, а в том, что Вы делаете вид, что теоретической красоты достаточно, а то, что на практике это не работает, — это досадная мелочь, не достойная внимания )))

если на «борьбу за чистоту» приходиться тратить слишком много усилий — оно не имеет смысла.
Именно!

Вы, видимо, не представляете себе, что может быть иначе… и обобщаете.
Ну, Вы добились, что я скачал Pharo и прочитал tutorial от ProfStef xD
Под типом подразумевается тип ручки, допустим: с колпачком или с кнопкой. В зависимости от него актор выберет стратегию работы с ручкой, ну или кинет исключение, если он не умеет работать с ручкой неопознанного типа.
А по поводу набора свойств, чем Вас не устраивает предложенный? Для большинства реальных применений ручек указанного набора свойств вполне хватает. Естественно, у неё как у любого физического объекта очень много свойств: масса, объём, длина, диаметр корпуса, цвет корпуса и т.д. Но это всё очень редко имеет значение. Так что «тип и цвет чернил» вполне достаточный набор.
Проблема не в «готовке», а в том, что десятки программистов, не входящие в одну команду, меняют одни и те же классы.
Приходится всякие хитрости придумывать. Чтобы очередное обновление зависимостей не сломало эти переопределения.
А как эта проблема решается в Smalltalk?
Вы меня извините, но чем больше я с Вами общаюсь, тем сильнее ощущение, что Вы преимущественно теоретик.
У меня нет опыта работы с Smalltalk, но если взять допустим C#, то концепция «всё есть объект» течёт там как дырявое решето на каждом шагу. И ничего путного Вы не напишете, если будете слепо её придерживаться.
А что значит «униморфно»? Не знаю такого слова.
А почему Вы меня об этом спрашиваете? Я это слово не употреблял.

я могу изменить в системе все что угодно. В том числе «библиотечные» объекты. Но вы же скажете, что это не нужно…
Мне этого в Ruby хватило выше крыше. Поверьте, на практике при разработке крупных проектов это ни фига не круто.
Да полно у неё свойств, а какие переносить в программу зависит от задачи. Можно, например, тип и цвет.
Ну, напишите там b * b — это тоже сообщение.
Я хотел написать b *: b, чтобы униформно было, но оказалось, что так нельзя (

Только squared как раз показывает намерение и понятнее, вы же сами сформулировали: «сумма квадратов»
С этим согласен… Только вот мне интересно, для кубов тоже библиотечный метод есть? )

От принципа, я так понимаю, это по-вашему не зависит?
Это уже философия… но вообще да, если принцип направлен на предельную минимизацию кол-ва концепций.
Потому что на каком-то этапе наступает конфликт с другим принципом: «Всё должно быть так просто, как только возможно, но не проще»
в комментарии выше есть об этом, автоупаковки/распаковки уже достаточно, чтобы сильно усложнить восприятие того, что вообще происходит
Да, структура данных. Она обладает свойствами, но не обладает собственным поведением.
… или для реализации.
В Lisp же принцип реализован, можно униформно программировать на голом AST, а синтаксический сахар всё равно добавляют.

Из ваших высказываний получается, что логика такая: нет систем, которые бы я знал и где соблюдался этот принцип => принцип не нужен
Не совсем, во-первых системы есть. А во-вторых, логика такая: увеличение уровня чистоты принципа не даёт соразмерного увеличения практической пользы. И даже наоборот отход от чистоты частенько позволяет решать задачи эффективнее.
К примеру, b squared — чище, b * b — понятнее
a +: b — чище (только не работает почему-то),
a + b — понятнее.
Вот, как раз некоторые считают, что дефолтное состояние человека — воспринимать окружающий мир и все сущности в нем как объекты: идентифицировав объект, мы начинаем пытаться на него воздействовать и смотреть, что же будет в ответ.
Как минимум, мы отличаем объекты с поведением (акторы) от объектов без поведения (данные) и принципиально по-разному к ним относимся. Благодаря чему у нас не возникает дилеммы «человек пишет ручкой» или «ручка пишет, используя человека».
Понимаете, наличие синтаксического сахара говорит о том, что концепция в чистом виде не слишком удобна и/или трудна для понимания. И тут встаёт выбор «вам шашечки (чистоту концепции) или ехать (возможность эффективно решать задачи)».
То, что теоретически что-то возможно, не делает это автоматически удобным для всех. C Lisp похожая ситуация, концепция изящна и удивительно проста. Но для легкости восприятия требуется либо отходить от привычного мышления, либо увешиваться синтаксическим сахаром.
Поэтому ни Smalltalk, ни Lisp и не захватили мейнстрим… среднестатистическому программисту банально не удобно с любой униформностью. Да и в физической реальности нас окружает наблюдаемое многообразие, а униформность остаётся теоретической концепцией.
Ok, пусть будет так:
Enum.reduce(1..n, 0, &(&1*&1 + &2))

чтобы без фокусов )))
Лично для меня, придание примитивным типам объектности, всегда имело смысл не в том, чтобы, собственно, работать с примитивными типами, как с объектами, а в том, чтобы иметь возможность работать с объектами, как с примитивными типами.
Хорошее дополнение в дискуссию. На мой взгляд, для расширения примитивных типов хватит и структур, над которыми имеется возможность определить любые операторы. Так ведь?

я ни разу не замечал, чтобы мне, например, в C# делать арифметику со встроенными типами было сложнее, чем в Си.
Загляните в IL-код, там нет никаких объектов для чисел. Но не задумываясь о разнице между числами и объектами, Вы легко можете написать код, где в цикле возникнет какой-нибудь box int32. И удар по производительности обеспечен. Смысл не в том, что нельзя работать с числами как с объектами. Смысл в том, что нельзя забывать, что число — это число, а объектом оно только притворяется. Поэтому переключение сознания между объектами и примитивными типами данных неизбежно для написания нормального кода.
Я понимаю, тут постановка задачи — показать несостоятельность ООП подхода
Нет, Вы вообще не поняли, что мы в этой ветке обсуждаем (невозможность униформности на всех уровнях системы), и даже статью, видимо, не дочитали.

но, например, плюсы
В Вашем примере куча не-ООП… 0 — это не объект в плюсах, for — не метод, +, * и даже return — это тоже не методы. Так что на униформную ООП-реализацию это точно не тянет.
Очень лаконично всё описывают.
А вот это Вы зачётно пошутили )))
Есть ведь разница между «меня не интересует» и «ООП не интересует»? Я сомневаюсь, что ООП обладает сознанием, но даже если так, то со мной своими переживаниями не делится.
Не придирайтесь… Это всего лишь сокращение для «Во время применения ООП нас не интересует»

мне не приходится постоянно переключать «режим» сознания при работе с сущностями различного рода. Понимаете?
Честно говоря, не понимаю в чём проблема. Мы в жизни постоянно переключаемся между сущностями различного рода, можно сказать, это дефолтное восприятие человека. Вы по-любому переключаетесь, когда говорите о массивах, строках, числах. Просто делаете вид, что это типа тоже объекты. Если бы можно было бы оставаться всегда на уровне объектов, не переключаясь, Вы бы названия обычных типов данных вообще забыли бы.

(0 to: n) reduce: [:a :b | a + b squared].
Кхм, и в каком месте тут униформность?
если вызов метода записывается как
object method: arg
то что такое квадратные скобки? что такое a + b? что такое b squared? что такое ":a :b |"?
Даже реализация такого микропримера совсем не униформна, о каком отсутствии «переключений» тогда вообще говорить…

Информация

В рейтинге
2 979-й
Откуда
Россия
Работает в
Зарегистрирован
Активность