Обновить
4
@Alex_MEread⁠-⁠only

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

7
Подписчики
Отправить сообщение

В Rust есть panic, сделал аналог. Можете не делать unwrap, а оставить только другие методы. Так даже более правильно.

Респект N+1 за силу воли.


Несмотря на отсутствие проблем со здоровьем, некоторое время наазд меня посещали мысли об использовании треккера глаз для переключения окон. Я использую тайловые WM, что (для меня) удобнее, чем возить мышкой, но, все равно, набрать хоткей медленее, чем перевести взгляд. А для переключения окон большая точность не требуется, точность в примерно в 1/4 — 1/8 часть монитора вполне достаточная.

Автор попытался имитировать тип-сумму через наследование. Я как-то делал Option, Result на Python, и сделал одним классом. Идея примерно такая (просите, я мог забыть C#):


class Option<T>
{
    private T _value;
    private bool _is_some;
    private Result() {}
    public static Result Some(value T)
    {
         var res = Result();
         res.v_value = value;
         res._is_some = true;
         return res;
     }
     static Option Nothing()
     {
          var res = Option();
          res._is_just = false;
          return res;
     }
     bool IsSome() => this._is_some;
     bool IsNothing() => this._is_nothing;
     T unwrap()
     {
          if (this._is_some) return this._value;
          raise NothingOptionUnwrapException();
     }
     // map, bind, unwrap_or_default и так далее

}

Состояние инкапсулировано в объекте и никакими кастами его не изменить. Попытка unwrap'а кидает эксепшн. Ну да, щито поделать. В Rust попытка unwrap'а пустого Option вызовет панику. Правда, у автора, вроде, был еще паттерн-матчинг, а тут не получится, вроде.

Это ошибка времени исполнения или ошибка времени компиляции? Это два разных «уровня»

Компилятор защищает разработчика, если он забыл обработать значение, пришедшее откуда-то, на ошибки, тем самым "разыменовав" Maybe/Either в нормальный объект, с которым он хочет работать.


Сторонний код может сгенерировать не только «свои ошибки», но и среды исполненения (переполнение стека, деление на ноль, выход за переделы индекса и т.д.) Любая ошибка может быть в любое время и в любом месте, а не только те что «мне удобно» и «я тут ожидаю».

Если говорить, к примеру, про Rust, в котором мне нравится, как сделана обработка ошибок, то там все делается через Maybe/Either, и нет никаких исключений, ни от библиотеки, ни от среды выполнения. (В самом крайнем, фатальном случае, есть panic). Поэтому, глядя на сигнатуру метода, я понимаю, что можно ждать.

Либо я что-то не понимаю, либо безболезненно превратить C<T> в T нельзя в любом случае.

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


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

Простейший пример. Но я не затрагиваю проблему реализации самих Maybe/Either на C#, я давно не писал на C#.


// Сигнатуры
Either<Foo, Error>  getFoo(); 
Either<Bar, Error> processFoo(Foo foo);

var foo = getFoo();
var bar = processFoo(foo); // Ошибка: Either<Foo, Error>, expected Foo.
// Нужна обработка:
var bar = foo.bind(f => processFoo(f));

Ошибка компиляции.

Проверка на наличие файла может быть полезна сама по себе, но разделение операции на две независимых функции "проверить" и "сделать" вроде логично, но приводит к тому, что ответственность за правильное использование ложиться на программиста (можно проигнорировать проверку или допустить ошибку). А подход Result позволяет в некотором роде на уровне типов выразить, что мы имеем корректное состояние. Проверка, по-сути, представляет собой отображение из "некоторое непонятно состояние" в "точно валидное состояние", выраженная в типах.


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

По моему скромному опыту Rust куда не завезли do-нотацию, именно в функциях обработки Option/Result сила, потому что паттерн матчинг ошибок быстро превращается в вермишель. Более того, такой подход принуждает разработчика декомпозировать функции. Там могло быть большое полотно с разными try-catch, if, match итп, приходится писать маленькие функции по выполнению того или иного действия в цепочке операций, образованных map и bind.

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


В то же время, условный


fn calc_improtant_thing() -> Result<ImportantThing, MyDomainError>

гарантирует, что у нас есть ошибки определенного вида, которые прописаны в сигнатуре.

По сути проглатывание ошибок.

Почему? Например, условный Maybe<T> не может быть применен там, где ожидается T.


А что будете делать для «не верный пароль», «нет памяти», «Timeout» и т.д.?

Either/Result хранят значением ошибки, если "не получилось". Которое может быть типом-суммой, по которому осуществляется match. К примеру.

Принципиальной разницы в обработке Exception или return resultCode

Исключение (также как return code и out-параметр) можно проигнорировать. Maybe/Either игнорировать не получится из-за несовпадения типов. Поэтому совсем уж проигнорировать ошибку не выйдет, пользователь кода увидит ошибку компиляции. Даже если везде вставлять условный unwrap(), это все равно более заметно, чем игнорирование ошибок. Можно даже линтер настроить какой-нибудь, чтобы ругался.

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


Предпочитаю Maybe/Either-подобные подходы. Они получаются громоздкими в языках, не имеющих для этого специальных средств. Например, если иметь набор методов в стиле map, bind (а также ряд других, для сахара, такие unwrap_or_default и многие другие), то это резко снижает громоздкость кода, он становится зачастую даже более лаконичным, чем с try-catch.

Вроде, только для pro-версии? А если на минутку допустить, что все пользуются лицензионной виндой, то далеко не все покупают про.

А стрипать пути, видимо, они не смогли, чтоб только относительные остались

Я лично ни разу не сталкивался с проблемой перезагрузки Win10 во время работы. И я знаю, что можно групповыми политиками настроить. Но.


Вот лично меня это "решение" раздражает. Мой режим дня отвратительный, и я не знаю, вдруг я завтра буду пользоваться компьютером в другое время, выходящее за пределы активности, но не MS меня лечить. Кроме того, могут быть разные внеплановые ситуации. Ну и наконец, самое главное, перезагружать компьютер без ведома пользователя, когда он работает, когда там запущены какие-то приложения (еще вопрос, как среди кучи процессов понять, что нужное) — это просто свинство.


Более того, на ранних версиях Win10 (не знаю, как сейчас), этот период активности не мог быть больше скольки-то часов. Свинство!

Office платный и по отдельной подписке (не знаю, может, остался еще классический, не облачный). В данном случае Microsoft предоставляет бесплатный офис или же просто какие-то рекламные ярлыки, демо-версии итп?

А solid state LiDAR и ToF-камеры — это одно и то же или там разные принципы?
Пока пытался найти информацию, нашел это видео:



Выглядит похоже на structured light (aka первый Kinect и подобные).

Без сравнения с классическими методами управления эта работа не полная. Мат. моделей коптеров разной степени точности немало.

Информация

В рейтинге
Не участвует
Откуда
Волгоградская обл., Россия
Зарегистрирован
Активность