LINUX.ORG.RU

Rust 1.12

 


1

6

Команда разработчиков Rust рада представить релиз Rust 1.12 — системного языка программирования, нацеленного на безопасную работу с памятью, скорость и параллельное выполнение кода. В этот релиз вошёл 1361 патч.

Новое в 1.12

По словам разработчиков, релиз 1.12 является, возможно, самым значительным с момента выпуска релиза 1.0. Самое заметное для пользователей изменение в версии 1.12 — это новый формат ошибок, выдаваемых rustc. Сообществом была проделана многочасовая работа по переводу вывода ошибок на новый формат. Кроме того, для лучшей интеграции и взаимодействия со средой разработки и другим инструментарием ошибки теперь можно выводить в формате JSON при помощи специального флага --error-format=json.

Самое большое внутреннее изменение — это переход на новый формат внутреннего представления программы MIR. Незаметное сегодня, это изменение открывает путь к череде будущих оптимизаций компилятора, и для некоторых кодовых баз оно уже показывает улучшения времени компиляции и уменьшение размера кода. Переход на MIR открывает ранее сложнодоступные возможности анализа и оптимизации. Первое из многочисленных грядущих изменений — переписывание прохода, генерирующего промежуточное представление LLVM, того, что rustc называет «трансляцией». После многомесячных усилий новый бэкенд, основанный на MIR, доказал, что готов к реальной работе. MIR содержит точную информацию о потоке управления программы, поэтому компилятор точно знает, перемещены типы или нет. Это значит, что он статически получает информацию о том, нужно ли выполнять деструктор значения. В случаях, когда значение может быть перемещено или не перемещено в конце области действия, компилятор просто использует флаг из одного бита на стеке, что, в свою очередь, проще для оптимизации проходов в LLVM. Конечный результат — уменьшенный объем работы компилятора и менее раздутый код во время исполнения.

Другие улучшения:

  • Множество мелких улучшений документации.
  • rustc теперь поддерживает три новые цели MUSL на платформе ARM: arm-unknown-linux-musleabi, arm-unknown-linux-musleabihf и armv7-unknown-linux-musleabihf. Эти цели поддерживают статически скомпонованные бинарные файлы. Однако, в собранном виде они пока не распространяются.
  • Повышена читабельность описаний ошибок в ссылках и неизвестных числовых типах.
  • Компилятор теперь может быть собран с LLVM 3.9.
  • Тестовые бинарные файлы теперь поддерживают аргумент --test-threads для указания количества потоков для запуска тестов, который действует точно так же, как переменная окружения RUST_TEST_THREADS.
  • В случае продолжительности выполнения тестов больше минуты показывается предупреждение.
  • Вместе с выпусками Rust теперь доступны пакеты с исходными кодами, которые можно установить при помощи rustup через команду % rustup component add rust-src. Исходные коды могут быть использованы для интеграции и взаимодействия со средой разработки и другим инструментарием.
  • Ускорено обновление индекса реестра.
  • cargo new получил флаг --lib.
  • Добавлен вывод профиля сборки (release/debug) после компиляции.
  • cargo publish получил флаг --dry-run.
  • Сокеты на Linux в подпроцессах теперь закрываются правильно через вызов SOCK_CLOEXEC.
  • Определения Unicode обновлены до 9.0.

Стабилизация библиотек:

  • Cell::as_ptr и RefCell::as_ptr.
  • IpAddr, Ivp4Addr и Ipv6Addr получили несколько новых методов.
  • LinkedList и VecDeque теперь имеют новый метод contains.
  • iter::Product и iter::Sum.
  • Option реализует From для содержащегося в нём типа.
  • Cell, RefCell и UnsafeCell реализует From для содержащихся в них типах.
  • Cow<str> реализует FromIterator для char, &str и String.
  • String реализует AddAssign.

Возможности Cargo

Самая большая возможность, добавленная в Cargo в этом цикле — «рабочие области». Описанные в RFC 1525, рабочие области позволяют группе пакетов разделять один общий файл Cargo.lock. Это позволяет намного легче придерживаться единственной версии общих зависимостей при наличии у вас проекта, который делится на несколько пакетов. Для включения этой возможности в большинстве мультипакетных проектов достаточно добавить одну единственную строчку [workspace] в Cargo.toml верхнего уровня, более сложным установкам может потребоваться дополнительная настройка.

Другая существенная возможность — переопределение источника пакета. При помощи инструментов cargo-vendor и cargo-local-registry можно переопределять зависимости локально (vendoring). Со временем это станет фундаментом для построения инфраструктуры зеркал crates.io.

>>> Подробный список изменений

>>> Подробности

★★★★★

Проверено: Falcon-peregrinus ()
Последнее исправление: Falcon-peregrinus (всего исправлений: 10)

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

Нет, тут смысл в том, что в C++ ты для этого создаешь НОВЫЙ ТИП, а в расте ты можешь волшебным образом добавить новое поведение старому.

Во первых, если работать с интерфейсами, то для кода на С++ создание нового типа пройдёт незамеченным. Во вторых, в расте надо явно импортировать трейт, методами которого хочешь пользоваться.

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

Вы столько времени пытаетесь донести до Rust-оманов простые и очевидные вещи, но все как горохом о стену.

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

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

Нельзя сделать список элементов разных типов, но поддерживающих (реализующих) один интерфейс (трейт)

А можешь показать как выглядит аналог на С++? А то есть ощущение, что оно или уже можно в расте или ты хочешь чего-то другого, чем описал.

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

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

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

Нет. Это ортогональные понятия.

Да. Не ортогональные.

Нет. Сходи по ссылке.

А вот в Java и его потомках, от множественного наследования отказались (ибо не смогли как в Eiffel), отсюда и пошло проникновение интерфейсов в мейнстрим.

Да какая разница, откуда они проникли в мейнстрим. Они были в языка с множественным наследованием (Си++), с одиночным (Objective C), и даже вектор операций в Си - тоже интерфейс.

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

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

Сокрытие реализации — это несколько другая тема.

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

Не менее необходимо доказать, что наследование интерфейсов — это есть то самое наследование из святой троицы ООП ;)

Вот на тебе определение сути ООП от человека, изобретшего само понятие ООП (обрати внимание, никакими троицами тут не пахнет):

http://c2.com/cgi/wiki?AlanKaysDefinitionOfObjectOriented

I have asked Alan Kay about his definition of «object oriented» and he told me in 2003:

OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme LateBinding of all things.


Вот на тебе определение ООП из википедии (что характерно, тоже без троиц):

https://en.wikipedia.org/wiki/Object-oriented_programming

Object-oriented programming (OOP) is a programming paradigm based on the concept of «objects», which may contain data, in the form of fields, often known as attributes; and code, in the form of procedures, often known as methods. A feature of objects is that an object's procedures can access and often modify the data fields of the object with which they are associated (objects have a notion of «this» or «self»). In OOP, computer programs are designed by making them out of objects that interact with one another.


Так что ваше увлечение троицами — это ваши личные, интимные проблемы. Жесткая связь между ООП и ортодоксальной «троицей» есть только в ваших субъективных преставляениях об ООП.

Лично для меня квинтессенция ООП — это принципы SOLID. И rust к ним вполне приспособлен.

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

Да какая разница, откуда они проникли в мейнстрим.

Разительная.

Они были в языка с множественным наследованием (Си++)

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

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

Лично для меня квинтессенция ООП — это принципы SOLID.

Ну найдите упоминания о SOLID-е в процитированных вами определениях. Потом расскажите всем о собственных интимных проблемах.

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

Ну найдите упоминания о SOLID-е в процитированных вами определениях.

Так ведь я, в отличие от вас, не пытаюсь подменить solid-ом само определение ООП. Давайте уже по существу: Rust 1.12 (комментарий)

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

в статически-типизированных языках, в которых не смогли во множественное наследование, появилась такая заморочка, как интерфейсы

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

И снова непонятно слово «заморочка». Интерфейс — вполне естественное понятие, вытекающее из статической типизации. Для меня заморочка - это скорее отсутствие явных интерфейсов в динамических языках. И эмуляция интерфейсов на классах как в C++ - тоже заморочка, не вполне естественная.

Также непонятны отсылки ко множественному наследованию — вроде оно ни в каких определениях ООП не фигурирует.

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

Вы как-то поздно спохватились. Rust 1.12 (комментарий) Троица уже давно была упомянута в треде. И только сейчас вы решились прибегнуть к схоластике и доказать, что упомянутая троица — это не ООП.

Ну удачи, чо.

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

сам факт их исчезновения из языка с множественным наследованием говорит сам за себя:

Факт их исчезновения говорит о том, что идея отвергается, если ее время не пришло.

в языке с нормальным множественным наследованием отдельное понятие интерфейса является лишней (т.е. не нужной) сущностью.

Как знать. Разговоры о runtime concepts - это неспроста.

tailgunner ★★★★★
()

Гм. А вот хотелось бы спросить у людей, которые в этой теме приводят аргументы за то, что Rust — ОО-язык. Haskell тоже ОО?

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

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

Вот тебе ссылка и не мешай нам флеймитьне оффтопь здесь.

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

Если помнишь, Гослинг, например, размышлял об полном отказе от наследования.

Не помню. Помню, как говорилось, что в Java решили не включать множественное наследование дабы избежать сложностей, которые были в C++ (ведь Java позиционировалась тогда как «правильно сделанный C++»). И это по официальной версии.

И снова непонятно слово «заморочка».

Поясню. Я специально характеризовал ООП в этом треде как троицу из наследования, инкапсуляции и полиморфизма. Ибо эти три качества, как показала история и практика, обнаруживаются в (насколько я помню) большинстве ООЯ вне зависимости от того, статически они типизированы или динамически, используются ли в них классы (как в наследниках Simula) или прототипы (как в наследниках Self-а).

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

Но вот если мы смотрим на ООП в статически типизированных языках, то обнаруживаем вещи, которые происходят из этой самой статической типизации. В частности, интерфейсы. Т.е. для самого ООП «вообще» отдельно оформленное понятие «интерфейса» как языковой сущности не нужно. Но в некоторых статически типизированных ООЯ — нужно, отсюда и «заморочка».

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

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

и не мешай нам флемит

Вот ещё! Надо больше неразберихи в треде.

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

Как знать. Разговоры о runtime concepts - это неспроста.

Как по мне, так это не имеет отношения к ООП.

C++ ведь никогда не был чистым ООЯ (в отличии от Eiffel-я и Java). В свое время он вбирал идеи из функциональщины (емнип, шаблоны в C++ — это заимствование из ML и Ada), и продолжает это делать. В эту же сторону и концепты.

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

Это вы троллите или реально не понимаете?

Реально не понимаю. Вот C - язык со статической типизацией. И без динамической диспетчеризации. И живёт. Раст, если бы в нём не было trait object'ов тоже был бы языком со статической типизацией и без динамической диспетчеризации. Трейты использовались бы только для ограничения дженериков. С другой стороны можно представить язык с динамической типизацией, в котором при компиляции методы всех классов собираются в один список и для каждого фактического класса создаётся виртуальная таблица, в которой просто чужие методы забиты заглушками.

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

Безусловно так и есть. Если вы под ОО языком понимаете язык, зацикленный на ОО парадигме, то да, Rust к таким не относится. Но поддержка ОО, тем не менее, в язык интегрирована.

И вот не понятно, зачем утверждать «Раст просто по факту язык, поддерживающий ОО»?

Потому что есть в нём инструменты для ОО. Вот сравнить с C#, в нём наследование данных и методов ограничено 1 предком, а в Rust'е данные ограничены 0, зато методы можно наследовать от неограниченного количества предков. Вот я почему-то уверен, что 20 лет назад C++ программисты, с опытом работы над старым проектом (без RTTI), когда читали книгу «java за 21 день» точно так же говорили, что java - не полноценный ОО язык, так как предок всего 1, а instanceof - это корявка для слабаков.

Типа, это не говно, я не зря на него перешел?

Тут, по-моему, только asaw считает, что поддержка ООП - это то, без чего язык неполноценен.

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

Разговоры о runtime concepts - это неспроста.

Как по мне, так это не имеет отношения к ООП.

Cами интерфейсы - это не ООП, поэтому выражение интерфейсов с помощью ООП (наследования в Си++) неестественно. Но у трейтов конкретно Rust есть операция наследования, и вот это уже можно (при желании) считать ООП.

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

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

Это противоречит самой природе динамической типизации.

Если вы под ОО языком понимаете язык, зацикленный на ОО парадигме, то да, Rust к таким не относится.

Я уже давно обозначил о чем идет речь: если язык из коробки поддерживает троицу «инкапсуляция, наследование и полиморфизм», то это ООЯ.

При этом ООЯ не обязательно должен быть «чистым ООЯ». В качестве примеров: С++ и OCaml, которые поддерживают ООП, но остаются мультпарадигменными.

Тут, по-моему, только asaw считает, что поддержка ООП - это то, без чего язык неполноценен.

Безотносительно того, прав ли asaw или нет, я лично не понимаю, почему растоманы так рьяно бросились доказывать, что Rust — это ООЯ. В Rust-е свой набор инструментов, как и, скажем, в Haskell-е. Возможно, в каких-то классах задач инструментарий Rust-а гораздо удобнее, чем таковой в Java или C#, или в C++.

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

Cами интерфейсы - это не ООП, поэтому выражение интерфейсов с помощью ООП (наследования в Си++) неестественно.

Можно и так сказать. Как по мне, так интерфейсы — это инструмент для поддержки абстрактных типов данных.

ООП так же может использоваться для реализации абстрактных типов данных.

Тем не менее, АТД и ООП — это разные вещи. Поэтому, на мой взгляд, Rust — это язык с АТД (и АлгТД в придачу), но вот ООП в нем в чистом виде нет.

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

я тут со всеми на ты общаюсь (в обе стороны)

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

если интересно именно это обсудить — то инкапсуляция это только один из способов обеспечить соблюдение инварианта

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

В качестве примера, предоставление доступа к внутренностям в режиме только для чтения никак не может повредить состоянию объекта, и тем не менее инкапсуляция в таком случае сомнительна.

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

вообще речь у нас о терминах, и там могут быть разные мнения — вон википедия пишет, что не все разделяют деление на инкапсуляцию и information hiding

но мой пойнт в том, что инварианты нужны железно (в смысле обязательно), а вот information hiding может быть под вопросом

скажем, если мы проектируем тип Time с обычными операциями Time::get_year(), Time::set_year(int), ... Time::get_second(), Time::set_second(int), то можно и позволить например time.set_second(100500), которая будет переводить секунды в минуты, часы и т.п. и добавлять их тоже, а не только ставить секунды (примерно как в ui андроида)

но обязательно get_second() после этого не должна возвращать 100500 — это будет нарушением инварианта

а теперь information hiding — нужно ли предоставлять get_seconds_since_epoch(), где эпоха не юниксовая, а некая своя? можно *спорить* на тему, что этот метод выдает наружу деталь реализации — именно спорить

еще пример: пусть нам нужен класс Point { float x; float y;} про который известно, что x и y имеют точность существенно ниже аппаратного float

и как ты будешь скрывать деталь реализации — а именно, последние мусорные биты float-а? скорее всего, никак

да, можно наколбасить на шаблонах imprecise_float, но у него *все* операции будут ровно те же, что и у обычного float-а, и смысл его будет только в том, чтобы где-то компилятор ругнулся на его конверсию в обычный float; вряд ли этот imprecise_float действительно будет полезным при разработке софта

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

Поэтому, на мой взгляд, Rust — это язык с АТД (и АлгТД в придачу), но вот ООП в нем в чистом виде нет.

Если чистым видом считать Java и Си++, с наследованием реализации - его нет. Но, с другой стороны, что мы теряем? Ну да, бывает удобно конструировать типы наследованием. Вопрос только в том, достаточно ли это часто - если нет, то приведенный выше трюк с перегрузкой Deref вполне жизнеспособен.

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

Проблема в том, что вы вполне здравую и актуальную на сегодняшний день идею ООП пытаетесь подменить бестолковой троицей. На каком-то этапе развития (20-30 лет назад, да) действительно казалось, что троица удачно детализирует само понятие ооп. С тех пор было собрано немало опыта, сделано выводов, и на сегодняшний день место троицы — где-то на обочине той дороги, по которой движется ооп. http://programmers.stackexchange.com/questions/253090/why-are-inheritance-enc...

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

Не помню

http://www.artima.com/intv/gosling34.html

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

Поясню

Мысль понял, но посмотри на это с другой стороны: если стоит выбор между множественным наследованием и интерфейсами, то что замороченнее, причем и для разработчиков языка, и для его пользователей?

Множественное наследование потенциально мощнее, но эта мощь нужна слишком редко, чтобы так всё усложнять (сужу по C++), и проще будет написать чуть больше кода. История ЯП эту мысль подтверждает (а отдельно интересна тенденция вообще отказываться от наследования в новых языках).

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

Если чистым видом считать Java и Си++, с наследованием реализации - его нет.

О том и речь. Безотносительно того, хорошо это или плохо.

Но, с другой стороны, что мы теряем?

Это уже совсем другой вопрос.

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

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

Проблема в том, что сейчас ООП в статически-типизированных языках — это уже не ООП в чистом виде.

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

А троица как описывала ООП, так и продолжает описывать.

Возьмите свой любимый SOLID и вы увидите, что SOLID описывает принципы, а троица дает вам средства для реализации этих самых принципов.

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

А троица как описывала ООП, так и продолжает описывать.

Троица описывает устаревший, имеющий серьезные изъяны, взгляд на ооп. ООП — это про локализацию и сокрытие state внутри объектов, про позднее связывание и про обмен сообщениями. Если опуститься до реализации, то чаще всего state заключен в аттрибутах объектов, позднее связывание достигается за счет того что объекты друг о друге мыслят в терминах абстракций (*контрактов*, и их бедных родственников - интерфейсов, трейтов, концептов), а обмен сообщениями осуществляется путем вызова стоящих за абстракциями конкретных связанных с конкретными данными процедур. Вполне возможны какие-то другие реализации, и это всё ещё будет ооп. А «троица» здесь попросту не релевантна.

Возьмите свой любимый SOLID и вы увидите, что SOLID описывает принципы, а троица дает вам средства для реализации этих самых принципов.

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

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

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

Прекрасно. Давайте считать C объектно-ориентированным языком.

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

я чуть сократил (ненужные изменения имени) и добавил печать и профессию рабочему https://play.rust-lang.org/?gist=292bdef40f50f8016d34f21088312d97&version...

то приведенный выше трюк с перегрузкой Deref вполне жизнеспособен.

хм? возможно после сильной доработки, т.к. перегрузка Deref всегда возвращает указатель на Human-а

как сделать так, чтобы у обоих — и Human, и Worker была функция say, и у человека она печатала

println!(«I am {}», human.name );

а у рабочего че-то типа

println!(«I am {} and I am {}», human.name, profession );

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

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

Пацаны, я слышал что етот ваш раст придумали инопланетяне. Как вообще можно читать код на нем?

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

Давайте считать C объектно-ориентированным языком.

На Си можно писать в объектом стиле (и GObject тому свидетель), но чтобы при этом считать сам Си объектно-ориентированным, не хватает сахара. Если сахар добавить, то получится очередной оо-язык с си-подобным синтаксисом. И что?

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

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

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

тебе тот же вопрос Rust 1.12 (комментарий)

как это сделать правильно?

может реализовать struct и trait OOPObject с таблицей виртуальных функций, плюс макрос(ы) для автоматической регистрации функции в этой таблице?

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

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

но чтобы при этом считать сам Си объектно-ориентированным, не хватает сахара.

сахар это не столь важно — сахар можно добавить внешним глупым препроцессором (даже на регекспах)

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

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

Вот так, TraitObject держит таблицу виртуальных функций.
Все вполне естественно и удобно. Я выше кидал ссылку на растбук, там все подробно описано

UPD: в 43 строке благодаря Deref можно просто писать self.name :)

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

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

Методы и сообщения, имхо, концептуально разные вещи. Сообщения юзер диспатчит сам как хочет:

receive
  {foo, A} ->
    foo(A);
  bar ->
    bar(A),
    ok
end

В то время как вызов методов диспатчит рантайм языка (ну или компилятор генерирует код для этого прямо на месте, как в С++).

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

Системный ЯП? А операционка на нём есть?

Несколько.

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