Source Generators C#
От: Разраб  
Дата: 03.10.23 02:30
Оценка: 3 (1)
Как думаете почему добавили SG, хотя можно было сразу добавить полноценные Macro(взять за основу тот же Nemerle|Nitra)
Неужели все так ужасно в этих макросах?
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: Source Generators C#
От: Osaka  
Дата: 03.10.23 09:39
Оценка: +1
Р>Неужели все так ужасно в этих макросах?
Нужна возможность пошаговой отладки сгенерённого. Без неё иногда случается ужасно.
Re: Source Generators C#
От: Shmj Ниоткуда  
Дата: 03.10.23 10:42
Оценка: +1 -1 :)))
Здравствуйте, Разраб, Вы писали:

Р>Как думаете почему добавили SG, хотя можно было сразу добавить полноценные Macro(взять за основу тот же Nemerle|Nitra)

Р>Неужели все так ужасно в этих макросах?

Макросы суть зло. В том же Rust — больше всего в Rust проблемы доставляют макросы. Нет полноценных инструментов для их написания и отладки.

Средний человек физически не способен на глубинном уровне понять код с множеством макросов.

C# и Java изначально принципиально отказались от этого зла. И вот C# придумал мягкую замену — весьма круть. Похоже что если брать объективно — то это сейчас самый продвинутый по мягким концепциям язык.
Re[2]: Source Generators C#
От: Разраб  
Дата: 03.10.23 12:41
Оценка:
Здравствуйте, Shmj, Вы писали:



S>Макросы суть зло. В том же Rust — больше всего в Rust проблемы доставляют макросы. Нет полноценных инструментов для их написания и отладки.

не знаю как в расте, в немерел, лиспе, кложуре все ОК.
S>Средний человек физически не способен на глубинном уровне понять код с множеством макросов.
не правда, они гораздо проще СГ.
S>C# и Java изначально принципиально отказались от этого зла. И вот C# придумал мягкую замену — весьма круть. Похоже что если брать объективно — то это сейчас самый продвинутый по мягким концепциям язык.
языки для веб-макак.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[2]: Source Generators C#
От: DarkEld3r  
Дата: 03.10.23 14:25
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Макросы суть зло. В том же Rust — больше всего в Rust проблемы доставляют макросы. Нет полноценных инструментов для их написания и отладки.


Слушай, ну мы ведь все знаем, что ты в расте ни в зуб ногой. Давай тогда не будешь рассказывать о "самых больших проблемах языка"?..

S>C# и Java изначально принципиально отказались от этого зла.


В джаве есть аннотации, которые принципиально ничем не отличаются в плане возможности "запутать код".
Отредактировано 03.10.2023 14:26 DarkEld3r . Предыдущая версия .
Re[3]: Source Generators C#
От: Shmj Ниоткуда  
Дата: 03.10.23 15:00
Оценка: :))
Здравствуйте, DarkEld3r, Вы писали:

S>>Макросы суть зло. В том же Rust — больше всего в Rust проблемы доставляют макросы. Нет полноценных инструментов для их написания и отладки.

DE>Слушай, ну мы ведь все знаем, что ты в расте ни в зуб ногой. Давай тогда не будешь рассказывать о "самых больших проблемах языка"?..

Во-первых, я уже прошел по нему базовый курс — так что основные концепции мне понятны.

Во-вторых, слушал интервью тех, кто годами на нем пишет — и именно такую проблему они назвали — макросы. С чем я полностью согласен.
Re[2]: Source Generators C#
От: Разраб  
Дата: 04.10.23 02:17
Оценка: +2
Здравствуйте, Shmj, Вы писали:



S>Средний человек физически не способен на глубинном уровне понять код с множеством макросов.

Да что же тут сложного? Макросы это то что должно быть в каждом ЯП. Это самый крутой инструмент разработчика.

(defmacro writeln (&;rest args)
  `(progn
     (loop for e in '(,@args)
       do
          (format t "~A" e))
     (format t "~%")))

(defstruct person name)

(defgeneric hello (obj)
  (:documentation "Say hello to object."))

(defmethod hello ((obj person))
  (writeln "Hello, " (person-name obj) "!"))

(defvar p1 (make-person
        :name "Alice"))

(hello p1)
;;печатает символы вместо значений 
;;c:\tmp>sbcl --script mac.lisp
;;sbcl --script mac.lisp
;;Hello, (PERSON-NAME OBJ)

аналог writeln из паскаля на немерле на макросе:
#pragma indent 
// io.n
using System.Console;
macro writeln (params  a: array[expr])
    mutable exps = [];     
        foreach(e in a)
         exps = <[ Write($e); ]> :: exps;

    exps = <[ WriteLine();]> :: exps;
    exps = exps.Reverse();
    <[ { .. $exps } ]>
//main.n compile with reference to io.n (compiled to dll)   
writeln ("Name = ", "Alice", ", age = ", 23, ", student = ", true);

то же самое на F# на функциях и рефлексии:
open System
open Microsoft.FSharp.Reflection

let readln = Console.ReadLine
let writeln = fun a ->
    let args = if FSharpType.IsTuple(a.GetType()) then FSharpValue.GetTupleFields(a) else [|a|]
    let fmt = args |> Array.indexed |> Array.fold (fun s e -> s + (sprintf "{%d}" (fst e))) ""
    Console.WriteLine(fmt.Trim(), args)
let write = fun a ->
    let args = if FSharpType.IsTuple(a.GetType()) then FSharpValue.GetTupleFields(a) else [|a|]
    let fmt = args |> Array.indexed |> Array.fold (fun s e -> s + (sprintf "{%d}" (fst e))) ""
    Console.Write(fmt.Trim(), args)
    
[<EntryPoint>]
let main argv = 
    write ("Ваше имя:")
    let name = readln ()
    writeln ("Hello, ", name , "!")
    readln () |> ignore
    0 // return an integer exit code


и сравните с этим:
using Microsoft.CodeAnalysis;

namespace SourceGenerator
{
    [Generator]
    public class HelloSourceGenerator : ISourceGenerator
    {
        public void Execute(GeneratorExecutionContext context)
        {
            // Find the main method
            var mainMethod = context.Compilation.GetEntryPoint(context.CancellationToken);

            // Build up the source code
            string source = $@"// <auto-generated/>
using System;

namespace {mainMethod.ContainingNamespace.ToDisplayString()}
{{
    public static partial class {mainMethod.ContainingType.Name}
    {{
        static partial void HelloFrom(string name) =>
            Console.WriteLine($""Generator says: Hi from '{{name}}'"");
    }}
}}
";
            var typeName = mainMethod.ContainingType.Name;

            // Add the source code to the compilation
            context.AddSource($"{typeName}.g.cs", source);
        }

        public void Initialize(GeneratorInitializationContext context)
        {
            // No initialization required for this one
        }
    }
}


сложнее в настройке в разы чем использование макросов в немерле. макрос как подпрограмма времени компиляция проходит такой же цикл как и обычная (отладка). кроме того всегда можно раскрыть макрос в исходники.
можно конечно страдать с функциями, но тут макры дают еще пару преимуществ — скорость работы, и простота технологии выраженная в отсутствии рефлексии в рантайме.
тут весь вопрос в том лететь или ползти. миллион мух выбрали второе. печалька ))
ПС подумал еще, а если вот этот текст больше чем три строчки, как его редактировать?
☭ ✊ В мире нет ничего, кроме движущейся материи.
Отредактировано 04.10.2023 2:21 Разраб . Предыдущая версия .
Re[3]: Source Generators C#
От: Михаил Романов Удмуртия https://mihailromanov.wordpress.com/
Дата: 04.10.23 09:11
Оценка: 3 (1) +1
Здравствуйте, Разраб, Вы писали:

S>>Средний человек физически не способен на глубинном уровне понять код с множеством макросов.

Р>Да что же тут сложного? Макросы это то что должно быть в каждом ЯП. Это самый крутой инструмент разработчика.
Возможно, я не понял до конца глубины вашего примера, но как по мне, то, что вы привели, не требует использования макросов, рекурсии или еще каких-то сложных инструментов.
public static void Writeln(params Object[] args)
{
    Console.WriteLine(string.Join("", args.Select(a => a.ToString())));
}

Я ведь правильно понимаю смысл макросов Writeln для Lisp и Nemerle?

Р>и сравните с этим:

Попытался, но не очень понял, что вы хотите сравнить — тут приведен абсолютно другой пример.
Если это не подтасовка, то объясните, на что именно нужно обратить внимание.

Р>сложнее в настройке в разы чем использование макросов в немерле.

Субъективно. Если этот вывод вы делаете на основе сравнения из вашего поста, то я уже сказал — это код делающий разные вещи.
Ну и в чем именно сложность — вы не указали.

Р>макрос как подпрограмма времени компиляция проходит такой же цикл как и обычная (отладка).

Нет, у макроса (по крайней мере в том виде как я видел в статье по Nemerle) цикл двойной — сначала нужно отладить сам макрос (т.е. удостовериться, что он генерирует именно то, что вам нужно), а потом отлаживать сгенерированное (удостоверяясь, что получившийся код — верный).
В этом смысле, отличий от SC я не вижу (по крайней мере принципиальных).

Р>можно конечно страдать с функциями, но тут макры дают еще пару преимуществ — скорость работы, и простота технологии выраженная в отсутствии рефлексии в рантайме.

Про скорость — спорно, нужны замеры.
А к рефлексии я обращаюсь раз в год, а то и реже. Вот нет у меня сейчас таких задач
Re: Source Generators C#
От: Михаил Романов Удмуртия https://mihailromanov.wordpress.com/
Дата: 04.10.23 09:57
Оценка: 2 (1) +2
Здравствуйте, Разраб, Вы писали:

Р>Как думаете почему добавили SG, хотя можно было сразу добавить полноценные Macro(взять за основу тот же Nemerle|Nitra)

Возможно потому, что цели "убить человеко-годы работы на нужную 1,5 гикам фичу, которые, если и так могут использовать F#, Nemerle ну или что там еще осталось живого".
А вот сделать простой механизм генерации кода, который:
— не требуя радикального переписывания, сможет заменить ранее существовавшие способы добавления сгенерированного кода (все эти Visual Studio Code Generators, MSBuild Precompiled Targets, ... — и более экзотические)
— унифицирует и упростит подключение таких генераторов
— позволит без специальных ухищрений (которые работали не всегда и не везде, типа специального генератора "MSBuild:Compile") видеть эти изменения в Design/Compile Time
— ну и за одно дать доступ к уже готовому и разобранному AST для исходного кода (обратите внимание — многим генераторам этого не нужно, они используют для описания генерируемого что-то иное, например XAML разметки — как бы здесь работали макросы я не очень представляю)
Re[3]: Source Generators C#
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 04.10.23 14:07
Оценка: 3 (1)
Здравствуйте, Разраб, Вы писали:

Очень хорошо, что SG сложнее макросов. Иначе Началось бы повальное загрязнение.
А вот использование SG через атрибуты намного более востребовано для расширения классов или их узкой специализации
А написать такой шаблон не большая проблема в отдельном файле и прочих конструкциях
и солнце б утром не вставало, когда бы не было меня
Re[4]: Source Generators C#
От: DarkEld3r  
Дата: 04.10.23 15:28
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Во-вторых, слушал интервью тех, кто годами на нем пишет — и именно такую проблему они назвали — макросы. С чем я полностью согласен.


И что же именно эти эксперты говорят?.. Я что-то жалобы на макросы, в основном, только от создателей ИДЕ видел так как они им жизнь усложняют. А так если люди чем-то и недовольны, так это нюансами реализации или замедлением компиляции, а не самим наличием макросов. Без них раст был бы намного менее востребован, не зря к 1.0 релизу их стабилизировали ударными темпами. Часть кривости как раз из-за того, что тянуть дольше и лучше продумать дизайн не могли.

Большого эксперта из себя строить не буду, но с 2017 года зарабатываю как раз тем, что пишу на расте. Думаю, что хоть что-то да понимаю.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.