Pull to refresh
32
0

Разработчик

Send message
Третья проблема из той же серии — вставка новой сущности, которая ссылается на существующую с известным ИДом.

EntityManager.getReference или я не понял проблемы?


Кэшировать JPA сущности нельзя.

Second-Level Cache?


В целом я согласен, JPA хороша для простых приложений. ORM это в целом сложная пролема

Почти все споры – споры о терминологии. "Преждевременная оптимизация – корень всех зол", "преждевременная" не значит "любая" и не значит "до окончания всего функционала".
С одной стороны потерять месяц на оптимизацию компонента, занимающего 10% времени выполнения глупо. С другой стороны разрабатывать систему обработки петабайтов потоковых данных в день изначально на PHP тоже не самая умная идея.
Ну и не забываем о том, что самый быстрый код обычно труднее всего читать и поддерживать.


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

Я решал похожую задачу для долгоиграющих процессов, остановился на screen и передаче аутпута через файл:


  • с процессом можно взаимодействовать вручную на машине, если нужно через screen
  • не нужен отдельный порт – вывод передается через tail основным ansible-каналом
  • минус в том, что интеррапт ансибла не прерывает сам процесс (но может быть это и плюс), а так же если процесс ждет ввода ансибл об этом не знает и тоже ждет
  • приходится костылить для получения exit code

            self._shell(" && ".join([
                "echo -e 'logfile %s\\nlogfile flush %d' >> %s" % (logfile, delay, config_path),
                "sudo touch %s" % logfile,
                "sudo chmod a+rw %s" % logfile
            ]))
            exit_code = "EXIT CODE "

            started = datetime.datetime.now()
            self._shell("screen -L -c %s -S %s -d -m sh -c $'(%s); echo %s$?'" %
                        (config_path, task_id, command.replace("'", "\\'"), exit_code))

            self._display.display("Command started in screen -r %s" % task_id)
            self._display.display("> %s\n" % command, color=C.COLOR_VERBOSE)

            offset = 1
            rc = None
            while True:
                status = self._raw("screen -S %s -Q info" % task_id)
                alive = status["rc"] == 0

                chunk = self._shell("tail -c +%d %s" % (offset, logfile))["stdout"]
                chunk_len = len(to_bytes(chunk))
                offset = offset + chunk_len

                last = chunk.rfind(exit_code)
                if last > -1:
                    rc = chunk[last + len(exit_code):]
                    rc = int(rc) if rc.isnumeric() else None

                if chunk_len > 0:
                    self._display.display(chunk[2:] if chunk.startswith("\r\n") else chunk)

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


List Int = Unit + (Int × List Int) = Unit + Int × Int × ... = Int^n
Int^n + Unit <> (Int + Unit) ^n

Согласен, как я писал выше — это как раз разница между tagged и untagged. Второе это T × Tag.

Пример тут ни к месту, List это не сумма, это рекурсивный тип, представляющий собой степень (Int^n = Int × Int × ...), конечно Int^n × Unit <> (Int × Unit) ^ n.
Объединение это термин из теории множеств, а сумма — категорий, но описывают они одно и то же для типов.

Типы суммы и типы объединения это одно и то же. Но тут вы правы: можно сказать что этот union-type из Scala 3 это untagged union в отличии от tagged union в Haskell и sealed types/enums в Scala.

Есть, они же sum types, их нельзя указать ad-hoc, есть возможность объявить именованное объединение. Как и в Scala через sealed family или в Scala 3 через enum (который тоже только синтаксический сахар).

Вы серьезно? Sealed не для этого создавались, это костыль в данном случае.

Вы серьезно? Именно для этого, sealed позволяет компилятору определять полноту кейсов и собственно является SUM частью алгебраических типов.


Я такого не говорил, с точки зрения смеси ФП с ООП это костыль, с точки зрения ФП монада в монаде, это увы перебор

Вы этого не говорили, тем не менее с точки зрения теории категорий и то и другое суть копродукт, о монадах речь вообще не шла и тут не важно, монады это или нет


А по моему у вас неверные сведения

Приведенная вами цитата не опровергает моего утверждения. Union types были добавлены для облегчения вывода типов, чтобы преждевременно не выводить Product и т.п. слишком общие и бесполезные типы. Увы, на практике это означает, что при выводе типов результатом почти никогда не будет юнион, иначе вывод типов бы вообще не работал и выводил бы Seq(1, 1.5): Seq[Int|Double]. В связи с этим вам придется почти всегда вручную указывать тип, что делает его очень неудобным. Плюс юнион не может быть рекурсивным. В целом буду рад ошибаться, но Scala не светит нормальный Haskell-like union в ближайшем будущем.

В Scala 3 их добавили совсем для других целей и они почти не участвуют в выводе типов, так что использовать union types вряд ли будет удобно.


В Scala 2 тоже есть union types – всегда можно создать sealed family для этих вариантов, так же как можно создать case class для пары, вопрос тут только в целесообразности. Позволю себе с вами не согласиться – с точки зрения ФП Option[Try[String]] и Throwable | String | None это одно и то же.

Конечно, я говорил про идеоматические подходы в каждом из языков.

На этом примере хорошо видно, насколько код на JavaScript перегружен разнообразной пунктуацией и служебными словами, без которых можно обойтись.

Вот уж в первый раз встречаю обвинение любого языка в перегруженности пунктуацией со стороны лиспа :)


Никто вам не мешает указывать собственные рейнджи в виде [25, "i"] и раскрывать их потом как вам нравится, но как по мне вместо


(set-walls (10 40) (i 20) (i 60))

лучше написать


wall({ x: [10, 40], y: 20 })
wall({ x: [10, 40], y: 60 })

или что-то подобное, более читабельное чем набор чисел.

Лисп использует нотацию "(операция агрументы)", соответственно польская запись является нативной, в современных лиспах что-то поменяли?

Лисп имеет свою органичную логику, вероятно, не самая красивая идея навешивать дополнения, чтобы его приблизить к «императивному» стилю мышления.

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


А есть ли сейчас такие приложения, которые позволяют быстро в игровой манере с удовольствием на алгоритмическом языке начать программировать игры и головоломки без изучения сложных сопутствующих фреймвороков и библиотек вида XCode (не важно на каком языке)?

как насчет scratch?

Ну, положим для арифметики можно макрос наваять. Базовые циклы тоже есть, это не хаскел, можно жить без рекурсии, но зачем? Лисп ведь тем и хорош, что для людей можно сделать dsl, при этом сохраняя гомоиконность и полную мощь для машины.
А так не ясно чем это лучше обычного чтовыизучалившколе?

Если уж речь зашла о взаимодействии программных агентов с исходным кодом и генерации кода то собственно диалект Lisp'a был бы отличным кандидатом, какие особенности вашего языка делают его лучшим выбором в вашей задаче?

Могу предположить, что проблема кроется в браузерах. По их вине фронт это JS, который не приспособлен для сложный проектов из коробки. Если бы у вас фронт был такой, каким JS задумывали — вы бы просто открыли HTML+JS файлик в браузере и увидели результат (вопрос о быстродействии браузера это отдельная тема, вот например).
Тут же происходит натягивание совы на глобус в виде транспайлинга тайпскрипта в JS, статических чеков, компиляции стилей, линковки горы библиотек (для которых происходит почти то же самое, так как они в исходниках), минификации и прочей вакханалии.
Так что не стоит винить фронтэндеров в том, что они не умеют в кодинг. Если бы ваш бэк ограничили только перфокартами я бы посмотрел на время сборки проекта в 1000 строк.

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

Разобрался немного, но как например контролируется запись в InPort? Ведь если старое значение еще не прочитано, новое перезапишет старое? Не требует ли такой подход слишком тщательно следить за взаимодействием, писать в каждый порт только раз за круг, не забыть записать в какой-то порт?

block() блокирует алгоритм актора

вот об этом я и говорю — эта фраза не объясняет ничего, описанию этого алгоритма стоило бы уделить больше внимания


в вашем примере нет разделения на системную и пользовательскую часть
вы не расписали subscriber.onNext(....)

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


Это снижает параллелизм в случае недобросовестного клиента, который нагружает свой onNext тяжелыми вычислениями

Тут согласен, циркулярный буфер и отдельная таска отправки решит эту проблему. Этот код призван только показать, что решить задачу можно просто, вопрос в том — что дает усложнение?

Information

Rating
Does not participate
Location
Украина
Date of birth
Registered
Activity