devops
Проводиться експеримент, щоб уникнути C як мови сумісності з Rust
Завдяки експериментальній роботі основного учасника Mojo Евана Овадії, універсали мови програмування тепер можна переносити з компілятора однієї мови на інший і назад.
Цей колишній інженер Google спробував перетворити Rust на бібліотеку, яку можна будувати іншими мовами, і показав спосіб передачі загальних типів даних і функцій між Rust та іншою мовою, яку C ABI не підтримує.
«Технічно це найсмішніше, що я читав за останні місяці», — сказав ведучий YouTube-каналу Let’s Get Rusty, коментуючи те, що він назвав «Rust++».
Це дивна перемога, але можна бути впевненим. Овадія описує свою роботу в пояснювальній публікації в блозі як «Золотий шип», який поєднує дві різні мови, посилаючись на останній шип, вбитий у першу трансконтинентальну залізничну лінію в Сполучених Штатах.
Замість того, щоб просто пакувати у сирі вагони C ABI, розділяти на сировину, бібліотеки з багатими можливостями можна транспортувати до чужих екосистем надійними високошвидкісними рейками.
Нарешті відмовитися від C ABI
Ця робота виникла в результаті спроби Овадії створити власну мову Valen (допоміжний продукт попередньої розробки під назвою Vale), яку він уявляє як швидшу та зручнішу для розробників версію Rust.
Проблема створення нової мови з нуля, як він виявив, полягала в тому, що він не міг використовувати улюблені бібліотеки Rust (особливо Rust wgpu графічна бібліотека).
Сьогодні поширеним способом використання бібліотеки з однієї мови в програмі, написаній іншою мовою, є C ABI (інтерфейс бінарного прикладного програмування), рівень функціональної сумісності, який визначає угоди для передачі даних і викликів функцій між скомпільованим кодом. (Rust має власний ABI, хоча він не гарантує стабільності.)
За допомогою C ABI, якщо бібліотека Rust розкриває свої функції як extern «C» і розкриває свої типи як repr(C), тоді до них можна отримати доступ з іншої мови за допомогою зовнішнього функціонального інтерфейсу (FFI).
Все добре, але проблема Ovadia полягала в тому, що C ABI не розумів концепції генериків (або заповнювачів для типів даних, які будуть представлені пізніше), тому що сам C не розуміє концепції генериків. Але Rust досить часто використовує генерики, як і Valen, хоча й не так багато.
«Тож центральне питання, головна загадка рішення полягає в тому, як ми створюємо міжмовні генерики?» – написав Овадія.
Нарешті міжмовні генерики
Дуже важко змусити двох компіляторів співпрацювати, оскільки компілятори зазвичай є окремими сутностями, самотніми королями своїх власних індивідуальних світів.
Тож Ovadia потрібно було знайти спосіб для Valen викликати загальну функцію Rust, а також мати загальну функцію Rust, яка повертає Valen для необхідних значень.
Після довгих роздумів Ovadia придумав рішення, що складається з двох частин для міжмовних генериків: спочатку реалізувати компілятор Rust як бібліотеку. Дивно, але Rust вже має таку можливість (rustc_driver), що дозволяє Valen розмістити rustc безпосередньо у своєму просторі пам’яті. Другим кроком буде виправлення Rust, щоб, коли він стикається з типами, відмінними від Rust Valen, він передавав керування компілятору Valen для обробки частини та очікування скомпільованого результату.
Овадія визнає, що виправлення компілятора Rust було «ядерним варіантом».
“Чесно кажучи, це була найнебезпечніша частина всієї спроби”, – написав він. Сам патч містить лише близько 100 рядків коду, але він хакерський і передбачає, що Rust використовує LLVM для створення машинного коду, що не завжди так. «Працює, але точно не топ», – написав Овадія.
Однак двосторонні міжмовні генерики Ovadia є реальним кроком до сумісності мов програмування.
На даний момент у Овадії повні руки з Валеном, хоча його міжмовна робота відкриває можливість використовувати Rust для забезпечення інших нових мов, створених із бібліотек Rust. Враховуючи кілька змін у самому Rust, залежність від скрипучого C ABI може залишитися в минулому.
На форумах розробників Reddit і Lobste.rs рецензенти хвалили Ovadia за вирішення такої складної проблеми, навіть якщо вони не розглядали деталі.
«Я ціную заміну C як «універсальної мови FFI», — написав один коментатор. «Це дуже сміливий вибір, і він вимагає зусиль».
Інший читач прокоментував, що Rust може бути не найкращою мовою для синхронізації, враховуючи системні обмеження типу.
«Але уявіть, якби ви могли створити зграю на Аді! Це було б дивовижно», — написали вони. ®