а можно не париться и дать возможность пользователю (разработчику) самому сформировать стратегию и тактику написания надежного кода.
«Не париться» при таком подходе у Вас не получится, ну или надёжный код не получится )
Потому что для надёжности Вам придётся держать в уме детали реализации каждого используемого метода, как бы он там что не изменил.
С методом тоже очевидно: он вернет результат вычисления на базе переданных аргументов и своего состояния, возможно изменив свое состояние :)
Так вот нифига. Я выше уже писал про OrderedCollection>>addAll, который с какого-то перепугу тупо вернул свой аргумент, а не результат вычисления. А на тему «возможно изменив свое состояние», зачем я должен об этом думать, когда можно принципиально разделить эти 2 варианта на уровне языка?
Откройте протокол класса Magnitude или его подкласса и убедитесь, что многие люди считают иначе :)
Ну открыл, вижу что эти люди и с SRP кардинально не согласны :)
А вот примеров объектного поведения я там не вижу. Все эти методы можно было бы распределить в несколько подходящих модулей. И это было бы лучше, чем «свалка» в классе Number.
Думаю, это следствие того, что довольно редко встречаются методы длиннее нескольких строк.
Ну, это в принципе даже плюс. Судя по редактору, типичный метод должен уместиться в 11 строк, включая комментарии.
А даже если и нет — они чем-то сильно мешают?
На самом деле спасают только продвинутые средства навигации по всему этому добру. Хотя я не уверен, что даже они позволяют всегда быстро найти то, что нужно. В общем, на мой субъективный взгляд они явно переборщили с набором методов.
Ну, и многие методы, разумеется, «подгружаются» в классы из пакетов.
Я-то как раз хочу чтобы «теоретическая красота» работала на практике.
Тогда Вам реально в Elixir.
Я намедни ещё на тему модели акторов читал и наткнулся на прекрасное описание Erlang… в нём очень хорошо сформулировано то, что я Вам пытался донести.
Что касается Elixir, то он добавил в Erlang ещё и метапрограммирование по образцу Lisp. И практически весь его синтаксис построен на макросах времени компиляции.
Вот, например, реализация синтаксиса для записи диапазонов: kernel.ex#L2597..L2638
Я как раз выше спросил: зачем это нужно каждый раз знать?
Мутабельный объект может пройти по цепочке вызовов и измениться где-то глубоко в недрах кода. Хотя вызывающий код может этого совсем не ожидать.
Если же у нас все аргументы функций иммутабельны, то эта проблема отпадает в принципе.
А когда вы вызываете функцию, вы не должны учитывать, что она вернет?
С функциями всегда очевидно, что она вернёт результат вычисления на базе переданных аргументов.
Напомню: это int где-нибудь в Java «маскируется» под объект; а числа в Smalltalk-е являются объектами
Неа, даже технически экземпляры SmallInteger в Smalltalk не совсем объекты.
Ну а уж концептуально, числа вообще не могут быть объектами, т.к. не обладают собственным поведением.
Я просто не люблю обсуждать то, что в глаза не видел )))
Возможности IDE впечатляют, хоть сам редактор кода слабоват, зато System Browser, Spotter, Finder (by examples), Debugger реализованы весьма интересно. Думаю, оттуда и дальше будут черпать вдохновение для инструментов разработки под другие языки.
Что касается, стандартной библиотеки, то она выглядит как ActiveSupport на стероидах — десятки тысяч методов, которые в 99.999% случаев вам не понадобятся… и, насколько я понял, без возможности подключить только нужные, потому что они все сразу в базовых классах реализованы, а не добавлены через композицию.
Может не означает обязан. Существует масса объектов, не изменяющих свое состояние.
Вы правы, не обязан. Только в этом и есть когнитивная нагрузка — каждый раз вспоминать:
* какие объекты мутабельны, какие иммутабельны
* на какие сообщения объект вернёт yourself, на какие один из аргументов сообщения, а на какие вернёт новый объект того же типа, что и получатель сообщения
Получается, что на практике никакого единообразия и в помине нет. Хотя мы ещё даже не добрались до сообщений, результат обработки которых нам не нужно ждать. В Smalltalk есть такие? Или поток выполнения всегда ждёт ответа на сообщение?
И я никак не пойму, что же вас не устраивает в числах-объектах?
Так исходный вопрос не я задавал )))
Я дополнил своим уточнением…
А то, что объект может изменить свое состояние, получив сообщение, вроде бы и так очевидно?
Это да. И это показывает, что числа — это не совсем объекты даже в Smalltalk. На самом деле закос под объекты очень сильно увеличивает когнитивную нагрузку при программировании.
Для сравнения, в Elixir акторы при получении сообщения могут менять своё состоянии. А данные — наоборот всегда неизменны.
P.S. Ну а в ответ на сообщение addAll вернуть аргумент — это вообще саботаж )))
Вот, кстати, я и на первые грабли 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)"
Не, погодите, что значит «как везде»? Далеко не везде можно переопределить любой метод/функцию из чужой библиотеки, не прибегая к форкам и пулл-реквестам )
Тесты — ok, допустим у нас 200% покрытия и они даже упали:
1) Как быстро понять, что дело именно в переопределении? Вы ведь не пишете тесты на стандартную библиотеку и на все зависимости.
2) Как быстро найти какая из зависимостей в этом виновата?
Дело не в распределении часов, а в том, что Вы делаете вид, что теоретической красоты достаточно, а то, что на практике это не работает, — это досадная мелочь, не достойная внимания )))
если на «борьбу за чистоту» приходиться тратить слишком много усилий — оно не имеет смысла.
Именно!
Вы, видимо, не представляете себе, что может быть иначе… и обобщаете.
Ну, Вы добились, что я скачал Pharo и прочитал tutorial от ProfStef xD
Под типом подразумевается тип ручки, допустим: с колпачком или с кнопкой. В зависимости от него актор выберет стратегию работы с ручкой, ну или кинет исключение, если он не умеет работать с ручкой неопознанного типа.
А по поводу набора свойств, чем Вас не устраивает предложенный? Для большинства реальных применений ручек указанного набора свойств вполне хватает. Естественно, у неё как у любого физического объекта очень много свойств: масса, объём, длина, диаметр корпуса, цвет корпуса и т.д. Но это всё очень редко имеет значение. Так что «тип и цвет чернил» вполне достаточный набор.
Проблема не в «готовке», а в том, что десятки программистов, не входящие в одну команду, меняют одни и те же классы.
Приходится всякие хитрости придумывать. Чтобы очередное обновление зависимостей не сломало эти переопределения.
А как эта проблема решается в Smalltalk?
Вы меня извините, но чем больше я с Вами общаюсь, тем сильнее ощущение, что Вы преимущественно теоретик.
У меня нет опыта работы с Smalltalk, но если взять допустим C#, то концепция «всё есть объект» течёт там как дырявое решето на каждом шагу. И ничего путного Вы не напишете, если будете слепо её придерживаться.
Я хотел написать b *: b, чтобы униформно было, но оказалось, что так нельзя (
Только squared как раз показывает намерение и понятнее, вы же сами сформулировали: «сумма квадратов»
С этим согласен… Только вот мне интересно, для кубов тоже библиотечный метод есть? )
От принципа, я так понимаю, это по-вашему не зависит?
Это уже философия… но вообще да, если принцип направлен на предельную минимизацию кол-ва концепций.
Потому что на каком-то этапе наступает конфликт с другим принципом: «Всё должно быть так просто, как только возможно, но не проще»
Потому что для надёжности Вам придётся держать в уме детали реализации каждого используемого метода, как бы он там что не изменил.
Так вот нифига. Я выше уже писал про OrderedCollection>>addAll, который с какого-то перепугу тупо вернул свой аргумент, а не результат вычисления. А на тему «возможно изменив свое состояние», зачем я должен об этом думать, когда можно принципиально разделить эти 2 варианта на уровне языка?
Ну открыл, вижу что эти люди и с SRP кардинально не согласны :)
А вот примеров объектного поведения я там не вижу. Все эти методы можно было бы распределить в несколько подходящих модулей. И это было бы лучше, чем «свалка» в классе Number.
На самом деле спасают только продвинутые средства навигации по всему этому добру. Хотя я не уверен, что даже они позволяют всегда быстро найти то, что нужно. В общем, на мой субъективный взгляд они явно переборщили с набором методов.
А можно пример? Реально интересно посмотреть.
Я намедни ещё на тему модели акторов читал и наткнулся на прекрасное описание Erlang… в нём очень хорошо сформулировано то, что я Вам пытался донести.
Что касается Elixir, то он добавил в Erlang ещё и метапрограммирование по образцу Lisp. И практически весь его синтаксис построен на макросах времени компиляции.
Вот, например, реализация синтаксиса для записи диапазонов: kernel.ex#L2597..L2638
Если же у нас все аргументы функций иммутабельны, то эта проблема отпадает в принципе.
С функциями всегда очевидно, что она вернёт результат вычисления на базе переданных аргументов.
Неа, даже технически экземпляры SmallInteger в Smalltalk не совсем объекты.
Ну а уж концептуально, числа вообще не могут быть объектами, т.к. не обладают собственным поведением.
Возможности IDE впечатляют, хоть сам редактор кода слабоват, зато System Browser, Spotter, Finder (by examples), Debugger реализованы весьма интересно. Думаю, оттуда и дальше будут черпать вдохновение для инструментов разработки под другие языки.
Что касается, стандартной библиотеки, то она выглядит как ActiveSupport на стероидах — десятки тысяч методов, которые в 99.999% случаев вам не понадобятся… и, насколько я понял, без возможности подключить только нужные, потому что они все сразу в базовых классах реализованы, а не добавлены через композицию.
* какие объекты мутабельны, какие иммутабельны
* на какие сообщения объект вернёт yourself, на какие один из аргументов сообщения, а на какие вернёт новый объект того же типа, что и получатель сообщения
Получается, что на практике никакого единообразия и в помине нет. Хотя мы ещё даже не добрались до сообщений, результат обработки которых нам не нужно ждать. В Smalltalk есть такие? Или поток выполнения всегда ждёт ответа на сообщение?
То, что они только маскируются под объекты.
Я дополнил своим уточнением…
Это да. И это показывает, что числа — это не совсем объекты даже в Smalltalk. На самом деле закос под объекты очень сильно увеличивает когнитивную нагрузку при программировании.
Для сравнения, в Elixir акторы при получении сообщения могут менять своё состоянии. А данные — наоборот всегда неизменны.
P.S. Ну а в ответ на сообщение addAll вернуть аргумент — это вообще саботаж )))
«Но не в обоих случаях d равно первоначальному значению a.»
«Take care that addAll: also returns its argument, and not the receiver!»
С чего это вдруг?
Исправленная версия:
Тесты — ok, допустим у нас 200% покрытия и они даже упали:
1) Как быстро понять, что дело именно в переопределении? Вы ведь не пишете тесты на стандартную библиотеку и на все зависимости.
2) Как быстро найти какая из зависимостей в этом виновата?
Именно!
Ну, Вы добились, что я скачал Pharo и прочитал tutorial от ProfStef xD
А по поводу набора свойств, чем Вас не устраивает предложенный? Для большинства реальных применений ручек указанного набора свойств вполне хватает. Естественно, у неё как у любого физического объекта очень много свойств: масса, объём, длина, диаметр корпуса, цвет корпуса и т.д. Но это всё очень редко имеет значение. Так что «тип и цвет чернил» вполне достаточный набор.
Приходится всякие хитрости придумывать. Чтобы очередное обновление зависимостей не сломало эти переопределения.
А как эта проблема решается в Smalltalk?
У меня нет опыта работы с Smalltalk, но если взять допустим C#, то концепция «всё есть объект» течёт там как дырявое решето на каждом шагу. И ничего путного Вы не напишете, если будете слепо её придерживаться.
Мне этого в Ruby хватило выше крыше. Поверьте, на практике при разработке крупных проектов это ни фига не круто.
b *: b, чтобы униформно было, но оказалось, что так нельзя (С этим согласен… Только вот мне интересно, для кубов тоже библиотечный метод есть? )
Это уже философия… но вообще да, если принцип направлен на предельную минимизацию кол-ва концепций.
Потому что на каком-то этапе наступает конфликт с другим принципом: «Всё должно быть так просто, как только возможно, но не проще»