Что мы вообще тут обсуждаем? На данный момент только известно, что ВС РФ решил оставить сделку между Лурье и Долиной в силе. Из этого вообще ничего не следует. Во всяком случае, пока. Всё будет зависеть от того, почему именно он так решил. А это пока ещё не огласили. В деле может быть тысяча нюансов, и на результат может повлиять какая-нибудь, совершенно левая херня.
Какого решения хотят, как мне кажется, большинство граждан? Если уважаемое государство горит желанием защитить бабушку, пострадавшую от действий преступников, то делать оно это должно, либо за счёт преступников, либо за свой собственный счёт, если не смогло найти преступника. Хотя, последнее тоже спорно, ведь это будет идти с наших налогов, но в этом хоть какой то смысл есть. Главное, никогда это не должно быть за счёт добросовестного гражданина, который просто оказался участником сделки, честно заплатил деньги за товар, и считай, тоже стал жертвой того же преступления.
Какое решение мы можем в итоге получить: сделка остаётся в силе, потому что продавец просила оставить ей пианино и стул. (кланяющийся пингвин.джепег)
По поводу "дыр" развёрнуто ответил на комментарий ниже.
Что же касается написания библиотеки, то пример как раз был расчитан на то, чтобы показать как это можно делать без всяких библиотек и наиболее прямолинейным способом. Это хорошо подходит для образовательных целей, и как мне показалось, дополнит статью. Если вам нужно немного таких классов, то подход вполне годится и в продакшен. А если нужно много, то можно вообще использовать F#.
Не совсем. Я имел в виду именно record. Но проблема действительно с конструкторами. Раз уж по этому поводу возникло недопонимание, попробую развёрнуто пояснить на примерах. Эх, придётся повоевать с редактором комментариев, чтобы это всё аккуратно оформить.
Буду использовать пример с BankAccount выше, как основу, но для краткости выкину из него методы ExhaustiveSwitch ибо они не имеют отношения к делу.
Для начала перепишем пример с использованием record вместо class.
Скрытый текст
public abstract record BankAccount(string Title, string BankName, string BankAddress)
{
private BankAccount() : this("", "", "") { }
public sealed record Iban(string Title, string BankName, string BankAddress, string Number) : BankAccount(Title,BankName,BankAddress);
public sealed record Swift(string Title, string BankName, string BankAddress, string Code) : BankAccount(Title,BankName,BankAddress);
}
Вроде бы, всё хорошо, конструктор по умолчанию успешно переопределён, а код стал сильно короче, даже без учёта выброшенных методов. Но есть проблемка. Объявление record через синтаксис вида record BankAccount(string Title, string BankName, string BankAddress) приводит к автоматическому созданию конструктора с тремя строковыми праметрами Title, BankName и BankAddress. Переопределить и скрыть его никак нельзя. А следовательно, кто угодно может теперь расширить BankAccount без каких либо препятствий. Например, вот так:
Просто берём и наследуемся, как будто так и надо
public record Mir(string Id) : BankAccount ("","","") { }
//Подразумевается, что запись Mir находится за пределами записи BankAccount
Конечно, мы можем переписать пример, не используя синтаксис с круглыми скобками, а объявив свойства вручную.
Объявляем свойства вручную. Лёгким движением, record превращается в "элегантный" class
public abstract record BankAccount
{
private BankAccount() { }
public required string Title { get; init; }
public required string BankName { get; init; }
public required string BankAddress { get; init; }
public sealed record Iban : BankAccount
{
public required string Number { get; init; }
}
public sealed record Swift : BankAccount
{
public required string Code { get; init; }
}
}
Но чем такой код будет отличаться от варианта с классом, кроме ключевого слова record? На самом деле, кое чем будет. Дело в том, что для записей автоматически генерируется конструктор копирования. И этот конструктор имеет уровень доступа protected. Иными словами, нет никаких проблем создать наследника от BankAccount, использовав этот автоматически сгенерированный конструктор.
Используем конструктор копирования, для обхода запрета на наследование
public record Mir : BankAccount
{
public required string Id { get; init; }
[System.Diagnostics.CodeAnalysis.SetsRequiredMembers]
public Mir() : base(new Iban { BankAddress = "", BankName = "", Number = "", Title = "" })
{ }
}
Единственный способ хоть как-то с этим побороться, это переопределить у BankAccount конструктор копирования вручную.
Переопределяем конструктор копирования
public abstract record BankAccount
{
private BankAccount() { }
[System.Diagnostics.CodeAnalysis.SetsRequiredMembers]
protected BankAccount(BankAccount bankAccount)
{
throw new Exception("Inheritance is not allowed");
}
public required string Title { get; init; }
public required string BankName { get; init; }
public required string BankAddress { get; init; }
public sealed record Iban : BankAccount
{
public required string Number { get; init; }
}
public sealed record Swift : BankAccount
{
public required string Code { get; init; }
}
}
Проблема в том, что изменить уровень доступа мы не можем, а можем только кинуть исключение. И если кто-то всё же попробует отнаследоваться от BankAccount, ошибка заметят лишь в рантайме, а вот во время компиляции никаких проблем не будет. Это уж не говоря о том, что вообще-то, recordу желательно иметь нормальный рабочий конструктор копирования. Не зря же компилятор нам его генерирует. Ну и не забываем о том, что от короткого синтаксиса уже пришлось отказаться, а в таком случае, зачем это всё? Класс работал лучше. Даже не так. Он работал идеально, если не считать некоторой многословности. А вот record - дырявый. Хотя, наверное не правильно ругать record. Сандали, вон, тоже дырявые. Но это не баг, и даже не совсем фича. Это их самая суть.
Резюмируя, можно сказать, что record просто не задуман по своему дизайну, чтобы мы игрались с его конструкторами, запрещали наследование, прятали там что-то и т.д. Это должен быть простой иммутабельный тип с value семантикой, по типу структуры, но только в отличие от структур, аллоцирующийся в куче. Идти против дизайна языка, воюя с тем, что нам автоматически генерирует компилятор - это всегда сомнительная идея. Если есть выбор, то лучше так не делать. Да и вообще, ради чего мы это пытаемся делать? Ради краткости синтаксиса? Серьёзно? Впрочем, даже её мы благополучно потеряли уже на втором примере.
Немного оффтопа
В какой-то степени, то же самое можно сказать и про всю идею с использованием DU в C#. Если прям очень нужно, язык нам это позволяет сделать штатными средствами и без сторонних библиотек. Именно это я и хотел показать своим первым комментарием. Несколько громоздко, что наверное отсекает значительную часть use case'ов, но тем не менее, когда надо - можно. И даже без каких-то оговорок. Код получается понятный, логика DU реализована как надо, никаких лишних зависимостей, да и бойлерплейт только на объявляющей стороне, а для пользовательского кода всё удобно. Что это значит на практике? Ну, лично для меня это как раз и значит, что я буду использовать этот подход ровно в тех случаях, когда он будет полезен несмотря на многословность синтаксиса. Что же до клепания DU на каждый чих, то если вам такое надо, то значит вы предпочитаете писать код в функциональном стиле, и на сегодня экосистема .net предоставляет вам аж целый язык F#. И если вы хотите писать в функциональном стиле, то и пишите на нём. Серьёзно, я считаю, что это наилучший вариант. Благо, среда исполнения одна. Можно совместить два языка, если не готовы отказаться от C# полностью. А C# это объектный язык, пусть и с примесями функциональщины. Ничего удивительного, что не все приёмы из ФП полноценно работают. Стоит ли заставлять их работать, подпирая код костылями? Я думаю, что нет. Уж точно не в продакшене. Так же как, например, не стоит пытаться писать в объектном стиле на языках не поддерживающих ООП. По мере развития C# расклад, конечно, может сильно поменяться. За последние годы и так дофига чего поменялось. В интересное время живём.
Запрещаем наследоваться от BankAccount, делая конструктор приватным. Record в этом плане дырявый, поэтому только класс. Наследники могут быть только вложенными классами и они оба sealed. Пишем свой метод для исчерпывающего свича (две перегрузки, с возвращаемым значением и без). На нативный свич полагаться нет смысла, т.к. он не поддерживает исчерпывающий свич (частично работает для enum, но и то через задницу). Поэтому, единственный верный вариант - написать свой метод. Дефолтная ветка с Exception добавлена для подавления предупреждений. По идее, она никогда не должна выполниться. Навероне можно умудриться в неё зайти с помощью рефлексии.
public abstract class BankAccount
{
private BankAccount()
{
Title = "";
BankName = "";
BankAddress = "";
}
public required string Title { get; init; }
public required string BankName { get; init; }
public required string BankAddress { get; init; }
public sealed class Iban : BankAccount
{
public required string Number { get; init; }
}
public sealed class Swift : BankAccount
{
public required string Code { get; init; }
}
public R ExhaustiveSwitch<R>(Func<Iban, R> ibanCase, Func<Swift, R> swiftCase)
{
return this switch
{
Iban iban => ibanCase(iban),
Swift swift => swiftCase(swift),
_ => throw new ArgumentOutOfRangeException("this", GetType().ToString(), "This should not happen. Are you using reflection?")
};
}
public void ExhaustiveSwitch(Action<Iban> ibanCase, Action<Swift> swiftCase)
{
switch(this)
{
case Iban iban: ibanCase(iban);
break;
case Swift swift: swiftCase(swift);
break;
default: throw new ArgumentOutOfRangeException("this", GetType().ToString(), "This should not happen. Are you using reflection?");
}
}
}
Никаких сторонних библиотек. Никакого шаманства с .editorconfig. Никаких неочевидных танцев с перегрузкой типов. Никакого Roslyn. Пользователь обязан указать лямбды (или методы) для обработки всех случаев, "забыть" ветку не выйдет. Расширить можно только внеся изменения в класс BankAccount, а следовательно, человек, вносящий изменения, обязан будет обновить методы ExhaustiveSwitch и ExhaustiveSwitch<R>. При расширении, старый пользовательский код сломается, до тех пор, пока не добавят обработку новых подклассов во все вызовы ExhaustiveSwitch. В общем, вроде бы все требования удовлетворены. Бойлерплейт конечно присутствует, особенно из-за невозможности использовать здесь record, но много ли таких алгебраических типов надо вам в системе? На мой взгляд, бойлерплейт здесь не критичен, именно по причине того, что таких типов надо не так уж и много. Но может это говорит привычка, а точнее отсутствие привычки такие типы использовать.
З.Ы. При необходимости, можно даже сделать такие перегрузки ExhaustiveSwitch, в которых какие-то обработчики будут требоваться строго, а другие будут необязательными параметрами. Если сделать перегрузку ExhaustiveSwitch, принимающую специальный класс с нужными делегатами, то можно вообще очень сложную логику накрутить. Ни один язык никогда из коробки такого не даст. Строго говоря, это уже будет и не алгебраический тип, а что-то по мотивам. Зато можно вручную контролировать, какие ветки обрабатывать обязательно, а какие нет.
Странная претензия. Если я даю ссылку на чужую статью, само собой это уже не может быть моя личная позиция, ведь автор статьи не я. А не делиться информацией вообще, это уже какой-то экстрим.
Вообще, я бы не назвал то что написано в той статье "позицией". Там просто изложены факты. Продвижением позиции это является только в том случае, если факты не соответствуют действительности. Именно на такой случай я и сделал свою оговорку в стиле "мопед не мой".
Да и свою позицию я тоже, как мне показалось, изложил. Я склонен верить, что ОПСОСы действительно просили об этой блокировке. А прокатила эта просьба потому, что и другие игроки увидели в этом выгоду. Иными словами, моя позиция не то чтобы противоречит фактам из статьи, скорее просто простирается чуть дальше. К этому могу ещё добавить, что моё отношение к происходящему - крайне негативное. Это так, на всякий случай. А то когда пытаешься спокойно проанализировать ситуацию, люди иногда путают спокойствие с одобрением.
перед суперкризисом для избежания бунтов.
Не проще интернет выключить на время суперкризиса? Тем более, что это всё равно придётся делать. Заблокировать звонки в двух мессенджерах - как-то слишком точечно получается. Почему не во всех? Зачем заранее? Чтобы люди успели найти альтернативы? Да и для координации действий будет достаточно и текста. Не говоря уж о том, что для коммуникации с большой толпой, звонки и вовсе не годятся. Скинуть текстовое сообщение в канал - гораздо лучше. Ну и различные способы обхода блокировок тоже никто не отменял. В общем, не выглядит это как мера против бунта. Тут только дёргать рубильник.
И поднимают все и всегда, а опсосы вдруг разучились?
Да они-то с радостью. Но нашлись и несогласные. Из той же статьи:
При этом сценарий кратного роста тарифов для абонентов не был поддержан антимонопольной службой РФ.
P.S. если что, я за что купил, за то продаю. Информация от Forbes, а не от меня, и даже не от Хабра. Лично я вижу и другие мотивы. Например, продвижение мессенджера Max. Ну и конечно, усиление гос контроля за коммуникациями. И на все эти беды с башкой нашёлся один ответ. В жизни ведь обычно так и бывает - решения рождаются на точках пересечения интересов нескольких крупных игроков. Во всяком случае, вероятность принятия таких решений сильно выше, по очевидным причинам.
С такой инициативой выступили операторы «большой четвёрки» в ходе стратегической сессии по развитию отрасли связи. На мероприятии операторы обозначили потребность в дополнительных доходах для поддержания существующей инфраструктуры.
Вот насчёт "читать код из аналогичного проекта" - вы переборщили.
Так я ж специально даже написал, что это не я придумал. Знал, что не поверят. Потому что сам бы не поверил.
Вот, например, цитата с сайта ReactOS:
Is ReactOS legal?
Yes. ReactOS is fully legal and adheres to the strongest standards of accountability, ie. it does not use any leaked version of Microsoft's code.
Windows source code is not publically available. ReactOS Developers (devs) do not and have not looked at any leaked Microsoft Windows™ source code. They can only use the publically available documentation that Microsoft publishes and that which exists is not comprehensive. As a result, ReactOS devs have to test Windows in detail to understand how every component of Microsoft Windows works. ReactOS inevitably intends to perform exactly the same as Windows but it WILL accomplish this differently due to having very different source code being programmed by a completely different team of developers. All code in ReactOS is released under the GNU GPL (General Public License) that allows external scrutiny.
Возможно, они тут пытаются перебдеть. С другой стороны, может в таких вещах и правда лучше перебдеть. Например, если вы мелкий разработчик, то сам факт иска от какой-нибудь корпорации может стать для вас фатальным. Чтобы судиться - ресурсы нужны. Ну и нервы, куда без них.
Отмечу, что с тем что суд, вообще-то, можно и выиграть, я не спорю. Но не все иски являются такой очевидной халтурой, что судье становится смешно. Впрочем, в суде, даже на смешной иск лучше отвечать серьёзно. А если ты сможешь показать, что у тебя всё прозрачно, и ты реально старался всё сделать правильно, то может именно за счёт этого суд и выиграешь.
Как обычно, в теме про ИИ, все обсуждают свои личные претензии к ИИ. Дело не в качестве кода. За качеством кода надо следить, не зависимо от использования ИИ. Дело не в безопасности и не в бэкдорах. Опять же, их и без ИИ можно затащить, а ИИ может быть одним из инструментов для их поиска, кстати. Между тем, в статье чётко сказано, что новые требования имеют юридическую причину:
Данный тег должен добавляться только человеком для юридически значимого подтверждения права на передачу кода под открытой лицензией.
ИИ, пока что, имеет спорные, не до конца устоявшиеся, отношения с авторским правом. Для проектов с копилефт лицензиями это настоящая красная тряпка. Поэтому, помечать код, сгенерированный ИИ, необходимо для прозрачности, и в самом крайнем случае, чтобы можно было этот код вычистить из проекта. Зачастую, ради юридической чистоты, разработчик свободного ПО не имеет права даже читать код из аналогичного проекта с проприетарной лицензией, чтобы потом к нему не могли предъявить претензии, что он идеи из проприетарного кода позаимствовал. Я знаю, что для многих это звучит как бред, но это не я придумал. Таков безумный мир авторского права. А на чём учился тот же Copilot? Вы не знаете. Где гарантия, что в обучающую выборку не попал код из какой-нибудь утечки, например? Потом что-то такое всплывёт, кто-нибудь кого-нибудь засудит, и пусть даже дело не будет иметь никакого отношения к Linux, а в результате код ядра окажется скомпрометированным, из-за того что использовался скомпрометированный ассистент. Оно нам надо? Оно нам не надо. Похоже, взвесив риски, руководители проекта решили пойти на компромисс, и разрешить использовать ИИ, при условии что сгенерированный код будет помечен. На самом деле, об этом и не только открытым проектам стоило бы думать, а вообще всем и каждому. С закрытым кодом, конечно, больше возможностей скрыть проблему, но это искушение, которому лучше не поддаваться. А то как кто-нибудь из сотрудников засвистит. Оно вам надо? Оно вам не надо.
Что же значит написанно 50% кода, в понимании обывателя и менеджера - ии сделал 50% работы, т.е. нужно в два раз меньше программистов.
Так в том и план. Сейчас идут массовые сокращения. Причины этих сокращений самые обычные: пузырь сдулся, надо резать расходы, чтобы отчёты лучше смотрелись, ну и т.д. Но насколько красивее это всё выглядит для инвесторов, когда им вливают в уши, что просто, благодаря ИИ, теперь нужно в два раза меньше программистов. Гораздо приятнее, чем "Спрос на наши продукты оказался в два раза ниже ожидаемого".
Вы сейчас описали мой опыт учёбы в универе. Однако, писать лабы да курсачи это не то же что работать. На работе не дают забыть старые проекты. Хочешь, а не дают. Эх. Где бы найти такую работу, чтобы написал и забыл? Была бы у меня такая работа, я может и не выгорел бы никогда.
разработал я её на языке программирования, который не знаю
Что по поддержке? Планируете и дальше на 100% использовать ИИ для внесния любых изменений? Или теперь изучаете этот язык? Или поддержка не планируется?
Претензия справедлива, и ваша попытка высмеять её, сути не меняет. Вы - проблема. На мой взгляд, вы здесь не нужны.
И я бы как обычно промолчал, не будь это ссылка на канал про вход в IT, с обещаниями историй успеха, в статье с предъявами против инфоцыган, засравших IT курсы. У меня от такого выскочила логическая ошибка, и я порвался. Можете промониторить все мои комментарии, вы там не найдёте жалоб на телеграм каналы. Ни одной. Кроме этой. Так что нет, это не я тут профессиональный патрульный. Это просто вы обнаглели уже настолько, прямо по Остаповски, что вас обычный, мимо проходящий гражданский отпатрулировать захотел.
Ты, это, ссылочку на свой телеграм убери из статьи. В идеале, ещё и из профиля удали. И вообще, сам канал лучше тоже грохнуть. Но для начала, хотя бы из статьи. Тогда поговориим. А пока ты для меня цыганёнышь. Не большой цыган, потому что ещё не на Бали. Но видно, что очень на это самое Бали рвёшься.
А если тебе кажется, что то что я написал, как-то грубовато, так это потому что ты и тебе подобные гниды телеграмщики ЗАСРАЛИ Хабр. За это вам не будет прощения. Ах да, владельцам Хабра тоже привет. Предали сообщество, и сидят, как будто так и надо.
И даже не знаю, было это кому-то нужно или просто сделали и оказалось что ерунда.
Браузер специально сделали неотъемлемой частью операционной системы, чтобы был аргумент в суде, мол ставим IE по умолчанию и не можем удалить его из системы, потому что без него система не работает.
Анализ ALICE показывает, что во время второго запуска БАК (2015-2018 гг.) в четырёх основных экспериментах было создано около 86 миллиардов ядер золота. В пересчёте на массу это соответствует всего 29 пикограммам (2,9 ×10^-11 г).
Что мы вообще тут обсуждаем? На данный момент только известно, что ВС РФ решил оставить сделку между Лурье и Долиной в силе. Из этого вообще ничего не следует. Во всяком случае, пока. Всё будет зависеть от того, почему именно он так решил. А это пока ещё не огласили. В деле может быть тысяча нюансов, и на результат может повлиять какая-нибудь, совершенно левая херня.
Какого решения хотят, как мне кажется, большинство граждан? Если уважаемое государство горит желанием защитить бабушку, пострадавшую от действий преступников, то делать оно это должно, либо за счёт преступников, либо за свой собственный счёт, если не смогло найти преступника. Хотя, последнее тоже спорно, ведь это будет идти с наших налогов, но в этом хоть какой то смысл есть. Главное, никогда это не должно быть за счёт добросовестного гражданина, который просто оказался участником сделки, честно заплатил деньги за товар, и считай, тоже стал жертвой того же преступления.
Какое решение мы можем в итоге получить: сделка остаётся в силе, потому что продавец просила оставить ей пианино и стул. (кланяющийся пингвин.джепег)
А когда мошенник "из ФСБ" бабушку разводит, это не уголовка что ли?
Научиться программировать самому? Да не, фигня какая-то...
По поводу "дыр" развёрнуто ответил на комментарий ниже.
Что же касается написания библиотеки, то пример как раз был расчитан на то, чтобы показать как это можно делать без всяких библиотек и наиболее прямолинейным способом. Это хорошо подходит для образовательных целей, и как мне показалось, дополнит статью. Если вам нужно немного таких классов, то подход вполне годится и в продакшен. А если нужно много, то можно вообще использовать F#.
Не совсем. Я имел в виду именно
record. Но проблема действительно с конструкторами. Раз уж по этому поводу возникло недопонимание, попробую развёрнуто пояснить на примерах. Эх, придётся повоевать с редактором комментариев, чтобы это всё аккуратно оформить.Буду использовать пример с
BankAccountвыше, как основу, но для краткости выкину из него методыExhaustiveSwitchибо они не имеют отношения к делу.Для начала перепишем пример с использованием
recordвместоclass.Скрытый текст
Вроде бы, всё хорошо, конструктор по умолчанию успешно переопределён, а код стал сильно короче, даже без учёта выброшенных методов. Но есть проблемка. Объявление record через синтаксис вида
record BankAccount(string Title, string BankName, string BankAddress)приводит к автоматическому созданию конструктора с тремя строковыми праметрамиTitle,BankNameиBankAddress. Переопределить и скрыть его никак нельзя. А следовательно, кто угодно может теперь расширитьBankAccountбез каких либо препятствий. Например, вот так:Просто берём и наследуемся, как будто так и надо
Конечно, мы можем переписать пример, не используя синтаксис с круглыми скобками, а объявив свойства вручную.
Объявляем свойства вручную. Лёгким движением, record превращается в "элегантный" class
Но чем такой код будет отличаться от варианта с классом, кроме ключевого слова
record? На самом деле, кое чем будет. Дело в том, что для записей автоматически генерируется конструктор копирования. И этот конструктор имеет уровень доступа protected. Иными словами, нет никаких проблем создать наследника от BankAccount, использовав этот автоматически сгенерированный конструктор.Используем конструктор копирования, для обхода запрета на наследование
Единственный способ хоть как-то с этим побороться, это переопределить у
BankAccountконструктор копирования вручную.Переопределяем конструктор копирования
Проблема в том, что изменить уровень доступа мы не можем, а можем только кинуть исключение. И если кто-то всё же попробует отнаследоваться от
BankAccount, ошибка заметят лишь в рантайме, а вот во время компиляции никаких проблем не будет. Это уж не говоря о том, что вообще-то,recordу желательно иметь нормальный рабочий конструктор копирования. Не зря же компилятор нам его генерирует. Ну и не забываем о том, что от короткого синтаксиса уже пришлось отказаться, а в таком случае, зачем это всё? Класс работал лучше. Даже не так. Он работал идеально, если не считать некоторой многословности. А вотrecord- дырявый. Хотя, наверное не правильно ругатьrecord. Сандали, вон, тоже дырявые. Но это не баг, и даже не совсем фича. Это их самая суть.Резюмируя, можно сказать, что record просто не задуман по своему дизайну, чтобы мы игрались с его конструкторами, запрещали наследование, прятали там что-то и т.д. Это должен быть простой иммутабельный тип с value семантикой, по типу структуры, но только в отличие от структур, аллоцирующийся в куче. Идти против дизайна языка, воюя с тем, что нам автоматически генерирует компилятор - это всегда сомнительная идея. Если есть выбор, то лучше так не делать. Да и вообще, ради чего мы это пытаемся делать? Ради краткости синтаксиса? Серьёзно? Впрочем, даже её мы благополучно потеряли уже на втором примере.
Немного оффтопа
В какой-то степени, то же самое можно сказать и про всю идею с использованием DU в C#. Если прям очень нужно, язык нам это позволяет сделать штатными средствами и без сторонних библиотек. Именно это я и хотел показать своим первым комментарием. Несколько громоздко, что наверное отсекает значительную часть use case'ов, но тем не менее, когда надо - можно. И даже без каких-то оговорок. Код получается понятный, логика DU реализована как надо, никаких лишних зависимостей, да и бойлерплейт только на объявляющей стороне, а для пользовательского кода всё удобно. Что это значит на практике? Ну, лично для меня это как раз и значит, что я буду использовать этот подход ровно в тех случаях, когда он будет полезен несмотря на многословность синтаксиса. Что же до клепания DU на каждый чих, то если вам такое надо, то значит вы предпочитаете писать код в функциональном стиле, и на сегодня экосистема .net предоставляет вам аж целый язык F#. И если вы хотите писать в функциональном стиле, то и пишите на нём. Серьёзно, я считаю, что это наилучший вариант. Благо, среда исполнения одна. Можно совместить два языка, если не готовы отказаться от C# полностью. А C# это объектный язык, пусть и с примесями функциональщины. Ничего удивительного, что не все приёмы из ФП полноценно работают. Стоит ли заставлять их работать, подпирая код костылями? Я думаю, что нет. Уж точно не в продакшене. Так же как, например, не стоит пытаться писать в объектном стиле на языках не поддерживающих ООП. По мере развития C# расклад, конечно, может сильно поменяться. За последние годы и так дофига чего поменялось. В интересное время живём.
Запрещаем наследоваться от BankAccount, делая конструктор приватным. Record в этом плане дырявый, поэтому только класс. Наследники могут быть только вложенными классами и они оба sealed. Пишем свой метод для исчерпывающего свича (две перегрузки, с возвращаемым значением и без). На нативный свич полагаться нет смысла, т.к. он не поддерживает исчерпывающий свич (частично работает для enum, но и то через задницу). Поэтому, единственный верный вариант - написать свой метод. Дефолтная ветка с Exception добавлена для подавления предупреждений. По идее, она никогда не должна выполниться. Навероне можно умудриться в неё зайти с помощью рефлексии.
Используем вот так:
Никаких сторонних библиотек. Никакого шаманства с .editorconfig. Никаких неочевидных танцев с перегрузкой типов. Никакого Roslyn. Пользователь обязан указать лямбды (или методы) для обработки всех случаев, "забыть" ветку не выйдет. Расширить можно только внеся изменения в класс BankAccount, а следовательно, человек, вносящий изменения, обязан будет обновить методы ExhaustiveSwitch и ExhaustiveSwitch<R>. При расширении, старый пользовательский код сломается, до тех пор, пока не добавят обработку новых подклассов во все вызовы ExhaustiveSwitch. В общем, вроде бы все требования удовлетворены. Бойлерплейт конечно присутствует, особенно из-за невозможности использовать здесь record, но много ли таких алгебраических типов надо вам в системе? На мой взгляд, бойлерплейт здесь не критичен, именно по причине того, что таких типов надо не так уж и много. Но может это говорит привычка, а точнее отсутствие привычки такие типы использовать.
З.Ы. При необходимости, можно даже сделать такие перегрузки ExhaustiveSwitch, в которых какие-то обработчики будут требоваться строго, а другие будут необязательными параметрами. Если сделать перегрузку ExhaustiveSwitch, принимающую специальный класс с нужными делегатами, то можно вообще очень сложную логику накрутить. Ни один язык никогда из коробки такого не даст. Строго говоря, это уже будет и не алгебраический тип, а что-то по мотивам. Зато можно вручную контролировать, какие ветки обрабатывать обязательно, а какие нет.
Если у менеджера есть время читать такие отчёты, значит он недостаточно загружен.
Странная претензия. Если я даю ссылку на чужую статью, само собой это уже не может быть моя личная позиция, ведь автор статьи не я. А не делиться информацией вообще, это уже какой-то экстрим.
Вообще, я бы не назвал то что написано в той статье "позицией". Там просто изложены факты. Продвижением позиции это является только в том случае, если факты не соответствуют действительности. Именно на такой случай я и сделал свою оговорку в стиле "мопед не мой".
Да и свою позицию я тоже, как мне показалось, изложил. Я склонен верить, что ОПСОСы действительно просили об этой блокировке. А прокатила эта просьба потому, что и другие игроки увидели в этом выгоду. Иными словами, моя позиция не то чтобы противоречит фактам из статьи, скорее просто простирается чуть дальше. К этому могу ещё добавить, что моё отношение к происходящему - крайне негативное. Это так, на всякий случай. А то когда пытаешься спокойно проанализировать ситуацию, люди иногда путают спокойствие с одобрением.
Не проще интернет выключить на время суперкризиса? Тем более, что это всё равно придётся делать. Заблокировать звонки в двух мессенджерах - как-то слишком точечно получается. Почему не во всех? Зачем заранее? Чтобы люди успели найти альтернативы? Да и для координации действий будет достаточно и текста. Не говоря уж о том, что для коммуникации с большой толпой, звонки и вовсе не годятся. Скинуть текстовое сообщение в канал - гораздо лучше. Ну и различные способы обхода блокировок тоже никто не отменял. В общем, не выглядит это как мера против бунта. Тут только дёргать рубильник.
Да они-то с радостью. Но нашлись и несогласные. Из той же статьи:
P.S. если что, я за что купил, за то продаю. Информация от Forbes, а не от меня, и даже не от Хабра. Лично я вижу и другие мотивы. Например, продвижение мессенджера Max. Ну и конечно, усиление гос контроля за коммуникациями. И на все эти беды с башкой нашёлся один ответ. В жизни ведь обычно так и бывает - решения рождаются на точках пересечения интересов нескольких крупных игроков. Во всяком случае, вероятность принятия таких решений сильно выше, по очевидным причинам.
Была же статья на Хабре, ещё за пару дней до блокировки. ОПСОСам понадобились дополнительные доходы.
Forbes: операторы связи РФ попросили регуляторов заблокировать голосовые вызовы в зарубежных мессенджерах
Так я ж специально даже написал, что это не я придумал. Знал, что не поверят. Потому что сам бы не поверил.
Вот, например, цитата с сайта ReactOS:
Source
Возможно, они тут пытаются перебдеть. С другой стороны, может в таких вещах и правда лучше перебдеть. Например, если вы мелкий разработчик, то сам факт иска от какой-нибудь корпорации может стать для вас фатальным. Чтобы судиться - ресурсы нужны. Ну и нервы, куда без них.
Отмечу, что с тем что суд, вообще-то, можно и выиграть, я не спорю. Но не все иски являются такой очевидной халтурой, что судье становится смешно. Впрочем, в суде, даже на смешной иск лучше отвечать серьёзно. А если ты сможешь показать, что у тебя всё прозрачно, и ты реально старался всё сделать правильно, то может именно за счёт этого суд и выиграешь.
Как обычно, в теме про ИИ, все обсуждают свои личные претензии к ИИ. Дело не в качестве кода. За качеством кода надо следить, не зависимо от использования ИИ. Дело не в безопасности и не в бэкдорах. Опять же, их и без ИИ можно затащить, а ИИ может быть одним из инструментов для их поиска, кстати. Между тем, в статье чётко сказано, что новые требования имеют юридическую причину:
ИИ, пока что, имеет спорные, не до конца устоявшиеся, отношения с авторским правом. Для проектов с копилефт лицензиями это настоящая красная тряпка. Поэтому, помечать код, сгенерированный ИИ, необходимо для прозрачности, и в самом крайнем случае, чтобы можно было этот код вычистить из проекта. Зачастую, ради юридической чистоты, разработчик свободного ПО не имеет права даже читать код из аналогичного проекта с проприетарной лицензией, чтобы потом к нему не могли предъявить претензии, что он идеи из проприетарного кода позаимствовал. Я знаю, что для многих это звучит как бред, но это не я придумал. Таков безумный мир авторского права. А на чём учился тот же Copilot? Вы не знаете. Где гарантия, что в обучающую выборку не попал код из какой-нибудь утечки, например? Потом что-то такое всплывёт, кто-нибудь кого-нибудь засудит, и пусть даже дело не будет иметь никакого отношения к Linux, а в результате код ядра окажется скомпрометированным, из-за того что использовался скомпрометированный ассистент. Оно нам надо? Оно нам не надо. Похоже, взвесив риски, руководители проекта решили пойти на компромисс, и разрешить использовать ИИ, при условии что сгенерированный код будет помечен. На самом деле, об этом и не только открытым проектам стоило бы думать, а вообще всем и каждому. С закрытым кодом, конечно, больше возможностей скрыть проблему, но это искушение, которому лучше не поддаваться. А то как кто-нибудь из сотрудников засвистит. Оно вам надо? Оно вам не надо.
Так в том и план. Сейчас идут массовые сокращения. Причины этих сокращений самые обычные: пузырь сдулся, надо резать расходы, чтобы отчёты лучше смотрелись, ну и т.д. Но насколько красивее это всё выглядит для инвесторов, когда им вливают в уши, что просто, благодаря ИИ, теперь нужно в два раза меньше программистов. Гораздо приятнее, чем "Спрос на наши продукты оказался в два раза ниже ожидаемого".
Вы сейчас описали мой опыт учёбы в универе. Однако, писать лабы да курсачи это не то же что работать. На работе не дают забыть старые проекты. Хочешь, а не дают. Эх. Где бы найти такую работу, чтобы написал и забыл? Была бы у меня такая работа, я может и не выгорел бы никогда.
Что по поддержке? Планируете и дальше на 100% использовать ИИ для внесния любых изменений? Или теперь изучаете этот язык? Или поддержка не планируется?
Претензия справедлива, и ваша попытка высмеять её, сути не меняет. Вы - проблема. На мой взгляд, вы здесь не нужны.
И я бы как обычно промолчал, не будь это ссылка на канал про вход в IT, с обещаниями историй успеха, в статье с предъявами против инфоцыган, засравших IT курсы. У меня от такого выскочила логическая ошибка, и я порвался. Можете промониторить все мои комментарии, вы там не найдёте жалоб на телеграм каналы. Ни одной. Кроме этой. Так что нет, это не я тут профессиональный патрульный. Это просто вы обнаглели уже настолько, прямо по Остаповски, что вас обычный, мимо проходящий гражданский отпатрулировать захотел.
Ты, это, ссылочку на свой телеграм убери из статьи. В идеале, ещё и из профиля удали. И вообще, сам канал лучше тоже грохнуть. Но для начала, хотя бы из статьи. Тогда поговориим. А пока ты для меня цыганёнышь. Не большой цыган, потому что ещё не на Бали. Но видно, что очень на это самое Бали рвёшься.
А если тебе кажется, что то что я написал, как-то грубовато, так это потому что ты и тебе подобные гниды телеграмщики ЗАСРАЛИ Хабр. За это вам не будет прощения. Ах да, владельцам Хабра тоже привет. Предали сообщество, и сидят, как будто так и надо.
Браузер специально сделали неотъемлемой частью операционной системы, чтобы был аргумент в суде, мол ставим IE по умолчанию и не можем удалить его из системы, потому что без него система не работает.
Нужно больше золота!
Судя по описанию, устройство просто прикладывается к шее. Почему вы называете это имплантацией? Имплантация подразумевает вживление внутрь организма.