Деревья выражений - есть ли где уровня C#|.Net?
От: Shmj Ниоткуда  
Дата: 01.10.23 21:24
Оценка: +1 :)
В продолжение темы концепций ЯП
Автор: Shmj
Дата: 30.09.23
.

Вот вы знакомы с концепцией деревьев выражений как в C#? По-моему это шедеврально, C# шел к этому несколько версий и довел все до логического завершения. Очень очень весьма круть.

Особенно круто когда в самом языке можно писать:

from c in db.Clients
where c.Rate < 5
select c.Id;


И понять как это работает, особенно создать свой провайдер — не так уж просто. Нужно уйму концепций знать.

В большинстве ЯП такого нет и не будет еще очень долго. Фишка в том что это все проверятся компилятором, а не просто как в SQL пиши что хочешь.

И вопрос такой.

В каких ЯП это есть еще на таком же уровне? Ну вот чтобы так писать не функциями а в виде как бы запроса с операторами (> < != = и т.д.), чтобы максимально наглядно и чтобы это все проверялось компилятором.
Отредактировано 01.10.2023 21:24 Shmj . Предыдущая версия .
Re: Деревья выражений - есть ли где уровня C#|.Net?
От: Разраб  
Дата: 02.10.23 05:59
Оценка: -1
Здравствуйте, Shmj, Вы писали:


S>
S>from c in db.Clients
S>where c.Rate < 5
S>select c.Id;
S>


db.Clients 
|> Seq.filter (fun c -> c.Rate < 5)
|> Seq.map (fun c -> c.Id)
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: Деревья выражений - есть ли где уровня C#|.Net?
От: Разраб  
Дата: 02.10.23 07:59
Оценка:
Здравствуйте, Shmj, Вы писали:



S>В каких ЯП это есть еще на таком же уровне? Ну вот чтобы так писать не функциями а в виде как бы запроса с операторами (> < != = и т.д.), чтобы максимально наглядно и чтобы это все проверялось компилятором.


Вообще во многих, ocmal, lisp, dlang
Кстати, что касается последнего, ведь он же как питон, только как java, и все равно нет. почему?
void main()
{
    import std.stdio : writefln;
    // An associative array mapping pairs of characters to integers
    int[char[2]] aa;
    auto arr = "ABBBA";

    // Iterate over all pairs in the string
    // ['A', 'B'], ['B', 'B'], ..., ['B', 'A']
    foreach (i; 0 .. arr.length - 1)
    {
        // String slicing doesn't allocate a copy
        char[2] pair = arr[i .. i + 2];
        // count occurrences
        aa[pair]++;
    }
    foreach (key, value; aa)
        writefln("key: %s, value: %d", key, value);
}
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[2]: Деревья выражений - есть ли где уровня C#|.Net?
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.10.23 08:10
Оценка: +2
Здравствуйте, Разраб, Вы писали:
Р>
Р>db.Clients 
Р>|> Seq.filter (fun c -> c.Rate < 5)
Р>|> Seq.map (fun c -> c.Id)
Р>

В каком виде эти fun попадают в Seq.filter? В виде "просто функции", которую можно только позвать, или в виде отквоченного AST?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Деревья выражений - есть ли где уровня C#|.Net?
От: Shmj Ниоткуда  
Дата: 02.10.23 09:11
Оценка: +1
Здравствуйте, Разраб, Вы писали:

Р>Вообще во многих, ocmal, lisp, dlang

Р>Кстати, что касается последнего, ведь он же как питон, только как java, и все равно нет. почему?

Вы понимаете что это:

from c in db.Clients
where c.Rate < 5
select c.Id;


— может преобразовываться в оптимизированный SQL-запрос для конкретной СУБД? При этом на уровне C# контролируется компилятором.
Re[2]: Деревья выражений - есть ли где уровня C#|.Net?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 02.10.23 10:08
Оценка:
Здравствуйте, Разраб, Вы писали:


S>>В каких ЯП это есть еще на таком же уровне? Ну вот чтобы так писать не функциями а в виде как бы запроса с операторами (> < != = и т.д.), чтобы максимально наглядно и чтобы это все проверялось компилятором.


Р>Вообще во многих, ocmal, lisp, dlang

Ну IQueriable?
Кстати в Object Linq запросы ленивые. То есть возвращается IEnumerable в большинстве своем созданные на yield
И итерация идет с права на лево.
from c in db.Clients
where c.Rate < 5
select c.Id;


То есть запрос получает IEnumerable Select
при MoveNext запрос дергает MoveNext Select, тот дергает MoveNext where а тот уже db.Clients.
В большинстве языков кстати нет yield и вычисления идут слева на право
и солнце б утром не вставало, когда бы не было меня
Re: Деревья выражений - есть ли где уровня C#|.Net?
От: fk0 Россия https://fk0.name
Дата: 02.10.23 10:54
Оценка:
Здравствуйте, Shmj, Вы писали:

S>И вопрос такой.


S>В каких ЯП это есть еще на таком же уровне? Ну вот чтобы так писать не функциями а в виде как бы запроса с операторами (> < != = и т.д.), чтобы максимально наглядно и чтобы это все проверялось компилятором.


HTML, DOM.
Re[3]: Деревья выражений - есть ли где уровня C#|.Net?
От: Разраб  
Дата: 02.10.23 11:34
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

Р>>
Р>>db.Clients 
Р>>|> Seq.filter (fun c -> c.Rate < 5)
Р>>|> Seq.map (fun c -> c.Id)
Р>>

S>В каком виде эти fun попадают в Seq.filter? В виде "просто функции", которую можно только позвать, или в виде отквоченного AST?

для чертовой магии в F# есть специальный Expression Builder
query {
        for customer in db.Customers do
            select customer
    }

потому что явное лучше не явного.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[3]: Деревья выражений - есть ли где уровня C#|.Net?
От: Разраб  
Дата: 02.10.23 11:35
Оценка:
Здравствуйте, Shmj, Вы писали:

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


Р>>Вообще во многих, ocmal, lisp, dlang

Р>>Кстати, что касается последнего, ведь он же как питон, только как java, и все равно нет. почему?

S>Вы понимаете что это:


S>
S>from c in db.Clients
S>where c.Rate < 5
S>select c.Id;
S>


S>- может преобразовываться в оптимизированный SQL-запрос для конкретной СУБД? При этом на уровне C# контролируется компилятором.


ничего оно компилятором не контролируется. Каждый день ef core падает в рантайме
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[4]: Деревья выражений - есть ли где уровня C#|.Net?
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.10.23 15:40
Оценка:
Здравствуйте, Разраб, Вы писали:
Р>для чертовой магии в F# есть специальный Expression Builder
Р>потому что явное лучше не явного.
pfew.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Деревья выражений - есть ли где уровня C#|.Net?
От: Shmj Ниоткуда  
Дата: 02.10.23 18:19
Оценка:
Здравствуйте, Разраб, Вы писали:

Р>ничего оно компилятором не контролируется. Каждый день ef core падает в рантайме


А на какой ошибке падает? Давайте предметно рассмотрим.
Re[5]: Деревья выражений - есть ли где уровня C#|.Net?
От: Jack128  
Дата: 02.10.23 18:22
Оценка:
Здравствуйте, Shmj, Вы писали:

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


Р>>ничего оно компилятором не контролируется. Каждый день ef core падает в рантайме


S>А на какой ошибке падает? Давайте предметно рассмотрим.


Я думаю, что имеется в виду что нить типа такого:

string GetCaption(Item item) => item.Caption;
db.Items.Select(item => GetCaption(item)).FirstOrDefault()
Re[5]: Деревья выражений - есть ли где уровня C#|.Net?
От: Разраб  
Дата: 03.10.23 12:39
Оценка:
Здравствуйте, Shmj, Вы писали:

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


Р>>ничего оно компилятором не контролируется. Каждый день ef core падает в рантайме


S>А на какой ошибке падает? Давайте предметно рассмотрим.


ну, пока у меня все отлажено. я ошибки не фиксирую. будет что-то напишу.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[5]: Деревья выражений - есть ли где уровня C#|.Net?
От: Разраб  
Дата: 05.10.23 01:40
Оценка: -1 :)
Здравствуйте, Shmj, Вы писали:

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


Р>>ничего оно компилятором не контролируется. Каждый день ef core падает в рантайме


S>А на какой ошибке падает? Давайте предметно рассмотрим.

System.InvalidOperationException: "The LINQ expression 'DbSet<Article>()
    .Count(a => a.UpdateTime < a.ProcessingTime.GetValueOrDefault(01.01.0001 0:00:00 +00:00))' could not be translated.
 Additional information: Translation of method 'System.DateTimeOffset?.GetValueOrDefault' failed. 
If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. 
Either rewrite the query in a form that can be translated, 
or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. 
See https://go.microsoft.com/fwlink/?linkid=2101038 for more information."
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[6]: Деревья выражений - есть ли где уровня C#|.Net?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 05.10.23 07:35
Оценка:
Здравствуйте, Разраб, Вы писали:

Ну наверное надо проверить a.ProcessingTime на null
и солнце б утром не вставало, когда бы не было меня
Re[6]: Деревья выражений - есть ли где уровня C#|.Net?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 05.10.23 08:27
Оценка:
Здравствуйте, Разраб, Вы писали:

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


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


Р>>>ничего оно компилятором не контролируется. Каждый день ef core падает в рантайме


S>>А на какой ошибке падает? Давайте предметно рассмотрим.

Р>
Р>System.InvalidOperationException: "The LINQ expression 'DbSet<Article>()
Р>    .Count(a => a.UpdateTime < a.ProcessingTime.GetValueOrDefault(01.01.0001 0:00:00 +00:00))' could not be translated.
Р> Additional information: Translation of method 'System.DateTimeOffset?.GetValueOrDefault' failed. 
Р>If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. 
Р>Either rewrite the query in a form that can be translated, 
Р>or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. 
Р>See https://go.microsoft.com/fwlink/?linkid=2101038 for more information."

Р>


Ну, баетнька, у вас руки не из того места
.Count(a => a.UpdateTime < a.ProcessingTime)

Достаточно

Если ProcessingTime is null, то выражение в SQL вернет undefined и Count не посчитает, то же самое если сравнить с минимальной датой. Более того если у тебя тип datetime, а не datetime2, то упадет с конверсией.
Re[6]: Деревья выражений - есть ли где уровня C#|.Net?
От: Sharov Россия  
Дата: 05.10.23 08:41
Оценка:
Здравствуйте, Разраб, Вы писали:


Р>
Р>System.InvalidOperationException: "The LINQ expression 'DbSet<Article>()
Р>    .Count(a => a.UpdateTime < a.ProcessingTime.GetValueOrDefault(01.01.0001 0:00:00 +00:00))' could not be translated.
Р> Additional information: Translation of method 'System.DateTimeOffset?.GetValueOrDefault' failed. 
Р>If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?lin
Р>


Linq провайдер не знает как транслировать метод GetValueOrDefault, о чем и написал.
Кодом людям нужно помогать!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.