LINUX.ORG.RU

Линус Торвальдс пояснил свою позицию в отношении приёма изменений на Rust

 ,


0

7

К обсуждению сопротивления мэйнтейнеров внедрению Rust в ядро подключился Линус Торвальдс, который пояснил, что никто не заставляет мэйнтейнеров изучать язык Rust, использовать код на Rust, или принимать во внимание наличие в ядре кода на Rust. Мэйнтейнеры могут спокойно продолжать работать только с кодом на Си и никак не пересекаться с Rust. Но подобные сопровождающие не могут и влиять на то, как развивается Rust в ядре, например, не могут вмешиваться в организацию внешнего взаимодействия Rust-кода с кодом их подистемы.

Линус раскритиковал действия Кристофа Хелвига, мэйнтейнера подсистем DMA, KVM, Slab Allocator и архитектуры PowerPC. По мнению Линуса, Кристоф превысил свои полномочия и попытался повлиять на код, который не затрагивал код подсистемы DMA, был реализован в отдельном подкаталоге и не влиял на код, за который отвечает Кристоф. Кристоф попытался контролировать то, для чего используется подсистема DMA, и его действия можно сравнить с попыткой запрета использования DMA в каком-то драйвере, лишь потому, что ему не понравился этот драйвер. Итог: несмотря на то, что сопровождающие отвечают за свой код, они не отвечают за то, кто и как использует результат работы этого кода.

>>> Письмо Линуса

>>> Подробности (OpenNet)

★★★★★

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

то есть и брейнфак отличный язык, ему просто нужно хорошее ide?

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

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

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

да фигово это читаемо… кстати, что будет если имплементировать два интерфейса в которых есть функции с одной сигнатурой? например print().

https://doc.rust-lang.org/rust-by-example/trait/disambiguating.html

То же что и везде.

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

Ты возмущался конкретным решением в расте, а я ответил, что названная проблема в наше время решается с помощью IDE.

это не ответ. с помощью ide решается все. ide это посторонний продукт, нигде не описанный в стандартах руста. для руста как языка, нет никакого ide, поскольку он никак на него не ссылается.

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

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

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

  class Old {...};

  class New:
    private Old,
    public NewFace 
  {
  }

  или

  class New:
    public NewFace 
  {
    Old _old_class_instance;
  }

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

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

Тебе шашечки или ехать? Ещё раз повторяю: эта проблема сейчас ВЕЗДЕ решается с помощью IDE. И в плюсах, и в жабе, везде. И нигде в стандартах оно (IDE) не описывается. Ну если шибко хочется и IDE принципиально не используешь, есть ещё автоматическая генерация документации. Нет абсолютно никакой необходимости извлекать это из исходника. Поэтому проблема надуманная. И даже эта надуманная проблема решена в Расте лучше чем в плюсах.

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

Не, ты явно не понял о чём я.

То что ты описал похоже на ньютайп и да, это в расте тоже есть.

Но я не об этом. Это когда ты говоришь в терминах полиморфизма: «некоторые вещи, в рамках моего кода, обладают свойством X, я описываю это через traitX, и вот такая уже существующая штука (например, вектор из интов) относится к этому классу и с ней надо работать так». И фишка в том, что этот объект (вектор интов, например) может быть где угодно, его может брать и возвращать тебе какая-нибудь внешняя либа и твой код при этом будет по-красоте с этой хренью работать как с полноценным наследником traitX, включая возможность динамического вызова методов. В классических ООП языках это потребовало бы дичи типа наследования от вектора, за что на кодревью тебе бы дали по башке и заставили бы читать GoF и делать по-человечески.

В расте ты просто заимплементишь свой traitX для Vec и обойдёшься без обёрток и кучи интерфейсного кода. Поэтому идея отделения «наследования» от объявления неплохая.

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

Достаточно чтоб знать про наследование реализации.

Вот тебе пример:

class MyA: public A
{
// data members
...
  public:
  void debug();
};

Давай, расскажи как ты без иде легко и быстро найдёшь все методы его.

А в реальных проектах с ООП (которые примерно все являются библиотеками для GUI), ядрёное дерево наследования от LibNameObject через 5 промежуточных абстрактных классов типа LibNameControl и т.п.

Это, конечно, гораздо легче чем просто нажать ctrl-f, ввести impl и найти

impl MyA {
...
}
khrundel ★★★★
()
Ответ на: комментарий от khrundel

В классических ООП языках это потребовало бы дичи типа наследования от вектора, за что на кодревью тебе бы дали по башке и заставили бы читать GoF и делать по-человечески.

наследование от вектора это не дичь, если он является классом. какая разница от чего наследовать?

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

пишется так

class OldClass {
public:
  void fun0();
}


///класс реализующий две новых функции, используя класс OldClass
class Decorator {
  OldClass &_ref;

public:
  Decorator(OldCLass& fref): _ref(fref){... }
  void fun1() { _ref.fun0(); }
  void fun2() {  }
}

использование:

  OldClass val_old; ///обьект старого класса
   
  Decorator(val_old).fun1(); ///на лету создаеи декоратор и тут же вызываем функцию

  или

  Decorator decor(val_old); ///создали обьект декорирующий val_old
  decor.fun1(); ///вызываем его методы сколько надо раз
  decor.fun2();
alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от khrundel

Давай, расскажи как ты без иде легко и быстро найдёшь все методы его.

да ты сам нарисовал его методы. он только один и зовут его debug. и мне не надо проверять весь файл на наличие других методов.

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

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

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

да ты сам нарисовал его методы. он только один и зовут его debug. и мне не надо проверять весь файл на наличие других методов.

Неверно.

методы же доставшиеся по наследству от A,

А тебе не пофиг, достались они от A или добавлены тут? Метод есть метод. Его можно вызвать. И он не становится второсортным, если добавлен в базовом классе. И чтоб найти нужный тебе придётся открывать несколько файлов. А знаешь ещё какая жесть бывает? Бывает что в наследнике добавляется перегрузка. Вот идёшь ты в хедер A, а там метод, который вроде бы делает то что нужно, но неудобно. И дальше твой выбор, либо поверить что этот неудобный API и есть единственное что есть, или на всякий случай идти до корня и искать более удобную перегрузку.

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

наследование трейтов вроде есть и в русте, не помню. если да - то претензии к русту, такие же как к плюсам. только хуже.

За последнюю соломинку хватаешься?

Нет, у Раста всё лучше, потому что делали люди поумнее нас с тобой и имея перед глазами кучу языков и понимая проблемы существующих. Почему так горит жопа от Раста? Да потому что ничего кроме паскаля на первом курсе и C++ на последующих не видели, а тут синтакс какой-то непривычный. Проблемы с наследованием трейтов нет никакой: в файле MyA.rs будут перечислены все методы, которые MyA реализует, независимо от иерархии трейтов. Так что если для тебя поиск методов без IDE представляет ценность - раст твой выбор.

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

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

наследование от вектора это не дичь, если он является классом. какая разница от чего наследовать?

А ты точно программист?

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

пишется так

Сам видишь, какое говно получилось. И всё ради чего? Ради того чтоб добавить метод к существующему объекту. А есть хороший язык, который делает это на раз-два.

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

Естественно, разница есть и разница эта например в том, что другой код считает что у тебя вектор.

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

Сам видишь, какое говно получилось.

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

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

А тебе не пофиг, достались они от A или добавлены тут? Метод есть метод. Его можно вызвать. И он не становится второсортным, если добавлен в базовом классе.

ты выдаешь одно за другое.

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

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

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

alysnix ★★★
()
Ответ на: комментарий от alysnix
struct OldSomething;

impl OldSomething {
    fn fun(&mut self) {
        println!("fun");
    }
}

struct Decorator<'a>(&'a mut OldSomething);

impl Decorator<'_> {
    fn fun1(&mut self) {
        self.0.fun();
        println!("fun1");
    }
    
    fn fun2(&self) {
        println!("fun2");
    }
}

fn main() {
    let mut smth = OldSomething;
    Decorator(&mut smth).fun1(); 
   
    let mut decor = Decorator(&mut smth); 
    decor.fun1();
    decor.fun2();
}
red75prim ★★★
()
Ответ на: комментарий от red75prim

переводим на нормальный

Раст

struct OldSomething;

impl OldSomething {
    fn fun(&mut self) {
        println!("fun");
    }
}

переводится как

struct OldSomething {
    void fun() { print("fun");}
}

Раст

struct Decorator<'a>(&'a mut OldSomething);

impl Decorator<'_> {
    fn fun1(&mut self) {
        self.0.fun();
        println!("fun1");
    }
    
    fn fun2(&self) {
        println!("fun2");
    }
}

переводится как

struct Decorator {
  OldSomething _ref;

  Decorator(OldSomething &fref):_ref(fref){}

  void fun1() {
     _ref.fun();
     print("fun1");
  }
    
   void fun2() {
      print("fun2");
   }
}

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

fn main() {
    let mut smth = OldSomething;
    Decorator(&mut smth).fun1(); 
   
    let mut decor = Decorator(&mut smth); 
    decor.fun1();
    decor.fun2();
}

переводится как

fn main() {
    OldSomething smth;
    Decorator(smth).fun1(); 
   
    Decorator decor(smth); 
    decor.fun1();
    decor.fun2();
}

итак.. с какой стати в русте «лучше»? в русте кстати две чудесатые конструкции

struct Decorator<'a>(&'a mut OldSomething);
...
self.0.fun();

такого бреда в плюсах нет… это похоже на введение анонимного поля в структуру декоратор, а потом обращение к нему по «индексу». так?

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

alysnix ★★★
()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)