Очередной идиотский тезис. Иди прогрепай stdlib на тему unsafe и расскажи об успехе, и да, по 100баксов вычти то же.
Кстати, замечаем как меняется риторика. Вначале у нас было «по умолчанию безопасный», теперь, оказывается, что надо грепать. А т.к. ты 100% что-то нагрепаешь, то оказывается нужно проводить ручной анализ.
Это типичный пример подмены понятий, вранья и манипуляций.
Никакой лоулевел код невозможен без unsafe. Любой биндинг — unsafe.
Что вы будете грепать в плюсах?
Берёшь какой-нибудь clang-tidy и пишешь за пол часа набор правил. Что надо искать? */&/new — искать не сложнее, чем unsafe.
Вполне выражаемые через зависимые типы.
Это неважно. Важно лишь то, что этого нет. Всё эти типы существуют, если существуют(что будет работать в этом кейсе), в языках, которые, мягко говоря, даже рядом с растом( я уж не говорю о си) не валялись. В них мы не экономим рантайм и может играться как хотим.
Т.е. есть безопасность, а есть бесплатная безопасность. Это разные вещи.
А к чему было про bounds checking?
bounds checking не заканчивается на обходе массива. Вернее он там и не нужен. Он нужен при доступах по индексу.
Действительно, мы можем реализовать какие-то безопасные индексы, на С++ может это сделать статически( раст, конечно, ничего тут не сможет), только вот проблема с интеграцией в текущий safe-код, да и с реализацией есть проблемы.
Нам нужно дать следующий блок? Как? Привет bounds checking. Мы же не будет в массив записывать весь набор index_t и ходить по нему?
Как мы преобразуем порядок бита в битмапе к валидному индексу? Будем делать unsafe cast? Да, мы можем(предположим) сделать интерфейс safe, но реализация будет unsafe.
В этом заключается типичная для всех пропагандистов раста подмена понятий, мы куда-то постоянно деваем реализацию. Вы это то же подтверждаете. Т.е. писать stdlib можно без safe? Писать биндинги можно без safe, писать любой лоулевел код — можно без safe? Его писать что-ли не надо? Как этому помогает раст? Никак.
Есть два разных мира — мир написания обёрток и мир их использования. И если я разработчик stdlib раста, то никаких фишек он мне не даёт. Он даёт их тем, кто будет использовать эту stdlib, и то это спорно.
Я не за ними повторяю. Я просто по своему опыту знаю, что в хаскеле я могу прогрепать код на предмет unsafe-функций (их там условно три), а также на предмет error и undefined, и в чём-то убедиться.
Из этого ничего не следует. В крестовом коде может быть то же ноль указателей, ноль new и прочее. И потом вы это можете точно так же искать.
Только вот проблема в том, что мир не заканчивается на ваших представлениях и вашем коде. Я вам уже приводил пример с stdlib раста. Идите и прогрепайте её. И так будет с любым лоулевел кодом.
Да, всегда можно написать условно-безопасную обёртку, но её нужно написать. И её нужно и можно написать и в крестах. А можно не написать — и ничего не поменяется. Это можно сделать что на крестах, что в расте.
Только это ключевая разница: в крестах код по умолчанию unsafe, в расте — по умолчанию safe.
Неверно. Очередная агитка, из которой ровным счётом ничего не следует. Никакого «умолчания» нету, вы придумали ахинею и повторяете её.
Код в расте по умолчанию такой же unsafe, а safe он будет тогда, когда глобально вырубить unsafe, но тогда это будет жаваскрипт, а не «альтерантива» крестам. Но и опять же, а если я разработчик stdlib, то у меня получается unsafe раст? В stdlib safe не нужно?
В конечном итоге всё сводится к проверке — написан ли у тебя unsafe код, а в каком виде этот unsafe код будет — в виде raw-pointer, либо unsafe raw-pointer — абсолютно неважно.
Я, если что, не апологет раста и вообще нежно люблю кресты. И хаскель ещё.
Не надо за апологетами повторять убогие тезисы. Они пустые и ничего не значат, из них ничего не следует.
Никто не мешает статически доказать, что после максимум одной данной проверки вне цикла индекс никогда за границу не вылезет.
Это всё голубые мечты. Да и данный кейс не про обход в массиве.
Кроме Option было оптимизировано ну просто много чего.
Ничего. Это капля в море. Да и опять же, дело не в этом — дело в том, что все это прошлогоднее, хотя о мистической оптимальности рассуждалось десять лет.
Приятно иметь такую оптимизацию из коробки, не правда ли?
Какой коробки и какую оптимизацию? Это не оптимизация, а костыльная оптимизация, которая закрывает изначальную дыру, которой нет в крестах и там эта «оптимизация» не нужна.
Да и это хелворд, цена которому ноль.
Может, ты перепутал c ключевым словом unsafe? Я еще не видел людей, которые бы хаяли изменяемость данных :D
Я про то, про что я.
Константность — это тоже фича(снимается добавлением ключевого слова mut).
Это не просто фича, это хайпилось как основной локомотив «безопасности», а теперь уже «просто фича». Хотя и safe — это просто фича.
Константность, которую не предоставляет C++, в котором есть псевдо, которая легко снимается const_cast, либо заметается под ковёр ключевым словом mutable либо очень
safe, которую не предоставляет rust, в котором есть псевдо, которая легко снимается unsafe.
«очевидным» implicit кастом const T -> T&&, который, вообще-то, мутабельный.
Очевидный кому? Никакой const T в T && не превратится — в T входит const. Поэтому это будет const T &&&, для константных lvalue.
Кстати, про constexpr в расте расскажешь?
Может =)
Не может, иначе бы unsafe был выключен. Загляни в свою stdlib, либо в любую, не хелвордистый, код — ты там увидишь unsafe через unsafe.
Звучит как «The flat earth society has members all around the globe».
Опять какая-то ахинея и ноль аргументации.
В крестах так же есть разделение unsafe/safe, только оно не декларируется через unsafe. На это различия заканчиваются. А декларация unsafe как unsafe не имеет смысла, вернее ни ты, ни кто-либо ещё никогда о нём не расскажет.
Написания raw-pointer и unsafe raw-pointer ничем друг от друга не отличаются, ведь raw-pointer итак unsafe в любом его проявлении.
Mozilla переносит некоторые наработки из Servo в Gecko, и обозвали этот проект Quantum.
Я уже сказал, что серво не умеет в css — это объективная реальность, но адепты, как всегда, её игнорируют.
Если бы вы прочитали хоть немного то что по ссылке, то поняли бы, что это это не только про парсинг.
Во-первых, по ссылки ничего не написано про firefox — и это ясно и понятно, ведь вы ничего мне не показали, и не покажете. Во-вторых, что за привычка такая — болтать и не показывать?
которое браузер задаёт этому движку CSS каждый раз при каждом рендеринге любого элемента на странице.
Никакого, хоть как-то работающего, движка css в серво не существует, именно поэтому его не может существовать в firefox. Никакой движок ни в какой firefox никто не добавлял.
Вот тут мы объявлением тезис, что ссылка чего-то там не может. Но тут есть ошибка, мы берём какое-то свойство, говорим о том, что оно есть. И далее делаем вывод о том, что «лучше», хотя из наличия какого-то свойства «лучше» не следует.
Мы просто так, на основании хрен пойми чего — требует от других то, что есть у нас. При этом я точно так же могу требовать от раста то, почему у меня ссылка не привязывается к объекту?
Что из этих требований следует? Ничего.
Ну и как я уже говорил — в расте нет никаких ссылок, да и вообще нет почти ничего — всё это stdlib. Поэтому мы не может сравнивать конструкции языка и обёртки.
Ну и самое главное — почему мы ссылку в расте сравниваем с ссылкой в С++, а не с std::reference_wrapper? А причина проста — мы мало того, что делаем сравнения из которых ничего не следует — мы заведомо ограничиваем одну из сторон сравнивая несравнимое.
В конечном итоге всё сводится к тому, что везде всё должно быть как в расте. Почему? Просто так. Хочешь как в расте — сделай как в расте, это С++ позволяет. Но путём подмены понятий, мы выдаём за альтернативу в С++ ссылку(&), а на самом деле не должны ничего выдавать — ведь в расте этого попросту нет.
В конечном итоге «ссылка» в С++ может быть такой же, как «ссылка» в расте. С единственной разницей в том, что там она будет в stdlib, а в С++ нет( и то не факт). Но из этого ровным счётом ничего не следует — ведь никаких свидетельства за то, что надо так, а не иначе — нет.
Поэтому, стандартная реализации из С++ имеет та кое же право на существование, как и реализация раста. А если необходим функционал «как в расте» — он реализуется, да и уже есть.
Возражения на что? У вас нет «по существу» ничего, и вам об этом уже сообщили. А возражать «по существу» на нечто — нельзя. «существу» нет.
Вы таки не понимаете, почему и для чего это сделано. Вы не понимаете, что системный язык вообще без прямой работы с памятью — не системный язык.
Дело не в том, что я понимаю, а что не понимаю. Вы там пытались рассуждать о том, что какой-то компилятор вам настучит, но теперь оказалось, что нет.
Причины того, почему он не настучит — мне не интересны и к делу отношения не имеют, мне важен факт «не настучит», а значит вы соврали — всё просто.
Но для начала неплохо бы владеть предметом. А для этого надо немножко почитать.
Опять же — ответа нет, а какой-то пустой трёп есть. Это основная проблема бесед в подобными евангелистами, вы не понимаете того, что нельзя просто так брать и требовать чего-то.
Вот у вас есть требования какого-то «предмета», но почему и на каком основании вы его требуете — у вас ничего этого нет. Это обыкновенный слив и ничего более.
Я чего-то не понимаю? — Что? И даже если будет что-то, чего не будет, то дальше будет финиш. Ведь вам нужно будет вывести из факта непонимания чего-то то, что вы из него выводите «необходимость и невозможность о чём-то рам рассуждать».
Эта ссылка была дана вам чтобы показать, что в С++ реализация итератора сводится далеко не к одному перегруженному оператору "++". Даже для простого InputIterator.
Во-первых, об этом никто не говорил. А во-вторых — en.cppreference.com/w/cpp/concept/InputIterator По это же ссылке чётко указанно — что нужно. ++/*/== — всё, при этом всё это необходимо для итератора.
В Rust нет категорий итераторов в понимании С++.
Причём тут понимание С++? О нём никто не говорил, говорилось о том, что абсолютно неважно что и как там называется. Факт остаётся фактом — всё, что сверху базового ++ — это дополнительный функционал, который в расте так же есть.
И это функционал к С++ отношения не имеет. Хочешь быстрое +10 — никто не будет долбить ++ 10раз. А хочешь долбить 10раз — что-то кроме InputIterator тебе не нужно и С++ никак к этому не обязывает.
В конечном итоге — что мы имеем? В руста * и ++ — это одна функция, а в С++ — две. Поэтому в С++ нужно реализовать лишь ==, что в ходит в первоначально определение «одну-две функции».
Я даже не знаю, что на это ответить. «Безопасность уровня программиста» это как? Не давать программисту нажимать неправильные кнопки? Rust даёт определённые средства отлова и устранения определённых классов ошибок. И даёт средства локально отключать некоторые из этих ограничений — если того требует задача.
Раст ничего не даёт, вы никогда не покажете то, что он даёт и причина проста — это невозможно.
Отключить глобально unsafe вы не можете, а значит оно будет включено, а значит все гарантии — гарантии уровня рантайм/обёрток/etc, но никак не языка. Все те же гарантии реализуются на С++.
На это финиш и ваши аргументы исчерпаны, хотя я это уже несколько раз писал и каждый раз вы это игнорировали.
Эта фраза чётко говорит о том, что вы не понимаете, что такое ссылки в Rust. Уважьте, перейдите по ссылкам и прочтите.
Как всегда я вижу одно и тоже. Бесполезный трёп из которого ровным счётом ничего не следует. Ну и самое главное, вы нигде мне не рассказали — что именно я не понимают, что именно в моей логике ошибочно, но и самое главное — с чего я вообще должен понимать непонятно что.
Смысл в разнице, т.к. из неё следует тот самый вывод. А разница в том, что в С++ ссылка не может быть перемещена и переназначена — что делает её применение сильно ограниченным.
Я уже заранее помножил на ноль эту попытку, но опять игнорирование.
В расте нет ссылок — в расте есть обёртка в stdlib. Никаким образом эту обёртку нельзя сравнивать с конструкцией языка.
Что в Rust ссылка может менять указуемый объект, может быть перемещена и может свободно храниться в поле структуры, не «пригвождая» структуру к одному месту. И что не может пережить объект, на который указывает.
В расте нет ссылок, повторю это ещё раз. Подобное поведение реализуется и на С++, если нужно. И никаким образом дефолтные ссылки это не ограничивают.
Как раз корректно. Ссылки в Rust несут ту же нагрузку, что и в С++ — и в дополнение бОльшую часть нагрузки указателей.
Неверно. Нельзя сравнивать обёртку над указателем и ссылку, у которой есть чёткая семантика. Нельзя выдавать своё «хочу» за правильно.
С чего вы взяли, что ваша «ссылка», которая «не имеет ограничений» лучше, нежели ссылка, которая их имеет? Для меня — лучше та, которая имеет?
Да и рассуждения про ограничения — смысла не имеют, ведь никаких ограничений у С++ нет, весь фокус в том, что мы сравниваем несравнимое, а если мы сравним обёртку над указателем и обёртку над указателем, то получить что? А ничего не получиться. Обёртка не имеет ограничений.
В целом, разговор защёл в тупик. Вы не приводите аргументов, только игнорируете либо отрицаете мои.
Я могу показать где и что вы игнорировали, но вы не сможете показать ни одного. Почему? Потому что это пустой трёп.
По поводу ваших обвинений в отрицании — это подмена понятий. Это стандартный приём, когда мы выкатываем тезис и наделяем его нужным нам следствием. Например — «у вас ник на T — вы идиот». И далее играть в игру «но ведь он на T».
Именно поэтому в рамках дискуссии принято чётко и ясно выводить все следствия из своих требования/тезисов. Чего от вас нет. Вы кидаетесь примитивными шаблонами «не понимаешь», «а это так», при этом — это демагогия. Это не аргументы, не тезисы — это трёп.
Вы не следите за развитием Firefox, поэтому делаете такие неверные выводы. Они переделывают движок.
Всё это — никакого отношения к firefox не имеет. Обе ссылки про серво, которое до сих пор не умеет к css.
В firefox добавили ксс-парсер, при этом никаких объективных свидетельств за то, что он быстрее — нет. Да и парсинг ксс — это копейки от времени рендеринга страницы. На этом нововведения(глобальные) заканчиваются. По крайней мере ни одна из ваших ссылок к ним отношения не имеет.
Ну и вы полностью проигнорировали всё, я вам повторил свои два тезиса, вдруг я первый раз сформулировал это непонятно. Но вы опять их проигнорировали. И тут уже нельзя сослаться на то, что вы сделали это не специально — нет, вы делаете это специально.
Я вам сказал про пример оверхеда на option, вы мне показали, что спустя 5-7 лет существования языка — кастыль впилили. Но ведь кастыль ничего не значит — это показывает фундаментальную дыру, когда у нас есть дырявые абстракции, для которых мы каждый раз должны нарушать логику, нарушать инкапсуляцию.
И я вас привёл следующий пример, который вы проигнорировали. Есть проблемы те, которые решает раст, но есть множество проблем, которые он производит. При этом, большинство эти решений — это решения не уровня языка, а уровня программиста, хотя почему-то раст их декларирует как решения уровня языка. Что странно.
Вся эта тема — это сплошные манипуляции. В stl есть много мест для совместимости с си, которые «не безопасны», но они там взялись не из-за того, что С++ — это «100% небезопасно», а из-за того, что есть множество сишного кода, который нужно интегрировать.
То же самое происходит и с растом — раст без unsafe не позволяет интегрировать в себя сишный/крестовый код, а раст без него попросту существовать не может. llvm, libc, шланговые рантайм для исключений и прочее и прочее. Сколько биндингов к сишному коду в том же серво?
Каким образом этот коде безопасней? Никаким. В идеально мире, где у нас весь код расте/смартпоинтерах — всё хорошо, и в хелвордах на ресте — то же всё хорошо, как и в хелвордах на смартпоинтерах. Но реальность она сложнее.
И не стоит заниматься этими манипуляциями и подменой понятий, сравнивая несравнимое. Это хорошо звучит, люди любят популизм, но далеко на нём не уедешь.
Как всегда, ничего нового. Ничего конкретно, одни обвинения «ты ничего не знаешь», «да иди читай и просвещайся» — зачем вы живёте? Какой смысл в вашем существовании и пребывании тут? Спастить мне ссылку? Просто так меня обвинять?
Ведь вы никогда мне не скажете и не покажете — где я не прав, в чём я не прав, что и почему мне нужно смотреть. Вы где-то прочитали тезис, но не можете его аргументировать, и именно поэтому как только у вас возникают проблемы — вы пытаетесь снять с себя ответственность.
Гарантии выражаются в отказе компилировать код, в котором они нарушаются. Этого недостаточно?
Это не более чем манипуляции. Компилятор компилирует код с unsafe? Компилирует. На это финиш.
Гарантии в расте — это такие же рукотворные гарантии, как и везде. Есть точно такие же требования, как и везде. Хочешь писать код — делай это правильно, но это не значит, ты неправильно его написать не можешь — можешь. И пишешь.
Это в жаве я не могу написать неправильный код( и то я даже не уверен в этом), но в данном случае все гарантии — это гарантии программиста.
Это из разряда «ремни безопасности гарантируют нам безопасность», только вот ремни сами на тебе не застёгиваются, и эта безопасность — лишь следствие желания человека её использовать. Никто не выдаёт эту безопасность за «бесплатную»/пассивную — она не такая.
Изучите вопрос. Ссылки выше в комментарии.
Это очень хорошо, когда вы не можете ничего ответить и пытаетесь делегировать эту обязанность на какие-то ссылки. Ведь я же говорю не с ссылка, а с вами.
И опять — ответов нет. К чему и что следует из этой ссылки, к чему вы её спастили и какие мои слова она опровергает — неясно. Недостаточно просто кинуть ссылку — надо связать её с контекстом и вывести следствие. У вас нет ни того, ни другого.
Категории итераторов — это расширение функционала и не более того. Если вы в расте взяли и определили, что у нас итератора есть InputIterator, то руководствуйтесь и в С++ такой же логикой. InputIterator такой же итератор — всё остальное — сверху.
Вы не получите поведение аналогичное другим категориям, реализую одну/две функции. Будь то С++, раст, пхп, либо что угодно.
В этом топике речь если шла, то о неидиоматичном коде. И вы, кстати, ни одного примера кода не привели.
Вот опять непонятно что и непонятно к чему. Я сразу же указал, что евангелисты раста часто путают безопасность уровня языка и безопасность уровня программиста, это же касается не только безопасности.
Вы говорите «раст, компилятор даст по рукам», а в следующем ответе уже говорите иное. Оказывается проверять ошибка не обязательно, иммутабельность — не обязательно, safe — не обязательно. И вся аргументация сводится к тому, что «а просто не пиши unsafe» — дак я то же самое могу делать и в С++.
Я могу точно так же нарушить unsafe как угодно, и осознания того, что это «неправильный код» — ничего мне не даст. И никакой компилятор мне ничего не скажет.
И опять то же самое. Зачем мне кидать ссылки? Что из них следует? Даже предположим, что отличия есть( на самом деле тут уже подлог, ведь в С++ ссылки — это конструкции языка, а в расте — просто обёртки и сравнивать их некорректно. Я могу сделать какую угодно обёртку и назвать её ссылкой), то что из этого следует?
Вы понимаете, что нельзя просто так взять и сказать «разница есть». Ведь смысл не в разнице, а в том, что из неё следует. И это следствие вы не вывели.
Кстати, у них названия разные — вот вам ссылка, прочитайте. Только что из этого следует? Ничего.
Вот и тут то же самое. Вам указали на то, что сравнивать голые указатели в С++ и ссылки в расте — некорректно. Вы поплыли в сторону «они различаются» — различаются, дальше что?
Забыл ещё один пример привести, кроме unwrap — это immutable. У нас так же везде immutable, но в реальности же — везде mut через mut, при этом в очередной раз мы услышим отмазку про то, что «а вот в реальных проектах». И какой бы код ты не показывай — везде ответ один «это неправильный код», при этом мы сразу же забываем о том, что «компилятор должен бить по руками» и «гарантии».
При этом, когда мы говорим о крестах — у нас почему-то этот аргумент пропадает. И почему я не могу сказать «а вот в реальном коде new чрез new никто не использует», и это действительно так.
Мы берём ссылки и сравниваем их с указателями, будто бы в крестах ссылок нет. Мы сравниваем то, что удобно нам, игнорируя то, что неудобно.
И так везде — никто не скажете того, чем строки в расте более safe, нежели в крестах. Мы всегда съезжаем на тему «а можно их не использовать», дак ведь в расте их то же можно не использовать.
Ну тут типичный набор вранья, игнорирования и манипуляций.
Я определил пару основных тезисов — никакой компилятор ничего не гарантирует и ни к чему, о чём говорилось — не имеет( это было проигнорировано), никакой компилятор ни по каким «рукам» не даст. Это всё обычная лапша и обёртки, которые есть везде, с одной лишь разницей — разделение языка на unsafe/safe, но из этого так же ничего не следует. И это мой второй тезис.
Использование указателя с припиской unsafe ничем не отличается от использования указателя без неё. А все рассуждения об unsafe в конечном итоге сводятся с тому «так надо», а не «компилятор бьёт по рукам». Это так же было проигнорировано.
Я привёл пример с unwrap(), и сказу же указал на то, что опять будет слив на «стайлгайды» и «так надо», но декларируется не «делай как надо» — ведь «делать как надо» — никто не запрещает и в крастах. Евангелистами декларируется какое-то обязательство со стороны языка, и через это они и выделяют преимущество — там можно, либо нельзя, а у нас только «можно». Что неверно.
Далее, на вопрос по теме unsafe ответа так же не последовало. Опять пошла песня про «лучше видно», при этом никаких оснований этому нет. Чем unsafe видно лучше, нежели new — непонятно. И никто и никогда этого не расскажет.
Разница есть. Либо вы прилагаете дополнительные усилия, пишете обёртки, доп. проверки, призываете статические чекеры чтобы не отстрелить себе ногу. Либо вы пишете дополнительный код, чтобы какие-то ограничения локально отменить.
Что это значит — неясно. Что из этого следует — неясно. Весь safe в расте — это примитивная stdlib, которая никакого отношения к языку не имеет. Аналогичное пишется на крестах и уже написано, при этом в крестах такой же safe.
Единственная разница в том, что в крестах unsafe пишется без приписки unsafe — на это разница заканчивается. Что-бы в расте появилась обёртка — её надо написать, точно так же, как и на крестах.
Что-бы в расте было safe — надо использовать эту обёртку. То же самое и в крестах.
Всякие рассуждения о статических проверках и прочем — это враньё и манипуляции. Если ты используешь в коде new — он ловиться статической проверкой, если используешь в расте unsafe new — это ловится тем же. Рассуждения о том, что unsafe можно вырубить — не котируются. Без unsafe ты ничего не напишешь.
Вот этот пассаж вообще не понял. Выше уже написал, что конкретно делает ансэйф.
Очередные попытки игнорировать реальность. О чём вы говорили? О том, что в расте что-то там выразительнее — вам сказали, что ваше утверждение ни из чего не следует. И вам нужно либо показать, что оно из чего-то следует, либо оно не следует и это просто трёп.
Попробуйте написать итератор над любой нетривиальной структурй данных. С поддержкой всех нужных категорий. И сравните с как правило одним или двумя методами, которые надо реализовать для итератора на Rust.
И опять же, у нас есть пустые утверждения цена которым ноль. Категории никакого отношения к крестам не имеют — это банальное свойство реальности, которые нужно реализовать, если хочешь эффективное поведение.
От того, что можно взять ++ и назвать это итератором — из этого мало что следует. Никакие категории никто не обязывает реализовывать — их не будет и в расте.
Итератор — это интерфейс, а реализация никакого отношения к итератору не имеет. И сложность абсолютно не зависит от интерфейса. Хочешь ++ — сделай ++ в крестах, если оптимальный интерфейс реализовать не можешь. И это сложность именно оптимальности, а не крестов.
Оптимизировано.
Прикостылен костыль, и чем больше будет «оптимизацией» — тем больше будет таких мест. Хотя спустя 5-7лет прикостылили оптимизацию для такого элементарного случая, а таких случаев тысячи и тысячи.
А далее мы захотим использовать индексы вместо указателей — привет bound checking и прощай производительность, либо прощай bound checking и привет unsafe.
Тогда зачем вообще комментируете эту часть? Если вы хотели пояснений — написали бы «Поясните». А не «Я не знаю, значит никто не знает, значит никому не нужно».
Ну дак что же вы не пояснили? И опять же — очередные попытки врать и выдавать враньё за мои цитаты.
Поясню. В С++ у вас вся программа представляет собой один сплошной unsafe блок. Где-то промахнулись с указателем — и всё, приехали. Причём учтите, что с тривиальными ошибками помогают смарт-указатели. С нетривиальными — всё по старому.
Всё не совсем так, а вернее совсем не так.
Все эти рассуждения сводятся к одному — мы сравниваем несравнимые вещи. Мы сравниваем кейсы с указателями, которые в расте точно так же требуют указателей, именно поэтому в stdlib через строчку unsafe.
Теперь — чем лучше rust конкретно здесь. Возможностью сказать компилятору «конкретно здесь я сделаю сам, а вокруг уж будь добр проконтроллируй ты». Именно поэтому я и говорю, что если, как вы пишете,
Опять же, не так. Никакой компилятор ничего не контролирует. Схема очень простая — мы просто запрещаем использовать всё опасное, а вернее 95% языка.
Решается это всё следующим образом — мы даём интерфейс, который реализован через unsafe, который является обёрткой вокруг этих самых опасных операций. Раст к этому не имеет никакого отношения, как и компилятор.
Такой же обёрткой является умный указатель, вектор, строка и прочее. Но почему-то мы всё это игнорирует со стороны C++.
В конечном итоге раст ничем не отличается от того же stl, где никакие указатели не нужны. Единственная разница в том, что в C++ писать unsafe не надо, а в расте надо. Но написать ты его можешь где угодно из его наличия ровным счётом ничего не следует.
Есть какие-то рассуждение на тему того, что «а unsafe видно лучше», но кем лучше и почему — не сообщается. Чем его лучше видно, нежели new — неясно. Все рассуждения про «new может быть где-то спрятан» — правильно, так же как и unsafe.
В конечном итоге раст — это просто набор обёрток, которые можно реализовать где угодно и они реализованы на С++. Никакой разницы нет. Единственная разница в том, что нужно писать unsafe — на этом разница заканчивается.
Все рассуждения о том, что unsafe что-то там — не работают. Такие же рассуждения были о том, что «мы заставляем всех проверять ошибки», но почему-то добавили unwrap() и теперь весь код — это unwrap() через unwrap() и где всё эти рассуждения? А нигде. Никому они не интересны. Остались на уровне гайдлайнов, как и в С++.
у вас получится, по факту, полотнище Си-стайл небезопасного кода. В таком случае на ржавчине код будет длиннее, т.к. подразумевает больше явности. И это было сделано намеренно.
Ничего из этого намеренно сделано не было, никакой явности нет. Никто и никогда не расскажет о том, чем код в unsafe более явный, нежели С++. Как максимум всякие субъективные рассуждения на тему «мне так нравится», но каждый своё болото хвалит и никаких объективных предпосылок к этому нет.
Если же вы имели ввиду написание максимально оптимального кода, но с соблюдением С++-стайл — на С++ будет, скорее всего, длиннее.
Чего длиннее и почему — никто не расскажет и не покажет.
Почему — инфраструктура написания кастомных контейнеров на С++ всё ещё в зачаточном состоянии.
В зачаточном состоянии она на расте — без unsafe ничего не напишешь.
Да, можно накастылить семантику указателя через ссылку + option, как это сделал автор, да и кто угодно сделает. Только есть нюансы — указатель хранит состояние бесплатно, а option платно. Привет оверхед по памяти 50-100% на ноду. Естественно, что в хелвордах это мало кому интересно, но это интересно за рамками оных.
Особенно в области написания типов итераторов.
Что это такое, какие тут есть проблемы — не знаю ни я, ни, скорее всего, все остальные.
В вашем коде последний аргумент (size) при всех вызовах memcpy равен offset = sizeof(int); При включенной оптимизации компилятор преобразует это выражение в константу времени компиляции, а следовательно, memcpy выродится в intrinsinc — простое копирование значения без вызова функции.
Из этого ничего не следует — причины просты: а) intrinsinc никакого отношения к константе времени компиляции не имеет. Это имеет отношение к оптимальности кода. б) инфа про медленный вызов функции устарела лет на 15.
В итоге, вы сравниваете методы std::vector: at() и push_back() в которых присутствует проверка граничных условий и выброс исключений, в случае неудачи (такие методы, как правило, не могут быть заинлайнены), и просто копирование значения по указателю, даже, без проверки выхода за границы.
C at() ладно, но push_back() — это проблема вектора. throw никак не влияет на возможность инлайнинга. Придирки к чему-то, кроме at() — не имеют смысла.
Но сравнение не корректно, на мой взгляд.
Никаких обоснований некорректности, кроме ат, приведено не было. Особенности работы push_back() к делу отношения не имеют. Если мне не нужен какой-то функционал и он есть, но его убрать я не могу — это не значит, что сравнение некорректно.
Ну какие же это баги. 90% недоработка является багом? Голословные утверждения являются багом? Это лишь то, что я за пару минут проверил. То, что мне первое пришло в голову. И это самое простое.
6) wr-stats учитывает только время отрисовки кадра(ибо это рендер, он про внешние запросы ничего не знает).
Это не накладные расходы. raf вызывается перед рендерингом кадра и если он вызывается через х2 после предыдущего — это явная просадка.
Но сам процесс отрисовки в webrender во многих случаях значительно быстрее, чем без него, что открывает возможности для дальнейших оптимизаций.
Это манипуляции. Там написано не «он кое как работает и быстрее нашего дефолтного, тормазного, рендеринга в firefox», а «в хроме 15фпс, у нас 60фпс — самый быстрый».
Если вы претендуете на оптимизацию аутсайдера, то это не дает вас быстрым. Если вы претендуете на «быстро» — сравнивайте с быстрыми. А именно с хромом.
А так это маркетинговый булшит уровня «самый шоколадный* *из всех наших продуктов» и что он делает тут — не ясно.
По поводу случаев. Их пока нет, либо по крайней мере я их не видел. Я вижу только подтасовку и пустые заявления.
В общем, вы пессимистично настроены. Вероятно вы во многом правы, но технология еще сырая и после сглаживания всех шероховатостей может привести к значительному росту производительности браузера в целом.
Понимаете в чём штука. Зачем заниматься подобными манипуляциями, если у нас что-то действительно есть? Зачем всё это про «самый быстрый/быстрый» и прочее? Почему не «возможно потом что-то да будет». Я не вижу этого — я вижу заявления, которые не соответствуют действительно.
Мне не нравится когда меня обманывают и считают за идиота. Я таким проектам не верю, таким людям не верю. И это правильно. И это не первое проявление.
Я могу рассказать краткую историю этого «движка». Вначале была параллельность. Мы придумали новый язык, который на это заточен и это должен был быть супер-параллельный движок. Потом как-то всё заглохло и вся параллельность превратилось в заспавн тысяч тредов и зависание через пару минут работы. Между тем в хромиуме есть многопоточный рендеринг и что-то я не вижу подобной желтухи и громких заявлений. И он есть и он работает.
Сейчас я вижу новую историю. Производительность с цпу мы не получили — теперь у нас новая идея — получить её с гпу. При этом казалось бы — причём тут раст, но вот так вот. И все эти рассуждения про «принципиально новое» — действительно. Верю. В гугле работают идиоты и до таких «инновационных» решений не доросли. При этом ладно, раньше было объяснение про «на расте проще писать многопоточные программы — поэтому мы даём фору хрому», но сейчас это не работает.
И естественно с «гпу» у нас работает 2-3% css, но мы уже всех побеждаем. Мы специально подбиваем под нас бенчмарки( которые на самом деле не бенчмарки, а фейк). Это не баги. Это подтасовка. Почему автор бенчмарка не написал там opacity? Знал что оно показывает 30фпс? Почему в видео специально зарезано качество? Чтобы люди не видели артефактов и качества рендера? Почему в видео содержится деза про 15фпс? В надежде что читатель не проверит?
И разве где-то в тексте это написано? Нет, это умалчивается. Опять же — мне не нравиться то, когда меня считают за идиота. Т.е. вам это нравиться и вы согласны с тем, что те, кто играют в подобные игры вам дадут хороший продукт?
Да и с технической части статья желтушная на 95%. Как будет у меня время я разберу её поподробнее. Возможно, кого-то это спасёт от слепой веры.
В любом случае. Тут плохо даже не всё это — тут плохо то, что подобное вгоняет комьюнити данного языка в средневековье. У нас везде победы, всё это враньё и желтуха затмевает нам разум. Всё это развивается в в сторону полного неадеквата семимильными шагами. И это плохо.
Примеры не заставляют себе долго ждать. Мои полностью объективные замечания минусуют. Хотя казалось бы — там нет ничего с чем можно соглашаться, либо не соглашаться. Там факты из реального мира. Отрицание этого — отрицание реальности. Именно в этом проблема.
При разработке WebRender мы поставили задачу, чтобы все приложения работали на 60 кадрах в секунду (FPS) или лучше, независимо от размера дисплея или от размера анимации. И это сработало. Страницы, которые пыхтят на 15 FPS в Chrome или нынешнем Firefox, летают на 60 FPS при запуске WebRender.
Это же явный подлог. Начиная с того, что какой-то отдельный бенчмарк — это явно не «все приложения».
В остальном. Мой chromium выдаёт так же 60фпс и я не знаю откуда взялись эти 15. Это явное враньё. Далее, я скачал это серво и запустил. Получил 60фпс(поверим, что это реальные), при этом я так же получил
1) артефакты, которые(на первый взгляд) так же видны на видео, которое ОЧЕНЬ хренового качества, почему? Совпадение?
2) нагрузка на цпу идентична хромиуму, а вот нагрузка на гпу выше.
3) У серво мало того, что артефакты, так ещё и визуальное качество рендеринга явно хуже.
4) Добавление банального box-shadow ломает полностью серво и все эти 60фпс пропадают.
5) Да что там box-shadow — даже банальное opacity уже не даёт 60фпс, а в хромиуме ничего не меняется и те же 60фпс.
6) графики в --debug wr-stats — врут. Я добавил банальный подсчёт максимального времени кадра на базе разницы между вызовами raf и что серво, что хромиум просаживаются до 30мс( в моём случае). Чего в графиках, конечно же, нет.
В конечном итоге, что мы имеем? Да ничего мы не имеем.
Нетривиальной функции template<Container, Value, Iterator> Iterator func(std::pair<Container, Value> val); которая бы делала что-то осмысленное в языке С++ существовать не может.
Что это за бредни? Во-первых откуда там взялся pair? Во-вторых — я уже назвал пример.
В любом случае — исход был заранее определён. Вы очень часто путаете ваши мечты и ваши возможности. Ваши возможности ограничены минусом «в крысу». В следующий раз не надо это путать. Остальные вон не перепутали.
Требовать назвать время жизни осмысленней, примерно то же самое, что отказываться решать уравнение 2*x+4=0, пока вместо x не поставят «неизвестное_количество_яблок» или что-то в этом роде.
Переменные обычно связаны с семантикой выполняемых функцией действий, поэтому имеет смысл называть их так, чтобы семантика функции становилась яснее.
Явное противоречие. Вы уж определитесь с тем — нужно ли вводить ассоциацию между значением и тем, что оно выражает, либо нет. А то в одном случае смысла нет, а в другом есть.
Как ни назови 'a, его значение будет «ссылка X живет столько же сколько ссылка Y», а это и так видно из кода.
Я уже давал вам вариации на тему, которые вы, благополучно, проигнорировали. Как не назови A, его значение будет «тип ссылки X является тем же, что у типа ссылки Y».
Я могу попытаться найти какое-то рациональное зерно в ваших рассуждения и сформулировать его. Переменные — это отображение неких сущностей из реальной мира, либо каких-то внешних моделей. Есть модель тех же уравнений — там у x есть чёткое определение, только оно определённо где-то в рамках этой модели. И записывая 2x+4=0 вы просто используете x как экспорт из этой модели. И уже каждый знает что такое x.
А вот если вы там напишите 2*g+4=0, то вы получите фейл. Т.к. вы привели банальный подлог.
Поэтому, если мы считаем яблоки, то у нас и название переменных будут яблоки, а не x — x это некая обобщённая форма неизвестной. Как то же value. И использовать везде abc вместо яблок — это моветон.
Тут имеет смысл только ссылка на то, что лайвтаймы — это про отношения ссылок/сущностей внутри самого языка. Мы не экспортируем что-то явно, либо по умолчанию( как в примере с x), а именно определяем их в определённом контексте.
Но опять же — это тупиковый путь. open_file(string a); — почему подобное является моветоном? Ведь контекст явно определён. file, да и тип string из которого мы сразу узнаём искомое свойство файла, но. Это некрасиво, это глупо.
Поэтому да, явно видно к чему привязан лайвтайм, но. Явно видно и то, что a = x * y. Но что дальше? По мне так лучше это назвать xy, пусть мы итак видим, что это x * y. Явно видно, что string a = file.name; Но что из этого следует? Да ничего, кроме того, что это явная глупость.
То же самое с лайвтаймами. Смотря на 'a — я не понимаю что это и откуда взялось. Мне надо смотреть на полный контекст, который может быть не таким примитивным. Зачем? А незачем. И причину я уже описал выше. А далее я делаю вывод, что вы используете это потому, что лайвтаймы — это введённые для компилятора кастыли. Вы итак видите продление времени жизни объекта — это вам не нужно. Именно поэтому вы и пытаетесь их писать write-only и после — игнорировать. Иначе подобное поведение не описать.
Таким образом это что-то типа. let a; a = b; c = a; — т.е. у меня есть a', которое никак и ни к чему не привязано. Оно болтается в воздухе. Далее, оно неизвестно где и неизвестно как привязывается ко времени жизни одного и второго(и далее) объекта как-бы уравнивая время их жизни. И ты никак из этого 'a не узнаешь что это, зачем это и почему.
Какой смысл в этом по сравнению с (a, b) -> c {return c{move(a)};} — я не вижу.
Это совершенно разные сигнатуры функций. В Haskell идентификаторы используемые в сигнатуре функции и начинающиеся со строчной буквы обозначают именно любой тип.
Я уже заранее ответил на это, но вы почему-то это проигнорировали. Никакие «любые типы» НИКОМУ и НИКОГДА не нужны. Это очень и очень редкий кейс.
В C++ это будет template<a,b,c> c func(std::pair<a,b> val){...} и Iterator func(std::pair<Container, Value> val) — разные вещи, в общем.
Это вещи идентичные. Либо вы не понимаете, что это шаблонные типы?
template<Container, Value, Iterator> Iterator func(std::pair<Container, Value> val); А не то, что вы написали.
Здесь у нас есть некий обобщённый(упрощённый) тип контейнера, который подразумевает контейнер, а не хрен пойми что. Некий обобщённый тип значения и некий обобщённый тип итератора. Т.е. имя наделяет переменную дополнительными свойствами, которых не на уровне языка. Но не только.
Существует нотации для определения свойств уровня языка в переменных. Кто-то их считается осмысленными и нужными. Да и много есть кейсов, где имя удобнее.
Т.е. даже если у меня есть механизмы внутри самого языка ограничить множество типов в a только контейнерами, то мне проще использовать Container, а не смотреть что там и как определенно. Особенно если это тонна лапши. Это лишь дополнительная строгость уровня языка…
Кстати, функция с сигнатурой (a,b) -> c довольно бессмысленна, так как может возвращать только bottom. Но это уже к обсуждению не относится.
Что? В этом и проблема, что вы уже запутались. А если бы вы посмотрели на имена — вы бы сразу там увидели банальную сигнатуру find(a, b) -> c.
Потому что сравнение в первом комментарии этой темы очевидно бессмысленно — третьесортный толстый троллинг с лора — и тратить время на анализ подобного не хочется.
Для вас всё неудобное троллинг. Очень удобно, не спорю.
Я не вижу что бы кто-то в этой теме заявлял о полной бесплатности ВЖ для читателя кода.
Выше, пожалуйста. Никто из ваших оппонентов не обязан что-то знать про ваш «язык». Приводят примеры и если что-то в них немного неверно написано, то их этого ничего не следует. Это ваша обязанность адаптировать примеры.
А то получается как «будет то же самое» и всё очень удобное — можно посмеяться над автором, но суть примера не в этом. Об этом в том треде сообщили и я вам тут сообщил, что вы, благополучно, проигнорировали. Очень удобно, повторю.
>> Явные ВЖ усложняют типы, только я считаю что это окупается более выразительной формальной семантикой — так и сам код понимать проще, и оптимизации дополнительные можно провести, и от кучи ошибок с памятью автоматически защищает.
Вся эта «более выразительная» — ничего общего с объективностью не имеет. Это итак ясно из контекста.
Наличие подобно в расте лишь следствие слабости компилятора и не более того. А все эти рассуждения об каких-то мистических оптимизациях ничего так же не стоят без примеров. Я их не видел, вы их не показали. Нет никаких оснований вам верить. Всё просто.
Первый комментарий был про уродство ржавого синтаксиса — вот с этим я не согласен, я уверен что это просто вопрос привычки.
Этим можно оправдать всё что угодно. Следует ли из этого что-то? Нет. Ваши слова значат не более чем его, либо чем мои. Никаких объективных свидетельств нету.
Обсуждений было много, лучше так никто и не предложил.
Из этого так же ничего не следует. Отсутствие предложения в какой-то определённой тусе мало что значит. Да и какое там могло быть обсуждение, если это просто рандомный символ на подобии *&. Что там остаётся? #@'? По мне так ' самое глупое из них. По причине 'a' ~= 'a.
Да и странно как-то обсуждалось всё это. Был ГЦ, был другой синтаксис. Потом вдруг бам. ГЦ не стало, ГЦ стал не моден. Идеальный синтаксис выпилили и взяли крестовый.
>>… И там нет возможности выразить эту полезную в некоторых ситуациях информацию, разве нет?
Ещё раз. Она там только по причине слабости компилятора. Никакой новой информации она не даёт — она итак выводится из контекста.
То же самое с автоматическим выводом типов. Оно не теряет типы. И нужно не для какой-то там неведомой «полезной информации», а чисто для ограничений, либо кастов всяких литералов в нужный тип.
Если у меня есть функция (a) -> b {return c{a};}, где с хранит ссылку a, но при этом это компилятор сам вывести не может — это никакой новой информации мне не даёт, да и вообще не даёт.
'a в данном случае никакого собственного смысла не несёт, единственная его функция — указать одинаковость времён жизни arch и возвращаемого значения.
Никакого собственного смысла имя типа в шаблонах не несёт, единственная его функция — указать одинаковость типов…
Никакого собственного смысла переменная не несёт, единственная её функция — указать одинаковость значений…
Ну и ключевое слово «в данном случае». А не в данном?
>>Для сравнения, в Haskell аннотации типов обычно тоже однобуквенные
И? Что же из этого следует? Т.е. вы мне предлагаете писать так: а<A, 'a, B, C>(arg0: &'a A, arg1: &'a B) -> &'a B? Либо как там у вас будет? Нет, спасибо.
Потому что нет никакого смысла писать (любойтип1 -> любойтип2)
Т.е. вместо (Container, Value) -> Iterator мне надо писать (a, b) -> c? Нет, спасибо. Проблема в том, что там не любой тип — любой тип никому не нужен.
Притом, что в других языках никаких лайвтаймов нет и если в крестах есть 2 вида аргументов, то тут есть уже три.
В любом языке при добавлении качественно отличающейся информации размер сигнатуры функции (да и любой другой записи) будет увеличиваться.
Не верно. В расте это дополнительный ахтунг, которого в другом языке(без лайвтаймов) не будет.
Я так понимаю что придирка сводится к тому что ржавчина умеет явно выражать ВЖ, а большинство других языков — нет?
Это не придирка. Раст ввёл в язык некую новую сущность, которая не бесплатна с т.з. читаемости и ой как не бесплатна. Да и синтаксис очень спорен — это как минимум.
А люди почему-то выдают её за бесплатную. В этом и есть проблема.
Тогда, надо выбрать победителем питон и успокоиться.
Это глупость. И почему — ниже так же объяснили на том же лоре.
И ваш пример крайне показателен. Вы не спорите с тем, что явная типизация не бесплатна, а в ситуации с растом это не так. Тип — это свойство переменной, который не указывается явно в питоне. Точно так же лайвтайм — это такое же дополнительное свойство. Т.е. ситуация аналогичная, но в случае с растом у нас «всё так же»( что явно неправда), а в случае с питоном всё не так же.
Таким образом питон < С++ < раст. Критерий ясен и понятен. С питоне только имя, в С++ имя и тип, в расте имя + тип + лайвтайм.
Очередной идиотский тезис. Иди прогрепай stdlib на тему unsafe и расскажи об успехе, и да, по 100баксов вычти то же.
Кстати, замечаем как меняется риторика. Вначале у нас было «по умолчанию безопасный», теперь, оказывается, что надо грепать. А т.к. ты 100% что-то нагрепаешь, то оказывается нужно проводить ручной анализ.
Это типичный пример подмены понятий, вранья и манипуляций.
Никакой лоулевел код невозможен без unsafe. Любой биндинг — unsafe.
Берёшь какой-нибудь clang-tidy и пишешь за пол часа набор правил. Что надо искать? */&/new — искать не сложнее, чем unsafe.
Это неважно. Важно лишь то, что этого нет. Всё эти типы существуют, если существуют(что будет работать в этом кейсе), в языках, которые, мягко говоря, даже рядом с растом( я уж не говорю о си) не валялись. В них мы не экономим рантайм и может играться как хотим.
Т.е. есть безопасность, а есть бесплатная безопасность. Это разные вещи.
bounds checking не заканчивается на обходе массива. Вернее он там и не нужен. Он нужен при доступах по индексу.
Действительно, мы можем реализовать какие-то безопасные индексы, на С++ может это сделать статически( раст, конечно, ничего тут не сможет), только вот проблема с интеграцией в текущий safe-код, да и с реализацией есть проблемы.
Нам нужно дать следующий блок? Как? Привет bounds checking. Мы же не будет в массив записывать весь набор index_t и ходить по нему?
Как мы преобразуем порядок бита в битмапе к валидному индексу? Будем делать unsafe cast? Да, мы можем(предположим) сделать интерфейс safe, но реализация будет unsafe.
В этом заключается типичная для всех пропагандистов раста подмена понятий, мы куда-то постоянно деваем реализацию. Вы это то же подтверждаете. Т.е. писать stdlib можно без safe? Писать биндинги можно без safe, писать любой лоулевел код — можно без safe? Его писать что-ли не надо? Как этому помогает раст? Никак.
Есть два разных мира — мир написания обёрток и мир их использования. И если я разработчик stdlib раста, то никаких фишек он мне не даёт. Он даёт их тем, кто будет использовать эту stdlib, и то это спорно.
Из этого ничего не следует. В крестовом коде может быть то же ноль указателей, ноль new и прочее. И потом вы это можете точно так же искать.
Только вот проблема в том, что мир не заканчивается на ваших представлениях и вашем коде. Я вам уже приводил пример с stdlib раста. Идите и прогрепайте её. И так будет с любым лоулевел кодом.
Да, всегда можно написать условно-безопасную обёртку, но её нужно написать. И её нужно и можно написать и в крестах. А можно не написать — и ничего не поменяется. Это можно сделать что на крестах, что в расте.
Неверно. Очередная агитка, из которой ровным счётом ничего не следует. Никакого «умолчания» нету, вы придумали ахинею и повторяете её.
Код в расте по умолчанию такой же unsafe, а safe он будет тогда, когда глобально вырубить unsafe, но тогда это будет жаваскрипт, а не «альтерантива» крестам. Но и опять же, а если я разработчик stdlib, то у меня получается unsafe раст? В stdlib safe не нужно?
В конечном итоге всё сводится к проверке — написан ли у тебя unsafe код, а в каком виде этот unsafe код будет — в виде raw-pointer, либо unsafe raw-pointer — абсолютно неважно.
Не надо за апологетами повторять убогие тезисы. Они пустые и ничего не значат, из них ничего не следует.
Это всё голубые мечты. Да и данный кейс не про обход в массиве.
Ничего. Это капля в море. Да и опять же, дело не в этом — дело в том, что все это прошлогоднее, хотя о мистической оптимальности рассуждалось десять лет.
Какой коробки и какую оптимизацию? Это не оптимизация, а костыльная оптимизация, которая закрывает изначальную дыру, которой нет в крестах и там эта «оптимизация» не нужна.
Да и это хелворд, цена которому ноль.
Я про то, про что я.
Это не просто фича, это хайпилось как основной локомотив «безопасности», а теперь уже «просто фича». Хотя и safe — это просто фича.
safe, которую не предоставляет rust, в котором есть псевдо, которая легко снимается unsafe.
Очевидный кому? Никакой const T в T && не превратится — в T входит const. Поэтому это будет const T &&&, для константных lvalue.
Кстати, про constexpr в расте расскажешь?
Не может, иначе бы unsafe был выключен. Загляни в свою stdlib, либо в любую, не хелвордистый, код — ты там увидишь unsafe через unsafe.
Опять какая-то ахинея и ноль аргументации.
В крестах так же есть разделение unsafe/safe, только оно не декларируется через unsafe. На это различия заканчиваются. А декларация unsafe как unsafe не имеет смысла, вернее ни ты, ни кто-либо ещё никогда о нём не расскажет.
Написания raw-pointer и unsafe raw-pointer ничем друг от друга не отличаются, ведь raw-pointer итак unsafe в любом его проявлении.
Нет, обе ссылки маркетинговый булшит.
Я уже сказал, что серво не умеет в css — это объективная реальность, но адепты, как всегда, её игнорируют.
Во-первых, по ссылки ничего не написано про firefox — и это ясно и понятно, ведь вы ничего мне не показали, и не покажете. Во-вторых, что за привычка такая — болтать и не показывать?
Никакого, хоть как-то работающего, движка css в серво не существует, именно поэтому его не может существовать в firefox. Никакой движок ни в какой firefox никто не добавлял.
Вот тут мы объявлением тезис, что ссылка чего-то там не может. Но тут есть ошибка, мы берём какое-то свойство, говорим о том, что оно есть. И далее делаем вывод о том, что «лучше», хотя из наличия какого-то свойства «лучше» не следует.
Мы просто так, на основании хрен пойми чего — требует от других то, что есть у нас. При этом я точно так же могу требовать от раста то, почему у меня ссылка не привязывается к объекту?
Что из этих требований следует? Ничего.
Ну и как я уже говорил — в расте нет никаких ссылок, да и вообще нет почти ничего — всё это stdlib. Поэтому мы не может сравнивать конструкции языка и обёртки.
Ну и самое главное — почему мы ссылку в расте сравниваем с ссылкой в С++, а не с std::reference_wrapper? А причина проста — мы мало того, что делаем сравнения из которых ничего не следует — мы заведомо ограничиваем одну из сторон сравнивая несравнимое.
В конечном итоге всё сводится к тому, что везде всё должно быть как в расте. Почему? Просто так. Хочешь как в расте — сделай как в расте, это С++ позволяет. Но путём подмены понятий, мы выдаём за альтернативу в С++ ссылку(&), а на самом деле не должны ничего выдавать — ведь в расте этого попросту нет.
В конечном итоге «ссылка» в С++ может быть такой же, как «ссылка» в расте. С единственной разницей в том, что там она будет в stdlib, а в С++ нет( и то не факт). Но из этого ровным счётом ничего не следует — ведь никаких свидетельства за то, что надо так, а не иначе — нет.
Поэтому, стандартная реализации из С++ имеет та кое же право на существование, как и реализация раста. А если необходим функционал «как в расте» — он реализуется, да и уже есть.
Возражения на что? У вас нет «по существу» ничего, и вам об этом уже сообщили. А возражать «по существу» на нечто — нельзя. «существу» нет.
Дело не в том, что я понимаю, а что не понимаю. Вы там пытались рассуждать о том, что какой-то компилятор вам настучит, но теперь оказалось, что нет.
Причины того, почему он не настучит — мне не интересны и к делу отношения не имеют, мне важен факт «не настучит», а значит вы соврали — всё просто.
Опять же — ответа нет, а какой-то пустой трёп есть. Это основная проблема бесед в подобными евангелистами, вы не понимаете того, что нельзя просто так брать и требовать чего-то.
Вот у вас есть требования какого-то «предмета», но почему и на каком основании вы его требуете — у вас ничего этого нет. Это обыкновенный слив и ничего более.
Я чего-то не понимаю? — Что? И даже если будет что-то, чего не будет, то дальше будет финиш. Ведь вам нужно будет вывести из факта непонимания чего-то то, что вы из него выводите «необходимость и невозможность о чём-то рам рассуждать».
Во-первых, об этом никто не говорил. А во-вторых — en.cppreference.com/w/cpp/concept/InputIterator По это же ссылке чётко указанно — что нужно. ++/*/== — всё, при этом всё это необходимо для итератора.
Причём тут понимание С++? О нём никто не говорил, говорилось о том, что абсолютно неважно что и как там называется. Факт остаётся фактом — всё, что сверху базового ++ — это дополнительный функционал, который в расте так же есть.
И это функционал к С++ отношения не имеет. Хочешь быстрое +10 — никто не будет долбить ++ 10раз. А хочешь долбить 10раз — что-то кроме InputIterator тебе не нужно и С++ никак к этому не обязывает.
В конечном итоге — что мы имеем? В руста * и ++ — это одна функция, а в С++ — две. Поэтому в С++ нужно реализовать лишь ==, что в ходит в первоначально определение «одну-две функции».
Раст ничего не даёт, вы никогда не покажете то, что он даёт и причина проста — это невозможно.
Отключить глобально unsafe вы не можете, а значит оно будет включено, а значит все гарантии — гарантии уровня рантайм/обёрток/etc, но никак не языка. Все те же гарантии реализуются на С++.
На это финиш и ваши аргументы исчерпаны, хотя я это уже несколько раз писал и каждый раз вы это игнорировали.
Как всегда я вижу одно и тоже. Бесполезный трёп из которого ровным счётом ничего не следует. Ну и самое главное, вы нигде мне не рассказали — что именно я не понимают, что именно в моей логике ошибочно, но и самое главное — с чего я вообще должен понимать непонятно что.
Я уже заранее помножил на ноль эту попытку, но опять игнорирование.
В расте нет ссылок — в расте есть обёртка в stdlib. Никаким образом эту обёртку нельзя сравнивать с конструкцией языка.
В расте нет ссылок, повторю это ещё раз. Подобное поведение реализуется и на С++, если нужно. И никаким образом дефолтные ссылки это не ограничивают.
Неверно. Нельзя сравнивать обёртку над указателем и ссылку, у которой есть чёткая семантика. Нельзя выдавать своё «хочу» за правильно.
С чего вы взяли, что ваша «ссылка», которая «не имеет ограничений» лучше, нежели ссылка, которая их имеет? Для меня — лучше та, которая имеет?
Да и рассуждения про ограничения — смысла не имеют, ведь никаких ограничений у С++ нет, весь фокус в том, что мы сравниваем несравнимое, а если мы сравним обёртку над указателем и обёртку над указателем, то получить что? А ничего не получиться. Обёртка не имеет ограничений.
Я могу показать где и что вы игнорировали, но вы не сможете показать ни одного. Почему? Потому что это пустой трёп.
По поводу ваших обвинений в отрицании — это подмена понятий. Это стандартный приём, когда мы выкатываем тезис и наделяем его нужным нам следствием. Например — «у вас ник на T — вы идиот». И далее играть в игру «но ведь он на T».
Именно поэтому в рамках дискуссии принято чётко и ясно выводить все следствия из своих требования/тезисов. Чего от вас нет. Вы кидаетесь примитивными шаблонами «не понимаешь», «а это так», при этом — это демагогия. Это не аргументы, не тезисы — это трёп.
Всё это — никакого отношения к firefox не имеет. Обе ссылки про серво, которое до сих пор не умеет к css.
В firefox добавили ксс-парсер, при этом никаких объективных свидетельств за то, что он быстрее — нет. Да и парсинг ксс — это копейки от времени рендеринга страницы. На этом нововведения(глобальные) заканчиваются. По крайней мере ни одна из ваших ссылок к ним отношения не имеет.
Я вам сказал про пример оверхеда на option, вы мне показали, что спустя 5-7 лет существования языка — кастыль впилили. Но ведь кастыль ничего не значит — это показывает фундаментальную дыру, когда у нас есть дырявые абстракции, для которых мы каждый раз должны нарушать логику, нарушать инкапсуляцию.
И я вас привёл следующий пример, который вы проигнорировали. Есть проблемы те, которые решает раст, но есть множество проблем, которые он производит. При этом, большинство эти решений — это решения не уровня языка, а уровня программиста, хотя почему-то раст их декларирует как решения уровня языка. Что странно.
Вся эта тема — это сплошные манипуляции. В stl есть много мест для совместимости с си, которые «не безопасны», но они там взялись не из-за того, что С++ — это «100% небезопасно», а из-за того, что есть множество сишного кода, который нужно интегрировать.
То же самое происходит и с растом — раст без unsafe не позволяет интегрировать в себя сишный/крестовый код, а раст без него попросту существовать не может. llvm, libc, шланговые рантайм для исключений и прочее и прочее. Сколько биндингов к сишному коду в том же серво?
Каким образом этот коде безопасней? Никаким. В идеально мире, где у нас весь код расте/смартпоинтерах — всё хорошо, и в хелвордах на ресте — то же всё хорошо, как и в хелвордах на смартпоинтерах. Но реальность она сложнее.
И не стоит заниматься этими манипуляциями и подменой понятий, сравнивая несравнимое. Это хорошо звучит, люди любят популизм, но далеко на нём не уедешь.
Ведь вы никогда мне не скажете и не покажете — где я не прав, в чём я не прав, что и почему мне нужно смотреть. Вы где-то прочитали тезис, но не можете его аргументировать, и именно поэтому как только у вас возникают проблемы — вы пытаетесь снять с себя ответственность.
Это не более чем манипуляции. Компилятор компилирует код с unsafe? Компилирует. На это финиш.
Гарантии в расте — это такие же рукотворные гарантии, как и везде. Есть точно такие же требования, как и везде. Хочешь писать код — делай это правильно, но это не значит, ты неправильно его написать не можешь — можешь. И пишешь.
Это в жаве я не могу написать неправильный код( и то я даже не уверен в этом), но в данном случае все гарантии — это гарантии программиста.
Это из разряда «ремни безопасности гарантируют нам безопасность», только вот ремни сами на тебе не застёгиваются, и эта безопасность — лишь следствие желания человека её использовать. Никто не выдаёт эту безопасность за «бесплатную»/пассивную — она не такая.
Это очень хорошо, когда вы не можете ничего ответить и пытаетесь делегировать эту обязанность на какие-то ссылки. Ведь я же говорю не с ссылка, а с вами.
И опять — ответов нет. К чему и что следует из этой ссылки, к чему вы её спастили и какие мои слова она опровергает — неясно. Недостаточно просто кинуть ссылку — надо связать её с контекстом и вывести следствие. У вас нет ни того, ни другого.
Категории итераторов — это расширение функционала и не более того. Если вы в расте взяли и определили, что у нас итератора есть InputIterator, то руководствуйтесь и в С++ такой же логикой. InputIterator такой же итератор — всё остальное — сверху.
Вы не получите поведение аналогичное другим категориям, реализую одну/две функции. Будь то С++, раст, пхп, либо что угодно.
Вот опять непонятно что и непонятно к чему. Я сразу же указал, что евангелисты раста часто путают безопасность уровня языка и безопасность уровня программиста, это же касается не только безопасности.
Вы говорите «раст, компилятор даст по рукам», а в следующем ответе уже говорите иное. Оказывается проверять ошибка не обязательно, иммутабельность — не обязательно, safe — не обязательно. И вся аргументация сводится к тому, что «а просто не пиши unsafe» — дак я то же самое могу делать и в С++.
Я могу точно так же нарушить unsafe как угодно, и осознания того, что это «неправильный код» — ничего мне не даст. И никакой компилятор мне ничего не скажет.
И опять то же самое. Зачем мне кидать ссылки? Что из них следует? Даже предположим, что отличия есть( на самом деле тут уже подлог, ведь в С++ ссылки — это конструкции языка, а в расте — просто обёртки и сравнивать их некорректно. Я могу сделать какую угодно обёртку и назвать её ссылкой), то что из этого следует?
Вы понимаете, что нельзя просто так взять и сказать «разница есть». Ведь смысл не в разнице, а в том, что из неё следует. И это следствие вы не вывели.
Кстати, у них названия разные — вот вам ссылка, прочитайте. Только что из этого следует? Ничего.
Вот и тут то же самое. Вам указали на то, что сравнивать голые указатели в С++ и ссылки в расте — некорректно. Вы поплыли в сторону «они различаются» — различаются, дальше что?
При этом, когда мы говорим о крестах — у нас почему-то этот аргумент пропадает. И почему я не могу сказать «а вот в реальном коде new чрез new никто не использует», и это действительно так.
Мы берём ссылки и сравниваем их с указателями, будто бы в крестах ссылок нет. Мы сравниваем то, что удобно нам, игнорируя то, что неудобно.
И так везде — никто не скажете того, чем строки в расте более safe, нежели в крестах. Мы всегда съезжаем на тему «а можно их не использовать», дак ведь в расте их то же можно не использовать.
Я определил пару основных тезисов — никакой компилятор ничего не гарантирует и ни к чему, о чём говорилось — не имеет( это было проигнорировано), никакой компилятор ни по каким «рукам» не даст. Это всё обычная лапша и обёртки, которые есть везде, с одной лишь разницей — разделение языка на unsafe/safe, но из этого так же ничего не следует. И это мой второй тезис.
Использование указателя с припиской unsafe ничем не отличается от использования указателя без неё. А все рассуждения об unsafe в конечном итоге сводятся с тому «так надо», а не «компилятор бьёт по рукам». Это так же было проигнорировано.
Я привёл пример с unwrap(), и сказу же указал на то, что опять будет слив на «стайлгайды» и «так надо», но декларируется не «делай как надо» — ведь «делать как надо» — никто не запрещает и в крастах. Евангелистами декларируется какое-то обязательство со стороны языка, и через это они и выделяют преимущество — там можно, либо нельзя, а у нас только «можно». Что неверно.
Далее, на вопрос по теме unsafe ответа так же не последовало. Опять пошла песня про «лучше видно», при этом никаких оснований этому нет. Чем unsafe видно лучше, нежели new — непонятно. И никто и никогда этого не расскажет.
Что это значит — неясно. Что из этого следует — неясно. Весь safe в расте — это примитивная stdlib, которая никакого отношения к языку не имеет. Аналогичное пишется на крестах и уже написано, при этом в крестах такой же safe.
Единственная разница в том, что в крестах unsafe пишется без приписки unsafe — на это разница заканчивается. Что-бы в расте появилась обёртка — её надо написать, точно так же, как и на крестах.
Что-бы в расте было safe — надо использовать эту обёртку. То же самое и в крестах.
Всякие рассуждения о статических проверках и прочем — это враньё и манипуляции. Если ты используешь в коде new — он ловиться статической проверкой, если используешь в расте unsafe new — это ловится тем же. Рассуждения о том, что unsafe можно вырубить — не котируются. Без unsafe ты ничего не напишешь.
Очередные попытки игнорировать реальность. О чём вы говорили? О том, что в расте что-то там выразительнее — вам сказали, что ваше утверждение ни из чего не следует. И вам нужно либо показать, что оно из чего-то следует, либо оно не следует и это просто трёп.
И опять же, у нас есть пустые утверждения цена которым ноль. Категории никакого отношения к крестам не имеют — это банальное свойство реальности, которые нужно реализовать, если хочешь эффективное поведение.
От того, что можно взять ++ и назвать это итератором — из этого мало что следует. Никакие категории никто не обязывает реализовывать — их не будет и в расте.
Итератор — это интерфейс, а реализация никакого отношения к итератору не имеет. И сложность абсолютно не зависит от интерфейса. Хочешь ++ — сделай ++ в крестах, если оптимальный интерфейс реализовать не можешь. И это сложность именно оптимальности, а не крестов.
Прикостылен костыль, и чем больше будет «оптимизацией» — тем больше будет таких мест. Хотя спустя 5-7лет прикостылили оптимизацию для такого элементарного случая, а таких случаев тысячи и тысячи.
А далее мы захотим использовать индексы вместо указателей — привет bound checking и прощай производительность, либо прощай bound checking и привет unsafe.
Ну дак что же вы не пояснили? И опять же — очередные попытки врать и выдавать враньё за мои цитаты.
Всё не совсем так, а вернее совсем не так.
Все эти рассуждения сводятся к одному — мы сравниваем несравнимые вещи. Мы сравниваем кейсы с указателями, которые в расте точно так же требуют указателей, именно поэтому в stdlib через строчку unsafe.
Опять же, не так. Никакой компилятор ничего не контролирует. Схема очень простая — мы просто запрещаем использовать всё опасное, а вернее 95% языка.
Решается это всё следующим образом — мы даём интерфейс, который реализован через unsafe, который является обёрткой вокруг этих самых опасных операций. Раст к этому не имеет никакого отношения, как и компилятор.
Такой же обёрткой является умный указатель, вектор, строка и прочее. Но почему-то мы всё это игнорирует со стороны C++.
В конечном итоге раст ничем не отличается от того же stl, где никакие указатели не нужны. Единственная разница в том, что в C++ писать unsafe не надо, а в расте надо. Но написать ты его можешь где угодно из его наличия ровным счётом ничего не следует.
Есть какие-то рассуждение на тему того, что «а unsafe видно лучше», но кем лучше и почему — не сообщается. Чем его лучше видно, нежели new — неясно. Все рассуждения про «new может быть где-то спрятан» — правильно, так же как и unsafe.
В конечном итоге раст — это просто набор обёрток, которые можно реализовать где угодно и они реализованы на С++. Никакой разницы нет. Единственная разница в том, что нужно писать unsafe — на этом разница заканчивается.
Все рассуждения о том, что unsafe что-то там — не работают. Такие же рассуждения были о том, что «мы заставляем всех проверять ошибки», но почему-то добавили unwrap() и теперь весь код — это unwrap() через unwrap() и где всё эти рассуждения? А нигде. Никому они не интересны. Остались на уровне гайдлайнов, как и в С++.
Ничего из этого намеренно сделано не было, никакой явности нет. Никто и никогда не расскажет о том, чем код в unsafe более явный, нежели С++. Как максимум всякие субъективные рассуждения на тему «мне так нравится», но каждый своё болото хвалит и никаких объективных предпосылок к этому нет.
Чего длиннее и почему — никто не расскажет и не покажет.
В зачаточном состоянии она на расте — без unsafe ничего не напишешь.
Да, можно накастылить семантику указателя через ссылку + option, как это сделал автор, да и кто угодно сделает. Только есть нюансы — указатель хранит состояние бесплатно, а option платно. Привет оверхед по памяти 50-100% на ноду. Естественно, что в хелвордах это мало кому интересно, но это интересно за рамками оных.
Что это такое, какие тут есть проблемы — не знаю ни я, ни, скорее всего, все остальные.
Из этого ничего не следует — причины просты: а) intrinsinc никакого отношения к константе времени компиляции не имеет. Это имеет отношение к оптимальности кода. б) инфа про медленный вызов функции устарела лет на 15.
C at() ладно, но push_back() — это проблема вектора. throw никак не влияет на возможность инлайнинга. Придирки к чему-то, кроме at() — не имеют смысла.
Никаких обоснований некорректности, кроме ат, приведено не было. Особенности работы push_back() к делу отношения не имеют. Если мне не нужен какой-то функционал и он есть, но его убрать я не могу — это не значит, что сравнение некорректно.
Ну какие же это баги. 90% недоработка является багом? Голословные утверждения являются багом? Это лишь то, что я за пару минут проверил. То, что мне первое пришло в голову. И это самое простое.
Это не накладные расходы. raf вызывается перед рендерингом кадра и если он вызывается через х2 после предыдущего — это явная просадка.
Это манипуляции. Там написано не «он кое как работает и быстрее нашего дефолтного, тормазного, рендеринга в firefox», а «в хроме 15фпс, у нас 60фпс — самый быстрый».
Если вы претендуете на оптимизацию аутсайдера, то это не дает вас быстрым. Если вы претендуете на «быстро» — сравнивайте с быстрыми. А именно с хромом.
А так это маркетинговый булшит уровня «самый шоколадный* *из всех наших продуктов» и что он делает тут — не ясно.
По поводу случаев. Их пока нет, либо по крайней мере я их не видел. Я вижу только подтасовку и пустые заявления.
Понимаете в чём штука. Зачем заниматься подобными манипуляциями, если у нас что-то действительно есть? Зачем всё это про «самый быстрый/быстрый» и прочее? Почему не «возможно потом что-то да будет». Я не вижу этого — я вижу заявления, которые не соответствуют действительно.
Мне не нравится когда меня обманывают и считают за идиота. Я таким проектам не верю, таким людям не верю. И это правильно. И это не первое проявление.
Я могу рассказать краткую историю этого «движка». Вначале была параллельность. Мы придумали новый язык, который на это заточен и это должен был быть супер-параллельный движок. Потом как-то всё заглохло и вся параллельность превратилось в заспавн тысяч тредов и зависание через пару минут работы. Между тем в хромиуме есть многопоточный рендеринг и что-то я не вижу подобной желтухи и громких заявлений. И он есть и он работает.
Сейчас я вижу новую историю. Производительность с цпу мы не получили — теперь у нас новая идея — получить её с гпу. При этом казалось бы — причём тут раст, но вот так вот. И все эти рассуждения про «принципиально новое» — действительно. Верю. В гугле работают идиоты и до таких «инновационных» решений не доросли. При этом ладно, раньше было объяснение про «на расте проще писать многопоточные программы — поэтому мы даём фору хрому», но сейчас это не работает.
И естественно с «гпу» у нас работает 2-3% css, но мы уже всех побеждаем. Мы специально подбиваем под нас бенчмарки( которые на самом деле не бенчмарки, а фейк). Это не баги. Это подтасовка. Почему автор бенчмарка не написал там opacity? Знал что оно показывает 30фпс? Почему в видео специально зарезано качество? Чтобы люди не видели артефактов и качества рендера? Почему в видео содержится деза про 15фпс? В надежде что читатель не проверит?
И разве где-то в тексте это написано? Нет, это умалчивается. Опять же — мне не нравиться то, когда меня считают за идиота. Т.е. вам это нравиться и вы согласны с тем, что те, кто играют в подобные игры вам дадут хороший продукт?
Да и с технической части статья желтушная на 95%. Как будет у меня время я разберу её поподробнее. Возможно, кого-то это спасёт от слепой веры.
В любом случае. Тут плохо даже не всё это — тут плохо то, что подобное вгоняет комьюнити данного языка в средневековье. У нас везде победы, всё это враньё и желтуха затмевает нам разум. Всё это развивается в в сторону полного неадеквата семимильными шагами. И это плохо.
Примеры не заставляют себе долго ждать. Мои полностью объективные замечания минусуют. Хотя казалось бы — там нет ничего с чем можно соглашаться, либо не соглашаться. Там факты из реального мира. Отрицание этого — отрицание реальности. Именно в этом проблема.
Это же явный подлог. Начиная с того, что какой-то отдельный бенчмарк — это явно не «все приложения».
В остальном. Мой chromium выдаёт так же 60фпс и я не знаю откуда взялись эти 15. Это явное враньё. Далее, я скачал это серво и запустил. Получил 60фпс(поверим, что это реальные), при этом я так же получил
1) артефакты, которые(на первый взгляд) так же видны на видео, которое ОЧЕНЬ хренового качества, почему? Совпадение?
2) нагрузка на цпу идентична хромиуму, а вот нагрузка на гпу выше.
3) У серво мало того, что артефакты, так ещё и визуальное качество рендеринга явно хуже.
4) Добавление банального box-shadow ломает полностью серво и все эти 60фпс пропадают.
5) Да что там box-shadow — даже банальное opacity уже не даёт 60фпс, а в хромиуме ничего не меняется и те же 60фпс.
6) графики в --debug wr-stats — врут. Я добавил банальный подсчёт максимального времени кадра на базе разницы между вызовами raf и что серво, что хромиум просаживаются до 30мс( в моём случае). Чего в графиках, конечно же, нет.
В конечном итоге, что мы имеем? Да ничего мы не имеем.
Что это за бредни? Во-первых откуда там взялся pair? Во-вторых — я уже назвал пример.
В любом случае — исход был заранее определён. Вы очень часто путаете ваши мечты и ваши возможности. Ваши возможности ограничены минусом «в крысу». В следующий раз не надо это путать. Остальные вон не перепутали.
Явное противоречие. Вы уж определитесь с тем — нужно ли вводить ассоциацию между значением и тем, что оно выражает, либо нет. А то в одном случае смысла нет, а в другом есть.
Я уже давал вам вариации на тему, которые вы, благополучно, проигнорировали. Как не назови A, его значение будет «тип ссылки X является тем же, что у типа ссылки Y».
Я могу попытаться найти какое-то рациональное зерно в ваших рассуждения и сформулировать его. Переменные — это отображение неких сущностей из реальной мира, либо каких-то внешних моделей. Есть модель тех же уравнений — там у x есть чёткое определение, только оно определённо где-то в рамках этой модели. И записывая 2x+4=0 вы просто используете x как экспорт из этой модели. И уже каждый знает что такое x.
А вот если вы там напишите 2*g+4=0, то вы получите фейл. Т.к. вы привели банальный подлог.
Поэтому, если мы считаем яблоки, то у нас и название переменных будут яблоки, а не x — x это некая обобщённая форма неизвестной. Как то же value. И использовать везде abc вместо яблок — это моветон.
Тут имеет смысл только ссылка на то, что лайвтаймы — это про отношения ссылок/сущностей внутри самого языка. Мы не экспортируем что-то явно, либо по умолчанию( как в примере с x), а именно определяем их в определённом контексте.
Но опять же — это тупиковый путь. open_file(string a); — почему подобное является моветоном? Ведь контекст явно определён. file, да и тип string из которого мы сразу узнаём искомое свойство файла, но. Это некрасиво, это глупо.
Поэтому да, явно видно к чему привязан лайвтайм, но. Явно видно и то, что a = x * y. Но что дальше? По мне так лучше это назвать xy, пусть мы итак видим, что это x * y. Явно видно, что string a = file.name; Но что из этого следует? Да ничего, кроме того, что это явная глупость.
То же самое с лайвтаймами. Смотря на 'a — я не понимаю что это и откуда взялось. Мне надо смотреть на полный контекст, который может быть не таким примитивным. Зачем? А незачем. И причину я уже описал выше. А далее я делаю вывод, что вы используете это потому, что лайвтаймы — это введённые для компилятора кастыли. Вы итак видите продление времени жизни объекта — это вам не нужно. Именно поэтому вы и пытаетесь их писать write-only и после — игнорировать. Иначе подобное поведение не описать.
Таким образом это что-то типа. let a; a = b; c = a; — т.е. у меня есть a', которое никак и ни к чему не привязано. Оно болтается в воздухе. Далее, оно неизвестно где и неизвестно как привязывается ко времени жизни одного и второго(и далее) объекта как-бы уравнивая время их жизни. И ты никак из этого 'a не узнаешь что это, зачем это и почему.
Какой смысл в этом по сравнению с (a, b) -> c {return c{move(a)};} — я не вижу.
Я уже заранее ответил на это, но вы почему-то это проигнорировали. Никакие «любые типы» НИКОМУ и НИКОГДА не нужны. Это очень и очень редкий кейс.
Это вещи идентичные. Либо вы не понимаете, что это шаблонные типы?
template<Container, Value, Iterator> Iterator func(std::pair<Container, Value> val); А не то, что вы написали.
Здесь у нас есть некий обобщённый(упрощённый) тип контейнера, который подразумевает контейнер, а не хрен пойми что. Некий обобщённый тип значения и некий обобщённый тип итератора. Т.е. имя наделяет переменную дополнительными свойствами, которых не на уровне языка. Но не только.
Существует нотации для определения свойств уровня языка в переменных. Кто-то их считается осмысленными и нужными. Да и много есть кейсов, где имя удобнее.
Т.е. даже если у меня есть механизмы внутри самого языка ограничить множество типов в a только контейнерами, то мне проще использовать Container, а не смотреть что там и как определенно. Особенно если это тонна лапши. Это лишь дополнительная строгость уровня языка…
Что? В этом и проблема, что вы уже запутались. А если бы вы посмотрели на имена — вы бы сразу там увидели банальную сигнатуру find(a, b) -> c.
Для вас всё неудобное троллинг. Очень удобно, не спорю.
Выше, пожалуйста. Никто из ваших оппонентов не обязан что-то знать про ваш «язык». Приводят примеры и если что-то в них немного неверно написано, то их этого ничего не следует. Это ваша обязанность адаптировать примеры.
А то получается как «будет то же самое» и всё очень удобное — можно посмеяться над автором, но суть примера не в этом. Об этом в том треде сообщили и я вам тут сообщил, что вы, благополучно, проигнорировали. Очень удобно, повторю.
>> Явные ВЖ усложняют типы, только я считаю что это окупается более выразительной формальной семантикой — так и сам код понимать проще, и оптимизации дополнительные можно провести, и от кучи ошибок с памятью автоматически защищает.
Вся эта «более выразительная» — ничего общего с объективностью не имеет. Это итак ясно из контекста.
Наличие подобно в расте лишь следствие слабости компилятора и не более того. А все эти рассуждения об каких-то мистических оптимизациях ничего так же не стоят без примеров. Я их не видел, вы их не показали. Нет никаких оснований вам верить. Всё просто.
Этим можно оправдать всё что угодно. Следует ли из этого что-то? Нет. Ваши слова значат не более чем его, либо чем мои. Никаких объективных свидетельств нету.
Из этого так же ничего не следует. Отсутствие предложения в какой-то определённой тусе мало что значит. Да и какое там могло быть обсуждение, если это просто рандомный символ на подобии *&. Что там остаётся? #@'? По мне так ' самое глупое из них. По причине 'a' ~= 'a.
Да и странно как-то обсуждалось всё это. Был ГЦ, был другой синтаксис. Потом вдруг бам. ГЦ не стало, ГЦ стал не моден. Идеальный синтаксис выпилили и взяли крестовый.
>>… И там нет возможности выразить эту полезную в некоторых ситуациях информацию, разве нет?
Ещё раз. Она там только по причине слабости компилятора. Никакой новой информации она не даёт — она итак выводится из контекста.
То же самое с автоматическим выводом типов. Оно не теряет типы. И нужно не для какой-то там неведомой «полезной информации», а чисто для ограничений, либо кастов всяких литералов в нужный тип.
Если у меня есть функция (a) -> b {return c{a};}, где с хранит ссылку a, но при этом это компилятор сам вывести не может — это никакой новой информации мне не даёт, да и вообще не даёт.
Никакого собственного смысла имя типа в шаблонах не несёт, единственная его функция — указать одинаковость типов…
Никакого собственного смысла переменная не несёт, единственная её функция — указать одинаковость значений…
Ну и ключевое слово «в данном случае». А не в данном?
>>Для сравнения, в Haskell аннотации типов обычно тоже однобуквенные
И? Что же из этого следует? Т.е. вы мне предлагаете писать так: а<A, 'a, B, C>(arg0: &'a A, arg1: &'a B) -> &'a B? Либо как там у вас будет? Нет, спасибо.
Т.е. вместо (Container, Value) -> Iterator мне надо писать (a, b) -> c? Нет, спасибо. Проблема в том, что там не любой тип — любой тип никому не нужен.
Зачем вы пытаетесь создавать себе «пути к отступлению» вводя какие-то непонятные критерии, которых ранее не было?
Подтверждение моим словам есть — www.linux.org.ru/forum/development/13699421#comment-13699478
Притом, что в других языках никаких лайвтаймов нет и если в крестах есть 2 вида аргументов, то тут есть уже три.
Не верно. В расте это дополнительный ахтунг, которого в другом языке(без лайвтаймов) не будет.
Это не придирка. Раст ввёл в язык некую новую сущность, которая не бесплатна с т.з. читаемости и ой как не бесплатна. Да и синтаксис очень спорен — это как минимум.
А люди почему-то выдают её за бесплатную. В этом и есть проблема.
Это глупость. И почему — ниже так же объяснили на том же лоре.
И ваш пример крайне показателен. Вы не спорите с тем, что явная типизация не бесплатна, а в ситуации с растом это не так. Тип — это свойство переменной, который не указывается явно в питоне. Точно так же лайвтайм — это такое же дополнительное свойство. Т.е. ситуация аналогичная, но в случае с растом у нас «всё так же»( что явно неправда), а в случае с питоном всё не так же.
Таким образом питон < С++ < раст. Критерий ясен и понятен. С питоне только имя, в С++ имя и тип, в расте имя + тип + лайвтайм.
Это явная манипуляция о которой я и говорил.