Pull to refresh
0
@AlexTheLostread⁠-⁠only

User

Send message

Привет, передача поведения это не равносильно callback-hell. То что вы называете callback-hell, вытекает из функций с сайд эффектом. Потому что вы передаете что-то что нужно выполнить потом и это что-то будет влиять на "произвольную" часть программы, т.е. будет выполняться некоторые: IO метод или модификацию данных в вашей программе(т.е данные у вас в программе мутабельны) читая функция может только возвратить аргумент и это для вас не будет напрягающим фактором. Как пример сортировка(пишу на псевдокоде):


Array[T] sort(array: Array[T], comparator: (T, T) => Int) // T что-то мы будем упорядочивать


  • Array[T] — Возвращаемый тип.
  • array: Array[T] — Сортируемый массив.
  • comparator: (T, T) => Int — Сравнивает два числа и определяет их порядок. Чистая функция.

Как вы видите преимущество очевидно. Вместо того что бы писать отдельный метод для каждого типа и его возможной сортировки вы просто передаете поведение(сравнение) как параметр.
Проблемы же с отложенными вычислениями решаются другими способами, использованием Promise, Future и т.д. которые как ни странно принимают на вход код(т.е. поведение), но их устройство само по себе помогает уменьшить умственную нагрузку на программиста.

возможные сложности при изучении функционального программирования

Я думаю этот тезис вводит людей в заблуждение. Код написанный с сильным упором в FP оказывается:


1) Копмактнее — вы переиспользуете поведении за счет передачи функции как аргумента или результат.
2) Проще для понимания — имутабельные данные не требуют думать о проблемах изменения их стотояния. Вы не думаете о сайд эфектах когда пишите чистые функции.
3) Лучше тестируемый — чистые функции легко проверить, они зависять только от входных параметров, т.е. не нужно гемороиться с моками.
4) Concurrency проще — за счет использования Imutability(вы пытаетесь понять почему данные случайным образом меняются на не валидны(всево лишь случайно/по незнанию написанный код рассихноризирующий конкурентное взнаимодейстиве), чистые функции легко паралелятся и не требуют синхронизации.

По поводу SEDA, исхожу только из вашего описания — реализовать задачу как последовательность событий/шагов, каждый из которых выполняется асинхронно можно без проблем и не используя акторы. Через композицию функций где каждая выполняется одна за другой и асинхронно(т.е. передается на выполнение в пул потоков). Можно через пулы сообщений/данных, у вас есть n сущностей или групп сущностей каждая отвечает за некоторый функционал, и есть пулы сообщений(или просто данных на вход), вы помещаете ваши данные в первый пул, скажем организованный просто как FIFO(т.е. очередь) а сущности-обработчики просто выбирают эти данные обрабатывают их и после помещают в пул сообщений следующей сущности-обработчика или группы сущностей-обработчиков.
Но вы не рассказали самое главное это хранение состояния в акторе, и создание актора на каждую сущность в системе — пользователя, обработчика событий(может быть много акторов) и т.д., хотя я тут не совсем корректен вы об этом мельком сказали и тут же написали что так делать не нужно.
Почему то негативно отозвались о прозрачном распределенном взаимодействии которое должна предоставлять система акторов, просто на основании того что вам нужны специализированные протоколы передачи данных(что я вижу в общем то проблемой конкретно данной реализации, ничего не мешает[кроме трудозатрат] определить общий интерфейс и для каждой группы акторов настраивать[предварительно написать] специализированный протокол межсетевого взаимодействия.
Ни чего не сказали о подходе fault-tolerance, хотя это скорее специфика конкретной реализации а не модели акторов, хотя это и вытекает из модели акторов.

Согласен с вами по поводу динамики vs статики для больших проектов.
К тому же это подтолкнет к экспериментам и появлению новых все лучших подходов к разработки для web.

Спасибо был не до конца осведомлен, я знал что Rust утилизирует память не явного участия программиста но не знал что это выполняется отличным от GC механизмами.
Если кому-то интересно: https://www.rust-lang.org/en-US/faq.html#is-rust-garbage-collected.

На мой взгляд идея крутая как и asm.js для написания именно библиотек/виртуальных машин, насколько я вижу они будут работать очень быстро(относительно быстро).
Но для реализации конечного продукта системные языки типа rust и с/с++ слишком не выразительны будет сильная потеря в производительности труда. По этому, интересно поддерживает ли данный модуль сборку мусора, которая в общем то есть в Rust? Насколько я понимаю память организуется как JS массив и управляется непосредственно модулем/приложением? Если уже реализована сборка мусора будет круто перенести на данный модуль ScalaJs, ClojureScript и др. нуждающиеся в автоматическом освобождении памяти.

Суть акторов, что любой актор может послать любое сообщение любому актору и только актор сам решает, может он обработать это сообщение или нет. Это позволяет строить очень гибкие решения.

Я с вами полностью согласен, но они одновременно и гибкие и не безопасные. Актор это скажем человек, вы можете пасти его на поле и кормить сеном, хотя он будет отказываться), но я думаю вам все же нужно знать что это человек и как с ним взаимодействовать — т.е. его тип и связанный с типом интерфейс.


Иначе у вас получится обычный ООП с дерганьем методов и сильной связанностью. Поэтому вам и Future больше подходит для задач чем акторы.

ООП и акторы это концепции очень схожие и да я хочу что бы у меня была сущность ведущая себя как актор но предоставляющая такие же гарантии как интерфейсы в ООП(дерганье методов).


Писал несколько проектов на Akka, вообще ни разу не сталкивался с неправильной инициализацией акторов и всеми теми проблемами что вы описали. Даже новички так не ошибались в коде.

Ну что ж тут я с вами спорить не буду, спасибо за "апелляцию к авторитету".)


2) Таких гарантий нет ни в одном приложении. Это все зависит только от разработчика. Он может забыть что угодно. В одном месте добавил метод, в другом забыл его «дернуть».

Не совсем об этом, речь о том что вы передали сообщение а оно не дошло, т.е. по аналогии вызвали метод а он не был вызван, причем по какой то внешней причине. Скажем вы в реализации без актора вызвали метод который проверяет является ли данный запрос мошенническим и вы будете уверены что он будет вызван, т.к. вы можете исходя из кода(т.к. это цепочка вызовов) быть уверены что на проде будет вызываться конкретная последовательность методов. Если у вас этот процесс реализован как передача сообщений от актора к актору таких гарантий нет, понятно — у вас могут быть и тесты и хорошие разработчики и тестировщики, но это дополнительная сложность, которая может привести к ошибке, и я уверен такие ошибки периодически будут встречаться вне зависимости от вашего уровня организации работы.


3) Таких гарантий тоже нет ни в одном приложении, см п 2.

Есть гарантия что если вы вызвали метод то он выполнится и есть гарантия какой будет конкретно вызван метод, понятно что только если ваш язык имеет достаточный уровень проверки типов, как в Scala.

Согласен нужно было уточнить что я говорю все же о Akka.
Касаемо:


По поводу контроля типов: ведь проблема того, что актор не обрабатывает сообщения типа A ничем не отличается от той проблемы, что актор-получатель по каким-то причинам решил не обрабатывать конкретное сообщение типа A...

Все таки я вижу отличие в одном случае это часть логики — т.е. мы так задумали что сообщение не обрабатывается, в другом это не ожидаемо(не корректное поведение).

Возможно я не везде ясно выражался, но в начале уточнил что у меня перечисленные вопросы возникли именно с Akka. В общем то это проблема не то что бы Akka+Scala а отсутствия проверки типа отправляемого сообщения. Отличие Scala лишь в том что одно имя означает близкие по сути но разные сущности. В самом простом виде эта проблема заключается в том что вы посылаете другому актору тип A но тот не имеет обработчика для этого типа(т.е. данное сообщение вообще не должно посылаться данному актору).

Использовал Akka+Scala. Был в начале воодушевлен идей акторов. Попробовал Akka, был несколько разочарован. В итоге для классического подхода считаю нужно выбирать Future, далее объясню что имею ввиду.


Почему? Мы работаем c актором просто как с ActorRef без типа, соответственно нет гарантий на стадии компиляции что сообщение передается конкретному актору(типу акторов) и актор может его обработать в принципе, нужно писать тесты. Нет гарантий на стадии компиляции что актор инициализируется корректно, из-за отсутствия типа, например передаются не корректные параметры как аргументы конструктора.


По итогу мы получаем такую цепочку боли:
1) Нет гарантии что все акторы инициализировались правильно при старте приложения.
2) Нет гарантий что все акторы передают сообщения тем акторам которым должны и принимаю сообщения от тех от которых должны.
3) Нет гарантии что актор сможет обработать пришедшее сообщение. Вы добавляете передачу сообщения в один актор но можете пропустить добавление его обработчика в один из акторов который потенциально его может принимать, и это из-за отсутствия типизации.
Т.е. нужно писать очень много тестов.


В целом хорошо описано тут: http://stew.vireo.org/posts/I-hate-akka/


Сейчас вижу только одно применение акторам, но сильное (по сути это и есть их суть, замысел) — построение stateful вместо stateless приложений когда на каждую сущность в системе ровно один актор и даже если это распределенная система(через akka claster). Если строить систему таким образом то получается очень много преимуществ — отсутствие необходимости кэша между backend'ом и хранилищем данных и состояния гонок, потому что за каждую сущность отвечает ровно один актор хранящий свое состояние и он обрабатывает все приходящие к нему данные последовательно. В случае распределенной системы akka cluster — это секционирование(partitioning) из коробки. Но остается все же вопрос как выполнить транзакцию которая захватывает больше одного актора(т.е. сущности).

В статье есть и на это ответ :)


Но пока пальцы на руках и ногах не закончились, мы создаём языки, которые содержат десятки ключевых слов, сотни ограничений, извилистый синтаксис и справочное руководство, которое читается как книга закона

Я за Option.)

"Скорее всего, будет расти как снежный ком" — пиар, пока о котлине я слышу разговоры только среди разработчиков под андроид. К тому же я не нашел ответа на главный вопрос зачем нужен этот язык, кроме замены java при разработке под андроид и здесь лишь по причине отсутствия собственного толстого SDK.


Те кого устраивает Java — инертные пользователи и крупные корпорации не будут массово переходить, те кто хочет остаться на jvm и получить великолепный язык для быстрого и лаконичного выражения своей мысли используют Scala. К тому же Scala имеет в дополнении к Java экосистеме свою собственную, очень крутую.


Подытоживая, массам разрабатывающим типовые CRUD не нужно ничего кроме Java, профессионалы если хотят уйти от Java, в основном выбирают Scala.

Красота это pattern matching. А по поводу switch, когда писал на Java всегда использовал if. Так и не нашел варианта когда он полезен.
Переход на Scala для меня решил проблему боли от ненужного и невыразительного кода который приходится писать используя Java.

Тема явно не раскрыта, существует не мало языков компилируемых в native code.

Здравствуйте, можно узнать почему? Я лично отдаю предпочтение Scala. Он в отличии от Rust, позволяет очень хорошо описывать сложную предметную область за счет сочетания ООП, ФП и других фич. К тому же имеет богатый набор средств для разработки конкурентных систем, не говоря уже о библиотеках под JVM на все случаи жизни.

Хорошо, можем не вести диалог. А я надеюсь это был диалог а не спор. Я во всяком случае старался аргументировать.


От вас же прошу напоследок простое. Приведите источник на основании которого можно понят что ваши утверждения о том что scalac генерирует плохо оптимизируемый JVM код, в сравнении с javac. И на этом разойдемся.)


Потому что если вы не можете как то подтвердить свои слова, получается вы пытаетесь утверждать о работе того что сами не понимаете.

Здравствуйте, я не утверждал что нужно нужно переписывать проект с нуля как только появилась новая лучшая технология. Это вы сами додумали. Используйте новые лучшие технологии для новых проектов/сервисов/микросервисов или в случае если вы уперлись в стену с текущими технологиями.


Если вы не согласны с тем что Kotlin по большому счету это просто синтаксический сахар, объясните пожалуйста свою позицию. Возможно я с вами соглашусь.
Я же вам как аргумент моим словам приведу ключевые утверждение о "Why Kotlin?", официальная доктрина разработчиков перечислена на главной странице сайта о языке:


Радикально уменьшить количество шаблонного кода, который необходимо написать.

Исключительно синтаксический сахар.


Избегает целого класса ошибок таких как NPE

Избегает это когда нет такого понятия как NULL, а elvis даже в Java не попал можно в интренте найти обсуждения почему. Но в общих чертах это лишь делает код более не понятным, в отличии скажем от монады Options. Тем более что в java уже давно можно использовть Optional, недавно он напряму вошел в JDK. В чем провыв Kotlin'а по в данном случая мне не ясно.


Позволяет писать приложения под разые целевые платформы.

Это 'приимущество' вообще не понятно, уже очень давно существуют технологии позволющие все тоже делать и на Java и на многих других языках. Но что-то так и ни одна не взлетела либо быстро умерла. GWT как пример.


100% со всеми существующими библиотеками для JVM

Это попросту а отсутсвие недостатка. Scala, Clojure и т.д. все они поддерживают такую возможность.


Теперь о Scala. Две ключевые концепции:


  • Scala полностью объектно ориентированный язык, в том смысле что — все является объектом, в т.ч. и примитивы.
  • Scala полностью функциональный языке, в том смысле что — любая функция объект первого рода. Так же Scala включает в себя много важных концепций из мира ФП.

А так же в Scala есть: Pattern Matching. Язык богат важными примитивами для разработки конкурентных и распределенных систем. Сотственная мощная STD lib. Интерполяция строк. Объекты компанъены. Можная поддержка обощенного программирования. Макросы. И ещё мное другое.
Но главное отличие это две фундаментальных концепии которые я кратко описал выше.


И ещё одно ключевое понятие, Scala это — "A Scalable language". Я пожалуй не смогу вам объяснить все лучше чем написано на www.scala-lang.org. Зайдите прочитайте, убедитесь.


Ко всему Scala, не экспериментальный язы "For Fun", а полностью готовый для промышленной разрабтки язык и платформа, т.е. обладающее достаточным набором библиотек и фреймворков для построения приложения любого уровня сложности.


SBT — мощная система сборки, реализует как деларативный(богатая встроенная система команд) так и императивый подход(можно описать процесс напрямую на scala).
Play Framework — разработка веб приложений, компактная документация, компактный фрейморк в сравнени с монстрами — javaEE и Spring. Имеет полный спект необходимых встоеных средст для современной Web разработки.
Akka Framework — разработка конкурентных и распределенных системы потребляющие минимум ресурсов, радикально уменьшающая сложность построение таких систем.
Slick — аналог LINQ, почитайте сами что это если не знаете.


и д.р. смотртите Lightbend Reactive Platform


Жду от ваc пояснения почему я не прав говоря так о Kotlin в стравнении со Scala.

Код на любом языке оптимизируется одинаково — уменьшается потребление ресурсов: памяти, процессора, io.

Мне кажется тут вы согласны, но если нет уточните.


JVM оптимизирует выполнение байт кода а не высокоуровневых конструкций языка

Это я так же считаю правильным.


а на низком уровне все есть байт-код который создается любым компилятором для JVM

Это утверждение тоже верно.


Каждое выражение истина следовательно и истинно их объединение. Т.е. писать что я не прав на основании только этого нельзя; нужно как-то уточнить где, в другом месте, я был не прав. Потому что иначе не понятно, что вас смущает.


Насколько я вижу вы считаете, что я не полностью раскрыл тему. И по этому пишите о том что важные отличия в перечисленных вами деталях.


Хорошо, давайте разберемся:


IT может оптимизировать одну последовательность байт-кодов, а не оптимизировать другую.

Согласен с вами, и это не противоречит моим словам.


Если одну последовательность байткодов часто генерирует javac, а другую javac не генерирует, а scalac генерирует, и у разработчиков JVM не хватает времени, то какую оптимизацию они впилят в первую очередь?

Вот тут я хотел бы от вас получить конкретные ссылки на источники, которые доказывают что javac байт код как-то отличается от scalac — таким образом что JVM лучше оптимизирует код первого(т.е. что байт код генерируемы scalac не попадает по какое то кол-во шаблонов оптимизации). Иначе это просто пустые слова.
Так же хочу уточнить что синтаксис и семантика Scala сильно отлична. По этому сравнивать можно как минимум только идентичные конструкции. И ниже об этом.
Могу согласится с тем что команда занимающаяся JVM, в первую очередь изучают результаты компиляции самого массового языка, но почем вы считаете что к коду scalac не будут применены какие-то из оптимизации?


Это не абстрактные умозаключения. Скажем,… результирующий массив точного размера и туда запишет результат конкатенации, а потом создаст объект String.

Scala использует тот же Java.lang.String, почему вы считаете что в scalac нет этой очевидной оптимизации, в точно той же форме которую требует шаблон в JVM, и на выходе будет что-то не оптимальное? Пожалуйста ссылку как аргумент, потому что иначе это и есть абстрактные умозаключения.
Так же получается Kotlin эту про обработку сделает, но если вы не защищает мысль выраженную комментатором с которым я не согласился, то вы в целом вырвали фразу из контекста.


Подытоживаю.
Вы не исправили мою ошибку, а уточнили сказанное мной и не во всем корректны сами.
Не раскрыли тему почему байт код на одном языке не будет соответствовать шаблонам оптимизации а на другом будет. Пожалуйста приведите ссылки, на авторитетный источник.

Я не ввожу в заблуждение, я не автор изначального сообщения.
Но как мне видится автор предполагал что общается со сведущим в теме человеком. Который понимает когда произошел отказ от CLR. А так да, если объяснять тому кто не знает хронологию событий нужно это уточнять. Напишите автору может он как-то эту не точность исправит.

Никогда не бывает ничего абсолютно лучшего, как и абсолютно худшего. Только Ситхи возводят все в абсолют

Я ничего не возводил в абсолю, это вы придумали. Даже описал один случай когда Kotlin объективно лучше Scala — это разработка под андроид.


А по делу,…, близкий к scala.

Я писал выше почему незначительное синтаксическое улучшение это не то же самое что прорывная Scala.


Тут проще, как мне кажется, понять как его лучше оптимизировать, и скорее всего JIT его лучше оптимизирует (поправьте если ошибаюсь).

Код на любом языке оптимизируется одинаково — уменьшается потребление ресурсов: памяти, процессора, io. JVM оптимизирует выполнение байт кода а не высокоуровневых конструкций языка, а на низком уровне все есть байт-код который создается любым компилятором для JVM. И вообще если вы не уверены не пишите то что может быть глупостью, а проверяйте.


Ну а какой язык использовать в новом проекте, это спорный вопрос. Поставьте себя на место тех. дира, и подумайте, из кого вы бы набрали команду? С учетом поиска людей в команду, его поддержки и т.п.

Тогда можно до конца дней человеческих, сидеть на Java и вообще ничего нового не разрабатывать. Только ныть когда проект разрастется, что все тормозит, невозможно рефакторить потому-то код ужасен и т.д. Зато в начале сэкономили чуть бюджета и не парились с этими новыми технологиями и хорошими специалистами.

Information

Rating
Does not participate
Registered
Activity