![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Что вы думаете о ковариантности и контравариантности?
Они от лукаваго, нужны только теоретикам, не существуют в реальной жизни, не нужны в продакшене, муть какая-то, вроде симфоний, балета и абстрактного искусства, или чо?
Они от лукаваго, нужны только теоретикам, не существуют в реальной жизни, не нужны в продакшене, муть какая-то, вроде симфоний, балета и абстрактного искусства, или чо?
no subject
Date: 2013-09-05 04:29 am (UTC)no subject
Date: 2013-09-05 11:12 am (UTC)no subject
Date: 2013-09-05 04:36 am (UTC)+'a
и-'a
. Как дети малые, чесслово.я таких слов не знаю
Date: 2013-09-05 05:26 am (UTC)Re: я таких слов не знаю
Date: 2013-09-05 02:03 pm (UTC)Re: я таких слов не знаю
Date: 2013-09-05 09:02 pm (UTC)Re: я таких слов не знаю
Date: 2013-09-06 06:00 am (UTC)Re: я таких слов не знаю
Date: 2013-09-06 11:14 am (UTC)no subject
Date: 2013-09-05 06:29 am (UTC)уже не скомпилируется, хотя вроде все логично выглядит. Приходится либо сырые указатели возвращать, либо отдельные функции заводить в потомке. При этом приводимость и умных указателей, и итераторов через конструктор от другого типа есть.
no subject
Date: 2013-09-05 07:48 pm (UTC)template
template <typename T,typename C> class AbstractNode {
public:
typedef C children;
virtual T *parent() = 0;
virtual children begin() = 0;
virtual children end() = 0;
};
class MyNode : public AbstractNode<MyNode,vector<MyNode*>::iterator> {
private:
MyNode *_parent;
vector<MyNode*> _children;
public:
virtual MyNode *parent() { return _parent; }
children begin() { return _children.begin(); }
children end() { return _children.end(); }
};
естественно, реализацию итератора можно варьировать на свой вкус. я просто влепила примитив, чтобы показать идею.
no subject
Date: 2013-09-05 08:00 pm (UTC)no subject
Date: 2013-09-05 08:27 pm (UTC)но на практике это не нужно. с детства пишу на С и С++, делала гигантские проекты федерального уровня. но вот наследование и всякие такие извраты практически не пригождаются. это так, для институтов.
no subject
Date: 2013-09-05 08:49 pm (UTC)no subject
Date: 2013-09-05 09:36 am (UTC)no subject
Date: 2013-09-05 01:01 pm (UTC)А вообще, конечно, нужны.
no subject
Date: 2013-09-05 02:13 pm (UTC)а над коллекцией объектов
no subject
Date: 2013-09-05 06:08 pm (UTC)no subject
Date: 2013-09-05 08:06 pm (UTC)жабу я когда-то давно смотрела. не понравилось: слишком мало свободы, слишком много информации, которую надо держать в голове.
no subject
Date: 2013-09-11 10:58 am (UTC)no subject
Date: 2013-09-11 12:23 pm (UTC)а ошибки - они не в языке, они в программистах :) да,в С нет защиты от дурака. предполагается, что дурака не пустят писать ответственный код.
и, кстати, нет ничего плохого в ассемблерах. иногда особо важные куски кода нужно написать на ассемблере. или бывают ошибки в компиляторах и надо не только уметь понять, где в скомпилированном коде ошибка, но и исправить её.
no subject
Date: 2013-09-11 12:46 pm (UTC)Масштабирование же. Для обработки статыщ запросов в секунду можно взять одну супермашину или стотыщ говномашин. Один чорт затык будет не в вашем коде, а в DBMS.
> да и под микроконироллеры пишут на С
Под микроконтроллеры - да ради бога, там не то количество кода, чтобы переживать из-за [не]выразительности средств.
> в С нет защиты от дурака. предполагается, что дурака не пустят писать ответственный код
А между тем регулярно пускают, судя по поведению иных драйверов. Да и дело не том, дурак пишет или нет. От ошибок никто не застрахован.
> нет ничего плохого в ассемблерах
Так-таки и "ничего"? Даже на солнце бывают пятна.
> иногда особо важные куски кода нужно написать на ассемблере
пить можно всем! знать нужно только когда и где, и с кем, и сколько
Лучше однако, чтобы это были очень небольшие куски и достаточно хорошо изолированные.
no subject
Date: 2013-09-11 01:24 pm (UTC)что касается драйверов и ошибок - в основном, это косяки непонимания свойств новых ядер систем. железо само по себе - это не игрушкечки с софтом. там очень большая специфика и сложность отладки. но надо сказать, что некоторые косяки в принципе неразрешимы. идеологию вендозного ядра, например, придумывали люди, нихрена не соображающие в контроллерах и шинах - поэтому получилось, что иногда железо в принципе не может поддерживать эту систему. при том виндузятники стараются как можно сильнее ограничить информацию по ядру. очень мало литературы на эту тему, а на сайте у них чёрт ногу сломит. а это, естественно, приводит к ошибкам. при переходе на 7-ку пошёл бум ошибок с дровами и это были не ошибки программирования. это были ошибки, связанные с несовместимостью железа. ну и плюс "лицензирование" дров под венду, ага - ещё одна палка в колесо разработчикам.
в этом плане гораздо проще писать дрова под линь. там всё открыто и понятно, отлаживаться легче. например, под линём я находила ошибки и писала разработчикам. и они сразу вносили исправления в код. или добавляла поддержку новых устройств, которые имели схожий интерфейс. это делается быстро и без проблем.
no subject
Date: 2013-09-05 07:58 pm (UTC)no subject
Date: 2013-09-05 09:38 pm (UTC)Я думаю, с *вариантностью не сталкиваются те, кто полиморфных функций не писывали.
Простейший пример. Читаем хип дамп. Указатели могут быть либо все 32-битные, либо все 64-битные. Ваши варианты решения на Си? Может, я тупой, но здесь полиморфизм налицо. Цепляем экзистенциональный квантификатор и пишем, как буд-то у нас один тип указателей. Теперь пишем функции, работающие с хип дампом. Опять полиморфизм. Результаты *вариантны размеру указателей.
Ещё пример? ок. Вот мап-редюс. Он не умеет параллелизовать деревья. Но умеет параллелизовать свёртку любого моноида. Но тут же сплошной функтор и монада. А вы на каждый пук свой параллелизм пишете?
А о посете событий вы в Си каким образом рассуждаете? Или у вас всегда один толстый лок на всё? Но это уже не о *вариантности как таковой, а что "си - это всё"
no subject
Date: 2013-09-05 09:43 pm (UTC)no subject
Date: 2013-09-05 09:55 pm (UTC)про массив понятно, а дальше? Хип дамп - он снят на одной машине, а смотрим на другой. Как вы собрались привязываться к размеру указателя в системе? Найти цепочку от GC Root до объектов, удовлетворяющих предикату, в этом массиве байт. По идее вы должны объяснить один простой вопрос:
а. вы везде будете делать проверку "у нас 32 или 64 бита указатель?", когда указатель из хипа прочитать нужно?
б. вы будете по две функции на каждый размер делать?
в. всё-таки напишете полиморфную функцию вида (forall a. IdSize a => Heap a -> ResultSet (Value a)
no subject
Date: 2013-09-05 10:20 pm (UTC)я не буду делать функции. я сделаю ptr+=size. size - известен.
параллелизм осуществляется системой, если программист явно не задал использование ядра потоком. чем прямее метод - тем он быстрее. и локов в программе могут быть тысячи. кто мешает-то? "большой и жирный" - это ваши фантазии.
no subject
Date: 2013-09-05 10:24 pm (UTC)size известен. Далее, вы как будете (int32)(ptr+size) и (int64)(ptr+size) в зависимости от size?
"параллелизм осуществляется системой"
я ж и говорю, параллельная вселенная какая-то.
no subject
Date: 2013-09-05 10:28 pm (UTC)охтытетить, какой студень упёртый! size один раз инициализируется, при старте. и всё. можете в регистровую переменную его засунуть (впрочем, компилятор и так это сделает, если в этом будет необходимость при частых обращениях). и не надо никаких проверок. адресация в дампе не меняется, от начала до его конца.
no subject
Date: 2013-09-05 10:30 pm (UTC)no subject
Date: 2013-09-05 10:32 pm (UTC)no subject
Date: 2013-09-05 10:36 pm (UTC)вы в какую переменную его засунете - в int32 или int64? вы же где-то объявите переменную, которая с этим значением что-то сделает - скажем, поищет что-нибудь в таблице.
no subject
Date: 2013-09-05 10:46 pm (UTC)no subject
Date: 2013-09-06 07:10 am (UTC)no subject
Date: 2013-09-05 10:33 pm (UTC):)
no subject
Date: 2013-09-05 10:35 pm (UTC)no subject
Date: 2013-09-05 10:40 pm (UTC)no subject
Date: 2013-09-05 11:08 pm (UTC)масштаб задачи был - на всю страну. сотни тысяч серверов под разными осями должны были работать с софтиной. причём быстро и без сбоев.
так что с масштабами у меня всё в порядке. я ещё и кроссплатформой много занимаюсь.
я все навороты С++, вплоть до С++11 и его реализации на разных копиляторах, знаю лучше любого студента и даже преподавателя. но! я понимаю, что этим лучше не злоупотреблять. лучше не усложнять вещи там, где этого не требуется.
да и, пожалуй, я с трудом могу представить себе задачу, где бы потребовалась перегрузка и виртуальность и она была бы оправдана. это какие-то слишком абстрактные задачи, с которыми на практике я лично не сталкиваюсь.
no subject
Date: 2013-09-06 12:15 am (UTC)no subject
Date: 2013-09-06 12:20 am (UTC)у Сбера - платежи, у таможни - свои документы. просто эти системы одна компания делала. там был целый комплекс софтин для тех и для других.
no subject
Date: 2013-09-06 07:26 am (UTC)123К запросов в секунду, время отклика 1.116 мс, нагрузка 24 ядер процессора 67%. Это значит, что мы используем 0.67*24=16.08 секунд процессорного времени в каждую секунду. Стало быть, на каждый запрос уходит ровно 16.08/123000=130.7 микросекунд процессорного времени с учётом Garbage Collection и прочего оверхеда. Если это всё переписать на волшебный язык Си настолько чудесным образом, что 130 микросекунд превратится в 0 (ноль), у меня время отклика изменится всего на 11.7%. Но ведь процессорное время не будет нулём.
Ок, напишете так, что будет работать в целых два раза быстрее. Это всего 5% разницы во времени отклика (соответственно и пропускная способность для фиксированного количества пользователей). И ради этого мучиться с pointer arithmetic и зажимать себя в рамки Сишного менталитета?
Тем же токеном можно эту систему переписать на скалу и разница в производительности будет доли процентов. Зачем тогда себя мучить недоделанной системой типов?
no subject
Date: 2013-09-05 10:24 pm (UTC)no subject
Date: 2013-09-05 11:05 pm (UTC)Вот такая суровая сишная ковариантность :)
no subject
Date: 2013-09-05 11:15 pm (UTC)да и никакая она не суровая, на самом деле. куда там до суровости! примитивные операции обработки данных.
no subject
Date: 2013-09-05 11:39 pm (UTC)FILE* f = fopen("dump.txt", "rb");
size_t size = items_in_dump * (item_bits>>3);
void* ptr = malloc(size);
fread(ptr, 1, size, f);
то может очень неудобно получиться, если CHAR_BIT != 8.
Потому что у нормальных людей байты - это байты, а у сишников байты - это черт знает что. Я лично работал с компилятором, где CHAR_BIT было равно 32. Что-то на SunOS, если я не ошибаюсь. Зато очень быстро :)
no subject
Date: 2013-09-06 07:33 am (UTC)no subject
Date: 2013-09-05 11:02 pm (UTC)no subject
Date: 2013-09-06 07:03 am (UTC)В жизни - от задачи зависит. Если сталкиваешься вообще с этим, то уже точно это некий универсальный код. Скажем, вот недавно нужно было расширить и сделать более удобным использование GWT DataGrid (ну то есть обычная табличка данных с перелистыванием по страницам в вебе написанная на Джаве). Задача абстрактная, дженерики везде, а дальше там уже недалеко и до extends Entity> которая как бы подразумевает ковариантность в море инвариантности... Ну и че - код универсальный, значит сдавать каждой группе, которой придется пользоваться, сразу с заточенным на них примером ("А вот так можно описать базовый и вот это надо доимплементировать для каждого из ваших специфических гридов")
Так я к чему. На примере грида - я не придумал красивого решения (это не значит, то его нет, конечно). Сделал инвариантным. Одни удобнее контраварианто делать, другим - коварианто. Зависит сильно от модели данных и решаемой задачи.