Pull to refresh
207
1
Андрей @impwx

Программист

Send message

Один раз по работе прислали JSON в виде сообщения в Teams и оказалось, что при копировании в него попали "неправильные" пробелы. Пока выяснили причину, седых волос изрядно прибавилось

А что еще вы предлагаете проводить на обрывке кода в ~10 строчек?

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

Мне не нравится, что switch expression служит той же цели, но отличается от switch statement практически во всем: ключевое слово switch пишется после выражения а не до, вместо default используется _, вместо case - стрелка =>, и самое важное - не проваливается на следующий вариант при отсутствии break.

Вместо этого можно было все унифицировать:

  • Писать switch всегда перед проверяемым выражением. Разделять на switch expression и switch statement по тому, располагается ли оно внутри выражения или нет.

  • Разрешить X => Y в switch statement как синоним case X: Y; break;, по аналогии с expression body в свойствах и функциях

  • Разрешить _ как синоним default

  • Не делать case > 1, а использовать более общий case var x when x > 1

Самое досадное, что в Java это сделали как надо, а в C# не смогли.

С технической точки зрения все решаемо: поставьте минимальный langversion в проекте, настройте codestyle на свое усмотрение с помощью Stylecop, Resharper, Roslyn Analyzers - на здоровье. Останется только найти людей, которые согласятся в таких условиях работать

зачем надо было смешивать строго типизированный язык с Яваскриптом и чисто функциональными языками

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

Что не так с MyClass c = new MyClass()?

Да всё в порядке. Если визуальный шум вам не мешает, то пишите на здоровье. В стайлгайдах Microsoft принято в большинстве случаев указывать тип, если только он не очевиден по выражению справа, как у вас. Но многим людям это кажется избыточным, поэтому они используют `var`.

самый простой switch-case превратился в тьюнинг-полного монстра

Опять же, обычный switch-case остался как есть. Вам никто не запрещает писать так, как вы писали во времена 15 лет назад во времена .NET 2.0. Лично мне новый switch expression тоже не нравится, я считаю его избыточным и плохо вписывающимся в язык, поэтому я им практически никогда не пользуюсь. Портит ли его наличие язык в целом? Едва ли, хотя разработчики инструментария (Resharper, Rider, статических анализаторов и т.д.), которые вынуждены это поддерживать, наверняка со мной не согласятся.

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

Если пытаться прочитать код на языке X, опираясь на интуицию и знание какого-то другого языка Y, то абсолютно любая фича языка X может показаться странной. Наверное, программисту на PHP покажется, что foo.bar - это конкатенация двух строк, а не обращение к методу, и так далее. Такой подход едва ли конструктивен.

В сишарпе добавление new меняет-таки семантику, потому что new { ... } - это выражение, и new () { ... } - это выражение, а вот просто { ... } - нет. Его нельзя сохранить в переменную или передать в функцию. Соответственно, когда вы пишете справа от знака равно что-то, что не является выражением, это не может быть обычным присваиванием и должно быть чем-то еще - в данном случае, инициализацией коллекции через последовательные вызовы метода Add.

Если у вас есть идеи, как можно было бы описать инициализацию вложенной коллекции лучше - поделитесь, пожалуйста.

Вроде все логично: конструкция с фигурными скобками разворачивается в серию последовательных вызовов .Add() на коллекции, и нововведением это не назовешь - кажется, еще с версии C# 5.0 доступно. Иногда эта возможность действительно удобна, например когда поле является get-only:

class Foo {
    public List<int> A { get; set; } = new List<int>();
    public List<int> B { get; } = new List<int>();
}

var foo = new Foo
{
    A = new List<int> { 1, 2 }, // работает
    // B = new List<int> { 3, 4 } // не сработает - ошибка компиляции
    B = { 3, 4 } // сработает
};

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

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

Имхо для таких объектов как ТЭЦ, коровники-свинарники и очистные сооружения радиус в 150 метров маловат, нужно брать километр минимум

В С# сделали то же самое в 2012 году - полет нормальный, никто не жалуется.

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

Проблем видится мне много:

  1. Нет игр, как вы упомянули. Когда они появятся и появятся ли вообще - вопрос

  2. Screen Mirroring c айфона не даст ни 4К, ни 60FPS, на динамичных играх будут заметны лаги

  3. Нужен телевизор с поддержкой AirPlay либо еще и Apple TV

  4. Это банально дорого - на разницу между обычным iPhone 15 и Pro можно купить PS5 или Switch и несколько игр

Итого: для геймера в качестве мотивации купить Pro вместо обычной версии выглядит несостоятельно. В качестве дополнительной плюшечки, которую человек получает "забесплатно" вместе с Pro версией, если он уже покупает ее по другим причинам - наверное норм.

Какое удовольствие играть в AAA-экшен на крошечном экране с виртуальным геймпадом?

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

  • При наведении на таб показывается одновременно и вкладка, и плашка - чзх?

  • "Дефолтный" цвет, который в настройках выглядит серым, в UI почему-то стал синим

  • Кнопка открытия новой вкладки не имеет эффекта при наведении

  • В полноэкранном режиме иконки прилеплены прямо к верхнему краю экрана

  • Кнопка "поиск по вкладкам" показывается в двух экземплярах - "модная новая" слева, и оригинальная справа, рядом с кнопкой "свернуть окно"

Как это вообще могли пропустить в релиз с таким количеством косяков?

К счастью, отключается в настройках флагом "Chrome Refresh 2023".

Вы уж определитесь. В параграфе "Bun — универсальный набор инструментов" написано, что не нужно отказываться от привычек, но нужно отказаться от набора стандартных инструментов, потому что… видимо, потому что в комплекте с Bun идут некие аналогичные, "совместимые" версии. Для меня инструменты разработки и привычки очень тесно переплетены, и отсюда возникает вопрос: насколько эти версии совместимы не только с самим ядром babel/webpack/jest, но и со всеми плагинами, которые к ним написаны? Ибо голый вебпак-подобный бандлер без каких-либо плагинов, будь он хоть в сто раз быстрее, все равно остается бесполезным

Они сами переписали на Zig и Babel, и Webpack, и Jest, и транспилятор TSC? Или просто приложили к рантайму некие дефолтные версии? В обоих случаях — как быть с обновлениями и плагинами? Кажется что вариант "забыть про все эти библиотеки" сработает только для хелловорлдов, в остальных случаях без плагинов будет туго

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

Статья в одном предложении: "Любителю Ruby не понравился Typescript". С учетом философии этих языков, я был бы удивлен услышать обратное.


По поводу жалоб на "полу-статическую типизацию" — обычно так выходит, если человек приходит со знанием языка X и ждет, что в TS поведение некой фичи будет точно таким же, а оно оказывается иным. Конечно, программист на фортране может на любом языке писать на фортране, но будет ожидаемо больно. Не надо так!


В TS действительно многие вещи работают непривычно. Дело в том, что у него изначально была уникальная задача: попытаться обуздать семантику абсолютно безумного языка, коим является JS. И решили ее, конечно, не без отдельных косяков, но в целом очень неплохо.


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


https://github.com/gcanti/io-ts

Имхо, если бы JSON.parse возвращал unknown, было бы неудобно работать. По аналогии: массив может вернуть undefined при обращении по несуществующему индексу, и по-честному нужно было бы делать тип возвращаемого значения T | undefined, но проверок будет больше чем осмысленного кода.

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

Information

Rating
1,531-st
Location
Berlin, Berlin, Германия
Registered
Activity

Specialization

Fullstack Developer
Lead
From 10,000 €
C#
.NET
SQL
TypeScript
Vue.js
Angular