LINUX.ORG.RU

Презентация «Rust - лучше, чем C++» на русском языке от разработчика из Яндекса

 


7

3

http://tech.yandex.ru/events/cpp-party/june-minsk/talks/1978

Степан Кольцов

Яндекс

Rust — это современный, практический, быстрый и безопасный язык программирования. Некоторые говорят, что Rust — это как C++, если бы его писал человек, знающий Haskell.

Система типов Rust решает главную проблему C++ — небезопасность. C++ очень легко сделать ошибки, которые приведут к поломкам (например, use after free). Rust позволяет писать безопасный код, сохраняя при этом выразительность и околонулевые накладные расходы C++. В докладе будут подробно описаны механизмы языка, которые контролируют безопасность программы.

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


Ответ на: комментарий от anonymous

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

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

quantum-troll ★★★★★
()
Ответ на: комментарий от anonymous

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

Они выводятся, но только внутри функции (как и остальные типы).

ozkriff
() автор топика
Ответ на: комментарий от ozkriff

Там слишком примитивный вывод(ищется пересечение уже известных регионов и пр. такое). Они скорее проверяются... Впрочем, может я плохо понял Rust. Но в примерах ничего такого не видел.

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

Я правильно понимаю, что если требуемые алгоритмы всё-таки появятся, их можно будет добавить в компилятор без необходимости [значительно] менять сам язык?

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

Смотря что за алгоритмы. Теоретически можем придти к тому, что писать можно будет примерно с теми же ограничениями, что и при «ручной»(в смысле не настоящий GC) работе с памятью, но при этом не думать об утилизации, ибо вывод регионов на статике определит сами регионы(соответственно места аллокации/деаллокации, а так же разрушения объектов), при этом мы будем иметь дело с некоторым небольшим рантаймом лишь для разруливания случаев сложных ветвей исполнения, где понадобиться что-то в духе подсчета ссылок(неявного для программиста, естественно) при исполнении. Для такого rust не заточен. И вот это уже реальный профит, а то я боюсь, что на практике rust ничего не даст...

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

Грустно.

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

А вот это интересно. И как на С++ будет выглядеть такой код?

scheme@(guile-user)> (define (adder x) (lambda (y) (+ x y)))
scheme@(guile-user)> (define add4 (adder 4))
scheme@(guile-user)> (add4 6)
$2 = 10
ugoday ★★★★★
()
Ответ на: комментарий от vertexua

Клёво. Но меня заинтересовало вот это высказывание:

объект-функцию. Конечно можно, если решишь проблему видимости типа/функции(тем или иным способом) или вернешь объект базового класса.

Собственно, хочется понять как это будет?

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

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

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

Если бы не Java, никакого планшета у тебя не было бы. Потому что разработать то же самое на Си

Если бы не Apple, никакого планшета бы не было. А там на Си, между прочим.

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

На старом c++:

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <functional>
#include <iostream>

boost::function1<int, int> Adder(int x)
{
	return boost::bind(std::plus<int>(), x, _1);
}

boost::function1<int, int> Add4()
{
	return Adder(4);
}

int main()
{
	std::cout << Add4()(6) << std::endl;
}
Manhunt ★★★★★
()
Ответ на: комментарий от ugoday

А, все, перечитал весь разговор и понял.

Короче раньше не было типа «функция». Были просто любые классы у которых перегружен оператор (). И люди делали велосипеды каждый раз когда нужно было заставить вернуть обьект, который «как функция». Это называли «функтором» (WHAT?!?) или фунциональным обьектом (уже лучше). Ну и ничего не мешало их возвращать из функции, а потом вызывать f(10), главное чтобы скомпилялось в итоге.

Теперь просто взяли и сделали нормальный тип, std::function. Он тоже попросту функциональный обьект, но зато стандартный. С бонусом что все лямбды - синтаксический сахар превращения в него.

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

Да, все верно.

Кроме:

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

Лямбды превращаются в анонимный объект анонимного класса. Но поскольку у него есть operator(), его можно сохранить в std::function

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

Лямбды превращаются в анонимный объект анонимного класса. Но поскольку у него есть operator(), его можно сохранить в std::function

Может и так, я это детали не знал. Точно не наследует std::function?

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

И вот это уже реальный профит, а то я боюсь, что на практике rust ничего не даст...

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

Долбоклюй поставит unsafe и будет писать как писал.

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

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

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

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

anonymous
()
Ответ на: комментарий от Manhunt

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

А если иногда надо? Просто если никогда не надо, то и на плюсах писать можно безопасно...

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

А если иногда надо?

Это «иногда» должно жить в отдельном модуле, при сборке которого слом на unsafe выключен. С письменным обоснованием почему оно *настолько* надо, с подписями архитектора и тимлида.

Просто если никогда не надо, то и на плюсах писать можно безопасно...

На практике это до сих пор мало кому удавалось :)

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

Важно, что возможность накосячить никуда не делась.

Ты про unsafe?

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

Что-то в таком виде (схематически):


class F
{
  int i;
public:
  F(int i) : i(i) {}
  int operator()(int j) {return i+j;}
};

F adder(int i) {return F(i);}

int main()
{
  auto f = adder(3);
  printf("%d\n", f(3));
}
Проблема „видимости“ в том, что тот, кто будет вызывать adder должен знать про F или кастовать его в std::function.

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

std::function это шаблон. Там просто применение оператора () к тому, чего ты ему скормил. Соответственно если там ф-ия, то вызывается ф-ия, если функтор, то вызывается оператор (). А лямбды это такой функтор у которой в качестве типа - уникальный хеш, который вроде и записать в коде нельзя. Поэтому переменные, которым присвоили лямбды, объявлять можно только с auto и они всегда разного типа, даже если у них сигнатуры одинаковые.

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

vertexua:

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

nanoolinux

Что-то в таком виде (схематически):

Иллюстративненько.

anonymous
()
Ответ на: комментарий от ugoday

На C++ как раз. Ибо D не взлетел, Go тормоз и убог, а Rust еще не готов.

anonymous
()
Ответ на: комментарий от sf

Сейчас понятно, откуда (на каких задачах) хотя-бы потенциально может взяться рост производительности?

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

Если с верхним понятно - отвечу :]

Ответь.

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

Мне понятно, что ты написал синтетический тест затрат на принудительное переключение потоков.

Отлично! Осталось научиться его усматривать в разных интерактивных нагрузках.

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

Даже тут (если представить, что yield - это тик таймера, а прямо перед ним - реальная работа) можно было бы уже сказать о меньшем потреблении ресурсов green threads программы по сравнению с native threads программой (при условии, что их частота переключения останется одинаковой). Но цифра - маленькая, не интересно :]

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

Вы представляете, откуда берутся переключения контекстов потоков, скажем, в web сервере в модели «1 OS thread per request»?

Или в программе, задача которой - создавать параллельную нагрузку на HTTP сервер.

> Если с верхним понятно - отвечу :]
Ответь.

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

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

Вы представляете, откуда берутся переключения контекстов потоков, скажем, в web сервере в модели «1 OS thread per request»?

Давай лучше посчитаем, сколько раз за время обработки одного запроса такой поток заблокируется на i/o, сколько времени он потеряет на принудительном переключении контекста в этих блокировках, сколько времени всего он будет бежать (включая блокировки), и сколько времени в % мы можем сэкономить, использую зеленые потоки вместо нативных. И тут желательно считать не только время на переключение зеленых потоков, но так же и потери на управление ими и всякий скрытый оверхед, вроде синхронизации с i/o-потоком.

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

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

anonymous
()
Ответ на: комментарий от ddos3

Давай лучше посчитаем, сколько раз ...

Осилите бенчмарк на С? А я попытаюсь аналог сляпать.

И тут желательно считать не только время на переключение зеленых потоков, но так же и потери на управление ими и всякий скрытый оверхед, вроде синхронизации с i/o-потоком.

Да всё вместе и попрофайлим. Делов то.

sf ★★★
()

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

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

Посмотри на код openssl, багу которого тут обсуждали. Это, во-первых, си, а не c++, а во-вторых никто их не заставлял так плохо писать, можно и на си писать нормально... От того, что такие люди возьмут rust ничего не изменится. А это ещё не самые плохие кодеры в индустрии.

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

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

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

Так вот и спрашивается в задачнике, дает ли что-то реальное rust на практике. Если у вас есть определенная дисциплина, то относительно безопасно у вас получается писать и на C++(на Си тоже, но сложнее). Ошибаетесь вы как правило только в местах, где делаете какие-то ручные операции, т.е. там, где в rust вам скорее всего потребуется unsafe. А про быдлокодеров вообще можно молчать - они везде найдут возможность набыдлокодить.

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

Если у вас есть определенная дисциплина, то относительно безопасно у вас получается писать и на C++(на Си тоже, но сложнее)

на Си тоже, но сложнее

А на Rust это будет еще проще, чем на Си++.

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

Вопрос в том, будет ли проще настолько, что появится смысл переходить на rust. Он навязывает многие вещи, в частности, модель конкурентности и параллельности. Или не навязывает?

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

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

Да, вопрос именно в этом. Но пока невозможно уверенно ответить ни «да», ни «нет».

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

Зависит от того, что понимать под «моделями конкурентности и параллельности».

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)

C лучше всего этого. Холвар окончен!

Sharezil
()

Даже бреинфак лучше, чем С++.

anonymous
()
Ответ на: комментарий от vertexua

Я думаю что основная ценность тех языков, которые называют современными, в green threads. Мне кажется это тяжело сделать в С++

Опрометчивое утверждение, т.к. те языки реализованы на С или С++ :)

Конкретно - см. например Boost Coroutine. Так же есть куча фреймворков для асинхронного программирования

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

Главная проблема C++ в том, что он пытается поддерживать все парадигмы программирования

В этом нет никакой проблемы. Язык с одной парадигмой не может быть полноценным языком общего назначения.

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

контексты ОС нужно будет значительно реже

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

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