Re[2]: [Snippets] Обновленный макрос with
От: para  
Дата: 17.03.11 12:49
Оценка: 1 (1)
Здравствуйте, hardcase, Вы писали:

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


C>>Народ (http://www.rsdn.ru/forum/nemerle/4067914.1.aspx
Автор: hardcase
Дата: 07.12.10
) хотел инициализаторы коллекций, так что я решил поделиться, и обновил реализацию with-макроса в сниппетах. Поддерживаются новые фичи.


H>Макрос переехал в стандартную библиотеку в пространство имен Nemerle.Extensions.

H>К сожалению, использовать оригинальное имя "with" в качестве имени оператора не вышло: виртуальный оператор с таким именем, используемый для поддержки PM-а, имеет неподходящие приоритеты. Использована синтетическая штуковина: <-. Пример тут. Как и макра анонимного типа, инициализатор пока не отражен в официальной документации.

having ?
Re[5]: [Snippets] Обновленный макрос with
От: BogdanMart Украина  
Дата: 20.03.11 10:32
Оценка:
Здравствуйте, catbert, Вы писали:

C>Ну, и еще, тогда этот макрос придется перенести в стандартную библиотеку.


А в чем проблема?
Re[2]: [Snippets] Обновленный макрос with
От: BogdanMart Украина  
Дата: 20.03.11 11:08
Оценка: 1 (1)
Здравствуйте, lomeo, Вы писали:

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



L>А макросы — первоклассные сущности? Так можно?


L>
L>    def props =
L>                {
L>                    MouseMove += handler;
L>                    Click => form.Text = "Click!"; // упрощенная форма, как в компиляторе Mono C#
L>                }

L>    def btn = Button() with props
L>


L>Практический смысл, например, такой — в tcl/lisp/javascript я могу нарожать схожие мне строки/списки/объекты в функции.


Идея забавная, и в принципе реализуемая, в виде макрос который преобразовывает код после себя.

    expr props =
               {
                    MouseMove += handler;
                    Click => form.Text = "Click!"; // упрощенная форма, как в компиляторе Mono C#
               }
    def btn = Button() with props


Как то так, может попробую реализовать, если время найду.
Re: [Snippets] Обновленный макрос with
От: BogdanMart Украина  
Дата: 30.03.11 19:12
Оценка:
Здравствуйте, catbert, Вы писали:

Крутая макра!!! НАконецто можно декларативно создавать формочки из немерловского кода.
Если доработать то и поддержка XAMLa будет не нужна.

Чего не хватало в оригинальном макросе -- возмодности присваивать промежуточные результаты глобальной области видимости (те. формочка создаеться макросом и все ее содержымое, но какой-то TextBox также помещается в переменную)

Набросал решение. выглядит примерно так:

      mutable txtBox;
      mutable lbl;
      
      def _w = Window() <-
      {
        Width = 200;
        Height = 100;
        Content = StackPanel() <-
        {
          Children <-
          [
            txtBox <- TextBox() <- { Text = "Some text"},
            Button() <- 
            {
              Content = "Copy";
              Click += (_) => { lbl.Content = txtBox.Text }
            },
            lbl <- Label()
          ]
        }
      }
      
      _ = _w.ShowDialog();


Обратить внимание на места lbl <- Label() и txtBox <- TextBox() то есть помещаем во внешнюю переменную(или поле класса) текущие контролы.

Приимущества:
  • Весь код формы находиться в одном месте, а не размазан по местам где создаются нужные переменные(и контрольчики)
  • нужные контрольчики лежат в переменных

    Ну мешать эту макру с "<-" не обязательно, просто этот символ для этого действия ажеться логичным(и другого не придумал) а оператор "=" как ихвестно имеет тип возврата void по этому надо как то выкручиваться

    Желаю услышать ваши мнения. Если катит то доведу до ума и закомичу ибо ИМХО полезная доработка для этого макроса.
  • Re[2]: [Snippets] Обновленный макрос with
    От: catbert  
    Дата: 01.04.11 10:18
    Оценка: 11 (1)
    Здравствуйте, BogdanMart, Вы писали:

    ВМ>Чего не хватало в оригинальном макросе -- возмодности присваивать промежуточные результаты глобальной области видимости


    А так не работает?

    mutable pnl : StackPanel;
    mutable txtBox : TextBox;
    
    def w = Window() <-
    {
        Content = pnl <-
        {
            Children <-
            [
                 txtBox <- { blah blah }
            ]
        }
    }


    Так, правда, приходится создавать переменные сверху. Чтобы автоматически добавлять переменные в область видимости (но это уже другой вопрос!), можно добавить оператор as, как в паттерн-матчинге:

    def w = Window() <-
    {
        Content = StackPanel() as pnl <-
        {
            Children <-
            [
                 TextBox() as this.txtBox <- { blah blah } // если написано this, то генерируется член класса, а не локальная переменная
            ]
        }
    }


    Преимущество в том, что повторно используется стандартный синтаксис ввода в область видимости. Недостаток в том, что Немерле при этом на шаг приближается к С++, где все выражения вроде int *&, (int*)&, const int *, const * int, * const int позволены и имеют различную семантику. Но это так, философия
    Re[3]: [Snippets] Обновленный макрос with
    От: hardcase Пират http://nemerle.org
    Дата: 01.04.11 11:34
    Оценка:
    Здравствуйте, catbert, Вы писали:

    C>Так, правда, приходится создавать переменные сверху. Чтобы автоматически добавлять переменные в область видимости (но это уже другой вопрос!), можно добавить оператор as, как в паттерн-матчинге:


    C>
    C>def w = Window() <-
    C>{
    C>    Content = StackPanel() as pnl <-
    C>    {
    C>        Children <-
    C>        [
    C>             TextBox() as this.txtBox <- { blah blah } // если написано this, то генерируется член класса, а не локальная переменная
    C>        ]
    C>    }
    C>}
    C>


    Идея хорошая с именами — они позволят записать инициализацию циклических структур:

    def x = Node() as n <-
    {
      Parent = n
    };


    Фактически это имя можно использовать вместо временного имени, генерируемого компилятором.
    /* иЗвиНите зА неРовнЫй поЧерК */
    Re[3]: [Snippets] Обновленный макрос with
    От: BogdanMart Украина  
    Дата: 01.04.11 13:21
    Оценка:
    Здравствуйте, catbert, Вы писали:

    C>
    C>def w = Window() <-
    C>{
    C>    Content = StackPanel() as pnl <-
    C>    {
    C>        Children <-
    C>        [
    C>             TextBox() as this.txtBox <- { blah blah } // если написано this, то генерируется член класса, а не локальная переменная
    C>        ]
    C>    }
    C>}
    C>


    Выглядит уже симпатично. Не придумал как cделать..
    Вот только с введением переменных во внешнюю область видимости могут быть сложности.. Компилятор вроде бы автоматически ставит блок вокруг тела макроса.. значит объявленные переменные будут внутри блока.
    Re[4]: [Snippets] Обновленный макрос with
    От: Ziaw Россия  
    Дата: 01.04.11 13:45
    Оценка:
    Здравствуйте, BogdanMart, Вы писали:

    BM>Выглядит уже симпатично. Не придумал как cделать..

    BM>Вот только с введением переменных во внешнюю область видимости могут быть сложности.. Компилятор вроде бы автоматически ставит блок вокруг тела макроса.. значит объявленные переменные будут внутри блока.

    ставит если макрос из нескольких выражений, попробуй так:

    <[
    def var = {
    your code
    }
    ]>;
    Re[5]: [Snippets] Обновленный макрос with
    От: BogdanMart Украина  
    Дата: 01.04.11 18:46
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    Z>ставит если макрос из нескольких выражений, попробуй так:


    Z><[

    Z>def var = {
    Z> your code
    Z>}
    Z>]>;

    А вот и нет

      public macro Macro2()
      {
        <[
          def var = 8
        ]>;
      }

       Main() : void
        {
          Macro2();      
          def a = var;
        }


    Main.n:26:15:26:18: ←[01;31merror←[0m: unbound name `var'


    Тоесть полюбому не даст(напрямую, кончено можно из Тайпера получить MethodBuilder и потом колдовать, но брррр).

    А еслибы и заработало с одним выражением, так нам надо и проретурнить и присвоить выражению.
    Re[3]: [Snippets] Обновленный макрос with
    От: BogdanMart Украина  
    Дата: 01.04.11 19:10
    Оценка:
    Здравствуйте, catbert, Вы писали:

    Могу реализовать и залить в таком виде:

    C>
    C>mutable pnl : StackPanel;
    C>mutable txtBox : TextBox;
    C>def w = Window() <-
    C>{
    C>    Content = StackPanel() as pnl <-
    C>    {
    C>        Children <-
    C>        [
    C>             TextBox() as this.txtBox <- { blah blah } // если написано this, то генерируется член класса, а не локальная переменная
    C>        ]
    C>    }
    C>}
    C>


    Из макроса их объявить более глобально -- это куча гемора связанная с доставанием MethodBuilder'a из Typer'a а это уже шаманство.
    Проще будет объявить нужную переменную

    вариант с
    mutable label = Label();
    Window() <-{ Contetn = label <- {....} }


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

    Хотя если вы знаете как по хорошему объявить переменную во внешней области.. то попробуйте..

    ПС, как мне кажется даже с объявлением полей класса могут возникнуть проблемы, так как другие методы могут быть уже обработаны к этому моменту и не находить соответствующих полей(+ непонятно какую область видимости им давать, или может их свойствами, или вообще DependencyProperty) по этому лучше оставить объявление мест хранения объектиков на откуп пользователю.
    Re[4]: [Snippets] Обновленный макрос with
    От: hardcase Пират http://nemerle.org
    Дата: 01.04.11 19:51
    Оценка:
    Здравствуйте, BogdanMart, Вы писали:

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


    BM>Могу реализовать и залить в таком виде:


    Предлагаю следующее решение.

    Случай 1: использование имени внутри инициализатора

    def x = X() as current <-
    {
       // используем current для создания циклических структур данных
    }




    Случай 2: возврат ссылки на некоторый внутренний подобъект во внешний контекст

    mutable obj;
    
    def x = X() <- 
    {
      Y = Y() as out obj <-
      {
        A = ... // используем инициализированный obj здесь 
        B = ...
      }
    }
    
    // а также уже после блока
    /* иЗвиНите зА неРовнЫй поЧерК */
    Re[5]: [Snippets] Обновленный макрос with
    От: hardcase Пират http://nemerle.org
    Дата: 01.04.11 19:56
    Оценка:
    Здравствуйте, hardcase, Вы писали:

    H>
    H>mutable obj;
    
    H>def x = X() <- 
    H>{
    H>  Y = Y() as out obj <-
    H>  {
    H>    A = ... // используем инициализированный obj здесь 
    H>    B = ...
    H>  }
    H>}
    
    H>// а также уже после блока
    H>


    Конкретно именно так работать не будет ввиду специфики разбора out-выражение, но можно поискать решения типа:

    mutable obj;
    
    def x = X() <- 
    {
      Y = out Y() as obj <-
      {
        A = ... // используем инициализированный obj здесь 
        B = ...
      }
    }
    
    // а также уже после блока
    /* иЗвиНите зА неРовнЫй поЧерК */
    Re[6]: [Snippets] Обновленный макрос with
    От: Ziaw Россия  
    Дата: 01.04.11 20:11
    Оценка: +1
    Здравствуйте, BogdanMart, Вы писали:

    BM>Тоесть полюбому не даст(напрямую, кончено можно из Тайпера получить MethodBuilder и потом колдовать, но брррр).


    Макросы гигиеничны, переменную надо задавать так: $("var" : usesite).

    BM>А еслибы и заработало с одним выражением, так нам надо и проретурнить и присвоить выражению.


    Все работает.
    Re[7]: [Snippets] Обновленный макрос with
    От: Ziaw Россия  
    Дата: 01.04.11 20:38
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    BM>>А еслибы и заработало с одним выражением, так нам надо и проретурнить и присвоить выражению.


    Z>Все работает.


    Впрочем туплю, не понял сразу проблему с тем, что выражение должно иметь значение.
    Re[5]: [Snippets] Обновленный макрос with
    От: BogdanMart Украина  
    Дата: 01.04.11 20:57
    Оценка:
    Здравствуйте, hardcase, Вы писали:

    H>Случай 1: использование имени внутри инициализатора


    H>
    H>def x = X() as current <-
    H>{
    H>   // используем current для создания циклических структур данных
    H>}
    H>


      public macro @as(obj, ing, initializer) // пробовал public macro @<-(obj, ing, initializer) как было в оригинале, не помогло..
      syntax( obj, "as", ing, "<-", initializer)
      {    
        WithMacroImpl.Run(obj, initializer);
      }


    def _w = Window() as temp <-  {}

    выдает: Error: found pattern expression () inside a raw expression
    Re[6]: [Snippets] Обновленный макрос with
    От: BogdanMart Украина  
    Дата: 01.04.11 21:43
    Оценка:
    Здравствуйте, BogdanMart, Вы писали:

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


    BM>выдает: Error: found pattern expression () inside a raw expression


    Вообщем as и in использовать не дает... мож что то не так делаю.

    Уже и так делал(макрос обявлен так же но параметр паршу):
        public Run(obj : PExpr, initializer : PExpr) : PExpr
        {
          def (name, assignment) =
            match (obj)
            {
              | <[ $obj in $inn ]> when inn is PExpr.Ref => (inn, <[ $inn = $obj;]>)
              | _                  => 
                def name = <[ $(Macros.NewSymbol("initializedObject") : name) ]>;
                (name, <[def $name = $obj;]>)
            }   
          def statements = MakeStatements(initializer, name);
          ;
            
          <[
            $(assignment);
            $(statements);
            $(name)
          ]>
        }


    а такой синтаксис пашет Window() $ tmp <- {} -- но это бредовый синтаксис и не понятно нифига...
    Re[8]: [Snippets] Обновленный макрос with
    От: catbert  
    Дата: 01.04.11 22:11
    Оценка: +1
    Здравствуйте, Ziaw, Вы писали:

    Z>Впрочем туплю, не понял сразу проблему с тем, что выражение должно иметь значение.


    Это что за проблема?
    Re[6]: [Snippets] Обновленный макрос with
    От: hardcase Пират http://nemerle.org
    Дата: 02.04.11 06:34
    Оценка:
    Здравствуйте, BogdanMart, Вы писали:

    BM>
    BM>  public macro @as(obj, ing, initializer) // пробовал public macro @<-(obj, ing, initializer) как было в оригинале, не помогло..
    BM>  syntax( obj, "as", ing, "<-", initializer)
    BM>  {    
    BM>    WithMacroImpl.Run(obj, initializer);
    BM>  }
    BM>


    Синтаксис трогать не нужно, я думаю достаточно этого:
    match(obj)
    {
      | <[ $ctor as $(var : name) ]>     => случай_1
      | <[ out $ctor as $(var : name) ]> => случай_2
    }
    /* иЗвиНите зА неРовнЫй поЧерК */
    Re[7]: [Snippets] Обновленный макрос with
    От: BogdanMart Украина  
    Дата: 02.04.11 09:36
    Оценка:
    Здравствуйте, hardcase, Вы писали:

    H>Синтаксис трогать не нужно, я думаю достаточно этого:

    H>
    H>match(obj)
    H>{
    H>  | <[ $ctor as $(var : name) ]>     => случай_1
    H>  | <[ out $ctor as $(var : name) ]> => случай_2
    H>}
    H>


    Так тоже не хочет.. (found pattern expression () inside a raw expression)
    Собственно писал на пост выше..
    Re[8]: [Snippets] Обновленный макрос with
    От: hardcase Пират http://nemerle.org
    Дата: 02.04.11 10:34
    Оценка: 8 (1)
    Здравствуйте, BogdanMart, Вы писали:

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


    H>>Синтаксис трогать не нужно, я думаю достаточно этого:

    H>>
    H>>match(obj)
    H>>{
    H>>  | <[ $ctor as $(var : name) ]>     => случай_1
    H>>  | <[ out $ctor as $(var : name) ]> => случай_2
    H>>}
    H>>


    BM>Так тоже не хочет.. (found pattern expression () inside a raw expression)

    BM>Собственно писал на пост выше..

    С out действительно проблема.
    Но можно поступить несколько хитрее — искать mutable переменные в текущем контексте:

      /// syntax is <[ obj <- { Foo = bar; ... } ]>
      /// or <[ obj <- ( Foo = bar, ... ) ]>
      /// or <[ obj <- [ foo, bar, ... ] ]>
      public macro @<-(obj, initializer)
      {
        def obj = match(obj)
        {
          | <[ $obj as $(n : name) ]> => 
            match(Macros.ImplicitCTX().LocalContext.FindLocal(n))
            {
              | Some(localValue) when localValue.IsMutable =>
                Message.Hint(n.Location, $"case2, mutable variable name detected: $n");
    
              | _ =>
                Message.Hint(n.Location, $"case1, variable name detected: $n");
            }
            obj
    
          | <[ $obj as $n ]> => 
            Message.Error(n.Location, $"variable name expected, but `$n' found");
            obj
            
          | _ => obj
        }
    
        WithMacroImpl.Run(obj, initializer);
      }


    Т.о. семантика выражения Ctor() as x определяется наличием объявления mutable переменной x в текущем контексте.
    /* иЗвиНите зА неРовнЫй поЧерК */
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.