LINUX.ORG.RU

Vim или Emacs? А LISP в 2021?

 , ,


1

4

https://www.youtube.com/watch?v=8Q9YjXgK38I&t=42s

Парень в определённых кругах, личность известная.
посмотрел я его ролик, стал ковыряться по истории:

А ведь Crashbandicoot была годной игрой…

Что выбрать? Vim или Emacs?
Изучать в 2021 году Lisp? Если изучать, какой? Практика?
А не засмеют сотрудики?

Времени в сутках маловато, на всё не хватает.


Планирую вот сейчас дела в org-mode, разные статьи и прочее экспортирую в tex.. Да не дай Бог, Emacs всё! Это будет означать крах, а не прогресс. Если есть люди с системным мышлением, подходящим для использования таких программ, значит и программы такие должны быть и развиваться.

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

Потому что для любой нетривиальной структуры в Rust приходится писать unsafe.

Я так понимаю, что «нетривиальная структура» определяется как «такая, для написания которой нужен ансейф»?..

В любом случае, далеко не в каждой программе требуется писать «нетривиальные структуры» (самому).

На нормальных языках песочница не протекает, если не использовать FFI.

Точно? Я вот погуглил и пишут, что в C# в unsafe блоках можно добиться неопределённого поведения. Это неправда (я что-то не так понял) или C# тоже не является нормальным языком?

А в Common Lisp safety 0 ничего не может поломать?

Зато нет паники.

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

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

Использовал ты at вместо индекса — дальше что?

Именно этим вопросом я выше и задавался.

Вот at и не используют.

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

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

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

Я в растосрачах детально пояснял…

Это замечательно, что пояснял. Но это не значит, что ты прав или что я с тобой согласен.

Отдельные кадры даже создавали тикеты с предложениями опции компилятора для запрета по умолчанию на использование unsafe в код

Эта опция (в виде атрибута) и так давно есть.

А команда хрома вполне конкретно высказалась по поводу миграции… примерно так же, как Торвальдс про переписываниt ядра на Rust.

У тебя устаревшие данные. Сейчас команда разработки хрома как раз рассматривает варианты. Использовать что-то более безопасное, чем С++ - один из них.

А я бы сказал, что если выдерживать все требования по растовой безопасности, то писать на расте дольше и сложнее.

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

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

либо, как поступили разрабы раста, иногда возвращать ошибку, иногда падать с паникой.

Нет

Что «нет»?

Процитированное - нет.

В стандартной библиотеке тебе дали возможность выбирать поведение в каждом конкретном случае.

Обратился по неверному индексу — получил панику. Вот так вот просто алгоритмическая ошибка превратилась в панику.

И как же должна выглядеть алгоритмическая ошибка, если тебя ни паника/исключения ни Option не устраивают?

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

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

У меня был случай, когда Notepad++ потерял вообще все открытые файлы и буферы. Не падал, а выдавал ошибки, ага. То есть, это разница между «упасть сразу» или «еще немножко попортить данные». Есть ли шанс безболезненно достать данные и выйти из программы? Есть. Но есть и шанс достать из программы мусор вместо данных.

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

И как же должна выглядеть алгоритмическая ошибка, если тебя ни паника/исключения ни Option не устраивают?

А я разве говорил, что паника и Option — это плохие варианты? Проблема не в них, а в неявной генерации ошибок. Но мода на необрабатывание ошибок тоже произошла не на пустом месте, поскольку если руками обрабатывать все ошибки тоже ни разу не прикольно. Разным проектам нужно разное умолчательное поведение: кому-то норм переполнение целого числа, но недопустима запись в несанкционированную ячейку памяти (вроде ядра ОС); кому-то при любой проблему проще упасть и загрузиться с последних сохраненных данных — как браузеру, под который Rust и писался; для кого-то падение вообще недопустимо и при ошибке сервис перезапускается, но общие данные при этом не теряются — как это происходит в Erlang; для кого-то UB — это вообще пофигу, главное чтобы хоть как-то выполняло задачу — вроде MS Office и прочих офисных софтин.

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

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

Я так понимаю, что «нетривиальная структура» определяется как «такая, для написания которой нужен ансейф»?..

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

C# в unsafe

В C# без них прожить можно. Также как без safety 0 в Lisp. Они только для производительности некритичных к надёжности частей программы.

А без unsafe в Rust некоторые алгоритмы реализовать невозможно.

В любом случае, далеко не в каждой программе требуется писать «нетривиальные структуры» (самому).

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

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

Рекурсивно включая все библиотеки? Например, запретить оператор[] для векторов.

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

Разным проектам нужно разное умолчательное поведение

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

почему я и пишу, что Rust — это специализированный инструмент для написания браузеров.

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

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

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

Хайп же ж. Наперсточники просто берут все незнакомые публике технологии: hyperautomation, blockchain, AI security, distributed cloud, autonomous things, ну и Rust туда же попал.

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

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

И в каждой второй программе непременно надо писать свой двухсвязный список? Ну и написать его без ансейф можно.

В C# без них прожить можно.

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

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

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

Рекурсивно включая все библиотеки?

Так нельзя, но не уверен, что это было бы продуктивно. Всё-таки без продвинутой системы типов (и желания с этим заморачиваться) всегда будут ситуации когда в коде будут встречаться комментарии «это безопасно потому что…». Автоматически отличить правда это или нет, есть ли тест и т.д. конечно нельзя. В общем, всё сводится к доверию, даже в Idris можно сказать trustMe.

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

И в каждой второй программе непременно надо писать свой двухсвязный список?

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

Ну и написать его без ансейф можно.

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

но можно точно так же придумать ситуации когда без этого никак

Какой алгоритм нельзя написать на C# без unsafe?

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

Только если осознанно хочешь поломать. В Rust приходится использовать unsafe просто чтобы решить задачу.

Всё-таки без продвинутой системы типов (и желания с этим заморачиваться) всегда будут ситуации когда в коде будут встречаться комментарии «это безопасно потому что…».

И я про то же. Есть языки небезопасные, но быстрые: C, C++. Есть языки безопасные: C#, Java, Lisp, Haskell. А Rust ни рыба ни мясо. По сравнению с небезопасными очень много кода, который не относится к алгоритму. По сравнению с безопасными, собственно, отсутствие безопасности, так как unsafe используется повсеместно. Реальный уровень безопасности на уровне C++ (там тоже почти везде умные указатели и безопасные контейнеры), но писать гораздо сложнее.

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

В каждой второй программе необходимы сложные структуры данных.

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

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

«Городить сборщик мусора на счётчиках» звучит страшнее, чем то, что происходит на самом деле: берём Rc (и при необходимости Weak) и готово. Заодно код начинает правильно отображать происходящее, а не так, что видим какие-то указали в контейнере и думай сколько оно живёт. А главное, что с такой код не развалится внезапно, как может быть с указателями, если ты ошибёшься с предположениями.

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

Ну и наконец, если устраивает сборка мусора, то зачем тебе раст или С++? Бери джаву/шарп/хаскель/лисп и вперёд. Я к тому, что давай не валить в кучу всё на свете. На С сложные структуры данных тоже сами собой не получатся, просто не компилятор по рукам бить будет, а будут утечки/сегфолты, если писать как попало. Опять же, опуститься на уровень unsafe ты всегда сможешь. Да, потеряются гарантии. Но если сравнивать с другими низкоуровневыми языками, то этот ансейф всё-таки можно явно выделить и изолировать.

Какой алгоритм нельзя написать на C# без unsafe?

Не всё упирается в алгоритмы. Есть непустое множество программ на C#, которые нельзя написать без ансейф. А ещё больше программ и библиотек, которые уже написаны с ансейфом, то есть такая же «проблема доверия».

Только если осознанно хочешь поломать. В Rust приходится использовать unsafe просто чтобы решить задачу.

Ага, прям каждую задачу. Поехали по второму кругу?

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

А Rust ни рыба ни мясо так как unsafe используется повсеместно

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

Повторюсь, при этом без ансейфа обходится во многих случаях можно. И даже не (сильно) жертвуя при этом эффективностью. Про «повсеместный ансейф» прям сильно не согласен. На прошлом проекте (400к строк кода) ансейфа было совсем немного и всегда с качественным обоснованием. На позапрошлом (110к) долгое время обходились, потом добавился один ансейф трейт и ещё пару экспериментальных применений выключенных по-умолчанию. Сейчас вот под рукой 20к кода вообще без ансейфа.

Ну и наконец: ты говоришь как будто у нас есть только две границы спектра: быстро или безопасно. Если мы получаем замедление на 5%, но при этом без уязвимостей, то оно того стоит? А если на 10%?.. А если на 5%, но с меньшим числом уязвимостей?..

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

Есть языки безопасные: C#, Java, Lisp, Haskell.

Кстати, хаскель ведь можно поломать unsafePerformIO? Или опять «это другое»?

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

Ага, прям каждую задачу. Поехали по второму кругу?

Даже в Servo более полутора сотен unsafe блоков (не в библиотеках, которые он использует).

Ну и наконец: ты говоришь как будто у нас есть только две границы спектра: быстро или безопасно. Если мы получаем замедление на 5%, но при этом без уязвимостей, то оно того стоит? А если на 10%?.. А если на 5%, но с меньшим числом уязвимостей?..

В том-то и дело. Rust медленнее, чем C++ и менее безопасный, чем C#. В задачах почти всегда требуется либо скорость, либо безопасность. Я с трудом представляю нишу, где безопасность не критична, но желательна и при этом скорость не критична, но желательна. И при этом не критично время разработки. Движок для браузера, разве что.

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

Вопрос не про эффективность, а про лишний код, Сравни двусвязный список на Си и Расте.

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

Кстати, хаскель ведь можно поломать unsafePerformIO? Или опять «это другое»?

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

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

Даже в Servo более полутора сотен unsafe блоков (не в библиотеках, которые он использует).

Почему Servo - это «даже»?

Бегло потыкался и увидел следующее: биндинги к Gecko, unsafe extern «C» (то есть, тоже биндинги), всякую срань для работы с джава-скриптом или домом. Может это и не всё, спорить не буду. Но на границе языков ансейф будет везде, «даже в безопасном C#».

В том-то и дело. Rust медленнее, чем C++ и менее безопасный, чем C#.

Ну если ты так сказал…

Вопрос не про эффективность, а про лишний код, Сравни двусвязный список на Си и Расте.

Средний код на С будет как раз многословнее.

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

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

И что это должно доказать? Где-то выше ты утверждал, что в безопасных языках нельзя ничего сломать без FFI. Всё-таки не так? И ведь это не единственная проблемная функция в хаскеле? Как насчёт unsafeCoerce? А Data.Array.Unsafe?

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

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

Добавлю к вышесказанному: считаю, что как разница в безопасности между хаскелем и растом заметна, так и между растом и С разница тоже заметная и сопоставимая.

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

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

Вот именно. Как только требуется что-то чуть сложнее списка, начинаются проблемы.

Но на границе языков ансейф будет везде, «даже в безопасном C#».

Разумеется.

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

И ведь это не единственная проблемная функция в хаскеле? Как насчёт unsafeCoerce? А Data.Array.Unsafe?

С этим согласен. Как насчёт того, чтобы в Расте все во все функции, содержащие unsafe, добавить слово unsafe к имени функции?

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

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

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

так и между растом и С разница тоже заметная и сопоставимая.

Там, где используют C (встраиваемые системы), там раст не втиснуть, так как рантайм не влезет.

Раст конкурирует не с C, а с C++ и Ada с одной стороны и Java и С# с другой стороны. При этом нормально не вписывается ни в ту, ни в другую нишу. Как микроавтобус: он уже не легковушка, но ещё не автобус. Но для микроавтобусов родилась новая ниша: маршрутное такси. Какая ниша у Раста?

То есть, если писать расчёт физического матмоделирования, то лучше выбрать Си++, если писать банковскую систему, то лучше джава. Какую категорию программ однозначно лучше писать на Расте, а не на другом языке?

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

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

Программу для которой нужна скорость выполнения уровня С++, но без С++?

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

но без С++

И такая категория программ есть? Или это относится не к программам, а к религиозным убеждениям программистов (как я для программ в нише Java использую Racket, а не Java)?

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

Или это относится не к программам, а к религиозным убеждениям программистов

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

как я для программ в нише Java использую Racket, а не Java

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

Объективные преимущества перед С++ у него тоже есть. Как и недостатки.

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

Вот именно. Как только требуется что-то чуть сложнее списка, начинаются проблемы.

Еее… речь была о FFI, но тебе опять списки покоя не дают. (:

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

Как насчёт того, чтобы в Расте все во все функции, содержащие unsafe, добавить слово unsafe к имени функции?

В «содержащие ансейф» или «использование которых может быть небезопасно»? Первое не имеет смысла иначе мы опять возвращаемся к тому, что небезопасными инструментами нельзя построить безопасную абстракцию: и джава становится ансейф ведь в потрохах JVM есть С и/или С++. Второе - да, так и принято делать. Только не к названию добавлять, а помечать как unsafe. Правда заставлять следовать этому соглашению, как и в хаскеле, компилятор не может.

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

А такое вообще бывает?..

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

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

Там, где используют C (встраиваемые системы), там раст не втиснуть, так как рантайм не влезет.

Во первых, встраиваемые системы бывают разные. Плюс у раста есть no_std режим.

Во вторых, используют не только там. Скажем, git написан на С.

То есть, если писать расчёт физического матмоделирования, то лучше выбрать Си++

Не согласен.

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

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

Еее… речь была о FFI, но тебе опять списки покоя не дают. (:

Ты писал про дом и джаваскрипт. Где FFI в

https://github.com/servo/servo/blob/0d0cfd030347ab0711b3c0607a9ee07ffe7124cf/components/script/dom/promise.rs#L60

https://github.com/servo/servo/blob/0d0cfd030347ab0711b3c0607a9ee07ffe7124cf/components/script/dom/imagedata.rs#L42

?

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

Первое не имеет смысла иначе мы опять возвращаемся к тому, что небезопасными инструментами нельзя построить безопасную абстракцию: и джава становится ансейф ведь в потрохах JVM есть С и/или С++.

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

А такое вообще бывает?

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

Но разве где-то ты полностью застрахован от «диверсий» авторов библиотеки?

В Racket и от диверсий застрахован. Если я пишу

(require foo bar)

(define foo-obj (make-foo)) ; создаю какие-то данные из foo

(bar-func) ; запускают какую-то обработку из bar

то у меня есть практическая гарантия, что данные foo-obj не изменятся после работы bar-func (если не считать хаки через FFI и прямой доступ к памяти). Если же доверия к автору bar нет совсем, то могу запускать как

(current-code-inspector (make-inspector (current-code-inspector))) ;; дальше недоверенный код
(bar-func)

и тогда bar-func не сможет использовать FFI.

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

Лично я брал бы раст вместо С++ во всех случаях, кроме

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

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

Ты писал про дом и джаваскрипт.

Я писал про «биндинги к Gecko, unsafe extern «C» (то есть, тоже биндинги)» и уже потом про дом и джваскрипт.

Где FFI в

Хорошо, может насчёт двух приведённых фрагментов кода я и не прав - лень вникать, да и в вебе и браузерных движках я мало что понимаю. Но разве все эти get_jsobject, permanent_js_root и прочее не является интерфейсом к джаваскрипту?

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

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

Разве не могу я в JS (и даже джаве) при помощи рефлексии что-то поломать в чужом коде?

В Racket и от диверсий застрахован.

И даже от бесконечного цикла в библиотечном коде?..

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

и уже потом про дом и джваскрипт.

А я отвечал (как видно по процитированному куску) именно про дом и джаваскрипт.

Но разве все эти get_jsobject, permanent_js_root и прочее не является интерфейсом к джаваскрипту?

Ты же раст умеешь читать:

pub fn get_jsobject(&self) -> HandleObject {
        // We're rooted, so it's safe to hand out a handle to object in Heap
        unsafe { HandleObject::from_raw(self.object.handle()) }
    }


permanent_js_root: Heap<JSVal>

Это не FFI, а похаканые растовые коллекции (чтобы не раст ругался на отдачу объекта в куче).

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

Разве не могу я в JS (и даже джаве) при помощи рефлексии что-то поломать в чужом коде?

Насчёт джавы не уверен, а в JS абстракция в виде замыкания абсолютно неломаемая.

function makeFunc() {
  var count = 0;
  function countUp() {
    count++;
    return count;
  }
  return countUp;
};

var myFunc = makeFunc();

Никакой рефлексией не сможешь заставить myFunc вернуть, например, отрицательное число.

И даже от бесконечного цикла в библиотечном коде?..

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

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

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

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

Писал бы везде unsafe

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

наслаждался лишних пару часов?

Да.

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

А я отвечал (как видно по процитированному куску) именно про дом и джаваскрипт.

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

Это не FFI, а похаканые растовые коллекции (чтобы не раст ругался на отдачу объекта в куче).

Отдачу куда? Не в джаваскрипт ли?

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

Никакой рефлексией не сможешь заставить myFunc вернуть, например, отрицательное число.

Дык, не обязательно именно твоё замыкание ломать, если можно изменить другие объекты.

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

И это прям с полпинка делается?

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

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

Для начала посмотрел бы на имеющиеся библиотеки, если бы ничего качественного не нашёл, то писал бы сам.

Там почти всегда структуры специфические.

Продолжаю не понимать этот аргумент. Во первых, не везде, а изолировал бы.

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

struct Node<T> {
  next: Option<&Node<T>>,
  prev: Option<&Node<T>>,
  data: T
}

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

В С++ был бы такой же ансейф, только неявный (и из-за этого его протекание сложнее ограничить)

В C++ быстрее код, потому что есть UB, позволяющее компилятору лучше оптимизировать.

наслаждался лишних пару часов?

ОК. Тогда вопрос про длительность написания сложных структур, похоже, отпадает.

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

воткнув unsafe в добавление узла.

Ну и что? Ещё раз: в С++ будет точно такой же ансейф, просто за ним уследить будет сложнее.

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

В C++ быстрее код, потому что есть UB, позволяющее компилятору лучше оптимизировать.

Я так тоже могу: «в расте везде restrict по-умолчанию, так что он быстрее».

Такие утверждения надо доказывать и насчёт среднего кода я совсем не уверен. Так как язык хоть и (сильно) влияет, но измерять надо скорость конкретного кода, а не абстрактного в вакууме. Опять же, если очень надо, то и в расте есть UB.

Ну и наконец - код, который быстро делает ерунду (из-за UB) хуже, чем «медленный», но корректный.

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

Ну и наконец - код, который быстро делает ерунду (из-за UB) хуже, чем «медленный», но корректный.

Ерунду он делает, если нарушены условия. Напоминаю, с чего началась эта ветка: в Си++ выход за границы массива UB и компилятор может оптимизировать проход по массиву, в Раст выход за границы массива обязан вызывать панику.

Я так тоже могу: «в расте везде restrict по-умолчанию, так что он быстрее».

Два года назад было, по факту (ключом оптимизации), наоборот.

https://stackoverflow.com/questions/57259126/why-does-the-rust-compiler-not-optimize-code-assuming-that-two-mutable-reference

Уже починили?

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

в Си++ выход за границы массива UB и компилятор может оптимизировать проход по массиву, в Раст выход за границы массива обязан вызывать панику.

Это справедливо только если мы говорим о доступе через квадратные скобки. Так-то и в С++ можно обращаться по индексу без UB и в расте можно получить все преимущества таких оптимизаций.

Уже починили?

Если мне не изменяет память, то на какое-то время эту штуку отключали из-за бага в ллвм. Вроде, как починили и включили назад: https://github.com/rust-lang/rust/issues/54878

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

и в расте можно получить все преимущества таких оптимизаций

А как в расте?

В Си++

void f(int *a, int n)
{
  for(int i = 0; i < n; i++) a[i] = 0;
}

Превращается в «установить 4*n нулевых байт начиная с указанного адреса». В rust, скорее всего, будет n проверок диапазонов.

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

Превращается в «установить 4*n нулевых байт начиная с указанного адреса». В rust, скорее всего, будет n проверок диапазонов.

А можно менее абстрактный пример? Откуда возникает адрес, где расположена память? Скажем, если это слайс (или массив или вектор, которые сводятся к слайсу), то a[0..n].fill(0). И никаких «n проверок диапазонов» не будет. Да, внутри библиотечного кода будет unsafe, но так и должна выглядеть правильная абстракция. Впрочем, одна проверка (при переходу к диапазону через квадратные скобки) останется, но и её можно избежать использовав get_unchecked:

unsafe { a.get_unchecked_mut(0..n) }.fill(0);

Получаем практически полный аналог с UB. Если очень хочется, то можно и так:

unsafe fn f(a: *mut u8, n: isize) {
    for i in 0..n {
        *a.offset(i) = 0;
    }
}

Будет вообще один в один с твоим кодом.

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

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

Если ты бездомный - просто купи дом.

Надо делать как надо, а как не надо - не надо делать.

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

Обратился по неверному индексу — получил панику. Вот так вот просто алгоритмическая ошибка превратилась в панику. Обрабатывать каждый доступ к любому контейнеру через Option?

[x] - паника если нет такого индексa.
.get(x) - возвращает Option<T>.

В коде где x ненадёжен, лучше использовать .get(x).
Если плохой индекс там нормальное явление, можно пропустить.
Когда индекс должен быть всегда правильным по алгоритму:
.expect("wrong index for some reason.")

Паника означает провал теста.

Надо делать как надо, а как не надо - не надо делать.

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

unsafe … unchecked

Сразу мимо.

внутри библиотечного кода будет unsafe

Я могу просто накатать «unsafe» библиотеку на крестах и подцепить в любой скриптоязычок, который будет в 100 раз проще и безопаснее раста. В качестве клея для «unsafe» раст нахрен не упал.

no-such-file ★★★★★
()
Ответ на: комментарий от monk

как замена Си++ годится

Зачем нужен ещё один C++, к тому же ещё более кривой и непоследовательный? Был бы он лучше, было б о чём говорить.

no-such-file ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.