Именно как очевидно неверную фразу я это и приводил, чтоб показать, что упомянутый авторитет не может являться авторитетом во всех областях науки и даже может допускать в свиох лекциях очевидно абсурдные высказывания не на тему лекции.
На мой взгляд тут очевиден эфект испорченого телефона.
«Не выиграл, а проиграл. Не в шахматы, а в преферанс. Не запорожец, а 5 рублей.»
Скажите, а как «системный аналитик» Вы всегда оперируете «последними данными» без указания какими, чьими или хотя бы в какой области науки с единственным указанием «в интернете»?
И все свои доказательства вы формулируете в виде «могу чётко и аргументированно доказать» без самого доказательства?
У вас великолепный дар говорить много и не сказать ни чего. К сожалению этот дар сейчас слишком распространен.
Спасибо за совет. Интересно будет почитать и посмотреть передачи.
Но вот что бросается в глаза сразу: она, несомненно, выдающийся лингвист и психолог, но среди ее многочисленных областей знаний нет ни одной, позволяющей судить о механике работы отдельный нейронов.
Читая работы ученых (даже самых выдающихся) следует правильно расценивать их высказывания не о их областях науки: порой они просто не придают значения таким заявлениям.
Вот пример из лекции Татьяны Владимировны:
Как мне сказал знакомый астроном, количество нейронных связей в мозгу больше, чем звезд во Вселенной, а после этого астронома физик знакомый сказал: «Не звезд во Вселенной, а частиц во Вселенной». Частиц! Это же ужас.
Это высказывание очевидно не верно, но его верность не важна — это всего лишь лирическое отступление.
Кстати да, "*" для пересечения — это тот еще ужас, учитывая наличие такой операции, как декартово произведение.
А "+" для объединения множеств не используется потому, что со времен iava "+" на всем подряд, кроме всевозможных чисел, приводит к toString и конкатенации строк. Оно так было до scala, пусть так и остается.
И совсем забыл:
>Я понимаю, что Вы знаете Scala. Разговор не про это.
А кто должен писать и читать код на scala? Тот, кто не знает scala?
Я — новичок в scala и у меня все эти ужасные 3 оператора на коллекциях (":+", "++", "/:") сложностей восприятия не вызывают, а кроме них и отправки сообщений операторов не распространенных в других языках в стандартной библиотеке фактически и нет.
>Зачем использовать ambigious символ, если можно a.send(b)?
Учитывая, что отправка сообщений — одно из основных действий в используемой модели многопоточности, логичным выглядит сократить его запись до минимума. Самое базовое действие имеет право на отдельный символ.
>Да, это то, что во всех христианских языках называется add().
Не add, а addFirst. Только зачем 2 слова, когда все понятно и с 2 буквами?
>addAll() в Java
Скажите честно, а Вы объединяете строки как str1.concatenate(str2) или через ужасно непонятный оператор?
Ответ прост: для базового часто используемого действия вполне можно ввести сокращенное обозначение.
>А чем слово foldLeft не угодило? Ну или, lfold?
Вот lfold — это воистину ужасно. Это выглядит как 1 слово, но им не является. Я с первого раза прочитать не могу. Но согласен, что foldLeft лучше, чем /:. Попробовали, идея оказалась неудачной, больше такие идеи не внедряют без прохождения инкубатора.
>Следует добавть: абсолютно бесполезных концепций, которые никем и никогда и нигде не будут использованы.
Разработчики typesafe stack некоторые операторы используют и другим советуют. Вот тут с 26 минуты: www.youtube.com/watch?v=YZxL0alO1yc
Другие операторы вымрут — на то и нужен инкубатор, чтоб проверять идеи на жизнеспособность.
>Я согласен, что оба механимзма взаимозаменяют друг друга, но вариант Скалы несколько больее громоздкий. Я не вижу больших плюсов в таком усложнении(не считая некоторых исключений).
Про "!a" Вы несколько перегибаете. "!a" не может быть отправкой сообщения, так как нет адресата.
А «a! b» не может быть отрицанием, так как отрицание — унарная операция.
+: — это прибавление элемента ко множеству. Зачем тут ":" поймет любой, кто знает синтаксис scala. И не менее очевидно, что элемент добавляется в начало.
++ — объединение множеств. «Множественное добавление».
::= — в отношении этого оператора действует тот же принцип, что и для всех аналогичных: для immutable коллекций «a ::= b» — сокращенная запись для «a = a.::(b)» оно же «a = b :: a». Для mutable — аналог с изменением исходной коллекции.
Сам же оператор "::" крайне часто используется в scala и тесно связан с контейнером linked list (класс List).
"/:" — foldLeft. Рекомендуется его не использовать, так как foldLeft нагляднее.
Вот остальное уже более специфично и зависит от библиотеки. Например в scalaz есть огромное количество экспериментальных операторов от которых голова кругом, но они реализуют определенные концепции ФП, суть которых в имени функции не выразить, так что более развернутое имя понятнее не сделает.
На скале очень просто и удобно пишутся простые не критичные по производительности парсеры (JavaTokenParsers).
А вот про сложные могу лишь догадываться, но не думаю что это может быть просто на каком-либо языке.
А вот про Kotlin я готов спорить долго. На мой взгляд он крайне непоследователен и, в отличии от scala, предлагает не стройную концепцию, а разрозненный набор плюшек:
Pattern matching? Долго и сложно! Мы переименуем switch и расширим его проверкой типа.
Выкинем все со словом «неявный». Даже если замена полностью эквивалентна. Не получается привести к интерфейсу, а итерировать по строке хочется? Введем структурную типизацию.
Синтаксис для структурной типизации? А давайте введем ее только для встроенных элементов языка!
Обход type erasure а неявных параметров нет? Добавим синтаксическую конструкцию!
Каррирование? Нет, не слышали. А в отдельных фигурных скобках можно указывать последний параметр, если он лямбда.
Перегрузка операторов! Почему операторы не добавить в список разрешенных имен функций? Ну так они же операторы!
Не нравится подчеркивание в лямбдах? А давайте первую попавшуюся переменную интерпретировать как аргумент!
Изменение типа переменных в зависимости от проведенных проверок! Не очевидно без IDE? Так пользуйтесь IDE — там такие переменные красиво подсвечиваются зеленым!
И так далее…
Не поймите меня неправильно, я считаю, что команда JetBrains делает очень хороший язык. Андрей Бреслав — умнейший человек. Они действительно создают нечто простое в использовании и крайне функциональное.
Но kotlin, в отличии от scala, я не могу мысленно свести в единую стройную концепцию.
Если в scala я вижу набор универсальных принципов на которых вырастает функционал самым логичным и естественным образом, как доказательства теорем из аксиом. Мне не нужно что-либо заучивать: понял принципы и все остальное кажется самоочевидным и единственно верным. И как в мат. аппарате те же принципы, что использовались для построения основы я сам могу использовать для ее расширения. Это то, что я бы назвал академическим подходом.
В Kotlin же нет лаконичного набора идей, а есть довольно большой и все еще раздувающийся набор не универсальных решений. Его мне надо заучивать. В итоге получается тот же C#, только на jvm. А зачем еще 1 C#?
Сложно обсуждать без примеров, может быть вы приведете свой достаточно нетривиальный?
Для обсуждения сложности для расшифровки и сложности для разбора в IDE лучше брать не неявные преобразования, которые полностью эквивалентны extension методам, обрабатываются точно так же и создают столько же вопросов, а неявные параметры.
Именно из-за неявных параметров IDE с большим трудом обрабатывают scala. Именно ради сокрытия неявных параметров в документации придуман синтаксический сахар для записи type class и use case в scala doc.
Это неявные параметры, такие как CanBuildFrom вызывают наибольшее количество вопросов.
Но эти сложности — это та цена, которую приходится платить за удобства. За гибкость, которую они создают.
>Никто же не мешает в String инъективровать метод toTraversable(). Код тогда становится гораздо более понятным, явным.
А зачем тогда вообще расширять класс? С тем же успехом можно писать toTraversable(string).
Если, например, требуется отрезать от строки префикс в верхнем регистре, то гораздо проще и нагляднее написать
«ABCabc» dropWhile { _.isUpper }
чем
«ABCabc».toTraversable.dropWhile{ _.isUpper }.toString
В этом прелесть неявного преобразования: мы не просто добавляем 1 метод, мы получаем рассматривать строку как коллекцию символов, которой она, в принципе, и является.
По моему опыту присваивание другого значения параметру используется крайне редко. Точнее это было запрещено конвенциями, если даже ЯП позволял, везде, где я писал код. Единственное исключение — T-SQL хранимки, где стандартной практикой является переопределение Null, но это не наш случай, ибо null в скале не используется.
Переопределение параметра создает очень большие проблемы при рефакторинге больших функций.
А вот перекрытие переменной из другой области видимости возможно в очень многих ЯП. Не могу сказать, что это абсолютное зло, но быть осторожным надо.
Я, кажется, понял в чем мы не поняли друг друга: «А уж многопоточность без иммутабельности вообще превращается в пытку.» — это об отсутствии полноценной поддержки immutable, позволяющей удобно обмениваться данными между потоками, а не о наличии где-либо mutable state. Например отсутствие неизменяемых интерфейсов коллекций в Java.
Плюсов 2:
1 более удобное повторное использование кода:
Чтобы добавить все методы Traversable в String при помощи extension методов надо явно прописать все эти методы. При помощи же implicit converrsion достаточно StringOps унаследовать от Traversable и реализовать 1 метод: foreach. Это гораздо менее громоздко. А вот добавление по 1 методу как раз зачастую зло, ибо такой мощный механизм как расширение класса надо использовать очень редко, но с очень большими последствиями (как LINQ).
2 приведение к интерфейсу, что позволяет не использовать структурную типизацию как в Kotlin (повторяюсь).
Состояние актора мутабельно, но все изменения очевидно в 1 потоке а, следовательно, удобны и безопасны. Проблемы с мутабельностью при передаче между потоками. Посылка актору мутабельного сообщения – самоубийство. Если 2 потока владеют ссылкой на общий изменяемый объект, то синхронизация становится нетривиальной задачей: habrahabr.ru/post/143074/
Я не это имел в виду под повторным использованием. Повторное использование – это использование переменной в 2 разных смыслах. То есть если Вы заводите переменную count и в начале метода используете как счетчик одних объектов а в конце – как счетчик других, то это и есть повторное использование.
Параметры функции – это то, что ей передали.
В частности невозможность изменить значение параметра функции дает возможность полагаться при изменениях кода в конце метода на то, что мы работаем именно с параметром, а не с каким-то значением присвоенным в процессе без просмотра всего кода.
И нельзя забывать про оптимизации, доступные только для неизменяемых объектов.
Согласен, в ногу себе выстрелить просто.
Мне кажется, что многие проблемы от неопытности и восторженности. Разработчикам хочется применить все средства языка и они пихают их где надо и не надо. Почему-то C# разработчики не часто пишут extension методы, хотя на них можно реализовать такие мощные вещи, как LINQ.
Так же многие не считаются с гайдлайнами и используют не оптимальные методы языка, как, например, использование implicit conversions вместо type class, хотя все специалисты вроде разработчиков typesafe stack рекомендуют использовать type class.
В стандартной библиотеке не так много implicit conversions, гораздо больше implicit parameters, но при использовании о них чаще всего можно забыть.
Побочные эффекты легко контролируемы. При желании можно писать только чистые функции везде, но зачем? Есть места где иммутабельность не лучший выход.
Иммутабельность позволяет проводить многие оптимизации. А уж многопоточность без иммутабельности вообще превращается в пытку.
Вообще иммутабельность везде контролируется: val vs var – ваш выбор.
В каком смысле параметры функции иммутабельны? В том же, что м в java? Так и ответ тот же, что и в java, зато если требуется вернуть 2-3 значения можно использовать TupleN.
Или в том смысле, что внутри функции нельзя использовать параметр как присваиваемую переменную? Так это во многих ЯП, в том числе и с ООП парадигмой. Вообще присваивание значения параметру функции – это повторное использование переменной, что есть зло.
Про неявное преобразование: приводится не к подклассу, а к любому другому классу. Экземпляр на самом деле не создается и в рантайме просто вызывается статический метод (где это возможно).
Затасканный пример: String приводится к Traversable, при этом String наследовать нельзя.
Это полный аналог механизма extension методов в C# и Kotlin с тем лишь полезным отличием, что позволяет не только добавлять методы, но и приводить к интерфейсам. Из-за того, что extension методы не позволяют приводить к интерфейсу в Kotlin, например, введена структурная типизация для таких конструкций языка как for.
И тут тоже инкапсуляция не нарушается.
Может быть.
Сложно судить без конкретных примернов. Пока все выглядит крайне логично и удобно.
Разве что xml в языке несколько странное впечатление производит как нечто пришпиленое сбоку чтоб было.
А то, что язык позиционируется болше на ФП, чем на ООП ни кто не скрывает. Во всех примерах, статьях и книгах skala-way ООП — это такое immutable ООП. Пока для меня это чаще всего очень удобно.
Все сервисцентры с которыми я имел неудовольствие общаться умели только одно: заменять «главную деталь»(тм), заказав ее из-за границы и взяв за это половину стоимости устройства.
Я лучше возьму в руки паяльник, а в случае неудачи куплю новое устройство. Это быстрее и веселее.
Больше всего поразивший меня случай: у фотоаппарата средней ценовой категории (15кр в 2006 году) сломалось гнездо карты памяти (вытащили карту рывком на себя). Все работает, только карта не держится.
Единственный предложенный в СЦ выход — замена платы. Обошлось бы ровно в половину стоимости фотоаппарата и 3 недели (сроки в СЦ не гарантировал, так что может и дольше).
А поразило меня абсолютное непонимание в глазах мастера при просьбе закрепить карту намертво.
Чтобы сделать это самостоятельно я в итоге потратил меньше времени, чем на дорогу до СЦ.
Я буду паять, перебирать и всячески чинить самостоятельно с полным осознанием риска ибо знаю, что найти мастера, которые будет работать не на «отвали» я не смогу.
Апофигей «мастеров» — это всевозможные «компьютерные сервисы». Я искренни верю, что есть хорошие компьютерные сервисы. Но они как суслики: они есть. Не видел, но есть!
На мой взгляд тут очевиден эфект испорченого телефона.
«Не выиграл, а проиграл. Не в шахматы, а в преферанс. Не запорожец, а 5 рублей.»
И все свои доказательства вы формулируете в виде «могу чётко и аргументированно доказать» без самого доказательства?
У вас великолепный дар говорить много и не сказать ни чего. К сожалению этот дар сейчас слишком распространен.
Но вот что бросается в глаза сразу: она, несомненно, выдающийся лингвист и психолог, но среди ее многочисленных областей знаний нет ни одной, позволяющей судить о механике работы отдельный нейронов.
Читая работы ученых (даже самых выдающихся) следует правильно расценивать их высказывания не о их областях науки: порой они просто не придают значения таким заявлениям.
Вот пример из лекции Татьяны Владимировны:
Как мне сказал знакомый астроном, количество нейронных связей в мозгу больше, чем звезд во Вселенной, а после этого астронома физик знакомый сказал: «Не звезд во Вселенной, а частиц во Вселенной». Частиц! Это же ужас.
Это высказывание очевидно не верно, но его верность не важна — это всего лишь лирическое отступление.
А "+" для объединения множеств не используется потому, что со времен iava "+" на всем подряд, кроме всевозможных чисел, приводит к toString и конкатенации строк. Оно так было до scala, пусть так и остается.
И совсем забыл:
>Я понимаю, что Вы знаете Scala. Разговор не про это.
А кто должен писать и читать код на scala? Тот, кто не знает scala?
Я — новичок в scala и у меня все эти ужасные 3 оператора на коллекциях (":+", "++", "/:") сложностей восприятия не вызывают, а кроме них и отправки сообщений операторов не распространенных в других языках в стандартной библиотеке фактически и нет.
Учитывая, что отправка сообщений — одно из основных действий в используемой модели многопоточности, логичным выглядит сократить его запись до минимума. Самое базовое действие имеет право на отдельный символ.
>Да, это то, что во всех христианских языках называется add().
Не add, а addFirst. Только зачем 2 слова, когда все понятно и с 2 буквами?
>addAll() в Java
Скажите честно, а Вы объединяете строки как str1.concatenate(str2) или через ужасно непонятный оператор?
Ответ прост: для базового часто используемого действия вполне можно ввести сокращенное обозначение.
>А чем слово foldLeft не угодило? Ну или, lfold?
Вот lfold — это воистину ужасно. Это выглядит как 1 слово, но им не является. Я с первого раза прочитать не могу. Но согласен, что foldLeft лучше, чем /:. Попробовали, идея оказалась неудачной, больше такие идеи не внедряют без прохождения инкубатора.
>Следует добавть: абсолютно бесполезных концепций, которые никем и никогда и нигде не будут использованы.
Разработчики typesafe stack некоторые операторы используют и другим советуют. Вот тут с 26 минуты:
www.youtube.com/watch?v=YZxL0alO1yc
Другие операторы вымрут — на то и нужен инкубатор, чтоб проверять идеи на жизнеспособность.
Как оказалось, разработчики scala с Вами согласны. Синтаксис упростили, теперь даже менее многословно, чем в C#, но все еще приводится к интерфейсы:
docs.scala-lang.org/sips/pending/implicit-classes.html
А «a! b» не может быть отрицанием, так как отрицание — унарная операция.
+: — это прибавление элемента ко множеству. Зачем тут ":" поймет любой, кто знает синтаксис scala. И не менее очевидно, что элемент добавляется в начало.
++ — объединение множеств. «Множественное добавление».
::= — в отношении этого оператора действует тот же принцип, что и для всех аналогичных: для immutable коллекций «a ::= b» — сокращенная запись для «a = a.::(b)» оно же «a = b :: a». Для mutable — аналог с изменением исходной коллекции.
Сам же оператор "::" крайне часто используется в scala и тесно связан с контейнером linked list (класс List).
"/:" — foldLeft. Рекомендуется его не использовать, так как foldLeft нагляднее.
Вот остальное уже более специфично и зависит от библиотеки. Например в scalaz есть огромное количество экспериментальных операторов от которых голова кругом, но они реализуют определенные концепции ФП, суть которых в имени функции не выразить, так что более развернутое имя понятнее не сделает.
А вот про сложные могу лишь догадываться, но не думаю что это может быть просто на каком-либо языке.
А вот про Kotlin я готов спорить долго. На мой взгляд он крайне непоследователен и, в отличии от scala, предлагает не стройную концепцию, а разрозненный набор плюшек:
Pattern matching? Долго и сложно! Мы переименуем switch и расширим его проверкой типа.
Выкинем все со словом «неявный». Даже если замена полностью эквивалентна. Не получается привести к интерфейсу, а итерировать по строке хочется? Введем структурную типизацию.
Синтаксис для структурной типизации? А давайте введем ее только для встроенных элементов языка!
Обход type erasure а неявных параметров нет? Добавим синтаксическую конструкцию!
Каррирование? Нет, не слышали. А в отдельных фигурных скобках можно указывать последний параметр, если он лямбда.
Перегрузка операторов! Почему операторы не добавить в список разрешенных имен функций? Ну так они же операторы!
Не нравится подчеркивание в лямбдах? А давайте первую попавшуюся переменную интерпретировать как аргумент!
Изменение типа переменных в зависимости от проведенных проверок! Не очевидно без IDE? Так пользуйтесь IDE — там такие переменные красиво подсвечиваются зеленым!
И так далее…
Не поймите меня неправильно, я считаю, что команда JetBrains делает очень хороший язык. Андрей Бреслав — умнейший человек. Они действительно создают нечто простое в использовании и крайне функциональное.
Но kotlin, в отличии от scala, я не могу мысленно свести в единую стройную концепцию.
Если в scala я вижу набор универсальных принципов на которых вырастает функционал самым логичным и естественным образом, как доказательства теорем из аксиом. Мне не нужно что-либо заучивать: понял принципы и все остальное кажется самоочевидным и единственно верным. И как в мат. аппарате те же принципы, что использовались для построения основы я сам могу использовать для ее расширения. Это то, что я бы назвал академическим подходом.
В Kotlin же нет лаконичного набора идей, а есть довольно большой и все еще раздувающийся набор не универсальных решений. Его мне надо заучивать. В итоге получается тот же C#, только на jvm. А зачем еще 1 C#?
Для обсуждения сложности для расшифровки и сложности для разбора в IDE лучше брать не неявные преобразования, которые полностью эквивалентны extension методам, обрабатываются точно так же и создают столько же вопросов, а неявные параметры.
Именно из-за неявных параметров IDE с большим трудом обрабатывают scala. Именно ради сокрытия неявных параметров в документации придуман синтаксический сахар для записи type class и use case в scala doc.
Это неявные параметры, такие как CanBuildFrom вызывают наибольшее количество вопросов.
Но эти сложности — это та цена, которую приходится платить за удобства. За гибкость, которую они создают.
А зачем тогда вообще расширять класс? С тем же успехом можно писать toTraversable(string).
Если, например, требуется отрезать от строки префикс в верхнем регистре, то гораздо проще и нагляднее написать
«ABCabc» dropWhile { _.isUpper }
чем
«ABCabc».toTraversable.dropWhile{ _.isUpper }.toString
В этом прелесть неявного преобразования: мы не просто добавляем 1 метод, мы получаем рассматривать строку как коллекцию символов, которой она, в принципе, и является.
Переопределение параметра создает очень большие проблемы при рефакторинге больших функций.
А вот перекрытие переменной из другой области видимости возможно в очень многих ЯП. Не могу сказать, что это абсолютное зло, но быть осторожным надо.
1 более удобное повторное использование кода:
Чтобы добавить все методы Traversable в String при помощи extension методов надо явно прописать все эти методы. При помощи же implicit converrsion достаточно StringOps унаследовать от Traversable и реализовать 1 метод: foreach. Это гораздо менее громоздко. А вот добавление по 1 методу как раз зачастую зло, ибо такой мощный механизм как расширение класса надо использовать очень редко, но с очень большими последствиями (как LINQ).
2 приведение к интерфейсу, что позволяет не использовать структурную типизацию как в Kotlin (повторяюсь).
Состояние актора мутабельно, но все изменения очевидно в 1 потоке а, следовательно, удобны и безопасны. Проблемы с мутабельностью при передаче между потоками. Посылка актору мутабельного сообщения – самоубийство. Если 2 потока владеют ссылкой на общий изменяемый объект, то синхронизация становится нетривиальной задачей: habrahabr.ru/post/143074/
Я не это имел в виду под повторным использованием. Повторное использование – это использование переменной в 2 разных смыслах. То есть если Вы заводите переменную count и в начале метода используете как счетчик одних объектов а в конце – как счетчик других, то это и есть повторное использование.
Параметры функции – это то, что ей передали.
В частности невозможность изменить значение параметра функции дает возможность полагаться при изменениях кода в конце метода на то, что мы работаем именно с параметром, а не с каким-то значением присвоенным в процессе без просмотра всего кода.
И нельзя забывать про оптимизации, доступные только для неизменяемых объектов.
Мне кажется, что многие проблемы от неопытности и восторженности. Разработчикам хочется применить все средства языка и они пихают их где надо и не надо. Почему-то C# разработчики не часто пишут extension методы, хотя на них можно реализовать такие мощные вещи, как LINQ.
Так же многие не считаются с гайдлайнами и используют не оптимальные методы языка, как, например, использование implicit conversions вместо type class, хотя все специалисты вроде разработчиков typesafe stack рекомендуют использовать type class.
В стандартной библиотеке не так много implicit conversions, гораздо больше implicit parameters, но при использовании о них чаще всего можно забыть.
Иммутабельность позволяет проводить многие оптимизации. А уж многопоточность без иммутабельности вообще превращается в пытку.
Вообще иммутабельность везде контролируется: val vs var – ваш выбор.
В каком смысле параметры функции иммутабельны? В том же, что м в java? Так и ответ тот же, что и в java, зато если требуется вернуть 2-3 значения можно использовать TupleN.
Или в том смысле, что внутри функции нельзя использовать параметр как присваиваемую переменную? Так это во многих ЯП, в том числе и с ООП парадигмой. Вообще присваивание значения параметру функции – это повторное использование переменной, что есть зло.
Про неявное преобразование: приводится не к подклассу, а к любому другому классу. Экземпляр на самом деле не создается и в рантайме просто вызывается статический метод (где это возможно).
Затасканный пример: String приводится к Traversable, при этом String наследовать нельзя.
Это полный аналог механизма extension методов в C# и Kotlin с тем лишь полезным отличием, что позволяет не только добавлять методы, но и приводить к интерфейсам. Из-за того, что extension методы не позволяют приводить к интерфейсу в Kotlin, например, введена структурная типизация для таких конструкций языка как for.
И тут тоже инкапсуляция не нарушается.
Сложно судить без конкретных примернов. Пока все выглядит крайне логично и удобно.
Разве что xml в языке несколько странное впечатление производит как нечто пришпиленое сбоку чтоб было.
А то, что язык позиционируется болше на ФП, чем на ООП ни кто не скрывает. Во всех примерах, статьях и книгах skala-way ООП — это такое immutable ООП. Пока для меня это чаще всего очень удобно.
И из всех она всех она взяла лучшее.
Все сервисцентры с которыми я имел неудовольствие общаться умели только одно: заменять «главную деталь»(тм), заказав ее из-за границы и взяв за это половину стоимости устройства.
Я лучше возьму в руки паяльник, а в случае неудачи куплю новое устройство. Это быстрее и веселее.
Больше всего поразивший меня случай: у фотоаппарата средней ценовой категории (15кр в 2006 году) сломалось гнездо карты памяти (вытащили карту рывком на себя). Все работает, только карта не держится.
Единственный предложенный в СЦ выход — замена платы. Обошлось бы ровно в половину стоимости фотоаппарата и 3 недели (сроки в СЦ не гарантировал, так что может и дольше).
А поразило меня абсолютное непонимание в глазах мастера при просьбе закрепить карту намертво.
Чтобы сделать это самостоятельно я в итоге потратил меньше времени, чем на дорогу до СЦ.
Я буду паять, перебирать и всячески чинить самостоятельно с полным осознанием риска ибо знаю, что найти мастера, которые будет работать не на «отвали» я не смогу.
Апофигей «мастеров» — это всевозможные «компьютерные сервисы». Я искренни верю, что есть хорошие компьютерные сервисы. Но они как суслики: они есть. Не видел, но есть!