Pull to refresh
4
0

Пользователь

Send message
А то, что покдачивается весь Электрон, ну с другой стороны и всякие NET Framework-и тоже подкачиваются.

  1. Необязательно. .Net Framework предустанавливается в ОС начиная с WindowsXP SP1. Если, например, в минимальных требованиях Windows 7, можно использовать .NET Framework 3.5.1. Приложения получаются очень компактные (например, окно с надписью Hello world на WPF — 4 кб)
  2. Все приложения .net разделяют общий фреймворк, а каждое Electron приложение включает в себя свой собственный инстанс хромиума. Отсюда разный размер и потребление памяти.
  3. Вообще сравнивать эти 2 платформы нечестно, т.к. .net framework работает только под windows (а .net core не имеет UI библиотек в составе). Кросплатформенный фреймворк всегда тяжелее нативного
Вы предлагаете реализовывать весь IDictionary?

Пардон, я имел ввиду это


interface DictAlias : IDictionary<IMyStupidType, IMyStupidType2> { }

Конечно ограничения есть, но


В общем всё, что связано с рефлекшном работать не будет

это сильное заявление. Вместо


if(typeof(obj).GetGenericDefinition() == typeof(Dictionary<>))

можно


if(obj is IDictionary<int, int>)

Можно юзать Type.IsAssignableFrom и т.д. ну вы поняли.
Если вы делаете "жесткую" проверку типа, на то должны быть причины.


алиасить sealed-типы как предлагаете?

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


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

Да уж, не удобно, но можно и не делать:


delegate void A();
delegate void B();

class Test
{
    public void Run(A a) => a();
}

B b = () => Console.WriteLine("qqq");

Test t = new Test();
t.Run(b);  // Error: Cannot convert from B to A
t.Run(b.Invoke); // Works :)
Серьёзно, в языке, для которого весьма нередок код в стиле IDictionnary<IMyStupidType, IMyStupidType2> Foo(Func<IMySupidType, int, bool, string> reallyStrangeCallback не сделать норм алиасы типов — это оооочень странное решение.

  1. class DictAlias: IDictionnary<IMyStupidType, IMyStupidType2> {}
  2. delegate IMySupidType FuncAlias(int, bool, string);
  3. Совмещаем 1 и 2: DictAlias Foo(FuncAlias reallyStrangeCallback)

Чем ему это не угодило то?

Разве ООП запрещает иммутабельные структуры данных, чистые функции, функции как first class citizens?

Не запрещает, но и не запрещает не использовать их тоже


Разве ФП запрещает абстракцию, инкапсуляцию, наследование и виртуальный полиморфизм?

Не запрещают, просто не поддерживают в удобном виде.
Чувствуете разницу?
Как я уже написал, есть мультипарадигмальне ЯП, где можно выбрать необходимый "арсенал" возможностей из ФП и ООП по ситуации для каждого компонента системы и они не будут противоречить друг другу, как вы и написали.


Кстати, там, где данные первичны, лучше подойдут базы данных :)

Может быть я не понял вас, но это неуместный сарказм. Вы же не будете писать сайт на SQL Sever, embdeded прошивку на Oracle, а 3Д игру на Postgres. Речь идет только лишь о ООП и ФП

логико-интуитивно собрал n языков, убрал штуки вида TypeScript, React, CSS и проч

Забыли убрать OpenGL

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

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


ФП не поможет с многопоточностью

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


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

Обычно, оно так и происходит. Только демоном называют отдельный процесс, а у нас это пул потоков. Но если мы хотим асинхронный сервер, то можно выстроить ф-ии в цепочки promis'ов, тут ФП тоже будет кстати.

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


Пример 1.
Мы пишем микросервис, без фреймворков. Для этого нам нужно:
1 открыть сокет на прослушивание и переадресовать клиента в обработчик
2 считать запрос в буфер
3 распарсить его
4 сделать ему валидацию
5 выполнить запрос к хранилищу
6 отправить ответ
Требования к сервису: многопоточность, надежность.


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


Пример 2.
Пишем десктопную корпоративную систему учета чего-то-там, пусть будет товара. В ТЗ у нас есть пользователи, права, виды товара, катерогии, группы, отчеты, загрузка/выгрузка данных, цены, скидки, контрагенты и еще 1000 других сущностей. Сущности могут вести себя по разному в зависимости от состояния. Все это хаотично взаимодействует с сервером, интерфейсом, файловой системой, БД, туда подключают сканер по COM порту…
Здесь предметная область сложная, запутанная, может не поддаваться строгой формализации, часто меняться. В этом основная сложность, и тут принципы ООП как раз могут помочь.

Лично для меня этот спор остался в далеком прошлом.
С приходом мультипарадигмальных ЯП, таких как Scala, C#, можно выбрать лучший подход по ситуации.
Но выбор не должен диктоваться личными предпочтениями. Там где есть большое и сложное состояние в памяти, там где данные первичны, лучше подойдет ООП, а там, где первичны алгоритмы, функции, многопоточность лучше выбрать ФП подход.
Именно этим и обусловлены рост и падение популярности разных подходов в разное время. В 90-е были популярные десктопные приложения. А это, в первую очередь, сложное состояние, которое декомпозировали, инкапсулировали, выстраивали предметную область из этих абстракций.
С приходом популярности веб приложений и HTTP протокола, приоритеты поменялись. Приложения стали выстраиваться как конвейер по обработки запросов, с внешним хранилищем состояния и популярность ФП стала расти.
Интересно к этом делу подошел ReactJS, где оба подхода совмещаются.

Я тоже не вижу рекламы после обновления

Замерил потребление потребление памяти у себя:
Skype 7: 145 Мб. Основной процесс 72 МБ + Skype Browser Host (2 шт.) 31 и 42 МБ
Skype 8: 281 Мб

Так принято поступать абсолютно во всех языках программирования, даже в C#

В C# есть кортежи:


(long sum, double avg) computeSumAndAverage(..) {...}
спасибо Microsoft за путаницу с IList в котором доступ по индексу в О(1) в документации не упомянут, хотя скорее всего реализован

скорее всего реализован?
IList — это интерфейс. Он не содержит реализации, поэтому в документации ничего не сказано про это. Так что не надо Microsoft зря ругать :)
Если мы хотим гарантий — надо использовать конкретную структуру данных.
Если хотим универсальности — через интерфейс.
Автор выбрал второй путь.

Допустим, у вас реализована эта модель.
Далее понадобилась новая функциональность: считать площадь в определенных единицах измерения на выбор.
Придется добавлять в методы IFiguresVisitor'а новый параметр, который будет абсолютно лишним для WriteToConsoleVisitor и DrawVisitor?

Интересно было бы послушать об опыте применения AOP техник (а-ля Fody + атрибуты) для "вшивания" проверок в код.

Я и не говорил, что это лучше. Немного короче. На вкус и цвет...

В C# 7 так же можно:


arg = arg ?? throw new ArgumentNullException(nameof(arg));
Запаситесь терпением

Видимо, не хватило терпения дописать.

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

Information

Rating
Does not participate
Location
Таганрог, Ростовская обл., Россия
Date of birth
Registered
Activity