LINUX.ORG.RU

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

Нет у нас наследования

Это действительно может быть преимуществом, когда присутствует автовывод типов (обычно через HM). Собственно, есть расширения HM с поддержкой подтипов [1], но там вроде как есть свои косяки, и потому оно не используется. Разработчики Rust выбрали HM, правда, не для всего кода, но такая возможность потенциально присутствует.

[1] http://www21.in.tum.de/~nipkow/pubs/aplas11.pdf

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

Лалка. А ничего, что через трейты без проблем реализуется мультидиспетчеризация и даже диспетчеризация по возвращаемому значению? Рядом с этим перегрузка функций просто унылая недоделка.

Знатно у тебя забомбило. Ты мне еще пример про две жалкие функции не показал, а уже разошелся про «без проблем реализуется». На словах то оно конечно без проблем, а на деле - только простыни из кода и костыли.

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

Шаблон там исключительно из-за того, что Rc сам параметризован по типу.

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

И поймешь что как и где.

struct A;
trait Param<T> { fn method(arg: T); }
impl<'a> Param<&'a u8> for A { fn method(arg: &u8) { println!("u8"); } }
impl Param<i32> for A { fn method(arg: i32) { println!("i32"); } }

Можно реализовать Fn, но тогда unstable. Да, многословно. Но просто в ржавчине не принята перегрузка. Да, нет = 0, таким образом его не сделать (можно другим трейтом).

Но, заметь, это реализуемо, хотя и не принято.

А теперь давай ты:

int A();
float A();

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

использовалось все это, конечно, через интерфейсы, но это тоже классика

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

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

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

А в rust оно реализовано с помощью святага духа, ога, или ты не считаешь реализацию в rust - функциями?

[code=cpp]

struct A; trait Param<T> { fn method(arg: T); } impl<'a> Param<&'a u8> for A { fn method(arg: &u8) { println!(«u8»); } } impl Param<i32> for A { fn method(arg: i32) { println!(«i32»); } }

Кроме того, что выглядит у%но, это еще и не полный аналог. Для полного не хватает макросов ^_^.

А теперь давай ты:

Хоть это и не имеет никакого практического смысла, но если хочется:

struct A {
   operator int() { return 0; }
   operator float() { return 1f; }
};
anonymous
()
Ответ на: комментарий от loyd

Ну давай, покажи теперь ты мне хоть какой-нибудь код для моих жалких двух функций =)

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

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

Кроме того, что выглядит у%но, это еще и не полный аналог. Для полного не хватает макросов ^_^.

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

Хоть это и не имеет никакого практического смысла,

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

но если хочется

Да, круто.

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

Подход с struct уже не подойдёт?

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

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

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

https://github.com/Gabriel439/post-rfc/blob/master/sotu.md#systems--embedded-...

Haskell fares really poorly in this area because:

The language is garbage collected, so there are no latency guarantees

Executable sizes are large

Memory usage is difficult to constrain (thanks to space leaks)

Haskell has a large and unavoidable runtime, which means you cannot easily embed Haskell within larger programs

You can't easily predict what machine code that Haskell code will compile to

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

Это, конечно, так. Только тред всё равно закончится тем, что железячники уйдут программировать контриллеры на Си. А хипстеры уйдут есть мамкин борщ, а потом (спойлер) тоже программировать контроллеры на Си, лол.

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

тред всё равно закончится тем

...что все пойдут спать. Но жизнь не заканчивается с этим тредом.

tailgunner ★★★★★
()

Нафига тебе в 2015-ом году AVR/Microchip? ARM дешевле, мощнее и под него больше всевозможных инструментов. Ну реально, назови хоть одну рациональную причину.

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

А смыслов два: 1) Си - убогое говно 2) Rust - убогая игрушка.

//fixed

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

Иначе меня повесят.

Максимум уволят.

конструкторы, раньше, были в комплекте с испытателями.
Т.е. максимум, это - на неопознанные фрагменты и кровавую морось =)

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

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

Раньше - это когда, 100 и больше лет назад? К тому времени, как появились программисты, конструктор и испытатель уже много лет были разными профессиями.

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

Что-то логику не уловил. Ржавчина это замена крестам, о какой «поддерживать» идёт речь? Если Вам надо поддерживать кучу дерьма на крестах, то нефиг сюда ржавого тянуть, вот и всё.

Успехов в продвижении ржавчины в массы. Кресты, для прихода в массы, даже синтаксис из С позаимствовали, не говоря уже о «Если Вам надо поддерживать кучу дерьма».

Это не замена си, ибо он отлично с ним уживается.

Нахрена тогда плодить энтропию? Разбазаривать программерские ресурсы, чтобы одно и тоже делать два раза?

так что во всяких servo имитируют наследование

Т.е. ежики плакали, кололись, но продолжали жрать кактус?

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

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

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

... эмбеддинг структур мало какие проблемы решает.

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

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

Можно имитировать наследование ... через реализацию Deref.

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

А вот от fow.is_tile_visible(pos) даже в ООП языках с множественным наследованием не избавился бы, ибо закон Деметры

Не понял мысль, как оно Закону Деметры противоречит? Я же просто сахар для делегации хочу, что бы руками не писать. Можно для слоупоков более развернуто? )

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

Я просто мысль сильно урезал. Имелось в виду, что логически State не наследует Fow, поэтому делегирование должно остатья в любом случае. Сама же обёртка is_tile_visible никуда не денеться тоже, ибо напрямую делать state.fow.is_tile_visible некультурно (LoD). Как-то так.

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

Т.е. ежики плакали, кололись, но продолжали жрать кактус?

Имитируют наследование для классовых по своей природе вещей (DOM), в чём проблема? А так да, жрут кактус.

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

были разными профессиями

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

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

Имитируют наследование для классовых по своей природе вещей (DOM), в чём проблема?

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

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

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

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

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

Подойдет. Просто A будет типом, конструктор которого принимает int. А дальше все как в предыдущем примере.

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

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

Вопрос в том, много ли существует ситуаций, где наследование удобнее композиции. AFAIK, в Servo нашлась одна - DOM, да и то потому, что DOM был разработан довольно давно в ОО-стиле.

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

Вопрос в том, много ли существует ситуаций, где наследование удобнее композиции

Зависит от предметной области. А так же от того, насколько часто тебе удобно использовать «открыт-закрыт» в своих модулях. На моей практике такое случается довольно часто. Кроме того, на ФП большие объемы кода превращаются в менее читаемую шляпу. ОО-декомпозиция для человека, как правило, понятнее. Я понимаю, что это вкусовщина, но дело в том, что сейчас очень большое число успешных ОО-проектов. И мне кажется, что отрицание ООП должно быть доказано, а не просто постулироваться.

Я еще могу понять, что исключения тяжело сделать эффективно. Но ООП-то чем не угодило?

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

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

А можешь сформулировать, чем трейты и структуры Rust - не ООП? Если вспоминать «святую троицу», то в Rust нет только наследования данных.

Я еще могу понять, что исключения тяжело сделать эффективно. Но ООП-то чем не угодило?

Не ООП, а наследование :) Я думаю, не сильно нужно было. Но, в общем, никто не против добавления одиночного наследования - может, будет в Rust 2.0

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

Проблема в том, что из-за тараканов в голове они отказываются от ООП

И всё-таки они отказываются не от ООП, а от классового ООП.

в минимальном виде легко реализуется в языке уровня rust

Выше уже приводили аргумент, что наследование на уровне языка не реализованно из-за проблем с выводом по HM. Ну и дополнительно возникают вопросы касательно ковариации и контравариации: Rust же позиционируется как ЯП с развитой системой типов и ограничений на эти типы. Поэтому довольно активно обсуждаются всякие fat objects, эмбеддинг и т.д.

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

И всё-таки они отказываются не от ООП, а от классового ООП.

А, ну тогда в С тоже ООП во все поля:

~$ cat ./test.c
#include <stdio.h>
#include <stdlib.h>

#define class typedef struct
#define fn(...) ({ void __fn__() { __VA_ARGS__; } __fn__; });
#define new( c ) ({ c* r = malloc( sizeof( c ) ); c ## _init( r ); r; })


class {
    int v;
    void (*foo)();
}
base;

void base_init( base* this ) { 
    this->v   = 123; 
    this->foo = fn( puts("base::foo") ); 
}

void foo( base* this ) { this->foo(); }


class {
    base super;
}
derived;

void derived_init( derived* d ) { 
    base_init( d ); 
    d->super.foo = fn( puts("derived::foo") ); 
}


int main() {
    derived* d = new( derived );
    foo( d );
    
    base* b = d;
    printf( "%d\n", b->v );
    
    free( d );
    return 0;
}
~$ gcc ./test.c
~$ ./a.out 
derived::foo
123
anonymous
()
Ответ на: комментарий от tailgunner

А почему у тебя метод foo статический?

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

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

А почему у тебя метод foo статический?

Вообще-то он виртуальный

В него не передается this.

this->foo()

Крутое ООП у вас в Си, да.

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

В него не передается this.

Так это вообще другой вопрос, а не статический/виртуальный. И проблемы тут никакой нет.

#include <stdio.h>
#include <stdlib.h>

#define class( c ) struct c; typedef struct c c; struct c
#define method(c, ...) ({ void __fn__( c* this ) { __VA_ARGS__; } __fn__; });
#define new( c ) ({ c* r = malloc( sizeof( c ) ); c ## _init( r ); r; })


class( base ) {
    int v;
    void (*foo)(base*);
};

void base_init( base* this ) { 
    this->v   = 123; 
    this->foo = method( base, printf( "%d\n", this->v ) ); 
}

void foo( base* this ) { this->foo( this ); }


class( derived ) {
    base super;
};

void derived_init( derived* this ) { 
    base_init( this ); 
    this->super.foo = method( base, printf("%d\n", this->v * 2 ) ); 
}


int main() {
    derived* d = new( derived );
    foo( d );
    
    return 0;
}

Крутое ООП у вас в Си, да.

Так и я о том - что в rust и С его нет. Если ты вдруг не понял очевидного сарказма.

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

В него не передается this.

Так это вообще другой вопрос, а не статический/виртуальный

Вообще-то «не передается this» - это определение статического метода.

Так и я о том - что в rust и С его нет

В Rust есть поддержка наследования интерфейсов, а в Си нет ничего подобного, если ты не знаешь очевидного факта (но ты знаешь, наверное - судя по тому, что не попытался расширить набор методов в derived). Так что в Rust кое-какая объектная ориентированность есть, а в Си нет никакой.

Но накостылить какое-нибудь говно и назвать его «ООП» можно в любом языке с указателями на функции, это да.

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

Вообще-то «не передается this» - это определение статического метода.

Это твои фантазии, а на самом деле:

«In object-oriented programming, a virtual function or virtual method is a function or method whose behavior can be overridden within an inheriting class by a function with the same signature.

В Rust есть поддержка наследования интерфейсов, а в Си нет ничего подобного, если ты не знаешь очевидного факта (но ты знаешь, наверное - судя по тому, что не попытался расширить набор методов в derived). Так что в Rust кое-какая объектная ориентированность есть, а в Си нет никакой.

Тебя оторвало от реальности, никакой проблемы расширить набор методов в derived нет. А вся „объектная ориентированность“ в rust на уровне проверки static_cast в С++, который не даст скастовать несвязанные структуры, и хотя в С и такого нет, но работать реализации это не мешает.

Но накостылить какое-нибудь говно и назвать его «ООП» можно в любом языке с указателями на функции, это да.

Ну так в rust тоже самое говно, только в профиль.

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

Ну реально, назови хоть одну рациональную причину.

Например, софт пилится как замена штатных прошивок в готовых девайсах.

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

Вообще-то «не передается this» - это определение статического метода.

Это твои фантазии

Это терминология Си++.

Тебя оторвало от реальности

В реальности ООП-костыли Си++ гораздо сложнее твоего нерабочего недокостыля, не пригодного даже для PoC.

никакой проблемы расширить набор методов в derived нет

Расширить - нет. Использовать - начинается говно.

А вся „объектная ориентированность“ в rust на уровне проверки static_cast в С++

Т.е про наследование трейтов ты не знаешь и знать не хочешь. Ну окей.

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

Это терминология Си++.

Значит ты не знаешь С++. В С++ статический метод не может быть переопределен, от слова «никак».

В реальности ООП-костыли Си++ гораздо сложнее твоего нерабочего недокостыля, не пригодного даже для PoC.

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

Расширить - нет. Использовать - начинается говно.

Авторы GObject смотрят на тебя грустно и с неудомением (впрочем они всегда так смотрят).

Т.е про наследование трейтов ты не знаешь и знать не хочешь. Ну окей.

Давай пример кода для конкретики.

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

Прежде чем спорить - матчасть поучи. Это касается и Си++, и Rust.

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

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