1.97K subscribers
3.95K photos
150 videos
15 files
4.1K links
Блог со звёздочкой.

Много репостов, немножко программирования.

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
#prog #rust #csharp #article

Статья о взаимной интеграции кода на C# и Rust. Спойлер: работает, но выглядит (на мой взгляд) шатко
#prog #csharp #article

Тут вот на Хабре недавно была статья про тестовое задание, суть которого сводилось к тому, чтобы распарсить расписание в cron-подобном формате и потом иметь возможность делать к нему запросы на ближайший описываемый расписанием момент времени относительно заданного аргумента, причём как в будущее, так и в прошлое. Аффтар Автор негодовал из-за того, что он это тестовое задание выполнил, но его решение завернули без внятного фидбека, поэтому он выложил свой вариант на всеобщее обозрение. Зрелище, мягко говоря, не для слабонервных: практически нулевая декомпозиция, куча сложной логики с копипастой и if-ы с семикратной (!) вложенностью. Вдобавок, автор почему-то оптимизировал парсинг, а не получение моментов времени.

Сама задачка, однако, всё же застряла у меня в голове, и у меня были идеи, как можно красиво сделать как минимум парсинг формата расписания. К сожалению, у меня так и не дошли руки до написания кода. А вот у PsyHaste, известного в телеге, как @Psilon — дошли. Используя тот же язык, что и у автора оригинальной статьи — C# — он написал своё решение, с монатками монадками и, внезапно, обоснованным goto (который, впрочем, потребовался исключительно в силу отсутствия в C# оператора continue по метке). Вышло на редкость понятно и читаемо. Об этом он написал свою статью, которую я вас и приглашаю прочитать — и не только в силу технических решений, но и потому, что у Алекса довольно приятный слог.

(тут должна быть рекомендация блога Алекса, но его нету)
#prog #rust #csharp #article

A comparison of Rust’s borrow checker to the one in C#

В C# есть явно ссылочные аргументы функций, переменные и поля, которые объявляются с префиксом ref. Помимо всего прочего, это позволяет передавать ссылки на размещённые на стеке данные. Разумеется, при отсутствии каких-либо проверок это небезопасно и позволяет получить висячую ссылку.

Для того, чтобы не допустить подобного, в C# есть свой статический анализатор. В данной статье автор сравнивает этот анализатор с borrow checker из Rust и разбирает, в чём этот анализатор слабее (и в чём неожиданно сильнее).

Лично мне напомнило немного про Oxidizing Ocaml, но в C# способов управления ссылками поменьше.
👍4🌚2
Статья называется Modern C# Techniques, Part 2: Value Records, если что

(#prog #csharp #suckassstory)
🤨6🤡4😁1
🔥21😁18👍4
#prog #csharp #article

Performance Improvements in .NET 10

Сентябрьская статья об оптимизациях в .NET. Как пишет автор, ускорение кода, как правило, достигается не за счёт одного большого изменения, а за счёт множества маленьких — и весь текст статьи это прекрасно иллюстрирует.

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

Вместе с тем статья несколько расстраивает тем, что ясно показывает, какие усилия приходится тратить разработчикам JIT, чтобы ускорить C#. Многие эти оптимизации были бы избыточны, если бы язык был бы более выразительным или если бы использовались более высокоуровневые (и удобные!) API. Думаю, напишу как-то об этом.
😢17👍3😁1🤔1
#prog #csharp #suckassstory

C# — пример того, как не надо делать язык программирования.

C# очень странно относится к затенению переменных. Обычно он это запрещает. Вот такой код, например, не компилируется:

string x = "Hi";

if (true) {
string x = "Bye";
}


Вывод компилятора:

error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter

Тут в if-блоке вводится новая переменная, которая перекрывает переменную выше. Однако компилятор C# (и это поведение описано в спецификации) смотрит только на включение имён в областях видимости, но не на то, когда они объявлены! Если переставить два оператора местами, код всё равно не компилируется:

if (true) {
string x = "Bye";
}

string x = "Hi";


Также нельзя написать код, который перекрывает параметр метода:

void method(int x) {
int x = 10; // Ошибка
}


Однако можно написать метод, который затеняет... Поля класса! Причём и локальными переменными, и аргументами:

class C {
int x;
int y;
void m(int y /* ок */) {
int x = 10; // тоже ок
}
}


...но только до тех пор, пока поля класса не упоминаются в области видимости. Если упоминаются, то нельзя переиспользовать их имена:

using System;

class C {
int x;
void m() {
Console.WriteLine(x);
int x = 10; // Ошибка
}
}


...но можно во вложенных областях видимости:

using System;

class C {
int x;
void m() {
Console.WriteLine(x);
{
int x = 10; // ок
}
}
}


Какой простой, консистентный и полезный набор правил!

BTW раньше было ещё хуже.
💯15😁7💩3
Блог*
#prog #csharp #suckassstory C# — пример того, как не надо делать язык программирования. C# очень странно относится к затенению переменных. Обычно он это запрещает. Вот такой код, например, не компилируется: string x = "Hi"; if (true) { string x = "Bye";…
#prog #csharp #suckassstory

using System;
using System.Collections.Generic;

var arr = new int[] {1, 2, 3};
Console.WriteLine(arr); // System.Int32[]
var list = new List<int>{1, 2, 3};
Console.WriteLine(list); // System.Collections.Generic.List`1[System.Int32]


Блин, спасибо, очень полезно.

Для сравнения, #java:

import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;

class Main {
public static void main() {
var arr = new int[] {1, 2, 3};
System.out.println(arr); // [I@251a69d7
System.out.println(Arrays.toString(arr)); // [1, 2, 3]
var list = new ArrayList<>(List.of(1, 2, 3));
System.out.println(list); // [1, 2, 3]
}
}
😁5🍌5