Как стать автором
Обновить

Комментарии 178

Эхх, хочется компилируемый язык с легковесным синтаксисом в стиле Go, управлением ресурсами и безопасностью в стиле Rust и лаконичностью (без этих var, func, mut) C...

Тогда необходимо написать нейронную сеть, которая будет читать ТЗ и писать весь код вместо вас. Только зачем тогда нужен будет программист.
Кто-то же должен будет обслуживать эту нейросеть. Причем сложность там будет на порядки выше тех программ, которые она будет писать, так что программисты станут нужны даже еще сильнее!
Аналитик, который пишет ТЗ и будет её обслуживать. А программистов для неё заменит сгенерированная ею же нейронка с делегированной для неё подзадачей.
Писать новые нейронки. Вряд ли нейросеть сможет сделать что-то лучше, чем она сама. Очевидно же.
Хорошо. Но с участием программиста и нейронки можно получить больше, чем просто одной лишь нейронкой. Больше это никогда не меньше.
Далеко не всегда. В частности Alpha Go Zero (не использующая «человеческое знание») некоторое время отстаёт от AlphaGo (которая для начального обучения использует их), но со временем обгоняет и в конечном итоге результат получается лучше.
Те же самые программисты. Просто вначале они учили сеть на играх человеческих мастеров, а потом — решили от этого отказаться и посмотреть что будет.

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

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

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

А этого никто не знает — обе сети чемпионов выносят «всухую».

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

Это-то мы можем понять: для того, чтобы сказать, что Ма́гнус Ка́рлсен играет сильнее Васи Пупкина не нужно даже правил игры знать — достаточно посмотреть на резлуьтаты матчей… но вот почему так — достоверно неизвестно.
Как-то серьёзно люди предложение приняли. Надо было тэг <sarcasm/> вставить По ссылке выше нейронка от гугла пыталась сгенерировать улучшенную нейронку и даже вроде успешно. Но с той скоростью обучения естественно что-то сложное писать оно научится лет через дцать.

привет из будущего!

кто тут про нейронки скепсис сеял?

НЛО прилетело и опубликовало эту надпись здесь
Rust и так лаконичнее некуда. Если что-то он и требует, то только для явности, которая является его священной коровой. Если вы хотите, чтобы все касты были автоматические, но компилятор ВДРУГ каким-то магическим образом определял, что вот тут может быть ошибка или переполнение — извините, не придумали пока. Кстати, явное приведение (что является примером «нелаконичности») автором оригинального поста рассматривается как существенный плюс, а не минус. Кстати, ключевого слова `var` в языке нет.
Больше всего убивают люди, которые категорически требуют от языка, чтобы он был предельно лаконичным… а потом наворачивают 15 уровней абстракций.

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

Во-первых, абстрактная интерпретация. Во многих компиляторах Lisp и Scheme ей пользуются для оптимизации, в том числе и для выяснения, будет переполнение или нет в тех или иных случаях. Кстати, проверка и вывод типов — частный случай абстрактной интерпретации.

Во-вторых, некоторые JIT-компиляторы тоже проводят такой анализ переполнений.

Концептуальный вопрос языкотворчества, конечно, тут в том, а нужны ли программисту просто числа для работы (которые потом компилятор может реализовать в машинном представлении, если видит, что разрядности хватает), или ему обязательно нужны кольца вычетов по модулю 2^N для некоторых N?

Расскажите пожалуйста, как абстрактная интерпретация залезет в голову программисту и поймет, что каст с переполнением является умышленным или программист ошибся?


Что до лиспа, то учитывая что это бестиповое лямбда-счисление то там таких вопросов вообще не стоит: это уже в расширения System F надо смотреть. Нет типов — нет и проблем с кастами.

А зачем абстрактной интерпретации залезать в голову программиста? Обычно есть примитивные операции, вроде number->u8/saturating, которые абстрактный интерпретатор понимает. При помощи таких операций программист может выразить своё намерение.

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

Может Сrystal?
НЛО прилетело и опубликовало эту надпись здесь
А там есть проверка времени жизни на этапе компиляции? Я на него мельком глянул, мог не заметить.
А зачем это нужно в С, когда почти всё это есть в С++? А С не для того и не о том (и вообще, имхо, не нужно в 2018 году ничего программировать на чистом С).
На чистом С еще много где нужно программировать — например, драйверы ядра писать. Или на микроконтроллерах ковыряться — интернет вещей же, вычовычо.

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

Пример кроссплатформенного редактирования скомпилированной функции в студию, пожалуйста. Сравним с вызовом eval().

Это если в вашей ОС нету или отключен DEP и W^X страницы

На чистом С еще много где нужно программировать — например, драйверы ядра писать.
Или на микроконтроллерах ковыряться — интернет вещей же, вычовычо.

Можно и на Rust. Ладно, патч в ядро не примут, а с AVR лучше переходить на STM32 и компанию.

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Никто ведь не произнес слова AVR

Кое-кто произнёс "микроконтроллеры". Разве STM32 и AVR это не самое первое, что вспоминается на эту тему? Ну у меня так.


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

ТТХ либо сравнимо, либо сильно лучше при более низкой цене. Речь больше о том, что под AVR на Rust только при помощи костыльного https://github.com/avr-rust можно что-то делать. Могу ответить вам как фанбой фанбою: AVR ненужен ибо для прогания на оном при использовании Rust будет слишком много костылей. Вас устроит такой ответ? Лично для меня подобной проблемы вообще не существует. Ящитаю, что выбирать инструменты стоит из характера задач, а не по религиозным причинам.

НЛО прилетело и опубликовало эту надпись здесь

У stm32, как и многих arm cortex-m очень всё богато с периферией, даже на самых мелких stm32f0 и stm32l0 (которые бывают как в tssop-20/tssop-14, который паяется относительно легко, так и в lqfp, qfn/qfpn и в bga-подобном wlcsp), в dip-корпусах, скорее всего что-то из cortex-m0/m0+ есть у других производителей. Для breadboard'ов вполне подходит вариант простой платы-переходника с tssop/soic на обычные 100mil/2.54, покупается где угодно (начиная от китайцев и заканчивая крупными радиорынками/чипидипом).


Например, stm32f031, который стоит 100-120 рублей, имеет:


  • ядро arm cortex-m0 с нормальным интерфейсом внутрисхемной отладки swd (можно дебажить из ide, ставить полноценные аппаратные breakpoint'ы, смотреть регистры и память и т. п.), NVIC (nested vector interrupt controller);
  • 9 таймеров (1x 24-bit systick; 1x advanced 7-ch 16-bit с PWM и deadtime generation; 1x 32-bit general purpose; 4x 16-bit general purpose; 2x watchdog);
  • внутренний генератор (т. е. можно использовать crystal-less вариант);
  • модуль расчёта crc32;
  • spi/i2s, i2c/smbus/pmbus, usart;
  • 12-bit ADC (12 каналов, из них 9 внешних, есть датчик температуры кристала);
  • 15 GPIO;
  • RTC;
  • 5-ch DMA (могут использоваться как для обмена память-память, так и для обмена с периферией в обе стороны: spi, usart, i2c, adc, timers);
  • управление питанием (различные варианты сна), включая поддержку питания RTC от батареи.

Чуть более мощные чипы имеют аппаратный usb.


Из важных особенностей:


  • питание 2.0..3.6v (против более привычных 5v для avr);
  • при использовании внутреннего генератора необходимо замыкать пару контактов на землю;
  • крайне рекомендуются блокировочные конденсаторы по 100nF около каждого входа питания (на avr они тоже желательны, но он может быть менее чувствителен, но не всегда).

Стандартно в линейке у них есть группы одинаковых контроллеров с разным количество rom и, иногда, ram. Пример: stm32f103 в lqfp64 бывает в 7 вариантах от 6/16 до 64/512 kB RAM/ROM с постепенным увеличением количества периферии и функциональности.


Плюс есть почти pin2pin совместимость между чипами различных линеек в рамках некоторых групп (при том, что там будут разные процессорные ядра). Для этих случаев у них есть подробные application notes по совместимости. Например AN4904 подробно рассказывает что надо иметь на плате, чтобы можно было легким движением паяльника заменить stm32f1 на stm32f4, плюс описывает отличия в периферии, которые подробно описаны. Как минимум, легко переключаться между линейками f1, f2 и f4.

НЛО прилетело и опубликовало эту надпись здесь
Вот все так напирают на дешевизну STM32, что попахивает манией.

И скажите сколько будет стоить аналогичная простеньким stm32f031 или stm32f103 mega/xmega? Всё-таки даже младшие f0 — это ни полраза не аналог attiny, которые имеют свою нишу.


А что насчет EEPROM?… Ставить отдельным корпусом? Серьезно? Или эмулировать флешом?

Кто вам мешает посмотреть на чипы другого производителя? NXP, Linear, TI? У некоторых на младших моделях вполне есть eeprom. Или использовать battery backup + глубокий сон, если хочется сидеть на stm32?


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

Сначала скажите что вы понимаете под "сравнимой атмегой". Обычно стоимость переходника/девборда и т. п. совсем нерелевантны, т. к. в готовое изделие это не пихается от слова совсем. Кто будет распаивать сначала tssop на переходник, напаивать ноги и потом паять получившийся dip вместо того, чтобы распаять сразу tssop?


И потерять два GPIO? Все ATtiny умеют работать xstal-less, а тот же 13 вообще не требует ни одной навесной детали для работы: только питание и прошивка. Из восьми ног 6 в распоряжении разработчика (5 если нужен RESET и/или ISP).

xstal-less — это только про отсутствие кристала (например, варианты с RC-цепочкой тоже можно назвать crystal-less), но это ничего не говорит про внешнюю коммутацию. Вы же не жалуетесь, что теряете две ноги на питание и землю? Так к чему переживать, что вам доступны 16 ног вместо 18, если на вашей attiny доступны всего 6?


Короче, из реально крутого вижу только отладку и DMA. В противовес — отсутствие EEPROM в нижне-средних линейках и крайне неприятные для ручного монтажа корпуса.

Если вам хватает attiny или аналогичных мелких pic'ов, то вообще не смотрите на мир за пределами 8 бит.


Обычно противопоставление avr/pic против cortex-m всплывает, когда народ начинает городить atmega328 в lqfp48+ или подобные большие xmega, реализует spi/i2c или тем более usb ногодрыгом и далее по тексту. И паять atmega в lqfp или stm32f1 — нет никакой разницы.

НЛО прилетело и опубликовало эту надпись здесь

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


Если у вас плохо с памятью, процитирую (выделение моё):


AVR лучше переходить на STM32 и компанию
НЛО прилетело и опубликовало эту надпись здесь
И что это за компания? На каком основании идет объединение производителей в компанию? А STM8 входит в эту компанию, или как?

Я предполагаю, что речь всё-таки шла о Cortex-M, можем спросить lain8dono. Из примеров: NXP, Atmel/Microchip, ST, TI, AD/Linear, Infineon. Приличное community по моим ощущениям у ST, NXP и TI.


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

Откуда цифра в час? При каком потреблении? Вы это измеряли и можете привести пруф (и заодно опровергнуть разрядные кривые производителей)?


Элемент Ni-Cd/Ni-MH считается разряженным как раз при 0.9 вольта. Давайте, расскажите что это никому не нужно и какой я дурак.

При чём здесь NiCd/NiMH аккумуляторы? Вы в современном мире питаетесь от двух банок оного барахла? Так поставьте buck-boost + линейный ldo, если так приспичило и питайтесь хоть от одной банки.


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

Ага, и какой baudrate на usart/spi будет при 32kHz? 16 kbit/s в пределе (реально меньше, паузы, старт/стоп-биты и т. п.), все счастливы. А если вдруг нужно что-нибудь на обычный растровый tft вывести, так 32kHz вообще спасение. Поржал.


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

С каких пор подразумевает? Удалённой прошивки устройств не бывает? Прошивки с sd-карты не бывает?


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

Вы все устройства питаете без стабилизаторов? У вас у всех компонент высокая толерантность по питанию и входам/выходам? Вам очень повезло или у вас очень простые задачи. Радуйтесь. Но не стоит считать, что у всех в мире так.

Большинство ATtiny начинаются с 1.8 вольта.

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

НЛО прилетело и опубликовало эту надпись здесь

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

НЛО прилетело и опубликовало эту надпись здесь
порог в 1.8 дает возможность использовать литивую таблетку на все 100%

Вы разрядную кривую литиевых элементов (стандартных Li-SOCl2 и Li-MnO2) видели? У Li-MnO2 при полном разряде малым током (0.001-0.005 C) при полном разряде 2v. У Li-SOCl2 — выше.


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

Правильнее будет сказать, что attiny4/5/9/10, attiny13a, attiny102/104, attiny212/412 и подобные, либо низковольтные модификации типа attiny25v/45v/85v имеют возможность работать в ограниченном режиме от 1.8v. С пониженной частотой, не всегда с возможностью перепрошивки при таком питании (т. е. необходимо усложнять плату для возможности перепрошивки, чтобы дать внешние 3.3-5v).


Теперь вернёмся к вашим воплям, где вы старательно подменяете питание от батареи питанием от источника 1.8v. Вы понимаете, что при батарейном питании кроме V_BAT эту же батарейку можно подключить в V_DD и V_DDA? Т. е. питать весь чип от батарейки? И вполне укладываться в необходимые параметры для питания чипа при использовании обычного литиевого первичного элемента?


V_BAT даёт вам дополнительные возможности (мониторинг напряжения на батарее, независимые от V_DD регистры и RTC).


Добавлю, что если вам реально нужно (т. е. не при питании от литиевой батарейки), то всегда есть низковольтная серия stm32f0x8, поддерживающая питание от 1.8v.

Ну так Rust это вам не Go. Он нацелен на убийство C, у него нулевой рантайм и прочие фичи.

Строго говоря, у всего, что не ассемблер — рантайм не нулевой. Даже у C.
Другое дело, что в стандартном рантайме там нет тяжелых вещей вроде сборщика мусора, но раскрутка стека, выделение/освобождение памяти — это тоже рантайм.
Так что какой-то рантайм там есть, то он небольшой.

Unwinding & Error processing/panic, но Rust может прикрасно обходиться без runtime, если нужно для твоей задачи, например, написания оси.

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


Освобождение и выделение памяти в ассемблере требует столько же времени, сколько и в Расте. Можно отключить std с динамическими контейнерами и хипом, получите stack-only язык, с 0 накладных расходов на абстракции.

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

Не совсем верно, по умолчанию при раскрутке умирает поток, а не всё программа. Такая естественная граница. Но никто не мешает включить abort при панике, а на некоторых таргетах подсунуть свой panic_fmt и eh_personality.


Освобождение и выделение памяти в ассемблере требует столько же времени, сколько и в Расте.

Зависит от аллокаторов. В текущий момент обычно это jemalloc или стандартные аллокаторы из libc.

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

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

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

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


Но про ассемблер неверно, так все такие языки позволяют писать платформозависимый код. В том же Rust inline assembly планируется как часть языка (емнип уже есть в nightly, но не stable сборках). В С на практике тоже, хотя это и не часть стандарта.


Для меня сейчас понятие "уровня" полностью сводится к наличию/отсутствию обязательного рантайма и возможности unsafe работы с памятью.

Для меня сейчас понятие "уровня" полностью сводится к наличию/отсутствию обязательного рантайма и возможности unsafe работы с памятью.

Ага, я для себя на 4 уровня делю языки:


  1. Низкий уровень — уровень железа: ассемблер, включая ассемблерные вставки из более высокоуровневых языков и интринсики.
  2. Средний уровень: прямой доступ к памяти, машинозависимые типы.
  3. Высокий уровень: отсутствие прямого доступа к памяти, языковые абстракции типа классов.
  4. Сверхвысокий уровень: скриптовые языки.

Современные языки довольно сложны, и они занимают сразу несколько уровней. Тот же C++ может быть как низкоуровневым (смесь шаблонов с векторными инструкциями в обработке изображений), так и высокоуровневым (код не использует сырые указатели вообще — только умные указатели).

Я программирую микроконтроллеры на С++, включая 8-битные. С шаблонами очень удобно писать компактный и при этом удобный в использовании код. Какая необходямость корячиться с С в драйверах, тем более не понимаю.
Например у C++ ABI не стандартизован. И вы не можете использовать библиотеку собранную другим компилятором. С растом такой проблемы нет, можно спокойно линковать библиотеку на раст с приложением на си и с++ с использованием любого компилятора.
С растом такой проблемы нет

В расте же придётся отключить манглинг не так ли? Так и в C++ можно, если extern "C" написать.

А что с классами из с++ делать? Оборачивать все в сишный интерфейс? То есть если вы хотите использовать вашу библиотеку написанную на с++ в коде на Си вы должны весь апи реализовать через сишные функции.
Да в расте тоже придется сделать некоторые телодвижения, но значительно меньше.
И что делать с исключениями с++ вобще не понятно… Хотя если функция rust возвращает Result или Options, то наверно тоже есть нюансы как с ней работать в С.
Но в правы, я был слишком категоричен, забыл что можно использовать extern для получения возможности вызывать код написанные на c++ из с путем создание оберток, в самом коде
При этом еще остается проблемма что типы могут не совпадать. Например интересный документ www.agner.org/optimize/calling_conventions.pdf
> То есть если вы хотите использовать вашу библиотеку написанную на с++ в коде на Си вы должны весь апи реализовать через сишные функции.

Завернуть его в С++ фасад с простым интерфейсом — не вариант?
Ну вот я хочу сейчас сделать враппинг OpenCV на расте. Знаете, что мне посоветовал один из ключевых разработчиков самого OpenCV? Цитата в студию:

adapting a ~1000 lines python monster (which to 90% covers weird edge cases) might look daunting, but on the other hand, doing things manually, like those folks try will result in a «toy example», that only covers the 5% most used cases. (which again IS cool, too, don't get me wrong. problem is, if you deviate only a millimeter from it, you're staring into an open abyss)


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

Т.е. если написать систему аналогичного масштаба на чистом идиоматичном Rust (с RAII и компайл-тайм полиморфизмом), то реализовать биндинги к, например, Python, будет тривиальной задачей?

К Ruby — тривиальная задача, если использовать Helix.

К Ruby — тривиальная задача, если использовать Helix.

Это не означает, что Rust какой-то особенный. Для C++ тоже давно существуют аналоги: CLIF и SWIG.

Слушайте, ну если вам нужен именно враппер вокруг огромной библиотеки типа OpenCV — может вам и не нужен враппер вокруг OpenCV?

Что вы там делаете на нем? Напишите кусок кода (то, что я назвал «С++ фасад с простым интерфейсом») на С++, который торчит наружу API-ем попроще, и используйте его в своем растовом коде.

Я вот использую ffmpeg в проекте на C++, но мне и мысли не приходит завернуть весь весь ffmpeg в С++.
Почему нет? Есть же обертка на питоне, есть на Java. Я хочу вот на раст сделать. Потому что переиспользование. Каждый раз ловить одни и те же баги не надо, если можно один раз всем миром написать враппер, где всё учесть. Обычная история.

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

Или я не прав и написать враппер на C++ для библиотеки на Rust — ничего не стоит?
Или я не прав и написать враппер на C++ для библиотеки на Rust — ничего не стоит?
Вообще вся эта ситуация и весь бред, происходящий в индустрии — это какая-то трагикомедия.

Вызвать функцию хоть на C++, хотя на rust — задача, блин, давно и успешно решённая! gdb и lldb её успешно решают. Может стоит в эту сторону копать?

Оно, правда, не будет на Windows работать — ну так и чёрт с ней.
Никто не говорил, что будет просто. Да, нужно потратить месяц-другой для того, чтобы это заработало. Но ведь и результат того стоит.

У меня была простая задача: написать бота, который бы мог сравнивать картинки, на расте, потому что хотел обучиться языку на примере реального проекта. Но оказалось, что для этого нужен opencv. Можно конечно было бы написать полтора враппера над конкретными функциями, но я нашел библиотеку, где было реализовано уже почти все. Потом я добавил туда пару нужных врапперов. Потом еще пару. И заверте…

В итоге, сейчас есть понимание, что нужно пошаманить кодогенерацию — на основании плюсовых хедеров генерировать растовый код. Это сложно, но реально. Так работают описаные мной врапперы на питоне и джаве. Так сейчас пишут враппер на Go.

Так что
Или я не прав и написать враппер на C++ для библиотеки на Rust — ничего не стоит?

Не понял, с чего такой вывод. Нужно дать пользователям Rust возможности, которые предоставляет OpenCV, хотя бы потому, что не все любят писать на плюсах. Остальное — следствие и мои приоритеты на трату свободного времени.
В итоге, сейчас есть понимание, что нужно пошаманить кодогенерацию — на основании плюсовых хедеров генерировать растовый код. Это сложно, но реально. Так работают описаные мной врапперы на питоне и джаве. Так сейчас пишут враппер на Go.

а что с mangling'ом?

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

Там почти нет темплейтов в API, поэтому манглинга нет.

В С++ манглится всё, что не extern "C", независимо от наличия шаблонов.

Я дал ссылку на описание, как все это работает, по ней можно перейти и почитать в деталях. Раз работает, значит с манглингом оно дружит. QED.
а что с mangling'ом?

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

А что с классами из с++ делать?

А что делать с RAII-структурами в Rust?


И что делать с исключениями с++ вобще не понятно

Ловить вcё в сишных обёртках и конвертировать в коды возврата. С растовыми статусами этого не придётся делать?

А что делать с RAII-структурами в Rust?

Т.е. если написать систему аналогичного масштаба на чистом идиоматичном Rust (с RAII и компайл-тайм полиморфизмом), то реализовать биндинги к, например, Python, будет тривиальной задачей?

Ну, явно попроще. Вот тут пример небольшой есть.

Ловить вcё в сишных обёртках и конвертировать в коды возврата. С растовыми статусами этого не придётся делать?

Код возврата это просто Union, проблем с ним нет. А вот эксепшны намного опаснее:
To implement this we must think about emulation of C++ exceptions in C, classes/methods/objects, etc, including some «runtime library» to support this.
For example, you could take a look on «golang» approach from here: #10129 (but they completely lost C++ exceptions handling).
Also you could take a look on OpenCV Python bindings, there are exceptions are re-wrapped into Python «exceptions» leaving message string only. Classes are emulated via Python runtime.

OpenCV 3.x doesn't not support C compilation mode officially. There are still legacy C API calls (from OpenCV 1.x) but they should be compiled in C++ compilation mode.
Even if you succeeded to build code with C compiler (and avoid cvRound problem: #6585) it would lead to terrible behavior like #6221 or silent crashes in case of raised C++ exceptions.

Гарантирую, что из-за использование растовых статусов silent crash'а произойти не может.
Код возврата это просто Union, проблем с ним нет.

Что значит "проблем с ним нет"? Обёртки для си всё равно писать надо. Что если в этом юнионе объекты с деструкторами лежат? Если нужно писать обёртки, то и в плюсах можно написать catch(...) и конвертировать исключения в коды возврата.

Попрошу минусующих показать, как вызвать из C rust-функцию, возвращающую Result<Resource, Error> без написания специальных сишных обёрток. C++ исключения — это проблема, но как вы убеждаетесь, что panic! не прилетит из глубин сторонней библиотеки, которой вы пользуетесь? Может, так? Чем это отличается от catch(...)?


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

Вот тут пример небольшой есть

Там владение объекта не передаётся в сторонний код. Сторонний код видит только указатель на объект, создаваемый и уничтожаемый в rust. Если стороннему коду нужно создавать и уничтожать экземпляры RustObject, нужно написать функции-обёртки для конструктора и деструктора. Один-в-один как в C++.

Если стороннему коду нужно создавать и уничтожать… нужно написать функции-обёртки для конструктора и деструктора

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

Ну так а чем тогда растовый FFI сильно проще плюсового?

Только вот незадача, у раста нет «другого компилятора». И почему вдруг для раста вам хватает одного компилятора, а для С++ нет? Вы уж определитесь там.
Для c/c++ у нас есть msvc/gcc/llvm/Green Hills/keil/iar/borland список можно долго продолжать. И мне «хватает» и одного. Проблемма в том что вам могут дать бинарник собранный другим компилятором.
Кстати у раста тоже есть под windows две вариации тулчейна msvc и gnu.

интересно какое interopability между msvc и gnu версиями?

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

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

Так же, разные версии раста несовместимы между собой. За примерами ходить не надо, мне уже кто-то рассказывал о том, что «в расте добавили супер-оптимизацию, которой нет в С/С++, потому что это супер-язык», а оказалось — просто врубили флажок существовавший в llvm уже сотни лет, который уже давно реализован в гцц/шланге(-fpack-struct). Естественно, что эти изменения породили бинарно-несовместимые версии компилятора раст.

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

Поэтому, подобная проблема существует только на одной платформе и с одним компилятором, и то кейс нереалистичный. Никто не будет под эту платформу собирать бинари gcc, а если будут собирать, то они должны быть совместимы с msvs.

По поводу подобного:

Для c/c++ у нас есть msvc/gcc/llvm/Green Hills/keil/iar/borland список можно долго продолжать.

Зачем эта глупя подмена понятий? Во-первых — откуда тут взялся си? Во вторых, с каких пор эти «компиляторы» стали уметь в С++?

Живых кросслпатформенных компилятора существует только два — гцц/шланг. Под одну платформу существует альтернативно-одарённый компилятор, который недавно только начал хоть как-то «уметь» в С++. Про их совместимость я уже написал выше.

даже бинарники из-под разных версий msvc не могут друг с другом слинковаться, а с gcc и подавно. Рантайм то он может быть и поддерживает, но скорее всего только если gcc собрать студией
даже бинарники из-под разных версий msvc не могут друг с другом слинковаться

И? Что же из этого следует? Да мало того, что ничего не следует и это очередной бред, да к тому же — я уже разобрал эту тему выше.

а с gcc и подавно

Заявления противоречат реальности. gcc должен уметь линковаться с msvs, и я на 99% уверен, что это именно так.

Про шланг/гцц я уже говорил, и тут я уже точно знаю, что это работает.

Рантайм то он может быть и поддерживает

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

но скорее всего только если gcc собрать студией

Как комментировать подобную ахинею я просто не знаю. Это ведь не просто ошибка — это отборный бред.

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

Заявления противоречат реальности. gcc должен уметь линковаться с msvs, и я на 99% уверен, что это именно так.

Спешу вас расстроить. Берете Qt'шные библиотеки собранные для msvc, берете gcc компилируете код и удачи вам с линковкой. Когда слинкуетесь прихотиде расскажите.

Или можно на оборот библиотеки собранные под gcc а линковать msvc. Разультат тотже.

Шланг c gcc может и слинкуются, так-как шланг старается мимикрировать под gcc. Но гарантий нету никаких. Да и то пока вы не будете передавать что-то через классы стандартной библиотеки. Так-как она у них по разному реализована.
Спешу вас расстроить.

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

Берете Qt'шные библиотеки

С чего я должен их брать? Когда на вы мне кути на расте покажите — тогда приходите. Для проверки достаточно любого С++ кода.

Или можно на оборот библиотеки собранные под gcc а линковать msvc. Разультат тотже.

Это я вообще не обсуждал, т.к. не нужно.

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

Точно известно, что шланг пытается поддерживать msvs abi. Этого уже достаточно для моей правоты. Я не верю, что за десятки лет в гцц так и не реализовали msvs abi, а по ключевым словам гуглится всякий шлак.

Шланг c gcc может и слинкуются, так-как шланг старается мимикрировать под gcc.

Не может, а слинкуются.

Но гарантий нету никаких.

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

Да и то пока вы не будете передавать что-то через классы стандартной библиотеки. Так-как она у них по разному реализована.

Шланг почти всегда существовал с гнутой stdlib, да и сейчас существует. Если понадобиться линковаться к гцц, то никто не будет использовать libc++.

Qt это C++. msvc/GCC бесплатно сосуществует только если наружу C API и рантайм нужной версии. В C++ интерьеров разумеется нету. Про разные версии msvc собираете Qt со статическим рантайм и линкуетемь от MSVC 2010+
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Только в режиме C++ и рантайм снаружи в других случаях, static runtime и C AP наружу торчит то все нормально линкуется и с GCC и clang. В случае C++ API наружу линкуется со всем msvc который поддерживает тот же стандарт что в api
Только вот незадача, у раста нет «другого компилятора»

Я тоже так думал, но потом случайно наткнулся на https://github.com/thepowersgang/mrustc
Он не production-ready, но какие-то усилия в этом направлении прилагаются.

Так оно же как раз по причине отсутсвия стандарта ABI все ещё unstable.
В языке С++ любая переменная живет до конца блока где она объявлена, даже если потеряла смысл раньше.

Наверное, стоит пояснить мысль.


В C++ есть множество методов, которые инвалидируют объект — обычные сценарии использования объекта после такого вызова ведут к UB или ошибке времени выполнения (по крайней мере, до повторной инициализации).


Среди них — std::unique_ptr::release, std::thread::detach и std::thread::join, std::future::share и std::future::get, перемещение через std::move.


Язык не имеет механизмов для предотвращения дальнейшей работы с объектом после вызова подобных методов.

На C++ можно программировать микроконтроллеры. C++ не обязательно тяжелее — никто не заставляет использовать его работу с памятью, STL, виртуальное наследование, исключения. Без всего этого он не тяжелее С, а жизнь упрощает существенно. Начиная от банальной перегрузки функций и заканчивая HAL на шаблонах без единого лишнего байта.


причудливой объектной ориентации в С

На мой взгляд — это костыли и извращения.

STL — очень нужная вещь, взять, хотя бы, банальный pair. А также всё, что связано с шаблонами и compile-time трюками — type_traits, std::forward и т. п.
Пришлось найти реализацию stdlib для AVR, и даже немного её дополнить свежими фичами из С++11/14. А вот в тулчейне Arduino Due, например, stdlib уже есть их коробки, и довольно свежий и полный.
НЛО прилетело и опубликовало эту надпись здесь
В C++ нет самого главного — безопасности управления памятью. Ну и алгебраических типов с pattern matching.
Pattern matching в формальных аргументах функции выглядит очень странно. Неужели именованные аргументы при вызове не поддерживаются?

Если вы об этом


my_func(Fubarize(true), Frobnify(false), Bazificate(true));

то так никто не пишет, потому что это громоздко. Именованных аргументов нет, поскольку и без них не хватает рук на все запланированное (хотя периодически намеки на них приплывают). Кроме того, против вызовов методов в стиле do(a, b, c, true, false) существует и поощряется использование билдеров и типажей для эмуляции перегрузки функций.

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

или заместа многих true-false юзать переменную с битовыми флагами а заместа численных — указатель на первую то бишь массив. по моему отсутствию опыта.
Вроде как есть только pre-RFC про это, но IntelliJ Rust может делать что-то похожее:
image

Это не именованые аргументы. IDE просто приводит подсказки из объявления методов.

А вы читали мой комментарий? Я и не утверждал, что это именованные аргументы.
IntelliJ Rust может делать что-то похожее
Закрытия — очевидно, имелись в виду замыкания?
Да, конечно, руки на секунду отделились от мозга, прошу прощения…
задолбали выдумывать языки, фича которых выпендрёжный синтаксис функционала который должен быть и есть либо в API либо в DSL.
напишите на этом супер Rust нейронку с умножением матриц, конволюцией и паралелизмом для CPU и потом сравните с производительностью на C
А зачем писать конволюцию на Си, когда её можно написать на ASM и подключить к Расту? И точно знать, что если баг есть, то он в коде на ASM.
Такое ощущение, что вы лид проекта, который писали на С, и вдруг все разработчики взяли и разбежались по раст-вакансиям, прям такая обида сочится из поста…
Просто компилятор раста немного умнее его. :)

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

В силу привычки может казаться что это не так, но синтаксис раста нагляднее. Кое-где получается многословнее, но нагляднее. Например, печатать const-корректный код на расте проще, чем const-некорректный
Проблема в том, что Си-подобный синтаксис накладывает довольно жёсткие ограничения, из-за которых дополнительные возможности языка выглядят как костыли. Хороший пример: язык-монстр С++17/2a+ с довольно многословным синтаксисом.
Парсер проще написать, например.
К тому же привычный — не значит лучший.
Современные языки массово используют var: type вместо type var, благодаря чему тип можно опустить.

Хотя в целом Rust выглядит неряшливо, на мой вкус.
К тому же привычный — не значит лучший.

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

Современные языки массово используют var: type вместо type var, благодаря чему тип можно опустить.

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

Я видел очень мало людей, которые понимают сишный синтаксис. 99% вообще напишет тут void f(int f(void)) указатель на функцию. То же самое с type qualifiers, то же самое с теми же указателями. Люди не понимают, что тип у переменной не type *, а *, а type и всё что слева — относится к операции разыменования.

Квалификаторы справа — дефолт, квалификатор слева в случае с * неоднозначен, а значит не может относится к *. Квалификаторы слева — так же никаких проблем, ведь всё логично.

Дано я уже не видел объективной критики сишного синтаксиса. Кроме возврата указателя на функцию я вообще не видел ничего.

Как насчет такого?
char * const (*(* const bar)[5])(int )

Дано я уже не видел объективной критики сишного синтаксиса. Кроме возврата указателя на функцию я вообще не видел ничего.

Да пожалуйста.


  1. Оператор "запятая". Зачем она вообще нужна? Я не могу представить случая, где она была бы полезна. А вот ограничения на синтаксис при этом накладываются довольно сильные.


  2. Оператор switch крайне непродуман. Переход управления из одной ветви в другую — ситуация, которая случается крайне редко. Писать каждый раз break малость напрягает. Поэтому логичнее было бы от break полностью отказаться, а переход в следующую ветку реализовать через goto. Ну и группировать несколько подряд идущих case в один, указывая условия через запятую.


  3. Объявления типов с квалификаторами и слева, и справа — затруднение чтения кода. Я бы предпочёл, чтобы мухи (тип) и котлеты (объявление переменной) были отдельно: Type a, b;, причём указатели относятся к типу, а не к переменной, т.е. в объявлении int * a, b обе переменные будут должны тип int *. Объявление массивов фиксированного размера: int[10] a, а не int a[10].


  4. Про указатели на функции: аналогично п. 3. хотелось бы видеть что-то типа:
    int function(int, int) * variable_name вместо int (*variable_name)(int, int).


  5. Имена типов в виде крокодилов unsigned long long.


  6. [C++] Неоднозначности между определением функции и инициализацией объекта, костыль в виде двух видов записи вызова конструктора — с обычными и фигурными скобками.

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

Угу, в C++ это костыль в виде auto, именно потому, что обявление без типа не предусмотрено синтаксисом. Особенно смешно выглядят лямбды: [](auto x, auto y) { return x + y; }, когда можно было бы написать (x, y) -> x + y;

Угу, в C++ это костыль в виде auto, именно потому, что обявление без типа не предусмотрено синтаксисом.
Кому-то этого показалось мало. Теперь бывает не только auto, но еще и decltype(auto)!

Кто из «знатоков» C++ способен пояснить где в функции foo — неопределённое поведение:
decltype(auto) foo() {
   int i = 1;
   return (i);
}
И почему в функции bar его нету:
decltype(auto) bar() {
   int i = 1;
   return i;
}


Кто не смог — сходите на godbolt

Отличный язык, тщательно спроектированный для попадания в ногу…
Да пожалуйста.

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

Оператор «запятая». Зачем она вообще нужна? Я не могу представить случая, где она была бы полезна. А вот ограничения на синтаксис при этом накладываются довольно сильные.

Везде, особенно в однострочниках. Вон пару сообщений назад мне кто-то пастил крестовый код, и там именно запятая.

Оператор switch крайне непродуман.

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

Переход управления из одной ветви в другую — ситуация, которая случается крайне редко.

Каждая вторая — подобная ситуация.

Ну и группировать несколько подряд идущих case в один, указывая условия через запятую.

Т.е. для тех ситуаций, которых две строчки назад «крайне редко»? Сильно.

Это итак работает. case: case: case: — сколько угодно.

Объявления типов с квалификаторами и слева, и справа — затруднение чтения кода.

Не объективно. Для меня затрудняет чтение обратное.

Я бы предпочёл, чтобы мухи (тип) и котлеты (объявление переменной) были отдельно

Это не критика. Меня мало должны волновать ваши предпочтения. Они так отдельно.

обе переменные будут должны тип int *

Как мне объявить int v, * p; в вашем супер-синтаксисе? Хотите ограничить типы — есть тайпдеф. Напишите там что угодно и это уже будет типов, а «составным типом».

Объявление массивов фиксированного размера: int[10] a, а не int a[10].

И? С каких пор «хочу» — стало критикой? [10] — это такое же свойство переменной. Хотите определить это на базе типа — есть тайпдефы.

Про указатели на функции: аналогично п. 3. хотелось бы видеть что-то типа:

Зачем нужно это «function» кастыльное непотребство? Мне не хотелось бы, дальше что?

Имена типов в виде крокодилов unsigned long long.

Есть тайпдефы, стандартизированные.

[C++] Неоднозначности между определением функции и инициализацией объекта, костыль в виде двух видов записи вызова конструктора — с обычными и фигурными скобками.

Нету никакой неоднозначности. Конструктор — это вызов функции. Другое дело, что на самом деле конструктор — инициализатор, а в си инициализатор {}. Поэтому всё вернулось на круги своя.

Угу, в C++ это костыль в виде auto

Это не костыль.

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

Неверно. К синтаксису языка это не имеет никакого отношения — это фундаментальная неоднозначность между использованием и объявлением. И auto в С++ не кастыль, ведь синтаксис определения не изменяется. type var;, а вот в кастыльном var: type; — меняется, ведь нам нужно добавлять ненужность в виде let, как и ненужность в виде function/fn и прочего колхоза.

Особенно смешно выглядят лямбды:

Сишный синтаксис позволяет опускать типы, но в С++ как всегда — решили пойти своим путём.

[](auto x, auto y) { return x + y; }, когда можно было бы написать (x, y) -> x + y;

А как только нам нужно больше логики? И опять же, это примитивный сахар, а не синтаксис. Убогая стрелка, которая ничем не лучше скобок.

Почему вам «лишнее» слово тут «int function(int, int)» не мешает, а тут мешает? Вы уж там определитесь.

А теперь [&]{ x += 1;}. Синтаксис намного мощнее, нежели эти хелворды.

Тем более, этот синтаксис итак есть в крестах [](auto x, auto y) -> auto {}, только синтаксис крестов несоизмеримо мощней, нежели эти хелворды, которые вы пытаетесь выдать за синтаксис.

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

Везде, особенно в однострочниках. Вон пару сообщений назад мне кто-то пастил крестовый код, и там именно запятая.

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


Каждая вторая — подобная ситуация.

Хм, видимо, вы программируете драйверы? Потому что в прикладном программировании я последние пару лет с такой ситуацией не сталкивался вообще.


Как мне объявить int v, * p; в вашем супер-синтаксисе?

Логично же:
int v;
int * p;


И? С каких пор «хочу» — стало критикой? [10] — это такое же свойство переменной. Хотите определить это на базе типа — есть тайпдефы.

Хочу — значит, что я критикую привязку свойств к переменной, а не к типу.
И да, проблема в том, что typedef для массива — это фактически указатель.


Зачем нужно это «function» кастыльное непотребство?

Чтобы разделить тип и переменную, неужели не понятно?


К синтаксису языка это не имеет никакого отношения — это фундаментальная неоднозначность между использованием и объявлением.

Так может разрешить неоднозначность? Заодно и парсинг станет легче — в случае недостающей/лишней фигурной скобки ошибочное место станет легче искать.


А как только нам нужно больше логики? И опять же, это примитивный сахар, а не синтаксис. Убогая стрелка, которая ничем не лучше скобок.

Самые частые лямбды — именно такие короткие, которые являются аргументами sort, map, reduce и т.д. А раздражают здесь слова auto и return, без которых можно было бы обойтись.


Почему вам «лишнее» слово тут «int function(int, int)» не мешает, а тут мешает? Вы уж там определитесь.

Потому что это определение функционального типа. Кстати, в C++ можно писать так: std::function<int(int, int)> — вполне удобно.


В этом проблема всех «критиков», помимо основной «я хочу так — это критика», — «я пащу левый синтаксис, который просто не может в ту семантику, которая существует в рамках крестов».

Просто я пишу ещё и на C# и вижу, насколько удобнее пользоваться шарповыми лябдами и делегатами.

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

У вас проблемы в логике, из A => B никак не следует, что !A => !B.
Нельзя. Именно для этого и существуют let-кастыли, т.к. выражение без типа — неоднозначно.

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


Ну… Люди — многое делают по привычке столетиями.

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

Цена использования этого метода для вас равна 0,01. А вот изучение нового, затем доведение до такого же автоматизма — это месяцы потерь.

С учетом того, как многие вещи меняются в программировании шустро, лучше подумать сто раз, изучить отзывы коллег, чем тратить свое время на изучение очередной «серебрянной пули», которой как известно не существует (@Ф. Брукс)
Если посмотреть историю, то изначально синтаксис смахивал на C. Значит в какой то момент поменяли и можно найти — почему.

Скажу про переменные. В Rust let — это объявление не переменной, а привязки. Это имеет два последствия. Во-первых, доступен pattern matching и деструктурирование. Во-вторых, привязки могут быть переобъявлены.


struct Foo(u32, u32);

fn main() {
    let foo = Foo(2, 3);
    let Foo(a, b) = foo;

    assert_eq!(a, 2);
    assert_eq!(b, 3);

    let foo = "hello world";
}
В рамках изучения языка написал «нейронку с умножением матриц, конволюцией и паралелизмом для CPU» для распознавания лиц: github.com/atomashpolskiy/rustface
Производительность на 5-10% выше, чем на C++. Знающие люди подсказывают, что это в пррвую очередь благодаря более аггрессивным оптимизациям компилятора, который в Rust имеет точную информацию о том, где используется адресная арифметика (блоки unsafe): тема на reddit
Производительность на 5-10% выше, чем на C++.

Можно увидеть код на rust/C++, который сравнивается? А так же, желательно, код самого бенчмарка.

Производительность на 5-10% выше, чем на C++


Открыли Америку.

Известно же, что С++ не самый быстрый в мире язык. Это заблуждение вызвано всего лишь близким родством с действительно быстрым чистым С.

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

В С++ слишком много автоматики, которая принимает решения просто так, на авось зачастую.

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

Эта требовательность Rust и позволяет произвести более глубокие оптимизации.

Учитывая возраст C++ и возраст Rust — стоит ожидать только увеличения отрыва по мере оптимизации компилятора.
Известно же, что С++ не самый быстрый в мире язык. Это заблуждение вызвано всего лишь близким родством с действительно быстрым чистым С.

В С++ слишком много автоматики, которая принимает решения просто так, на авось зачастую.

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

Учитывая возраст C++ и возраст Rust — стоит ожидать только увеличения отрыва по мере оптимизации компилятора.

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


Ну да, а с ассемблерными вставками — еще быстрее.

Мы не можем так говорить, как вы предлагаете. Так как это предполагает конкретного программиста, пишущего конкретную программу.

Речь-то же об языке в целом.

вы же понимаете, что почти все оптимизации в компилятор раста пришли из компиляторов тех же си/с++/фортрана?


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

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

Для реализации подобного поведения в С++ — пришлось бы управлять памятью шибко уж вручную, откататься на уровень С фактически.
Ну да, а с ассемблерными вставками — еще быстрее.

Не надо пожалуйста передергивать. В одном месте с++/раст программист злоупотребит строками и получит потерю в 5% производительности GUI, а в другом месте использует библиотечную хеш-таблицу вместо полиномиального решения (потому что универсальных хеш-таблиц для си, насколько я знаю, не существует, а делать их самому долго) и получит выигрыш в 20% в горячем цикле. Кое-где использует динамические контейнеры вместо ручной работы с памятью, но зато сэкономит кучу времени на написании и дебаге для оптимизации боттлнеков.

Речь-то же об языке в целом.

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

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

утечки — не самая хорошая альтернатива освобождению памяти
утечки — не самая хорошая альтернатива освобождению памяти


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

я не спорю, что подобного рода оптимизаций может быть много. Давайте поставим вопрос иначе: что именно в расте позволяет проводить оптимизации аллокаций лучше, чем с++? Пока что я нашел лишь что в расте при OOM программа абортится
НЛО прилетело и опубликовало эту надпись здесь
Нет такого понятия как «быстродействие языка», но можно оценить быстродействие инструментария.

Строго говоря, язык программирования — это только синтаксис + API стандартной библиотеки.
Но когда мы говорим «язык программирования» то подразумеваем, вестимо, и среду исполнения и компилятор и реализацию стандартной библиотеки, конечно.
Открыли Америку.

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

Известно же, что С++ не самый быстрый в мире язык. Это заблуждение вызвано всего лишь близким родством с действительно быстрым чистым С.


Действительно — С++ позволяет писать «как на си» и люди любят брать свойства этого «как на си» и натягивать на современные/новомодные С++-реалии. Именно на эту тему много спекуляций, но всё равно — формально это не так, и С++ действительно почти как си.

А «чистый си» — это далеко не «быстрый си». Быстрый си почти никогда не бывает чистым.

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

Не видел ни единого проявления подобного поведения.

Эта требовательность Rust и позволяет произвести более глубокие оптимизации.

Есть примеры живые примеры?

Учитывая возраст C++ и возраст Rust — стоит ожидать только увеличения отрыва по мере оптимизации компилятора.

У раста нет компилятора — раст это фронтенд к крестовому llvm. И какие там вообще оптимизации на уровне фронтенда?

А разрыва пока никто не показал.
Действительно — С++ позволяет писать «как на си» и люди любят брать свойства этого «как на си» и натягивать на современные/новомодные С++-реалии. Именно на эту тему много спекуляций, но всё равно — формально это не так, и С++ действительно почти как си.


С такой позиции мы будем обсуждать не язык, а конкретного программиста.

У раста нет компилятора — раст это фронтенд к крестовому llvm. И какие там вообще оптимизации на уровне фронтенда?


Например, по алгоритмам работы с памятью (стек, куча). До того как войдет в llvm
Не видел ни единого проявления подобного поведения.

Весь browning, к примеру.
Понятно, что ради благого дела.
Есть примеры живые примеры?

Например вы можете получить две мутабельные ссылки и быть уверенным, что они указывают на разные объекты. Классический случай pointer aliasing'а. В плюсах есть костыль в виде__restrict__ , но компилятор никак не проверяет это, все на совести разработчика. Раст же не заставляет выбирать между производительностью и корректностью.
Например вы можете получить две мутабельные ссылки и быть уверенным, что они указывают на разные объекты.

И? Во-первых это попытка выдать ограничение за фичу.

Во-вторых, алиаситься может не только мутабельное с мутабельным, а так же мутабельное с иммутабельным. Это подлог, либо явное непонимание темы.

Второе, разные объекты ничего не значат. Ссылка на элемент массива и сам массив — являются разными объектами, но они алиасятся. Ссылка на поле и структура — так же. Я сомневаюсь, что нельзя взять ссылку на на поле, либо на елемент и что это идёт в счёт той самой «только одной» ссылки.

Классический случай pointer aliasing'а.

Для разных типов это итак не работает.

В плюсах есть костыль в виде__restrict__

В плюсах нету рестрикта, он есть в си. Хотя раст не имеет никакого отношения к унификации и стандартизации, поэтому мы можем брать любую фишку любого компилятора и приписывать её к С/С++.

но компилятор никак не проверяет это, все на совести разработчика.

Продолжим, как вы ответите на мои вопросы. Но в любом случае — это невозможно.

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

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

Пруфы? Пожалуйста — начало ветки. У автора ансейф через ансейф. Где же мистическая «производительность без выбора»? Как только автор предоставит код — можно будет посмотреть, что именно там намерено и как. Уже потом можно будет и исходный крестовый код посмотреть. Пока что — тут рассуждать не о чём.

Ещё пруфы? Пожалуйста, «предыдущая» тема про раст, которая касалась сравнения раста и С++. 72 плюса, 7 минусов и ноль сообщений о том, что это убогая клоунада, а не сравнение. Множество восторженных сообщений. Как вы это объясните?

Нужны пруфы того, что это клоунада? Пожалуйста — habrahabr.ru/post/344282/#comment_10563198

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

Во-вторых, алиаситься может не только мутабельное с мутабельным, а так же мутабельное с иммутабельным. Это подлог, либо явное непонимание темы.
Ну да — вы «не понимаете тему», дальше что?

Второе, разные объекты ничего не значат.
В C/C++ — да.

Ссылка на элемент массива и сам массив — являются разными объектами, но они алиасятся.
И именно поэтому rust не даст вам передать в процедуру одновременно и ссылку на элемент массива и ссылку на массив.

Я сомневаюсь, что нельзя взять ссылку на на поле, либо на елемент и что это идёт в счёт той самой «только одной» ссылки.
А вы бы не сомневались, а почитали. «Живая» ссылка на любой элемент может быть одна и только одна. Что значит «живая» — описано в документации.

Это, вообще говоря, сделано для безопасности — но ничто не мешает оптимизатору испольовать эту информацию и для чего-то ещё.

Продолжим, как вы ответите на мои вопросы. Но в любом случае — это невозможно.
Ага. Потому что земля плоская и стоит на трёх китах. Или черепахах?

Это невозможно в C++, потому что там нет соотвествующих понятий. В rust — это возможно. Собственно это его основная фишка.

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

Это не производительность, даже близко. Люди, которые ничего о ней не знают — очень любят раст и порассуждать.
Где-то частица «не» пропущена. Ибо вы явно ненавидите rust, но берётесь о нём рассуждать не зная и не понимаю его. Типичное «Пастернака не читал, но осуждаю»…

P.S. Я, кстати, не фанат rust'а. И я до сих пор не уверен, что в реальных проектах необходимость всё укладывать в «прокрустово ложе» borrow checker'а не приведёт к проблемам. Но я, в отличие от вас, хотя бы понимаю — чего в этом языке люди пытаются добиться и зачем.
Ну да — вы «не понимаете тему», дальше что?

Кроме трёпа ничего не будет, я правильно понимаю?

В C/C++ — да.

Неверно, это свойства базовой реальности. Почему вы проигнорировали это? Где ответы?

fn main() {
let s1 = String::from("hello");

let mut rs = &s1;
let mut len = calculate_length(&s1, &rs);
len = calculate_length(&s1, &s1) + len;
let mut slice = &s1[..3];

println!("The length of '{}' is {} is {} is {}.", s1, len, slice, rs);
}

fn calculate_length(mut s: &String, mut sl: &String) -> usize {
s.len() + sl.len()
}


Это что такое? Где вообще пруфцы от вас? Почему я вижу только ссылки на хрен пойми что в интернете и пустые заявления?

Это, вообще говоря, сделано для безопасности — но ничто не мешает оптимизатору испольовать эту информацию и для чего-то ещё.

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

И в инлайн и в статическую функцию в C++ могут придти пара указателей — и всё.

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

godbolt.org/g/V3KXCW — шлангу даже рестрикт не помог, а шансом 98% — это проблема в ллвм, в значит расту ничего не поможет.

Да, есть так нелюбимый вами __restrict__, но нет реальной культуры его применения.

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

Где-то частица «не» пропущена. Ибо вы явно ненавидите rust, но берётесь о нём рассуждать не зная и не понимаю его. Типичное «Пастернака не читал, но осуждаю»…

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

А ненавижу я не раст, а рекламный булшит и балаболов.

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

P.S. Я, кстати, не фанат rust'а.

Фанат. Без понимания чего-то лезть куда-то и что-то вещать — это типичная фанатичная глупость. Я где-то услышал какие-то лозунги — и пошел вещать об этом в комментах.

Достаточно посмотреть ваши подобные попытки, когда вы пытались вещать мне про ГЦ. Фанатизм во все поля, ссылки на левые хелворды, отсутствие ответов. А это первое, что я вспомнил. Подобных наших баталий помню больше одной, но мне лень их искать.

И я до сих пор не уверен, что в реальных проектах необходимость всё укладывать в «прокрустово ложе» borrow checker'а не приведёт к проблемам.

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

Да что там далеко ходить, оно даже слайс на константную(времени компилтайма) строку borrow checker'ом ловит. Колхоз колхоза.

Но я, в отличие от вас, хотя бы понимаю — чего в этом языке люди пытаются добиться и зачем.

Нет, вы не понимаете. И в этом проблема. Вы лезете в тему производительности, в тему лоулевел и С/С++, в которых ничего не понимаете. Как и все остальные адепты.

Хотите делать свои супер-языки? Делайте, но не лезьте в эти темы и не рассказывайте мне о том, что ваш колхоз хоть как-то заменяет С/С++.

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

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

Это что такое?
Ну… я бы назвал это незнанием rust'а. Вы, в своём примере, наплодили миллион изменяемых ссылок на один неизменяемый обьект. Так как обьет неизменяем, то, разумеется, никаких проблем алиасинга нет и быть не может.

Чего вы этим хотите доказать и кому — я не знаю. Смею предположить, что вы просто не понимаете (или делаете вид, что не понимаете) в чём разница между mut s: &String и s : &mut String.

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

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

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

Ссылка на элемент массива и сам массив — являются разными объектами, но они алиасятся.
Однако использование этих ссылок — не является проблемой в случае, если обе ссылки указывают на неизменяемый объет. Что, собственно, в вашей программе и происходит.

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

Так чего обсуждать-то?

godbolt.org/g/V3KXCW — шлангу даже рестрикт не помог, а шансом 98% — это проблема в ллвм, в значит расту ничего не поможет.
Не очень понятно что и как должен был помочь сделать __restrict__ в данном примере, так что неясно чего вы вообще тут пытаетесь доказать.

Да что там далеко ходить, оно даже слайс на константную(времени компилтайма) строку borrow checker'ом ловит.
Ещё одно невнятное утверждение, не имеющее смысла.

Вы хоть иногда пытаетесь за деревьями лес увидеть? Или только подгоняете примеры под нужные вам ответы не обращая внимание ни на что другое?
У автора ансейф через ансейф

Шесть слов на весь проект. По сравнению с С++ — это очень мало (потому что в С++ весь код unsafe в понимании Rust)

НЛО прилетело и опубликовало эту надпись здесь
и более строгой типизации.

А можете пояснить, в чём заключается строгость типизации C++ по сравнению с C?

НЛО прилетело и опубликовало эту надпись здесь

Ну это если действительно писать на С++, а не на С с классами.

Даже если не использовать никакие особые фичи, то C++ не позволит написать:
int *p = malloc(1);

Хотя в C это валидный код.
Я, к сожалению, очень слабо во всём этом разбираюсь. Единственный вопрос: чего было такого в древнем Си по стравнению с Турбопаскалем в плане выделения памяти?
турбопаскаль был уродливым детищем чисто для ДОСа с его особенностями памяти а так лично мне просто синтаксис паскаля не нравился. ух как народ взбесился из за поста, посмотрю че за проэкты и заодно ознакомлюсь с языком.
почему написал про API и DSL, например «сравнивать грёбаные строки» в производительном коде не надо так как сравнение по всей строке долго и заместо этого юзаем просто тип или enum или обходимся вообще без свича.
а с каким кодом С++ вы сравниваете, этот ваш раст может компилить в sse инструкции или в несколько ядер, как это прописывается в языке?
Rust использует llvm, как и clang, который транслирует в него си, плюсы и обжси. Вопрос снят?
НЛО прилетело и опубликовало эту надпись здесь
автор книги «Язык программирования Rust»

Товарищ Федерико автором книги не является, и соответственно во это


Я ещё не закончил работу над главой о «бесстрашном параллелизме»

тоже интерпретировано неверно. Он имеет в виду что c многопоточностью в Rust еще не работал, а не то что главу не дописал.

Нет целочисленного переполнения
Сказано достаточно.

Хочу уточнить: переполнения проверяются при компиляции на debug, в release этого нет, ибо оверхед.

Внутренние функции зачастую статические. Это значит, что их нельзя вызвать за пределами исходного файла, где их объявили. Программа теста должна или сделать #include исходного файла с этими статическими функции, или использовать директивы #ifdef для удаления статики только на время тестирования


Очень странно слышать подобные вещи из уст опытного разработчика на С. Как будто о вызове по указателю он никогда не слышал.
Откуда указатель возьмётся? Самозародится в тесте?
В контексте ООП на С, статические функции используются в качестве замены методов класса. Указатели на них берутся в тех функциях, которые генерируют структуры. Например, вот так:

--my.h--
typedef struct My
{
	int param;
	void (*setParam)(struct My *self, int new_param);
} My;

My* MakeMy();

--my.c--
#include "my.h"

static void My_setParam(My *self, int new_param)
{
	if(self)
		*self->param = new_param;
}

My* MakeMy()
{
	My *self = (My*)calloc(1, sizeof(*self));
	if(self) {
		self->setParam = My_setParam;
		return self;
	}
	
	return 0x0;
}

--test.c--
#include "my.h"

int main()
{
	My *dummy_struct = MakeMy();
	dummy_struct->setParam(10500);
	
	if(dummy_struct->param != 100500)
		return 1;
	else
		return 0;
}

Ошибочка: вместо dummy_struct->setParam(10500); должно быть dummy_struct->setParam(dummy_struct, 10500);

Да, вы правы. Забыл передать self.
В тех местах, где статические функции используются для реализации классов — да. Но в моей практике гораздо чаще статические функции — это просто вспомогательные функции, которые сами по себе в API никак не представлены, но которые было бы не грех и протестировать.
Смешная статья. 99% перечисленных вкусностей Rust'а имеются в C++, причём большинство уже очень давно. Если автору так это всё нравится, то совершенно непонятно где он был все эти годы — на другой планете, где нет C++?

И да, у Rust'а имеется ряд преимуществ над C++. Это и более строгая работа с памятью и нормальное метапрограммирование (а не корявые вычисления на шаблонах) и т.п. Но про это в статье нет ни одного слова…
Хм, все что вы описали есть в D. Есть Unit тесты, есть GC. На слайсы(slices) так вообще сделан большой упор. Весьма приятный синтаксис после C и C++. Максросы да, в С это опасное зло в неумелых руках. Их нет в D, но есть альтернативы, которые выглядят куда лаконичнее. Управление зависимостями сделано в DUB. Может Вам стоит рассмотреть и его?

p.s. я знаю про вечный спор о Rust vs D.
p.s. я знаю про вечный спор о Rust vs D.
Не знаю ни о каком «вечном споре». Знаю что rust не пошёл на поводу у моды и вся его библиотека — работоспособна без всякого GC, что ставит его в один ряд с Pascal'ем, C, C++… и в другой класс, нежели D, Go, Java.

Или сейчас у них уже есть не только громкие заявляения о том, что GC можно выключить, но это реально можно сделать?
80% того, чего автору не хватает в С — отлично и безкомпромиссно компенсируется библиотеками.
Ну например, про срезы строк — это просто смешная претензия, пока писал этот текст, уже мысленно набрасал решение. Причем, что и делать-то самому ничего не нужно. Это уже написано до вас. Нужно просто приучиться пользоваться определенным набором любимых библиотек.

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

Обобщённые типы без проседания производительности на Сях могут быть достигнуты только магией макросов. Но даже такое решение не позволит использовать типажи.

Замыкания — это по определению элемент языка, в Си его просто нет.

Что осталось-то?
НЛО прилетело и опубликовало эту надпись здесь

80% это всё же не 100%. А главных фич Rust(семантика перемещения, borrow checker, lifetimes, отсутствие UB за пределами синтаксически выделенных участков кода, параметрический полиморфизм, явное приведение типов) в C нет и никакими библиотеками их не прикрутить. А если и прикрутить чем-то, то выйдет в любом случае коряво. Ну и зачем тогда это всё когда есть Rust? Только ради тех, кому лень в течении месяца по несколько часов в неделю тратить на изучение другого ЯП?

А главных фич


Почему в сравнении языков всегда всплывает этот бред?
Разумеется языки разные.
И ожидать от одного почти полного повторения того, что есть в другом — глупо.
Делать язык «точно такой же как С, только синенький» тоже глупо. Языки должны быть сильно разные, чтобы можно было приложить значительные усилия к его развитию.

Напомню ваши слова:


80% того, чего автору не хватает в С — отлично и безкомпромиссно компенсируется библиотеками.

Так вот, автору не хватает именно фич языка! Которых в Си просто нет. И не будет. Именно потому что языки разные.

Когда в команде Evolution всё шло наперекосяк. Нам тогда пришлось купить машину Solaris просто чтобы иметь возможность купить Purify; тогда не было Valgrind.


И всё это время, пока не было Rust, была Ада. Вместо покупки Solaris и Purify можно было бы просто собирать бесплатным GNAT'ом со всеми включенными проверками, да так и оставить в продакшне с проверками. Как учил меня Каменский Никита Викторович в НГУ, 90% кода — проверка ошибок, так пусть генерятся автоматом, если делать их в любом случае нужно. В отличие от Purify и Valgrind, это вполне можно оставить работать в штатном режиме.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации