История изменений
Исправление byko3y, (текущая версия) :
К слову, не в последнюю очередь поэтому в Go отказались от обобщений.
B Go дженрики уже почти завезли
Уже который год «почти».
Этак и сишные шаблоны можно можно объявить средством обобщённого программирования с «небольшими отличиями»
Разве это не так? В большинстве случаев сишные макросы применяют для типонезависимых описаний.
В C++ это такая же вспомогательная формальная конструкция.
Не понял мысль
string_view слизано с раста, его не было в C++ очень долго, и этот класс создает огромный потенциал для use-after-free в C++, потому-то его и не было в крестах. Это чужеродная конструкция для крестов, короче говоря.
И почему же нельзя сразу вызвать методы для слайсов?
Почему нельзя вызывать методы A на объекте типа B? Потому что это разные объекты (в том числе, не связанные отношением наследования)
Эту проблему решает в том числе Go, который позволяет делегировать методы к содержащимся объектам.
Строки.
Слайсы.
Box (грубо говоря, «владеющий слайс»).
Символы.
Ссылки на символы.
Cow
Из растовых особенностей тут разве что отдельный итератор по ссылкам на символы, а в остальном всё плюс-минус как в плюсах. Интерфейс немного разный, но это потому что сами итераторы иначе выглядят
Ну и где ты увидел в крестах конструкторы из коробки/коровы (Box/Cow)? Они тоже являются итераторами? Так-то я могу придумать еще десяток контейнеров, и создатели языка как бы подразумевают, что я должен буду так же реализовать под них трейты FromIterator для строк.
Clone и From пересекаются
Пересекаются, да. Но смысл-то разный. Первое - это «дай мне копию объекта», второе - «преобразуй A в Б». И второе как раз позволяет писать меньше: вместо двух перегрузок from_A и from_Б можно иметь одну функцию, если типы уже умеют преобразовываться друг в друга
Мне кажется, что мы отходим от изначальной сути разхговора. А была она про вот это:
impl From<String> for Vec<u8, Global>
impl From<String> for Arc<str>
impl From<String> for Box<str, Global>
impl From<String> for Box<dyn Error + Send + Sync>
impl From<String> for Box<dyn Error>
impl From<String> for OsString
impl From<String> for PathBuf
impl From<char> for String
Расскажи мне, как это не относится к модели ручного ковыряния вилкой в модели Rust. Я бы сказал «да, прикольная реализация множественной диспетчеризации/полиморфизма», однако же, в данном случае полиморфизм происходит по служебным структурам, а не по различным типам данных. А реализация множественного полиморфизма через специальные функции «все со всеми» имеет сложность O(N^k), где k — число переменных типов в одной функции. То есть, улететь туземун с таким подходом очень просто.
Мне кажется, что ты неявно подразумеваешь, что в крестах этой помешанности не было, а вот в расте они появилось и якобы я это безобразие обличил. Нет, в крестах оно было в подобном виде (многочисленных специальных функций), но все же не настолько запущенном — в расте формальных функций просто стало больше для обслуживания дополнительных формальностей
Да вот как раз не думаю, что в системном/низкоуровневом языке можно обойтись без этих формальностей. Они могут существовать «в уме» (как лайфтайм у плюсовых спанов), но они есть. И если у нас есть символы, последовательности символов, слайсы/спаны, владеющие строки, то куда от этого деваться? Это всё не бесполезные сущности
Не могу полностью согласиться, но и отчасти согласен. Хардкорное повторное использование областей памяти через указатели/ссылки/смещения с буцанием их по разным функциям с потенциальным протуханием лежащей в основе области памяти до протухания ссылок на нее — это прием, который можно видеть всё реже. Да, это вроде как классическая низкоуровневость образца восьмидесятых-девяностых годов. Однако, нынче так не работают с GPGPU, не работают с SIMD, не работают с многопоточным кодом, где, как правило, работают большими неизменяемыми блоками данных передаваемыми в одном направлении, а не изменяемыми по месту. То есть, классическую «низкоуровневость» уже пора бы закапывать, а ее до сих пор насилуют.
К слову о том, почему я сам не начал делать свой «низкоуровневый» ЯП, на котором мне было бы приятно работать — потому что процессоры уже давно не работают по принципу Тьюринг-машины, хотя ловко притворяются онной, но это далеко не идеально получается. К тому же, модель алгоритмов на изменяемых ячейках данных, как и любая модель автомата, сложна для понимания как человеком, так и машиной, что усложняет проведение оптимизаций.
Rust, вроде бы, начал путь с неизменяемых данных и передачи владения, а получилось как всегда — крайне переусложненная модель данных аля C++. Хочется задать вопрос создателям: почему нельзя было вообще всю работу с «mut» сделать «unsafe»? Она ведь в любом случае очень быстро становится unsafe, потому что даже имеющихся в расте переусложенных инструментов очень быстро начинает на хватать. Я могу даже попытаться дать ответ на этот вопрос: потому что создатели Rust были прожженныи крестовиками, и грили «зочем нам этот недоязык? Сделайте нам ХОРОШО, КАК В КРЕСТАХ».
Что проект компилируется час даже на мощном сервере? Да ничего страшного, на крестах приходилось и дольше ждать. Естественно, большая часть штата разрабов не будут осваивать персистентные структуры данных, однонаправленную передачу, которые гарантируют безопасность с минимальными накладными расходами. Просто потому что. В крестах делали на блокировках — в расте сделаем блокировки. То что это ненадежный (из-за дедлоков) и имеющий серьезные накладные расходы вариант организации многопотока? Да кого это волнует. В крестах не волновало — в расте не волнует тем более.
Пять проблем C++ решили — пять новых проблем создали в собственном языке, и двести проблем из C++ скопировали без изменения. И теперь вот это вот подается чуть ли не как как революция.
Исходная версия byko3y, :
К слову, не в последнюю очередь поэтому в Go отказались от обобщений.
B Go дженрики уже почти завезли
Уже который год «почти».
Этак и сишные шаблоны можно можно объявить средством обобщённого программирования с «небольшими отличиями»
Разве это не так? В большинстве случаев сишные макросы применяют для типонезависимых описаний.
В C++ это такая же вспомогательная формальная конструкция.
Не понял мысль
string_view слизано с раста, его не было в C++ очень долго, и этот класс создает огромный потенциал для use-after-free в C++, потому-то его и не было в крестах. Это чужеродная конструкция для крестов, короче говоря.
И почему же нельзя сразу вызвать методы для слайсов?
Почему нельзя вызывать методы A на объекте типа B? Потому что это разные объекты (в том числе, не связанные отношением наследования)
Эту проблему решает в том числе Go, который позволяет делегировать методы к содержащимся объектам.
Строки.
Слайсы.
Box (грубо говоря, «владеющий слайс»).
Символы.
Ссылки на символы.
Cow
Из растовых особенностей тут разве что отдельный итератор по ссылкам на символы, а в остальном всё плюс-минус как в плюсах. Интерфейс немного разный, но это потому что сами итераторы иначе выглядят
Ну и где ты увидел в крестах конструкторы из коробки/коровы (Box/Cow)? Они тоже являются итераторами? Так-то я могу придумать еще десяток контейнеров, и создатели языка как бы подразумевают, что я должен буду так же реализовать под них трейты FromIterator для строк.
Clone и From пересекаются
Пересекаются, да. Но смысл-то разный. Первое - это «дай мне копию объекта», второе - «преобразуй A в Б». И второе как раз позволяет писать меньше: вместо двух перегрузок from_A и from_Б можно иметь одну функцию, если типы уже умеют преобразовываться друг в друга
Мне кажется, что мы отходим от изначальной сути разхговора. А была она про вот это:
impl From<String> for Vec<u8, Global>
impl From<String> for Arc<str>
impl From<String> for Box<str, Global>
impl From<String> for Box<dyn Error + Send + Sync>
impl From<String> for Box<dyn Error>
impl From<String> for OsString
impl From<String> for PathBuf
impl From<char> for String
Расскажи мне, как это не относится к модели ручного ковыряния вилкой в модели Rust. Я бы сказал «да, прикольная реализация множественной диспетчеризации/полиморфизма», однако же, в данном случае полиморфизм происходит по служебным структурам, а не по различным типам данных. А реализация множественного полиморфизма через специальные функции «все со всеми» имеет сложность O(N^k), где k — число переменных типов в одной функции. То есть, улететь туземун с таким подходом очень просто.
Мне кажется, что ты неявно подразумеваешь, что в крестах этой помешанности не было, а вот в расте они появилось и якобы я это безобразие обличил. Нет, в крестах оно было в подобном виде (многочисленных специальных функций), но все же не настолько запущенном — в расте формальных функций просто стало больше для обслуживания дополнительных формальностей
Да вот как раз не думаю, что в системном/низкоуровневом языке можно обойтись без этих формальностей. Они могут существовать «в уме» (как лайфтайм у плюсовых спанов), но они есть. И если у нас есть символы, последовательности символов, слайсы/спаны, владеющие строки, то куда от этого деваться? Это всё не бесполезные сущности
Не могу полностью согласиться, но и отчасти согласен. Хардкорное повторное использование областей памяти через указатели/ссылки/смещения с буцанием их по разным функциям с потенциальным протуханием лежащей в основе области памяти до протухания ссылок на нее — это прием, который можно видеть всё реже. Да, это вроде как классическая низкоуровневость образца восьмидесятых-девяностых годов. Однако, нынче так не работают с GPGPU, не работают с SIMD, не работают с многопоточным кодом, где, как правило, работают большими неизменяемыми блоками данных передаваемыми в одном направлении, а не изменяемыми по месту. То есть, классическую «низкоуровневость» уже пора бы закапывать, а ее до сих пор насилуют.
К слову о том, почему я сам не начал делать свой «низкоуровневый» ЯП, на котором мне было бы приятно работать — потому что процессоры уже давно не работают по принципу Тьюринг-машины, хотя ловко притворяются онной, но это далеко не идеально получается. К тому же, модель алгоритмов на изменяемых ячейках данных, как и любая модель автомата, сложна для понимания как человеком, так и машиной, что усложняет проведение оптимизаций.
Rust, вроде бы, начал путь с неизменяемых данных и передачи владения, а получилось как всегда — крайне переусложненная модель данных аля C++. Хочется задать вопрос создателям: почему нельзя было вообще всю работу с «mut» сделать «unsafe»? Она ведь в любом случае очень быстро становится unsafe, потому что даже имеющихся в расте переусложенных инструментов очень быстро начинает на хватать. Я могу даже попытаться дать ответ на этот вопрос: потому что создатели Rust были прожженныи крестовиками, и грили «зочем нам этот недоязык? Сделайте нам ХОРОШО, КАК В КРЕСТАХ».
Что проект компилируется час даже на мощном сервере? Да ничего страшного, на крестах приходилось и дольше ждать. Естественно, большая часть штата разрабов не будут осваивать персистентные структуры данных, однонаправленную передачу, которые гарантируют безопасность с минимальными накладными расходами. Просто потому что. В крестах делали на блокировках — в расте сделаем блокировки. То что это ненадежный (из-за дедлоков) и имеющий серьезные накладные расходы вариант организации многопотока? Да кого это волнует. В крестах не волновало — в расте не волнует тем более.
Пять проблем C++ решили — пять новых проблем создали в собственном языке, и двести проблем из C++ скопировали без изменения. И теперь вот это вот подается чуть ли не как как революция.