Re[19]: Welcome to C# 9.0
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.06.20 02:41
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, Sinclair, Вы писали:


S>>Но теперь, получается, надо заново применять вторую фазу, т.к. из той же таблицы фактов мы знаем, что {h} >= {0}, и мы должны свернуть выражение в {true}.


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

В целом — да. Но пример из https://github.com/igor-tkachev/Linq.Expressions.Deconstruct/blob/master/Tests/Tests.cs#L156-L183, например, делает неполный фолдинг.
Например, i + 1 — 1 + 2 — i свёрнут не будет — нет правил для перегруппировки.
А как только мы введём такие правила, их придётся гонять по кругу.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Welcome to C# 9.0
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.06.20 02:43
Оценка: -1 :)
Здравствуйте, vmpire, Вы писали:
V>А потом автор метода решил их поменять местами. При компиляции ничего не развалилось, при выполнении будет неправильный результат.
Да, в дорешарперные эпохи так и было. А сейчас всё делает IDE — вот и с классом также будет.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: Welcome to C# 9.0
От: vmpire Россия  
Дата: 04.06.20 11:44
Оценка: +2
Здравствуйте, Sinclair, Вы писали:

V>>А потом автор метода решил их поменять местами. При компиляции ничего не развалилось, при выполнении будет неправильный результат.

S>Да, в дорешарперные эпохи так и было. А сейчас всё делает IDE — вот и с классом также будет.
"Всё делает IDE" только если у вас маленькие простые проекты.
А если метод, который изменился, находится в библиотеке, которая в отдельном солюшне и используется другой командой, которая её только через месяц в виде пакета подтянет в свой проект, то начинаются очень интересные вещи.
Re[25]: Welcome to C# 9.0
От: IT Россия linq2db.com
Дата: 04.06.20 13:21
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Мне же надо что-то вроде

S>
S>Add(Constant(T x), Constant(T y)) => Constant(x+y)
                                                ___ // вот это можно передать в такой метод в виде лямбды
S>
Если нам не помогут, то мы тоже никого не пощадим.
Re[26]: Welcome to C# 9.0
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.06.20 03:41
Оценка:
Здравствуйте, IT, Вы писали:

S>>Мне же надо что-то вроде

S>>
S>>Add(Constant(T x), Constant(T y)) => Constant(x+y)
IT>                                                ___ // вот это можно передать в такой метод в виде лямбды
S>>

Ты имеешь в виду Add(Constant(T x), Constant(T y)) => Constant(new LambdaExpression(expr).Compile()())?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[23]: Welcome to C# 9.0
От: Jack128  
Дата: 05.06.20 12:27
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Sinclair, Вы писали:

S>>Да, давненько я не перечитывал Аппеля.
S>Короче, теперь остро не хватает шейпов или вроде того. Потому что все правила с константами приходится повторять для всех числовых типов.
S>Либо надо допиливать как-то так:
S>
S>Multiply(Constant(Type t, var x) e, _) when t.IsNumeric && Convert.ToDouble(x) == 0.0 => e,                                // 0 * e => 0
S>


Не очень понятно, что у тебя за калькулятор, но если допустимо считать всё в Double, не проще изначально пробежаться по всему дереву и заменить все константы int/byte/... на соответствующие константы Double. И в оптимизаторе уже матчить всё на Double
Multiply(Constant(0.0) e,   _)               => e ..
Re[27]: Welcome to C# 9.0
От: IT Россия linq2db.com
Дата: 05.06.20 14:32
Оценка: 74 (1)
Здравствуйте, Sinclair, Вы писали:

S>Ты имеешь в виду Add(Constant(T x), Constant(T y)) => Constant(new LambdaExpression(expr).Compile()())?


Что-то типа вот этого:

[Test]
public void ConstantFoldingExTest2()
{
    Expression<Func<int,int>> f = i => i + 1 - 1 + 2 - i;

    Expr Transform<T>(Expr ex, Func<T,T,T> multiply, Func<T,T,T> divide, Func<T,T,T> add, Func<T,T,T> subst)
    {
        return ex switch
        {
            Multiply(Constant(T x), Constant(T y)) => Constant(multiply(x, y)), // x * y => e
            Divide  (Constant(T x), Constant(T y)) => Constant(divide  (x, y)), // x / y => e
            Add     (Constant(T x), Constant(T y)) => Constant(add     (x, y)), // x + y => e
            Subtract(Constant(T x), Constant(T y)) => Constant(subst   (x, y)), // x - y => e
            _                                      => null
        };
    };

    var f1 = f.TransformEx(ex => ex switch
    {
        Multiply(Constant(0) e,   _)               => e,               // 0 * e => 0
        Multiply(_,               Constant(0) e)   => e,               // e * 0 => 0
        Multiply(Constant(1),     var e)           => e,               // 1 * e => e
        Multiply(var e,           Constant(1))     => e,               // e * 1 => e
        Divide  (Constant(0) e,   _)               => e,               // 0 / e => 0
        Divide  (var e,           Constant(1))     => e,               // e / 1 => e
        Add     (Constant(0),     var e)           => e,               // 0 + e => e
        Add     (var e,           Constant(0))     => e,               // e + 0 => e
        Subtract(Constant(0),     var e)           => Negate(e),       // 0 - e => -e
        Subtract(var e,           Constant(0))     => e,               // e - 0 => e
        _ when Transform<int>   (ex, (x,y) => x * y, (x, y) => x / y, (x, y) => x + y, (x, y) => x - y) is Expr e => e,
        _ when Transform<long>  (ex, (x,y) => x * y, (x, y) => x / y, (x, y) => x + y, (x, y) => x - y) is Expr e => e,
        _ when Transform<double>(ex, (x,y) => x * y, (x, y) => x / y, (x, y) => x + y, (x, y) => x - y) is Expr e => e,
        _                                          => ex
    });

    Console.WriteLine(f);
    Console.WriteLine(f1);

    Assert.IsTrue(f1.EqualsTo(i => 2));
}


Только вместо лямбд, если уж заниматься этим серьёзно, следует залудить какой-нибудь интерфейс или базовый класс и сделать все арифметические операции в нём.

Либо сгенерировать всю эту хрень.
Если нам не помогут, то мы тоже никого не пощадим.
Re[24]: Welcome to C# 9.0
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.06.20 14:36
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Не очень понятно, что у тебя за калькулятор, но если допустимо считать всё в Double, не проще изначально пробежаться по всему дереву и заменить все константы int/byte/... на соответствующие константы Double.

Всё — нет, недопустимо. Потом запаришься обратно приводить — потому что there is no built-in operator Add defined for the types [byte] and [Double].
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[25]: Welcome to C# 9.0
От: IT Россия linq2db.com
Дата: 05.06.20 14:47
Оценка:
Здравствуйте, Sinclair, Вы писали:

J>>Не очень понятно, что у тебя за калькулятор, но если допустимо считать всё в Double, не проще изначально пробежаться по всему дереву и заменить все константы int/byte/... на соответствующие константы Double.

S>Всё — нет, недопустимо. Потом запаришься обратно приводить — потому что there is no built-in operator Add defined for the types [byte] and [Double].

Кстати, эту идею стоит помусолить. Например, ввести наряду с Constant что-нибудь типа Numerical, которая будет такой же константой, но любого числового типа. Количество явно используемых констант используемых в паттернах, вроде 0,1 должно быть ограниченным и можно смело использовать целые числа.
Если нам не помогут, то мы тоже никого не пощадим.
Re[26]: Welcome to C# 9.0
От: IT Россия linq2db.com
Дата: 05.06.20 14:53
Оценка:
Здравствуйте, IT, Вы писали:

IT>Кстати, эту идею стоит помусолить. Например, ввести наряду с Constant что-нибудь типа Numerical, которая будет такой же константой, но любого числового типа. Количество явно используемых констант используемых в паттернах, вроде 0,1 должно быть ограниченным и можно смело использовать целые числа.


Даже ещё проще. Нужен ещё один деконструктор для Constant, который будет заточен исключительно на числа и сравнивать их значения с целым.
Если нам не помогут, то мы тоже никого не пощадим.
Re[22]: Welcome to C# 9.0
От: IT Россия linq2db.com
Дата: 05.06.20 20:52
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Спасибо. Помогло. Хотя Мучниковские правила какие-то избыточные — R9 и R10 не нужны:


Похоже, что как раз они и делают основную свёртку.
Если нам не помогут, то мы тоже никого не пощадим.
Re[20]: Welcome to C# 9.0
От: IT Россия linq2db.com
Дата: 05.06.20 21:04
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>А как только мы введём такие правила, их придётся гонять по кругу.


Вот вариант с частичным гонянием по кругу:

public static T Fold<T>(T expr)
    where T : notnull, LambdaExpression
{
    return expr.TransformEx<T>(FoldExpr);
}

public static Expression? Fold(Expression? expr)
{
    return expr.TransformEx(FoldExpr);
}

static Expr FoldExpr(Expr ex)
{
    return ex switch
    {
        Multiply(Constant(0) e,   _)               => e,                // 0 * e => 0
        Multiply(_,               Constant(0) e)   => e,                // e * 0 => 0
        Multiply(Constant(1),     var e)           => e,                // 1 * e => e
        Multiply(var e,           Constant(1))     => e,                // e * 1 => e
        Divide  (Constant(0) e,   _)               => e,                // 0 / e => 0
        Divide  (var e,           Constant(1))     => e,                // e / 1 => e
        Add     (Constant(0),     var e)           => e,                // 0 + e => e
        Add     (var e,           Constant(0))     => e,                // e + 0 => e
        Subtract(Constant(0),     var e)           => Negate(e)!,       // 0 - e => -e
        Subtract(var e,           Constant(0))     => e,                // e - 0 => e
        Multiply(Constant(int x), Constant(int y)) => Constant(x * y)!, // x * y => e
        Divide  (Constant(int x), Constant(int y)) => Constant(x / y)!, // x / y => e
        Add     (Constant(int x), Constant(int y)) => Constant(x + y)!, // x + y => e
        Subtract(Constant(int x), Constant(int y)) => Constant(x - y)!, // x - y => e

        Add     (Add     (Constant(int c1), var e), Constant(int c2)) => Fold(Add     (Constant(c1 + c2), e)),  // (c1 + e) + c2 = (c1 + e2) + e
        Multiply(Multiply(Constant(int c1), var e), Constant(int c2)) => Fold(Multiply(Constant(c1 * c2), e)),  // (c1 + e) + c2 = (c1 + e2) + e

        Add     (var e,           Constant c)      => Add     (c, e),            // e + c => c + e
        Multiply(var e,           Constant c)      => Multiply(c, e),            // e * c => c * e
        Subtract(var e,           Constant(int x)) => Add     (Constant(-x), e), // e - c => (-c) + e

        Add     (var e1,          Add     (var e2, var e3)) => Fold(Add     (Add     (e1, e2), e3)),  // e1 + (e2 + e3) = (e1 + e2) + e3
        Multiply(var e1,          Multiply(var e2, var e3)) => Fold(Multiply(Multiply(e1, e2), e3)),  // e1 + (e2 + e3) = (e1 + e2) + e3

        Subtract(Add(var e1, var e2), var e3) when e2 == e3 => e1,      // (e1 + e2) - e2 => e1

        _                                          => ex
    };
}


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

ЗЫ. Насчёт типов (шейпов) тоже есть идея как решить проблему.
Если нам не помогут, то мы тоже никого не пощадим.
Re[8]: Welcome to C# 9.0
От: Евгений Акиньшин grapholite.com
Дата: 11.09.20 02:42
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, VladD2, Вы писали:


VD>>Причем новое лючевое слово все равно вводят. Можно было бы тупо писать "record" вместо "data class"


НС>А вместо data struct?


Таки сделали "record" без "class"

https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9

Не шалю, никого не трогаю, починяю примус Diagrams Designer for iPad and Windows 10
Re[3]: Лигатуры
От: Shtole  
Дата: 11.09.20 04:35
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>В шрифте с лигатурами нормально:

Q>http://prntscr.com/skm9mh

Wow. Just wow.
Do you want to develop an app?
Re: Про рекорды
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 15.09.20 11:00
Оценка: 74 (1) +1
Про рекорды

https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9
и солнце б утром не вставало, когда бы не было меня
Отредактировано 16.09.2020 16:17 Serginio1 . Предыдущая версия .
Re[9]: Welcome to C# 9.0
От: AlexRK  
Дата: 15.09.20 11:15
Оценка: -1
Здравствуйте, Евгений Акиньшин, Вы писали:

ЕА>Таки сделали "record" без "class"

ЕА>https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9

MWA-HA-HA-HA.


UPD. Правда, зачем мутабельными их сделали — это загадка, конечно. Как фсигда: вроде в целом неплохо, но обязательно что-то должно быть через очко. А у сектантов всегда есть оправдание любому говну.
Отредактировано 15.09.2020 11:23 AlexRK . Предыдущая версия .
Re[10]: Welcome to C# 9.0
От: Sinclair Россия https://github.com/evilguest/
Дата: 15.09.20 14:00
Оценка: +4
Здравствуйте, AlexRK, Вы писали:
ARK>UPD. Правда, зачем мутабельными их сделали — это загадка, конечно. Как фсигда: вроде в целом неплохо, но обязательно что-то должно быть через очко. А у сектантов всегда есть оправдание любому говну.
Почему мутабельными-то???

Records are immutable by default.

Как фсигда: разобраться времени нет, но надо обязательно покритиковать.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[10]: Welcome to C# 9.0
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 15.09.20 14:11
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>UPD. Правда, зачем мутабельными их сделали — это загадка, конечно. Как фсигда: вроде в целом неплохо, но обязательно что-то должно быть через очко. А у сектантов всегда есть оправдание любому говну.


https://devblogs.microsoft.com/dotnet/announcing-net-5-0-rc-1/

Records are specialized classes
As I just covered, the record and the class variants of LoginResource are almost identical. The class definition is a semantically identical subset of the record. The record provides more, specialized, behavior.

Just so we’re on the same page, the following comparison is between a record, and a class that uses init instead of set for properties, as demonstrated earlier.

What’s the same?

Construction
Immutability
Copy semantics (records are classes under the hood)
What’s different?

Record equality is based on content. Class equality based on object identity.
Records provide a GetHashCode() implementation is that is based on record content.
Records provide an IEquatable<T> implementation. It uses the unique GetHashCode() behavior as the mechanism to provide the content-based equality semantic for records.
Record ToString() is overridden to print record content.

и солнце б утром не вставало, когда бы не было меня
Re[11]: Welcome to C# 9.0
От: AlexRK  
Дата: 15.09.20 14:22
Оценка: -5
Здравствуйте, Sinclair, Вы писали:

S>Почему мутабельными-то???

S>

S>Records are immutable by default.


Не надо никаких by default. Уже есть классы и структуры.
Re[12]: Welcome to C# 9.0
От: Sinclair Россия https://github.com/evilguest/
Дата: 16.09.20 05:50
Оценка: +1 -1
Здравствуйте, AlexRK, Вы писали:
ARK>Не надо никаких by default. Уже есть классы и структуры.
Отличная тактика. Если спорол чушь, то не надо признавать это — надо тут же спороть другую чушь, чтобы отвлечь собеседников от чуши предыдущей.
Продолжайте, мне сейчас курьер пакет попкорна должен привезти.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.