LINUX.ORG.RU

О бедном Crystal замолвите слово

 , , ,


2

7

Рассматриваю варианты на замену Go для личного проекта. Сообществом Crystal высказывается мнение, что он то как раз на эту роль и годится, во всём превосходит первый и незаслуженно обделён вниманием (это же слышу от апологетов Nim). Go, конечно, куц и по возможности я бы предпочёл не популяризировать посредственный ЯП, если есть варианты. На Ruby никогда не писал, но после беглого ознакомления некоторые элементы заходят. Кто заглядывал под хвосткапот этому Crystal? Там всё серъёзно или я-его-сварила-из-того-что-было, как в V?



Последнее исправление: Rabinovich (всего исправлений: 1)
Ответ на: комментарий от asdpm

в js? окажется что? наверняка какая-нибудь дичь: типа что equality-тестов там нет, только identity (допустим). или что нет equal/hashcode контракта. или… что нет мап, а объект для этих целей использовать будет не удобно. или вообще что нет ответа (среньк-пук вместо ответа, ой, мы об этом не подумали, ты неправильно делаешь, зачем тебе это надо, читай вот тут книжку гуры-мудака)

Если говорить про мое мнение, то мне эти пляски с перегрузками операторов глубоко противны. Любые сложные объекты нельзя просто сравнивать, потому что их можно сравнивать по разному — потому они и сложные.

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

жава документирована. да даже если я захочу вообще понять что либо в жаба - я найду ответ в официальной документации. и окажется что это все продумано, есть какая-то «система» (понятий, инструментов)

Я тебе умоляю, вот в этом
https://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html
ты видишь какую-то ценность? Что для сраного списка создано семь интерфейсов и пять уровней иерархии — я должен быть благодарен? Фактически настолько сложная система не поддается модификации в базовые сущностях (если в них специально не добавлен десяток интерфейсов расширения) — что есть типовой реазультат чрезмерного употребления класс-ориентированного программирования.

не надо никакие сраные ю-донт-ноу-говно-js-книжки на 1000 страниц, где вынуждены обсуждать каждую молекулу высера именумого js

Добрая половина фич JS в проде просто не используется, потому на собеседовании на фронт тебя даже не спросят про оператор нечеткого сравнения «==».

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

А получилось говно. Sun ответил за свои грехи. Я еще раз напомню свой тезис из соседнего треда:
Как вкатиться в проект? (комментарий)

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

Крупные корпорации очень часто скатываются в говно, используя имеющиеся ресурсы всё менее и менее эффективно. Вот ты пишешь, что доки стройные, модель стройная — именно это увидели люди, ответственные за принятие решений, именно для них это всё рисовалось. Что в реальном кодинге это не работает — никогда не волновало, потому что это люди изначально не умели реализовывать сложные системы, хотя считали, что умеют. Опять же, самоцитируясь:
Как вкатиться в проект? (комментарий)

разгребая говно тысячу раз, две тысячи раз, три тысячи раз, ты ни на шаг не приближаешься к получению навыка постройки дома. Ну то есть может и получил, но совсем не от того, что разгребал говно. Это болезнь, которой больна большая часть профессионального общества. Думают эти люди так: я выполнил работу, я получил деньги — значит я выполнил работу хорошо, значит я что-то умею, значит я могу создавать собственные программы...
Люди в упор не могут увидеть, что они не научились писать софт, они научились лишь выполнять работу/зарабатывать ­— это разные вещи, как тёплое и мягкое, как канал и канализация, как белый цвет и розовый шум, они могут быть вместе, но могут и не быть.

другое - посрали, called it a day. через полтора десятиления (вроде) стали вливать огромные деньги в.. ускорение кала

В JS ввели новые инструменты взамен старым, но для совместимости оставили старые. В современном проекте старые инструменты уже не используются, вместо них применяют только строгое равенство, стандартизированные модули, «let» вместо «var», лямбды вместо «function», форматирование строк вместо знака «+», контейнеры Map и Set для данных, спред "..." массивов и деструктурирование сложных объектов, и прочее — это уже совсем другой язык, нежели 20 лет назад. Уже не говоря про TypeScript, который в прямом смысле другой язык.

byko3y ★★★★
()
Ответ на: комментарий от asdpm

зачем вам чтобы «само», можно же дополнительную работу сделать и частично того же эффекта достичь. разница между тем что сделал компилятор и тем что сделали автотесты - это разница между «автоматически» и «вручную».

Обычно считается, что статическая типизация заменяет часть тестов. Действительно, заменяется, но не бесплатно — нужно прописывать типы и снижается читаемость от лишних типов (не имею ничего против ЯП с опциональной типизацией).

byko3y ★★★★
()
Ответ на: комментарий от Shadow

Мне очевидно, что это тело блока первого (верхнего) for.

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

byko3y ★★★★
()
Ответ на: комментарий от Aber

Ты исследуешь то как же так получилось что состояние объекта совсем не такое каким оно должно было быть. И как детектив ходишь «по коду», ищешь источник проблемы, расставляешь все больше брейкпоинтов которые останавливают исполнение программы все раньше.

Ну то есть мне нужен отладчик, который умеет показывать исходный код при пошаговом выполнении. Это умеет даже gdb. Зачем мне эта ваша «IDE»?

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Что для сраного списка создано семь интерфейсов

Это и прекрасно, LinkedList несет реализацию семи контрактов: реализует контракт списка, контракт очереди (в том числе двухсторонней), можно получить его копию (интерфейс Clonable), можно сохранить на диск (Serializable), элементы можно обходить разными способами (Interator, Collection).

Чего тут действительно не хватает так это интерфейса Stack, потому как на основе LinkedList реализуется и стек (методы push, pop). Но только вот когда-то в 90-х была опрометчива создана коллекция Stack и теперь ничего не поделать, этот анахронизм теперь до конца жизни платформы.

Aber ★★★★★
()
Последнее исправление: Aber (всего исправлений: 2)
Ответ на: комментарий от asdpm

у жавы есть стандартная библиотека и считается что она (за каким-то исключениями) имеет очень высокое качество

Медленно работает и жрет кучу памяти — это входит в понятие «очень высокое качество»?

например там есть collection framework. сравнение не пользу JS

Стандартные типы данных в JS закрывают эдак 80% задач, для которых применяются collection framework. Можно спорить по поводу того, насколько эффективно они это делают, но, тем не менее, делают.

жаба среди манажед языков имеет наверное самую можную поддержку многопоточности (ну или одну из самых). и с некоторых пор имеет формализованную, документированную memory model. сравнение не пользу JS

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

Многопоточность в JS еще хуже, да, она там на уровне C/C++, так что не стоит о грустном.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Действительно, заменяется, но не бесплатно — нужно прописывать типы и снижается читаемость от лишних типов (не имею ничего против ЯП с опциональной типизацией).

Поэтому в современных языках повсеместно внедряется автоматический вывод типа. Т.е. если тип можно получить из контекста то его явное указание в коде не нужно. И языки с гарантиями статической типизации выглядят почти как скрипты.
Одновременно с этим возникает необходимость в IDE, а точнее в том чтоб IDE явно писала информацию о типе рядом с переменной/объектом. Контекст может находиться в совершенно другом файле, и т.к. человек не компилятор то чтоб однозначно прочитать код ему нужно показать связанную метаинформацию.

Aber ★★★★★
()
Ответ на: комментарий от byko3y

Любые сложные объекты нельзя просто сравнивать, потому что их можно сравнивать по разному — потому они и сложные.

разверни мыль пожалуйста, разве запроектированное в языке соглашение equals/hash не об этом? если нет этой идеи в языке изначально, то нет и мап, множеств которые имеют sane поведение. без этого даже элементарный мелких задач не решить. то есть если инструмент проектировали, продумывали - то это лучше, чем когда нет. всякий раз в языке, где, например, вышеназванного контракта не обнаруживается, оказывается что сам язык и его библиотека это бесполезная помойка, для работы непригодная, не позволяющая даже самую элементарную макакскую задачу решить.

В JS ввели новые инструменты взамен старым, но для совместимости оставили старые

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

применяют только строгое равенство

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

я уверен, ты знаешь, но чтобы уточнить мою мысль: над экземплярам reference types можно провести identity test (бесполезный в нормальных задачах) и equality test. семантика последнего должна быть sane по-дефолту для встроенных в язык и библиотеку типов и определима программистом для его типов. иначе не сможет работать set, dict. но если она определима, то чтобы работало сносно нужно еще hash-code, но тогда он должен быть тоже определим. и тут возникает контракт который нужно документировать, и возникает или интерфейс или «протокол» (питон). и возникает, не только, как ты мне помог выразиться - стройность. что еще важнее, оно работает в практических задачах, особенно если сравнивать с тем, где этого нет. поэтому нечто, над чем думали - оно лучше, по крайней мере для макаки типа меня.

у value types identity нет, а equality тест очевиден.

ну и остается еще для value types equality тест в виде коэрсивное х..-пойми, которое вообще никогда не должно быть нигде и которое непонятно почему нельзя просто взять и выбросить наплевав на обратную совместимость. это видимо «нестрогое равенство».

---

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

asdpm
()
Ответ на: комментарий от byko3y

Ну то есть мне нужен отладчик, который умеет показывать исходный код при пошаговом выполнении. Это умеет даже gdb. Зачем мне эта ваша «IDE»?

В CLI ты потратишь на дебаг не 30 минут а 2-3 часа :)

Aber ★★★★★
()
Ответ на: комментарий от byko3y

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

я признаться смутно помню и не эксперт, но там полно инструментов, они надежны, считается, что выверены/вычитаны. там ассортимент. можешь интринсик монитор брать синтаксисом, можешь мютексы из библиотеки, есть condition variables, есть executor сервисы, пулы, есть коллекции в которых там как-то само всё сделано. это даже я как пхпшник знаю, пробовал и могу сказать всё там нормально. и документировано всё. и оно работает и никаких дедлоков. и изучать для этого главу про JMM из JLS вовсе необязательно, есть другая точная официальная документация / публикации авторов.

с инструментами многопоточности в Go, которое хоть и не дает безупречных гарантий

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

безупречных гарантий

прямо «безупречные гарантии» я не знаю такой язык, это не язык нужен наверное, а ОС без многозадачности ну и с одним процессором понятно.

asdpm
()
Ответ на: комментарий от byko3y


у жавы есть стандартная библиотека и считается что она (за каким-то исключениями) имеет очень высокое качество


Медленно работает и жрет кучу памяти — это входит в понятие «очень высокое качество»?

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

asdpm
()
Ответ на: комментарий от Aber

А есть сишные проекты написанные почти целиком в одном файле на 10к-100к строк, им наверное тоже не нужны никакие сложные IDE, хватит одного VIM с 2-3 плагинами, нужен поиск функции по имени, быстрый переход на функцию, автозамена, автодополннеие и пожалуй все.

Еще один всё понел. Все проблемы от того, что какие-то умники нашинковали цельный код на тысячу частей, якобы это какая-то «модульность» и «абстракция», хотя по факту это противоположность модульности. «Модульность» — это когда ты можешь читать одну часть кода, не зная другой части кода. А если у тебя одна часть кода намертво завязана на семь интерфейсов и пять базовых реализаций — это не «модульность», это монолитная лапша.

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

byko3y ★★★★
()
Ответ на: комментарий от Aber

Это и прекрасно, LinkedList несет реализацию семи контрактов: реализует контракт списка, контракт очереди (в том числе двухсторонней), можно получить его копию (интерфейс Clonable), можно сохранить на диск (Serializable), элементы можно обходить разными способами (Interator, Collection)

А теперь представь, что список в JS реализует всё это без парада интерфейсов. Можно тихо-спокойно выполнить задачу, а можно выполнить ее пафосно, с торжественным парадом и оркестром. Как и сделали в Sun. Та же история была в Facebook:
https://habr.com/articles/593167/
Что они сделали в Facebook? Да вообщем-то ничего, они заменили Zookeeper на Zookeeper с их прокладкой. Но проект сдан, премии выплачены, задачи в жире закрыты, по графику и даже с опережением.

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

Чего тут действительно не хватает так это интерфейса Stack, потому как на основе LinkedList реализуется и стек (методы push, pop). Но только вот когда-то в 90-х была опрометчива создана коллекция Stack и теперь ничего не поделать, этот анахронизм теперь до конца жизни платформы.

Это типовой результат применения класс-ориентированной парадигмы. Реальные алгоритмы и интерфейсы имеют схожесть, но они никогда идеально не наследуются друг от друга, и всегда найдется какой-то очередной объект, который не впишется ни в одну модель. Именно потому МОДЕЛЬ ДОЛЖНА БЫТЬ КАК МОЖНО ПРОЩЕ.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

А теперь представь, что список в JS реализует всё это без парада интерфейсов.

Ты что-то имеешь против статической типизации? Ранее ты утверждал что тесты могут заменить статическую проверку типов, только они не заменяют. Проверка типов удостоверяется в совместимости типов, тесты проверяют поведение.
Есть только одна альтернатива – Haskel, там вроде все гарантии на стадии компиляции, но желание осиливать FP у меня нет. Даже мальком увиденной дискуссии между FP кодерами как правильнее обернуть сайд эффект в манаду отбивает всякое желание. У меня такое ощущение что они не пишут программы а решают головоломки.

Aber ★★★★★
()
Ответ на: комментарий от asdpm

winforms, fx, pyside примерно в один миллиард раз проще чем на html+css+js

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

В конце концов, если твои альтернативы так хороши, никто не запрещает тебе скомпилировать их в wasm и разместить вместо ненавистного HTML/CSS. Но пользователи отчего-то не сильно радуются такому.

Rabinovich
() автор топика
Последнее исправление: Rabinovich (всего исправлений: 1)
Ответ на: комментарий от byko3y

А теперь представь, что список в JS реализует всё это без парада интерфейсов

Списки в JS из коробки? Любопытно.

А теперь представь, что есть некоторый набор стандартных функций, который работает со списками (ну там filter, map, reduce и всё такое прочее), и тебе надо сделать, чтобы они работали и с твоим пользовательским типом тоже. Ну чтобы не городить этот чёртов map каждый чёртов раз для каждого чёртова нового типа.

Если стандартные функции реализованы в терминах абстракций (например, абстрактных типов данных, спрятанных за некоторым интерфейсом), ты просто реализуешь интерфейсы этих абстракций (условные cons, first и rest для абстрактного списка) в своём типе и откидываешься на спинку кресла, у тебя всё просто работает (тм).

Если же стандартные функции реализованы в терминах одного конкретного типа данных… ты вздыхаешь, запускаешь вим и начинаешь писать my-twisted-set-map. Ну или наследуешься от конкретного типа, который умеет map, со всеми вытекающими. Если тебе это высочайше позволено, конечно.

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 6)
Ответ на: комментарий от Aber

Одновременно с этим возникает необходимость в IDE, а точнее в том чтоб IDE явно писала информацию о типе рядом с переменной/объектом. Контекст может находиться в совершенно другом файле, и т.к. человек не компилятор то чтоб однозначно прочитать код ему нужно показать связанную метаинформацию

Люто плюсую к информации о типе ­­— в крестах я страдаю от отсутствия информации о типе.

Правда, по типам у меня есть замечание. Венгерская нотация была чудовищно извращена массовым программистом. Изначально префиксом переменной было НАЗНАЧЕНИЕ переменной. То есть, «индекс в строке имени» или «имя файла конфигурации» — это не просто «строка», не просто «число», а конкретная информация с конкретными применением. В пределе это «аргумент, который нужен этой функции» и «результат, возвращаемый этой функцией» — это и есть «тип».

Это я о том, что такую информацию в полезной форме выдать все-таки сложнее, чем может показаться. И здесь хочется как бы спросить «а где же ваши IDE?» — и ответить в рифму, потому что дефекты в дизайне языка никаким IDE не исправляются.

byko3y ★★★★
()
Ответ на: комментарий от asdpm

разверни мыль пожалуйста, разве запроектированное в языке соглашение equals/hash не об этом?

Для хэшмапа есть как минимум три распространенных формы сравнения: identity, равенство ключей, и равенство всех пар ключ-значение. Если хэшмап упорядоченный, то может добавиться равенство порядка... а может и не добавляться. Из-за сложности объекта возникает более одного сравнения для одого и того же объекта.

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

Зато этот тупиковый подход является хорошим оправданием для того, чтобы оставаться при работе, строгать метод за методом и интерфейс за интерфесом, получать гигантскую кучу взаимодублирующего кода, писать к ней такую же по объему документацию. Грубо говоря, для класса «собака» реализуем функции «почесать за ухом», «понюхать другую собаку», «пописать под кустом», «записаться в стрим» — короче говоря, формы взаимодействия С ДРУГИМИ ОБЪЕКТАМИ, что есть заранее невыполнимая до конца задача, потому что других объектов бесконечное число.

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

Кстати, за это же ненавижу Rust, только там кроме бесконечных специализированных функций есть еще нашествие ёлочек Option<Box<Vec<char>>>.

над экземплярам reference types можно провести identity test (бесполезный в нормальных задачах) и equality test. семантика последнего должна быть sane по-дефолту для встроенных в язык и библиотеку типов и определима программистом для его типов

Ты опять мыслишь в парадигме «класс должен уметь решать все на свете задачи». Как правило, сложный объект создают не для того, чтобы просто иметь ассоциативный массив строка-строка, там хранятся непростые ключи и непростые значения, которые могут по разному применяться в зависимости от того, какая функция с ними работает — именно потому нет никакого смысла раз и навсегда привязывать все функции к этому ассоциативному массиву. И когда ты это поймешь, то поймешь, что все эти сравнения сложных объектов должны реализовываться в ИСПОЛЬЗУЮЩЕМ хэшмап коде, а не в самом хэшмапе, реализацией либо явными функциями с говорящими названиями, либо прямо по месту инлайновым алгоритмом.

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

Единственная «практическая задача», которую я тут вижу — это написать строки кода и пропорционально заработать деньги за них, в два раза больше строчек — в два раза больше денег. Красота.

Есть классная статья по этой теме, но для питона, там в том числе пример того, как код писателя строчек получилось ужать в 120 раз:
https://habr.com/articles/140581/

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

Решает задачи пользователя. Больше меня ничего не колышет.

byko3y ★★★★
()
Последнее исправление: byko3y (всего исправлений: 2)
Ответ на: комментарий от Aber

В CLI ты потратишь на дебаг не 30 минут а 2-3 часа

Да, я чувствую отсутствие адекватных отладчиков под линь, но торможение получается максимум в два раза. В частности, примерно потому никто не спешит делать удобный отладчик (не сильно горит). А еще в отладке собственных сложных проектов пошаговый проход отходит на второй план, важнее становятся логи и кордампы. Но да, порой хочется пройтись по незнакомому коду и просмотреть изменение переменных — этого реально не хватает, даже в GUI к GDB это реализовано всрато.

byko3y ★★★★
()
Ответ на: комментарий от Nervous

А в докстринге это описать не проще?

Можно и в докстринге. Я имел в виду, что ни названия переменных, ни названия типов не было достаточно для настоящего описания типа переменной ­— отсюда родилась венгерская нотация, когда присвоение целого числа от одной переменной inpVal к другой idxStart как бы кастует тип, хотя, казалось бы, у обоих переменных формальный тип int.

byko3y ★★★★
()
Ответ на: комментарий от asdpm

можешь интринсик монитор брать синтаксисом, можешь мютексы из библиотеки, есть condition variables, есть executor сервисы, пулы, есть коллекции в которых там как-то само всё сделано

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

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

Go исповедует идеологию shared nothing, как и Erlang.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

присвоение целого числа от одной переменной inpVal к другой idxStart как бы кастует тип, хотя, казалось бы, у обоих переменных формальный тип int

Понел. Наверное, лучше так, чем писать два дополнительных класса InputValue<Integer> и StartIndex — хотя и на такое любители найдутся.

Nervous ★★★★★
()
Ответ на: комментарий от asdpm

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

Ну что значит «насколько это разумно». Вот по-твоему, манагеры из Sun сидели и думали «как бы нам сделать стандартные контейнера, которые бы жрали память как не в себя и без тщательного прогрева на JIT-оптимизаторе имели бы производительность уровня Perl»? Но по результатам имеем именно это — ресурсожоркоое решение, лучше которого бывает даже питон на отдельных задачах (и именно потому питон до сих пор жив).

Очевидно, что ничего подобного они не думали, они существовали в собственном коллективном шизоидном бреду, где завоевывали царство драконов скача по радуге на единорогах. И завоевали, и получили ордена от друида. А потом проснулись в обосранной кровати с компанией-банкротом.

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

byko3y ★★★★
()
Ответ на: комментарий от Nervous

Наверное, лучше так, чем писать два дополнительных класса InputValue<Integer> и StartIndex — хотя и на такое любители найдутся.

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

byko3y ★★★★
()
Ответ на: комментарий от asdpm

вот пока ты хейтишь жаву, они вроде бы уже LVTI добавили как котлине чтобы.

Если я не ошибаюсь, продвинутый локальный вывод типов с самого начала оно был в котлине. Осталось только классы убрать из языка — и можно начинать пользоваться. Я потерял интервью и всё никак не могу найти, в нем один из участников создания Java признавался, что главное ошибкой в Java были классы — их не должно было быть.

byko3y ★★★★
()
Ответ на: комментарий от Aber

Проверка типов удостоверяется в совместимости типов, тесты проверяют поведение.

В ЯП со статической типизацией проверка типов обычно лишь удостоверяется, что символ «A» будет интерпретирован как байты 65 и 0, а не как вещественное число с черт пойми каким значением. Больше они нихрена не проверяют, а в C/C++ есть еще и безумные приведения типов с подводными камнями, которые делают пользу от статических проверок еще более сомнительной.

Даже мальком увиденной дискуссии между FP кодерами как правильнее обернуть сайд эффект в манаду отбивает всякое желание. У меня такое ощущение что они не пишут программы а решают головоломки.

Ты всё правильно понял. Главная цель Haskell — никогда не решить практическую задачу. Но это не является какой-то неотъемлимой частью функционального программирования, это лишь убогость одного конкретного хаскеля, построенного на фундаментально непрактичной ленивости и дихотомии чистых-грязных функций.

На самом деле нынче и C++, и C#, и Java бодро идут в сторону функционального программирования, другое дело, что инструментов для удобства писания ФП в них всего-ничего.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Из этого списка тебе всё приложение не повесят только многопотоковые коллекции

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

asdpm
()
Ответ на: комментарий от byko3y

то поймешь, что все эти сравнения сложных объектов должны реализовываться в ИСПОЛЬЗУЮЩЕМ хэшмап коде

У меня когда-то была задача, где нужно было в качестве ключей использовать картинки. Причем нужно было «неточное сравнение» (т.е. допустимая разница в нексольких пикселях в несколько градаций серого). Причем нужно было лимит на размер мапы, то есть старое вытеснять. Деталей я не помню, по документации я обнаружил более подходящую мапу (чтобы выкидывала элементы и соответственно теряла ссылки на ключи). Дальше там то ли компаратор как-то подсунуть можно было, то ли я обернул просто эти картинки, но короче нужный equals добавил. Вполне работало, непроизводительно разумеется т.к. hashcode очевидно для неточного сравнения сделать невозможно. Но всё же. То есть вот это, то что ты говоришь, оно решается если нужно. При том что я не экперт вообще в жаве и вообще программист средний скажем так. То есть вот эта херота джавоская, которая ты говоришь ненужна (всмысле «стройность», наличие готового) - оно в целом помогало, мне так думается.

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

Это понятно. Кстати, и у питона и жавы (насколко помню) семантика сравнения словарей одинаковая. И если спросить меня, то я считаю, что она sane и практична. Что косвенно может говорить о том, что useful «дефолтное» equals для многих объектов придумать можно.

то поймешь, что все эти сравнения сложных объектов должны реализовываться в ИСПОЛЬЗУЮЩЕМ хэшмап коде

Для огромного числа объектов встроенная в него самого логика сравнения вполне себе возможна и нужна. То есть с этим лучше чем без. А «кастомное» - так оно всегда «кастомное».

asdpm
()
Ответ на: комментарий от Nervous

Если стандартные функции реализованы в терминах абстракций (например, абстрактных типов данных, спрятанных за некоторым интерфейсом), ты просто реализуешь интерфейсы этих абстракций (условные cons, first и rest для абстрактного списка) в своём типе и откидываешься на спинку кресла, у тебя всё просто работает (тм).

Чтобы мы чуть конкретнее понимали задачу, можем взять, например, сериализацию в поток. Есть стандартный интерфейс сериализуемого объекта, есть стандартный интерфейс потока — что может пойти не так? Дело в том, что в любом случае на одной, второй, или обоих сторонах нужно будет адаптировать имеющиеся структуро-алгоримты к конкретной задаче сериализации, которая имеет свои причудливости в разных случаях. Нужна дополнительная передача по боковому каналу TCP/UDP? Сасаем со стандартными потоками. Нужна неблокирующая асинхронность? Снова сасаем. И так далее, Input/OutputStream в стандартной либе сделан по вполне конкретный спектр задач, и бесполезен за его пределами.

Да, можно лепить прокладку к библиотечной функции, принимающей стрим, чтобы адаптировать ее под новую задачу, но это на самом деле и есть то самое «городить этот чёртов map каждый чёртов раз для каждого чёртова нового типа» в завуалированной форме — и еще не ясно, лучше ли будет городить заново или делать спагетти из наследуемой реализации.

Я уже не стал упоминать, как нужно будет гнуть сами объекты для того, чтобы они завернулись в поток — это как бы очевидно, что LinkedList сам себя в JSON не завернет.

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

условные cons, first и rest для абстрактного списка

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

byko3y ★★★★
()
Последнее исправление: byko3y (всего исправлений: 1)
Ответ на: комментарий от asdpm

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

Язык, который никак не предупреждает про гонки в данных? А ты уверен вообще, что у тебя твой код всегда работает, а не просто «в большинстве случаев»?

byko3y ★★★★
()
Ответ на: комментарий от asdpm

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

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

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

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

и у питона и жавы (насколко помню) семантика сравнения словарей одинаковая. И если спросить меня, то я считаю, что она sane и практична. Что косвенно может говорить о том, что useful «дефолтное» equals для многих объектов придумать можно.

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

Для огромного числа объектов встроенная в него самого логика сравнения вполне себе возможна и нужна. То есть с этим лучше чем без.

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

byko3y ★★★★
()
Ответ на: комментарий от byko3y

А ты уверен вообще, что у тебя твой код всегда работает, а не просто «в большинстве случаев»?

А ты когда пишешь многопоточный код на мютексах, condition variables, семафорах и пр., уверен вообще, что у тебя твой код всегда работает, а не просто «в большинстве случаев»? Вот конкретно твой код.

asdpm
()
Ответ на: комментарий от Rabinovich

Racket (на нём HN крутится, вроде)
Почти так и есть. 6 миллионов пользователей в день [https://news.ycombinator.com/item?id=28479595]. Диалект Лиспа Arc, написанный на Racket, на одном дедике (от M5 Hosting) [https://news.ycombinator.com/item?id=16065992]

Здесь стоит отметить два момента. Во-первых, не пользователей, а запросов в день. И тогда получается 70 запросов в секунду в среднем, пусть будет 200-300 в пике — это совершенно не фантастические показатели. Темпестовый кэш вывозит миллион запросов В СЕКУНДУ на смартфоне пятиклассника.

Во-вторых, Hacker New — максимально убогий сайт без юзабилити, на котором нет нормальных уведомлений об ответах (я пытался пользоваться имеющимися). Там нет картинок. В 2023 году на сайте нет НИ ОДНОЙ КАРТИНКИ. Чтобы прочитать статью и посмотреть картинки — нужно пройти по ссылке (Ъ лоровцы негодуют).

В общем, сайта там как такового нет, это скорее похоже на сделанную на колонке за пару недель корпоративную доску объявлений — для такого одного сервака на зионе более чем достаточно, там нечего толком обсчитывать и обрабатывать. По сути там больше роли играет раскрученный в околостартапных кругах бренд — если обратить внимание, то новости на сайте тоже стартапно-желтушного толка. Для стартапной движухи всратый слепленный на коленке сайт — это даже плюс, а не минус, как обшарпанные стены в антикафе.

На лиспе еще был reddit написан, и тоже был всартым, потом владельцы взялись на ум и анконец переписали его на питоне и реддит стал еще более всратым.

Поиск показывает, что якобы библиотеки Clojure более консистентные, подход более инженерный

Подход Clojure новаторский, в какой-то степени этот проект больше всего меня сподвигнул написать PSO. Другое дело, что он сделан на JVM, а значит медленный и мучительный, как самая страшная смерть. К сожалению, проблему не так просто решить, потому что персистентные структуры данных создают огромное количество мусора. Эту проблему можно решить, избавившись от JVM платформы, но Clojure сейчас используется в проде ТОЛЬКО для совместимости с Java, в ином виде она никому не нужна. На HN кто-то писал про свою попытку написать с нуля платформу для Clojure, но забросил это дело, потому что это неподъемная для него трудоемкость — людям свойственно забывать о том, насколько сложны сборщики мусоров (и чуть менее сложны менеджеры памяти), они просто выделяют объекты и думают, что это бесплатно.

byko3y ★★★★
()
Ответ на: комментарий от asdpm

А ты когда пишешь многопоточный код на мютексах, condition variables, семафорах и пр., уверен вообще, что у тебя твой код всегда работает, а не просто «в большинстве случаев»? Вот конкретно твой код.

Каждый раз читая свой многопоточный код я читаю его так, будто в нём есть баг и мне нужно его найти. Я не представляю, что должно случиться, чтобы я наконец мог сказать «ага, эти функции полностью проверены, в них ошибки быть не может».

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Есть стандартный интерфейс сериализуемого объекта, есть стандартный интерфейс потока — что может пойти не так?

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

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

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

Нужна дополнительная передача по боковому каналу TCP/UDP? Сасаем со стандартными потоками. Нужна неблокирующая асинхронность? Снова сасаем. И так далее

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

Input/OutputStream в стандартной либе сделан по вполне конкретный спектр задач, и бесполезен за его пределами.

Молоток сделан под конкретный спектр задач и бесполезен за его пределами. Удивительно %)

Nervous ★★★★★
()
Ответ на: комментарий от byko3y

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

ты не понял, к чему эта иллюстрация была

Хэшмап полностью бесполезен, если у тебя нет точного сравнения

я в курсе и в цитате на которую ты отвечаешь это понятно

многомерные деревья, которые используются для задач

вероятно, но я в такое не умею

asdpm
()
Ответ на: комментарий от byko3y

Каждый раз читая свой многопоточный код я читаю его так, будто в нём есть баг и мне нужно его найти. Я не представляю, что должно случиться, чтобы я наконец мог сказать «ага, эти функции полностью проверены, в них ошибки быть не может».

вот и я так же.

asdpm
()
Ответ на: комментарий от byko3y

что ты упростил, создав десятки интерфейсов? Типовые задачи, реализация которых не представляет сложности

Взаимозаменяемость реализаций же. Молоток может быть на деревянной ручке, пластиковой или металлической, и забивать любые гвозди примерно одинаково. map, filter и reduce могут одинаково работать со списками, векторами и строками. Не нужно изобретать гвозди для молотков с металлической ручкой и отдельные vector-map, vector-filter и vector-reduce.

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

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 4)
Ответ на: комментарий от byko3y

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

не понял кто кого косплеит. или я не знаю, что значит косплеить

насколько я помню, в джаве есть только небольшое число традиционных операторов над встроенными в язык value types. для объектов в java вообще нет операторов. исключения только == (чтобы сравнить ссылки можно было) и особняком стоит «+» существующий для строк. но плюс это особый случай, самой такой практики операторов для объектов в жаве нет. так же в java нет и пользовательского operator overloading.

в питоне самих символов не сильно больше, но многие из них определены для многих встроенных типов, что пораждает огромное число в итоге. дополнительно программисту предлагается operator overloading чтобы для своих типов тоже добавить.

asdpm
()
Ответ на: комментарий от byko3y

Просто срыв покровов. Только упоминание смартфона пятиклассника выдаёт в тебе восьмиклассника. Не вижу смысла спрашивать у тебя, с чего ты взял, что запросы ровным слоем распределяются в течение суток или там указывать на то, что «new» - это не единственное число слова «news», пусть это будет на совести Марь Иванны. Скажу лишь, что HN со своими задачами успешно справляется: большая платёжеспособная аудитория, куча проектов вокруг (рассылки, сайты, группы, новостные издания), которые копируют данные с HN. Нет проще и дешевле способа раскрутить проект: коммерческий или opensource, чем попасть на главную страницу HN.

Rabinovich
() автор топика
Ответ на: комментарий от byko3y

условные cons, first и rest для абстрактного списка

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

На самом деле можно, просто это будет неэффективно. Вектор тут подходит лучше. Почему он подходит лучше? Потому что позволяет определение количества элементов и доступ по индексу элемента за постоянное время.

Поэтому может иметь смысл реализовать условный fold-right не в терминах абстрактного списка (последовательности), а в терминах абстрактной структуры данных с произвольным доступом по индексу элемента. И тогда fold-right будет автоматически работать с любым объектом, который такой интерфейс реализует. Строки, массивы, векторы, что угодно (но не односвязные списки).

И всё, что построено на fold-right, тоже будет работать со всеми этими объектами без дополнительных телодвижений. И с любыми новыми объектами — если они реализуют интерфейс нужного абстрактного типа данных.

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 3)
Ответ на: комментарий от Nervous

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

Мне вспоминаются примеры на стандартном жавопарсере XML, где «все интерфейсы разделены», и потому для парсинга одного элемента в файлике нужно написать 20 строк кода — мне такая «грамотная организация» даром не нужна, пожалуй, я лучше буду дальше писать однострочники на мерзком JS.

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

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

Нужна дополнительная передача по боковому каналу TCP/UDP? Сасаем со стандартными потоками. Нужна неблокирующая асинхронность? Снова сасаем. И так далее

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

В том числе потому я не верю в C++ STL. Этот инструмент устарел примерно в тот момент, как вышел, поскольку модель однопоточного программирования с синхронным вводом-выводом и выделением данных в стэковой форме или «бесплатной» куче перестала удовлетворять потребности где-то в конце 90-х, а вышла STL в начале 90-х. А потом какие-то придурки сделали Boost, чтобы hello world комплиировался несколько минут.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

NH чрезвычайно говеный ресурс в информационном плане, с гнилой уродской зомби-публикой, орган тоталитарной фашистской пропаганды. и с изрядной долей местечковости причем.

asdpm
()
Ответ на: комментарий от asdpm

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

ты не понял, к чему эта иллюстрация была

Ты мне перегрузку оператора хотел показать? А если тебе нужно сделать точное сравнение картинки или сравнение по адерсу указателя — ты чем собрался пользоваться?

byko3y ★★★★
()