Само утверждение «все сущности в системе являются A» делает систему простой
Нет. Простой она станет, если все сущности действительно являются А. Но по факту мы имеем систему «Давайте будем считать, что все сущности являются А».
Я был не в курсе как это в Smalltalk реализовано )))
Понятно, что Smalltalk в этом не виноват, но сейчас = для сравнения редко, где используется.
А абстракция действительно протекает… SmallInteger и LargePositiveInteger ведут себя совсем по-разному и при этом между ними есть неявное приведение типов.
Да не, дико, что разные алгоритмы сравнения для однотипных типов используются, на мой взгляд LargePositiveInteger тоже должен быть value-type. Впрочем, одинарное = частично решает эту несостыковку.
Спасибо, так лучше, но всё ещё осталось управление потоком выполнения через исключения.
А по поводу доступности для новичков я бы ещё Вам попенял за название "->>keys", которое для новичка выглядит как-будто вариант использования "->>", лучше было бы банальное «send-key» или «press-key»
Бага — неожиданное (для разработчика) поведение системы. Нет?
Необязательно, большинство багов встречаются в бизнес-логике или в логике самого программиста (алгоритмов, которые он реализует). В общем, только часть багов связана с неожиданным поведением языка и его стандартной библиотеки.
Но вот списки и функции — они «униформность» ведь не нарушают? Я так понимаю, для вас несколько «параллельных» терминов/понятий в рамках одной концепции — это ОК?
Это лишь для большей понятности. По факту, любой список — это вызов функции, т.е. это не разные понятия, а одно и то же разными словами. Даже «списки-литералы» записываются как вызов функции list:
(list 1 2 3)
А вопрос — в простоте исходных положений. Вам это не интересно, а я считаю, что именно оттуда «растут ноги» у избыточной сложности.
Это всё очень субъективно… Краткость исходных положений не означает простоту. На мой взгляд «всё есть объект» — это очень сложное исходное положение, как в реализации, так и в следовании ему и главное — не отражающее реальное положение дел ни концептуально, ни технически. Т.е. если пытаться следовать этому тезису абсолютно, то вся система будет построена вокруг этой идеи, а не с её помощью.
Все существующие символы тоже никто не хранит, только те, которые в программе используются. Но это не суть.
Я правильно понял, что привычные «операторы» сравнения никогда не сравнивают по значению в Smalltalk? А иллюзия сравнения по значению возникает только в случаях, когда по факту имеется один объект для обеих сторон сравнения.
гарантирует второе (отсутствие неожиданного поведения)? В программах на Scheme не бывает багов?
А как отсутствие неожиданного поведения связано с отсутствием багов? С неожиданным поведением только часть багов связана, причём чаще меньшая, т.к. программисты привыкают к «особенностям» используемого языка.
Функция — это тоже список? Да, она задается списком, но это же объект другого рода?
Определение функции — это список с вызовом функции define. Да, разумеется, есть с десяток функций, которые реализуются внутри интерпретатора, но для программиста они ведут они себя точно так же, как и все остальные функции.
тут тоже есть примитивные конструкции, которые не совсем соответствуют исходной концепции?
да вроде нет, можно пример?
Ваша позиция понятна, но всё-таки заметно что Вы ей следуете, исходя из того, что неравнодушны к Smalltalk. Это создаёт некоторую предвзятость.
Концепция, в которую вовлечено два компонента (объект и сообщение) скорее всего проще, чем та, в которой присутствует большее количество.
Вот это не факт. Простота применения ЯП на практике с количеством компонентов в концепции слабо коррелирует.
Есть, например, концепция с нулём компонент — «всё есть ничто» и даже соответствующий ЯП. А вот решить на нём практическую задачу совсем не просто :-D
по моим ощущениям ООП не менее мощная, чем ФП, так как в объектах можно смоделировать любую концепцию ФП
OMFG, зачем? Эти парадигмы совершенно ортогональны. Моя позиция в том, что они должны применяться комплементарно на разных уровнях абстракции. ООП можно применять и в Erlang/Elixir и в диалектах Lisp, но там, где оно реально имеет смысл и пользу. А протаскивание идей ООП через все уровни абстракции вплоть до самых примитивных типов ведёт к излишнему и неоправданному усложнению системы.
Собственно изначальная статья посвящена тому, что «Здравствуй ФП» не обозначает «Прощай ООП», оно означает «Здравствуй нормальное ООП, теперь ты будешь работать для меня, а не наоборот»
Просто в одном случае (с дробями) в ответ на сообщения возвращается один и тот же объект (что логично: число 1/5 как объект существует в единственном экземпляре)
Было бы логично, только в том то и фишка, что возвращаются разные.
Обратите внимание, что 1/5 не равна 1/5 в Smalltalk, несмотря на то, что в данном случае это рациональные дроби, а не десятичные.
Нет, конечно. Какие-то WAT есть практически в любом ЯП, но больше всего их от сайд-эффектов и от неявного приведения типов.
ключевые слова: «позднее связывание»
Так позднее связывание сейчас очень во многих ЯП есть. И возможность «обработать сообщение, для которого у объекта метода нет вообще». Точнее метод то есть, он просто работает как fallback, в Ruby он method_missing называется. А в целом это обычный dynamic dispatch.
Я ожидал от Smalltalk гораздо большего в этом плане…
Согласен. В статье вместо демонстрации сильных сторон Clojure, идёт сравнение тёплого (Selenium WebDriver) с мягким (Selenium IDE). Ну а REPL'ом давно уже никого не удивить )))
Код теста в примере пока что выглядит как-будто его с Java 1-в-1 переписали, не говоря уж о том, что запуск браузера, логирование и подсчёт результатов — это не обязанность конкретного теста.
На мой вкус этот тест (без потери функционала) должен выглядеть примерно так:
Не, ну это не просто нежелание отвечать на какое-то сообщение, это не желание инстанцироваться так же как концептуально аналогичный класс. Они ещё и сравниваются по значению, а дроби уже по ссылке.
Единообразие, как концептуальное, так и синтаксическое. И как следствие отсутствие неожиданного поведения на уровне языка и стандартной библиотеки.
Хороший пример униформности — Scheme, вот ранее обсуждаемая задачка на Racket Scheme:
(define (sum-squared-up-to n)
(foldl
(lambda (x acc) (+ (* x x) acc))
0
(range 1 (+ n 1))))
Синтаксис абсолютно однороден. Концепция чистая, даже без сахара. Всё есть список. Первый элемент списка — имя вызываемой функции, остальные — аргументы для неё.
Где я говорил про униформность Smalltalk?
Хм, а что мы тогда тут обсуждаем? Насколько я уловил Вашу позицию: «В Elixir униформности нет, не то что в Smalltalk, а как же жить без униформности возможно»
Спасибо, разобрался. Чтобы по-нормальному расширить базовый класс, надо создать свой пакет, потом перейти к определению класса, добавить протокол *ИмяСвоегоПакета и туда уже нужные методы.
А в пакете они появятся автомагически сразу после Accept :-)
Возможно, первым пользователям метода было так удобнее, а потом сработал принцип «здесь так принято»
О том и речь. Когда можно сайд-эффекты замутить над примитивными данными — это рано или поздно приводит к WAT.
Вроде бы очень алогичная вещь: как мы вообще можем писать программы в таких условиях?!? И у вас постоянно проскальзывает это недоумение…
У меня? У меня на эту тему никакого недоумения нет, потому как процессы в Elixir действительно принимают сообщения, и тот, кто посылает сообщение, даже не догадывается какой функцией оно будет обработано и когда (можно задать только таймаут, после которого сообщение теряет актуальность).
А вот в Smalltalk это не так, насколько я понял из PBE. Там посылка сообщения от вызова метода отличается только в теоретическом плане. На практике сообщение обрабатывается одноименным методом и технически от вызова метода это ничем не отличается. Да есть детали реализации, о которых они пишут, типа методы класса-экземпляра. Но фундаментально это ничего не меняет.
Хотя может я что-то недопонял… Буду благодарен, если Вы продемонстрируете практическое отличие сообщений в Pharo от вызова метода в Ruby.
я не выдерживаю данный формат дискуссии — надо куда-то ее переносить.
LargePositiveInteger new. "-> 0"
SmallInteger new. "-> Error: SmallIntegers can only be created by performing arithmetic"
Ну и Formal Specification of the Primitive Methods заодно.
P.S. Чем больше читаю про Smalltalk, тем сильнее у меня ощущение, что Вы рассказывали про какой-то другой ЯП, потому что в этом униформности точно нет. Не то что бы в этом есть что-то плохое, но это факт.
Там есть синтаксический сахар, позволяющий записать
но это эквивалент
Просто список, не являющийся вызовом функции, записать нельзя.
Понятно, что Smalltalk в этом не виноват, но сейчас = для сравнения редко, где используется.
А абстракция действительно протекает… SmallInteger и LargePositiveInteger ведут себя совсем по-разному и при этом между ними есть неявное приведение типов.
А по поводу доступности для новичков я бы ещё Вам попенял за название "->>keys", которое для новичка выглядит как-будто вариант использования "->>", лучше было бы банальное «send-key» или «press-key»
Хотя я нашёл всё-таки метод сравнения по значению:
Это лишь для большей понятности. По факту, любой список — это вызов функции, т.е. это не разные понятия, а одно и то же разными словами. Даже «списки-литералы» записываются как вызов функции list:
Это всё очень субъективно… Краткость исходных положений не означает простоту. На мой взгляд «всё есть объект» — это очень сложное исходное положение, как в реализации, так и в следовании ему и главное — не отражающее реальное положение дел ни концептуально, ни технически. Т.е. если пытаться следовать этому тезису абсолютно, то вся система будет построена вокруг этой идеи, а не с её помощью.
кажется, я совсем запутался с == в Smalltalk :facepalm:
Я правильно понял, что привычные «операторы» сравнения никогда не сравнивают по значению в Smalltalk? А иллюзия сравнения по значению возникает только в случаях, когда по факту имеется один объект для обеих сторон сравнения.
В остальном согласен, действительно весьма прогрессивная платформа разработки.
Определение функции — это список с вызовом функции define. Да, разумеется, есть с десяток функций, которые реализуются внутри интерпретатора, но для программиста они ведут они себя точно так же, как и все остальные функции.
да вроде нет, можно пример?
Ваша позиция понятна, но всё-таки заметно что Вы ей следуете, исходя из того, что неравнодушны к Smalltalk. Это создаёт некоторую предвзятость.
Вот это не факт. Простота применения ЯП на практике с количеством компонентов в концепции слабо коррелирует.
Есть, например, концепция с нулём компонент — «всё есть ничто» и даже соответствующий ЯП. А вот решить на нём практическую задачу совсем не просто :-D
OMFG, зачем? Эти парадигмы совершенно ортогональны. Моя позиция в том, что они должны применяться комплементарно на разных уровнях абстракции. ООП можно применять и в Erlang/Elixir и в диалектах Lisp, но там, где оно реально имеет смысл и пользу. А протаскивание идей ООП через все уровни абстракции вплоть до самых примитивных типов ведёт к излишнему и неоправданному усложнению системы.
Собственно изначальная статья посвящена тому, что «Здравствуй ФП» не обозначает «Прощай ООП», оно означает «Здравствуй нормальное ООП, теперь ты будешь работать для меня, а не наоборот»
Обратите внимание, что 1/5 не равна 1/5 в Smalltalk, несмотря на то, что в данном случае это рациональные дроби, а не десятичные.
Так позднее связывание сейчас очень во многих ЯП есть. И возможность «обработать сообщение, для которого у объекта метода нет вообще». Точнее метод то есть, он просто работает как fallback, в Ruby он method_missing называется. А в целом это обычный dynamic dispatch.
Я ожидал от Smalltalk гораздо большего в этом плане…
Код теста в примере пока что выглядит как-будто его с Java 1-в-1 переписали, не говоря уж о том, что запуск браузера, логирование и подсчёт результатов — это не обязанность конкретного теста.
На мой вкус этот тест (без потери функционала) должен выглядеть примерно так:
Единообразие, как концептуальное, так и синтаксическое. И как следствие отсутствие неожиданного поведения на уровне языка и стандартной библиотеки.
Хороший пример униформности — Scheme, вот ранее обсуждаемая задачка на Racket Scheme:
Синтаксис абсолютно однороден. Концепция чистая, даже без сахара. Всё есть список. Первый элемент списка — имя вызываемой функции, остальные — аргументы для неё.
Хм, а что мы тогда тут обсуждаем? Насколько я уловил Вашу позицию: «В Elixir униформности нет, не то что в Smalltalk, а как же жить без униформности возможно»
А в пакете они появятся автомагически сразу после Accept :-)
У меня? У меня на эту тему никакого недоумения нет, потому как процессы в Elixir действительно принимают сообщения, и тот, кто посылает сообщение, даже не догадывается какой функцией оно будет обработано и когда (можно задать только таймаут, после которого сообщение теряет актуальность).
А вот в Smalltalk это не так, насколько я понял из PBE. Там посылка сообщения от вызова метода отличается только в теоретическом плане. На практике сообщение обрабатывается одноименным методом и технически от вызова метода это ничем не отличается. Да есть детали реализации, о которых они пишут, типа методы класса-экземпляра. Но фундаментально это ничего не меняет.
Хотя может я что-то недопонял… Буду благодарен, если Вы продемонстрируете практическое отличие сообщений в Pharo от вызова метода в Ruby.
придётся всё-таки митап по ООП организовывать )))
Ну и Formal Specification of the Primitive Methods заодно.
P.S. Чем больше читаю про Smalltalk, тем сильнее у меня ощущение, что Вы рассказывали про какой-то другой ЯП, потому что в этом униформности точно нет. Не то что бы в этом есть что-то плохое, но это факт.