Два дурацких вопроса по примеру реализации for
От: FDSC Россия consp11.github.io блог
Дата: 25.05.07 11:43
Оценка: :)
Есть такое
macro for(init, cond, change, body) 
syntax ("for", "(", init, ";", cond, ";", change, ")", body) 
{ 
  ... 
}


Чего-то я не понял, где вообще найти, как определяются границы body. Т.е. если там будут какие-то макросы или ещё что-то, где закончится body и начётся новый блок кода, уже не входящий в параметры макроса. А так же где находятся ограничение на применяемые символы в строках syntax, т.е. что нельзя писать внутри syntax, например syntax(",", "{") точно нельзя...


Второй вопрос
Пытался для развлечения определить свой макрос, по типу for
    macro forAll(j, j0, je, body)
    syntax("forAll", j, "=", "[", j0, ";", je, "]", body)
    {
        for(mutable j = j0; j <= je; j++)
        {
            body;
        }
    }


Пишет "Error 1 unbound type name 'IMacro'. Unbound type name 'Nemerle.Compiler.Location'. Unbound type name 'Nemerle.Compiler.Location'. Unbound type name 'PExpr'. Unbound type name 'SyntaxElement'. Unbound type name 'Typer'. Unbound type name 'SyntaxElement'. Unbound type name 'PExpr'. Unbound type name 'GrammarElement'. Unbound type name 'SyntaxElement'. Unbound type name 'SyntaxElement' F:\Prg\BarCalculator\Current\BarsCalculator\CalcProcessor\Численные методы\СЛАУ\MGauss.n 12 5 CalcProcessor"

В чём тут дело?
Re: Два дурацких вопроса по примеру реализации for
От: konsoletyper Россия https://github.com/konsoletyper
Дата: 25.05.07 13:39
Оценка: +2
Здравствуйте, FDSC, Вы писали:

FDS>Есть такое

FDS>
FDS>macro for(init, cond, change, body) 
FDS>syntax ("for", "(", init, ";", cond, ";", change, ")", body) 
FDS>{ 
FDS>  ... 
FDS>} 

FDS>


FDS>Чего-то я не понял, где вообще найти, как определяются границы body. Т.е. если там будут какие-то макросы или ещё что-то, где закончится body и начётся новый блок кода, уже не входящий в параметры макроса. А так же где находятся ограничение на применяемые символы в строках syntax, т.е. что нельзя писать внутри syntax, например syntax(",", "{") точно нельзя...


на место body будет подставлено выражение, следующее напосредственно за ")".


FDS>Второй вопрос

FDS>Пытался для развлечения определить свой макрос, по типу for
FDS>
FDS>    macro forAll(j, j0, je, body)
FDS>    syntax("forAll", j, "=", "[", j0, ";", je, "]", body)
FDS>    {
FDS>        for(mutable j = j0; j <= je; j++)
FDS>        {
FDS>            body;
FDS>        }
FDS>    }
FDS>


FDS>Пишет "Error 1 unbound type name 'IMacro'. Unbound type name 'Nemerle.Compiler.Location'. Unbound type name 'Nemerle.Compiler.Location'. Unbound type name 'PExpr'. Unbound type name 'SyntaxElement'. Unbound type name 'Typer'. Unbound type name 'SyntaxElement'. Unbound type name 'PExpr'. Unbound type name 'GrammarElement'. Unbound type name 'SyntaxElement'. Unbound type name 'SyntaxElement' F:\Prg\BarCalculator\Current\BarsCalculator\CalcProcessor\Численные методы\СЛАУ\MGauss.n 12 5 CalcProcessor"


FDS>В чём тут дело?


Во-первых, надо включить в референсы Nemerle.Compiler.dll. Во-вторых, у тебя неправильный код. Такой макрос должен возвращать что-либо типа PExpr, а у тебя вообще непонятно что делается. Надо бы юзать список и квазицитирование. В-третьих, на месте j0 и je будут не int'ы, а PExpr'ы. Надо их вручную обходить (тут поможет паттерн-матчинг, ещё надо учитывать, что синтаксиси декомпозиции AST похож на синтаксис квазицитирования) и проверять, чтобы в них были значения, вычислимые в compile-time. Или ты не этого пытался достичь?
... << RSDN@Home 1.2.0 alpha rev. 672>>
Re: Два дурацких вопроса по примеру реализации for
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.05.07 14:22
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Пытался для развлечения определить свой макрос, по типу for

FDS>
FDS>    macro forAll(j, j0, je, body)
FDS>    syntax("forAll", j, "=", "[", j0, ";", je, "]", body)
FDS>    {
FDS>        for(mutable j = j0; j <= je; j++)
FDS>        {
FDS>            body;
FDS>        }
FDS>    }
FDS>


Лучше опиши разговорным языком, что хочешь добиться и попробуем разобрать, что и как для этого нужно сделать. Думаю, это будет интересно и можно будет включить в одну из следующих частей статьи про макросы.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Два дурацких вопроса по примеру реализации for
От: FDSC Россия consp11.github.io блог
Дата: 25.05.07 16:02
Оценка:
Здравствуйте, VladD2, Вы писали:

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


FDS>>Пытался для развлечения определить свой макрос, по типу for

FDS>>
FDS>>    macro forAll(j, j0, je, body)
FDS>>    syntax("forAll", j, "=", "[", j0, ";", je, "]", body)
FDS>>    {
FDS>>        for(mutable j = j0; j <= je; j++)
FDS>>        {
FDS>>            body;
FDS>>        }
FDS>>    }
FDS>>


VD>Лучше опиши разговорным языком, что хочешь добиться и попробуем разобрать, что и как для этого нужно сделать. Думаю, это будет интересно и можно будет включить в одну из следующих частей статьи про макросы.


Блин... я опять забыл, что дерево нужно возвращать, а не просто писать выражения....

Ничего интересного, я просто хочу сделать for, но с другим синтаксисом. Т.е. вместо for (int i = 0; i < klsdajfhaklsdjh; i++) { что-то }
я должен смочь написать forAll i = [0; klsdajfhaklsdjh] { что-то }

Вот новая версия, только всё равно не хочет работать....
macro @forAll(j, j0, je, body)
    syntax("forAll", j, "=", "[", j0, ";", je, "]", body)
{ 

    def typer = Macros.ImplicitCTX ();
    
    def tj  = typer.TypeExpr(j);
    def tj0 = typer.TypeExpr(j0);
    def tje = typer.TypeExpr(je);
    
    def k = Nemerle.Macros.Symbol (Util.tmpname ("forAll_"));
    
    if (tj.Type.Require (<[ ttype: int ]>)/*tj.Type == <[ ttype: int ]> &&  tj0.Type == <[ ttype: int ]> && tje.Type == <[ ttype: int ]>*/)
    {
    <[
      for (mutable $(k: name) = $j0; $(k: name) <= $je; $(k: name)++)
      {
        body
      }
    ]>
    }
    else 
    {
        Message.Error("'forAll' j, j0, je must have type int, while it has $(tj.Type.ToString()),  $(tj0.Type.ToString()), $(tje.Type.ToString())");
        <[ () ]>
    }
}
}



Кто-нибудь может сказать, что делает "None ()" и что означают строки "$("_N_break" : global)" и "$("_N_continue" : global)" в этом макросе (из Core.n):

  macro @while (cond, body)
  syntax ("while", "(", cond, ")", body) 
  {
    def loop = Nemerle.Macros.Symbol (Util.tmpname ("while_"));

    <[ 
      $("_N_break" : global) : {
        def $(loop : name) () : void {
          when ($cond) {
            $("_N_continue" : global) : {
              $body 
            } 
            $(loop : name) ()
          }
        } 
        $(loop : name) (); 
      }
    ]>
  }


?



P.S. Пока я это всё делал, я замучал интеграцию до того, что она мне стала иногда выдавать

---------------------------
Assertion Failed: Abort=Quit, Retry=Debug, Ignore=Continue
---------------------------






    at NemerleLanguageService.Check(ParseRequest request)  

    at NemerleLanguageService.ParseSource(ParseRequest request)  

    at LanguageService.ParseRequest(ParseRequest req)  

    at LanguageService.ParseThread()  

    at ThreadHelper.ThreadStart_Context(Object state)  

    at ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)  

    at ThreadHelper.ThreadStart()  


---------------------------
Прервать   Повтор   Пропустить   
---------------------------



и ещё сам компилятор на это


if (tj.Type.Require (<[ ttype: mutable int ]>)


выдавал это

Error    10    Internal compiler error, please report a bug to bugs.nemerle.org. You can try modifying program near this location.    F:\Prg\BarCalculator\Current\BarsCalculator\CalcProcessor\CalcProcessor.n    26    30    CalcProcessor
Re[3]: Два дурацких вопроса по примеру реализации for
От: Kisloid Мухосранск  
Дата: 25.05.07 16:53
Оценка:
Здравствуйте, FDSC, Вы писали:

Может так?
using Nemerle.Compiler;


namespace Nemerle.Core
{
  macro @range (var : parameter, begin, end, body)
  syntax ("range", var, "in", "[", begin, ";", end, "]", body) 
  {
      match (var)
      {
          | <[ parameter : $(iname : name) : $ty ]> => 
              <[
                  for ($(iname : name) = $begin; $(iname : name) <= $end; $(iname : name)++)
                  {
                      $body
                  }
              ]>
          | _ =>
            Message.FatalError ("expected a single parameter for the range operator");
      }
  }
}


Пример использования:

using System;
using System.Console;

module Program
{
  Main() : void
  {
    mutable i : int;

    range i in [5; 7]
    {
        WriteLine($"$i");
    }

    ReadKey();
  }
}
((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))
Re[4]: Два дурацких вопроса по примеру реализации for
От: FDSC Россия consp11.github.io блог
Дата: 25.05.07 17:10
Оценка:
Здравствуйте, Kisloid, Вы писали:

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


K>Может так?


Не работает.


using System;
using System.Console;
using Nemerle.Utility;
using Nemerle.Compiler;

namespace VV
{
  macro @range (var : parameter, begin, end, body)
  syntax ("range", var, "in", "[", begin, ";", end, "]", body) 
  {
      match (var)
      {
          | <[ parameter : $(iname : name) : $ty ]> => 
              <[
                  for ($(iname : name) = $begin; $(iname : name) <= $end; $(iname : name)++)
                  {
                      $body
                  }
              ]>
          | _ =>
            Message.FatalError ("expected a single parameter for the range operator");
      }
  }

module Program
{
  Main() : void
  {
    mutable i : int;

    range i in [5; 7]
    {
        WriteLine($"$i");
    }
 
    
    _ = Console.ReadLine();
  }
}

}




Error    1    expected ';'. Parse error near identifier 'i': unexpected token after expression in sequence
    F:\Prg\tmp\070524\NilListCheck\Main.n    53    8    NilListCheck
Error    2    unbound name 'range'    F:\Prg\tmp\070524\NilListCheck\Main.n    53    2    NilListCheck
Error    3    expected `;'    F:\Prg\tmp\070524\NilListCheck\Main.n    53    9    NilListCheck
Error    4    parse error near identifier `i': unexpected token after expression in sequence    
F:\Prg\tmp\070524\NilListCheck\Main.n    53    9    NilListCheck


К тому же, макрос сам должен объявлять счётчик цикла. Т.е. выражение должно быть написано в декларативном стиле,
для всех i из диапазона такого-то то-то и то-то. При этом если в следующий раз опять будет написана та же переменная i = [], то не должно возникнуть ошибки компиляции. Т.е. цикл должен выглядеть как декларативное описание диапазона значения переменной и операции, которая в этом диапазоне значений производится
Re[5]: Два дурацких вопроса по примеру реализации for
От: Kisloid Мухосранск  
Дата: 25.05.07 17:34
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>[c#]

FDS>using System;
FDS>using System.Console;
FDS>using Nemerle.Utility;
FDS>using Nemerle.Compiler;

FDS>namespace Nemerle.Core

FDS>{

<skipped>
((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))
Re[5]: Два дурацких вопроса по примеру реализации for
От: ie Россия http://ziez.blogspot.com/
Дата: 25.05.07 17:40
Оценка: 1 (1)
Здравствуйте, FDSC, Вы писали:

FDS>Не работает.


1. Вынеси марос в отдельную сборку.
2. Компилятор как-то неравнодушен к in в макросе, причем иногда ему пофиг, а иногда начинает странно материться.

//a.n
using Nemerle.Compiler;

namespace MyMacros
{
  macro @range (var, begin, end, body)
  syntax ("range", var, "_in_", "[", begin, ";", end, "]", body) 
  {
    <[
      for (mutable $var = $begin; $var <= $end; $var++)
      {
        $body
      }
    ]>
  }
}

Компилим в a.dll: ncc a.n /r:Nemerle.Compiler.dll /out:a.dll /t:dll

// b.n
using System;
using System.Console;
using MyMacros;

module Program
{
  Main() : void
  {
    range i _in_ [5; 7]
    {
        WriteLine($"$i");
    }
  }
}

Компилим: ncc b.n /r:a.dll

Вроде все должно заработать...
... << RSDN@Home 1.2.0 alpha rev. 655>>
Превратим окружающую нас среду в воскресенье.
Re[5]: Два дурацких вопроса по примеру реализации for
От: Kisloid Мухосранск  
Дата: 25.05.07 17:45
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>К тому же, макрос сам должен объявлять счётчик цикла. Т.е. выражение должно быть написано в декларативном стиле,


Дык:
  macro @range (var : parameter, begin, end, body)
  syntax ("range", var, "in", "[", begin, ";", end, "]", body) 
  {
      match (var)
      {
          | <[ parameter : $(iname : name) : $ty ]> =>
             <[
                 mutable $(iname : name) : int;
                  for ($(iname : name) = $begin; $(iname : name) <= $end; $(iname : name)++)
                  {
                      $body
                  }
              ]>
          | _ =>
              Message.FatalError ("expected a single parameter for the range operator");
      }
  }
((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))
Re[6]: Два дурацких вопроса по примеру реализации for
От: Kisloid Мухосранск  
Дата: 25.05.07 17:50
Оценка:
Здравствуйте, ie, Вы писали:

ie>2. Компилятор как-то неравнодушен к in в макросе, причем иногда ему пофиг, а иногда начинает странно материться.


Ага, т.к. оказывается есть такое ключевое слово. А я и не знал
((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))
Re[6]: Два дурацких вопроса по примеру реализации for
От: FDSC Россия consp11.github.io блог
Дата: 25.05.07 18:30
Оценка:
Здравствуйте, Kisloid, Вы писали:

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


FDS>>К тому же, макрос сам должен объявлять счётчик цикла. Т.е. выражение должно быть написано в декларативном стиле,


K>Дык:

K>
K>  macro @range (var : parameter, begin, end, body)
K>  syntax ("range", var, "in", "[", begin, ";", end, "]", body) 
K>  {
K>      match (var)
K>      {
K>          | <[ parameter : $(iname : name) : $ty ]> =>
K>             <[
K>                 mutable $(iname : name) : int;
K>                  for ($(iname : name) = $begin; $(iname : name) <= $end; $(iname : name)++)
K>                  {
K>                      $body
K>                  }
K>              ]>
K>          | _ =>
K>              Message.FatalError ("expected a single parameter for the range operator");
K>      }
K>  }
K>


А теперь объясните кто-нибудь почему она не выдаёт ошибку, если используешь этот макрос два раза с одной и той же переменной (а он не выдаёт...)

Да и ещё, что обозначают эти строки?
K>  macro @range (var : parameter, begin, end, body)



| <[ parameter : $(iname : name) : $ty ]> =>


и почему компилятор не придирается к

Message.FatalError ("expected a single parameter for the range operator");

Message.FatalError разве что-то возвращает?
Re[7]: Два дурацких вопроса по примеру реализации for
От: Kisloid Мухосранск  
Дата: 25.05.07 18:52
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>А теперь объясните кто-нибудь почему она не выдаёт ошибку, если используешь этот макрос два раза с одной и той же переменной (а он не выдаёт...)


Пример? Я на словах не совсем понимаю, что ты имеешь ввиду.

FDS>Да и ещё, что обозначают эти строки?

FDS>
K>>  macro @range (var : parameter, begin, end, body)


FDS>| <[ parameter : $(iname : name) : $ty ]> =>
FDS>


Вкратце, это для того первоначального моего варианта, когда я принимал переменную как параметр. И вообще, забудь про мой пример, он неправильный Смотри на пример приведенный ie, красивое и правильное решение.

FDS>и почему компилятор не придирается к


FDS>
FDS>Message.FatalError ("expected a single parameter for the range operator");
FDS>

FDS>Message.FatalError разве что-то возвращает?

А почему он должен к нему придираться? Незнаю точно, что он возвращает, но могу предположить, что (). Это просто вывод сообщения об ошибке компилятором.
((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))
Re[8]: Два дурацких вопроса по примеру реализации for
От: FDSC Россия consp11.github.io блог
Дата: 25.05.07 19:12
Оценка:
Здравствуйте, Kisloid, Вы писали:

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


FDS>>А теперь объясните кто-нибудь почему она не выдаёт ошибку, если используешь этот макрос два раза с одной и той же переменной (а он не выдаёт...)


K>Пример? Я на словах не совсем понимаю, что ты имеешь ввиду.


Код
    range i in [5; 7]
    {
        WriteLine($"$i");
    }
 
 
    range i in [3; 6]
    {
        WriteLine($"$i");
    }

Компилируется без ошибок и работает как и предполагается
Должна же быть ошибка переопределения переменной (именно в твоём макросе она же определяется не в цикле for)


Кстати, зачем там перед "$i"? Мне всё время казалось, что и так должно работать... а оказывается нет?

FDS>>Да и ещё, что обозначают эти строки?

FDS>>
K>>>  macro @range (var : parameter, begin, end, body)


FDS>>| <[ parameter : $(iname : name) : $ty ]> =>
FDS>>


K>Вкратце, это для того первоначального моего варианта, когда я принимал переменную как параметр. И вообще, забудь про мой пример, он неправильный Смотри на пример приведенный ie, красивое и правильное решение.


FDS>>и почему компилятор не придирается к


FDS>>
FDS>>Message.FatalError ("expected a single parameter for the range operator");
FDS>>

FDS>>Message.FatalError разве что-то возвращает?

K>А почему он должен к нему придираться? Незнаю точно, что он возвращает, но могу предположить, что (). Это просто вывод сообщения об ошибке компилятором.


Ну я и говорю, что вроде как макрос всё равно же должен вернуть PExpr или как там этот тип называется
Re[6]: Можно ли это сделать с "="
От: FDSC Россия consp11.github.io блог
Дата: 25.05.07 19:22
Оценка:
Здравствуйте, ie, Вы писали:

ie>
ie>namespace MyMacros
ie>{
ie>  macro @range (var, begin, end, body)
ie>  syntax ("range", var, "_in_", "[", begin, ";", end, "]", body) 
ie>  {
ie>    <[
ie>      for (mutable $var = $begin; $var <= $end; $var++)
ie>      {
ie>        $body
ie>      }
ie>    ]>
ie>  }
ie>}
ie>

ie>Компилим в a.dll: ncc a.n /r:Nemerle.Compiler.dll /out:a.dll /t:dll

ie>Вроде все должно заработать...


Вроде правда работает, НО

мне бы хотелось использовать именно "=", а не "in". В этом примере не проходит просто заменить... не хочет


Пытался сделать так
  macro @range (varI, begin, end, body)
  syntax ("range", varI, "[", begin, ";", end, "]", body) 
  {
    
     match(varI)
     {
         | <[ $(var : name) = $empty ]> => <[
      for (mutable $var = $begin; $var <= $end; $var++)
      {
        $body
      }
    ]>
         | _ => Message.FatalError ("expected a single parameter for the range operator");
     }
  }

но тоже не работает, причём, вроде, именно не понимает, что равно тоже относится к параметру макроса
Re[7]: Обшибочка
От: FDSC Россия consp11.github.io блог
Дата: 25.05.07 22:03
Оценка:
Здравствуйте, FDSC, Вы писали:

Читать листинг так:
FDS>
FDS>  macro @range (varI, begin, end, body)
FDS>  syntax ("range", varI, "[", begin, ";", end, "]", body) 
FDS>  {
    
FDS>     match(varI)
FDS>     {
FDS>         | <[ $var = $empty ]> => <[
FDS>      for (mutable $var = $begin; $var <= $end; $var++)
FDS>      {
FDS>        $body
FDS>      }
FDS>    ]>
FDS>         | _ => Message.FatalError ("expected a single parameter for the range operator");
FDS>     }
FDS>  }
FDS>


Хотя, какая разница, если не работает?
Re[9]: Два дурацких вопроса по примеру реализации for
От: Kisloid Мухосранск  
Дата: 26.05.07 08:35
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Компилируется без ошибок и работает как и предполагается

FDS>Должна же быть ошибка переопределения переменной (именно в твоём макросе она же определяется не в цикле for)

Для Немерла это нормально, т.е. такой код:
def x = 5;
def x = 10;

В порядке вещей, т.е. переменные можно переопределять.


FDS>Кстати, зачем там перед "$i"? Мне всё время казалось, что и так должно работать... а оказывается нет?


Это так называемая активная область, если не ошибаюсь. Т.е. вместо $i будет подставлено значение i.
На самом деле для начала не помешало бы прочитать вводную статью по Немерлу здесь на сайте.


K>>А почему он должен к нему придираться? Незнаю точно, что он возвращает, но могу предположить, что (). Это просто вывод сообщения об ошибке компилятором.


FDS>Ну я и говорю, что вроде как макрос всё равно же должен вернуть PExpr или как там этот тип называется


Ничего он не должен возвращать, он просто кидает эксепшн.
((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))
Re[9]: Два дурацких вопроса по примеру реализации for
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.05.07 11:14
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Код

FDS>
FDS>    range i in [5; 7]
FDS>    {
FDS>        WriteLine($"$i");
FDS>    }
 
 
FDS>    range i in [3; 6]
FDS>    {
FDS>        WriteLine($"$i");
FDS>    }
FDS>

FDS>Компилируется без ошибок и работает как и предполагается
FDS>Должна же быть ошибка переопределения переменной (именно в твоём макросе она же определяется не в цикле for)

1. Каждый макрос разворачивается в отдельное выражение. Если макрос возвращает несколько выражений, то они в обязательном порядке помещаются в блок кода. Так что если бы даже переменные бпересекались, то они разруливались бы по областям видимости:
{
  mutable x = ...; // в одной области видимости
    ...
}
{
  mutable x = ...; // в другой области видимости
    ...
}

2. В макросах Немерле применяется так называемая "гигиена". Это значит, что по-умолчанию все генерируемые переменные специальным образом переименовываются компилятором и не пересекаются с другими такими же, но объявленными в других местах. Именам как бы придаются оттенки (цвета). Если нужно явно обратиться к переменной из области объявления нужно сказать об этом компилятору специльным образом. Например так:
<[ $("someName" : usesite) = 0; ]>

в данном случае мы порождаем код иземяющий значение переменной с именем someName из основного кода.
Кроме того можно переключиться в режим использования "цветов" области кода вызвав метод Manager.MacroColors.PushUseSiteColor(). При этом важно в последствии не забыть вызвать метод Manager.MacroColors.PopColor() который вернет обратно текущие цвета.

FDS>Кстати, зачем там перед "$i"? Мне всё время казалось, что и так должно работать... а оказывается нет?


Да, это соврешенно бессмысленный код. Видимо работают стереотипы.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Два дурацких вопроса по примеру реализации for
От: Kisloid Мухосранск  
Дата: 26.05.07 13:50
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Да, это соврешенно бессмысленный код. Видимо работают стереотипы.


Никакие не стереотипы, просто изначально хотел вывести строку с комментариями, что то вроде этого:
WriteLine($"Для i = $i из диапазона... бла бла");
((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))
Re[7]: Можно ли это сделать с "="
От: ie Россия http://ziez.blogspot.com/
Дата: 26.05.07 14:24
Оценка:
Здравствуйте, FDSC, Вы писали:

ie>>Вроде все должно заработать...

FDS>Вроде правда работает, НО
FDS>мне бы хотелось использовать именно "=", а не "in". В этом примере не проходит просто заменить... не хочет

Я думаю использовать "=" так просто не получится. Компилятор будет расценивать это использование как assignment.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Превратим окружающую нас среду в воскресенье.
Re[11]: Два дурацких вопроса по примеру реализации for
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.05.07 17:51
Оценка:
K>Никакие не стереотипы, просто изначально хотел вывести строку с комментариями, что то вроде этого:
K>
K>WriteLine($"Для i = $i из диапазона... бла бла");
K>


Ну, нихай. В любом случае ничего нужного в этоем нет. WriteLine перегружен для всех простых типов данных и на крайняк принимает object.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Можно ли это сделать с "="
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.05.07 17:51
Оценка:
Здравствуйте, ie, Вы писали:

ie>Я думаю использовать "=" так просто не получится. Компилятор будет расценивать это использование как assignment.


Значич так. Можно делать почти все что угодно, но по хитрому.

Как? Смотрите как реализован foreach:
  macro @foreach (inexpr, body)
  syntax ("foreach", "(", inexpr, ")", body)
  {
    ...

Как видите никаких in в помине нет. Вместо этого мы получаем некое (абстрактное) выражение inexpr.

Далее inexpr обрабатывается паттерн-матчингом и из него вычленяются нужные конструкции. Естественно, что если они не вычленелись, то мы имеем дело с ошибочным синтаксисом. Собственно пример из того же foreach-а:
def (iter, collection) =
    match (inexpr) {
        | <[ $i in $c ]> => (i, c)
        | e =>
            Message.FatalError ($ "the syntax is 'foreach (x in collection)', "
                                                        "got $e");
    }

Никаких проблем в том, чтобы заменить "in" на "=" нет.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Два дурацких вопроса по примеру реализации for
От: Kisloid Мухосранск  
Дата: 27.05.07 07:25
Оценка:
Здравствуйте, VladD2, Вы писали:

K>>Никакие не стереотипы, просто изначально хотел вывести строку с комментариями, что то вроде этого:

K>>
K>>WriteLine($"Для i = $i из диапазона... бла бла");
K>>


VD>Ну, нихай. В любом случае ничего нужного в этоем нет. WriteLine перегружен для всех простых типов данных и на крайняк принимает object.


Да согласный я, облажался, писал это на подсознательном уровне, не задумываясь. Да и по мне удобнее писать так:
WriteLine($"Arg1 = $arg1, Arg2 = $arg2, Arg3 = $arg3 ...");

чем так:
WriteLine("Arg1 = " + arg1 + ", Arg2 = " + arg2 + ", Arg3 = " + arg3 + " ...");

или еще хуже:
WriteLine("Arg1 = {0}, Arg2 = {1}, Arg3 = {2} ...", arg1, arg2, arg3);

((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))
Re[13]: Два дурацких вопроса по примеру реализации for
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.05.07 14:41
Оценка:
Здравствуйте, Kisloid, Вы писали:

K> Да и по мне удобнее писать так:

K>
K>WriteLine($"Arg1 = $arg1, Arg2 = $arg2, Arg3 = $arg3 ...");
K>

K>чем так:
K>
K>WriteLine("Arg1 = " + arg1 + ", Arg2 = " + arg2 + ", Arg3 = " + arg3 + " ...");
K>


+1

K>или еще хуже:

K>
K>WriteLine("Arg1 = {0}, Arg2 = {1}, Arg3 = {2} ...", arg1, arg2, arg3);
K>


А вот это уже завист.
У такого способа есть свои приемущества которых нельзя достичь средствами $-строки.
1. Можно применять расширенное форматирвоание.
2. Можно заменять строку формата динамически.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Можно ли это сделать с "="
От: FDSC Россия consp11.github.io блог
Дата: 27.05.07 17:27
Оценка:
Здравствуйте, VladD2, Вы писали:

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


ie>>Я думаю использовать "=" так просто не получится. Компилятор будет расценивать это использование как assignment.


VD>Значич так. Можно делать почти все что угодно, но по хитрому.


VD>Как? Смотрите как реализован foreach:

VD>
VD>  macro @foreach (inexpr, body)
VD>  syntax ("foreach", "(", inexpr, ")", body)
VD>  {
VD>    ...
VD>

VD>Как видите никаких in в помине нет. Вместо этого мы получаем некое (абстрактное) выражение inexpr.

VD>Далее inexpr обрабатывается паттерн-матчингом и из него вычленяются нужные конструкции. Естественно, что если они не вычленелись, то мы имеем дело с ошибочным синтаксисом. Собственно пример из того же foreach-а:

VD>
VD>def (iter, collection) =
VD>    match (inexpr) {
VD>        | <[ $i in $c ]> => (i, c)
VD>        | e =>
VD>            Message.FatalError ($ "the syntax is 'foreach (x in collection)', "
VD>                                                        "got $e");
VD>    }
VD>

VD>Никаких проблем в том, чтобы заменить "in" на "=" нет.

Угу, тут слишком хитро... дело в том, что foreach( вполне может восприниматься компилятором как начало явного вызова макроса,
а вот forAll i = [0; 1] так восприниматься не будет, потому что в синтаксисе нет открывающей скобки



  macro @forAll (varI, begin, end, body)
  syntax ("forAll", varI, "[", begin, "..", end, "]", body) 
  {
    
     match(varI)
     {
         | <[ $var = $empty ]> => <[
          for (mutable $var = $begin; $var <= $end; $var++)
      {
        $body
      }
    ]>
         | _ => <[()]>
     }
  }
  
  macro @forAllBad (varI, body)
  syntax ("forAllBad", "(", varI, ")", body) 
  {
    
     match(varI)
     {
         | <[ $var = [$begin , $end] ]> => <[
          for (mutable $var = $begin; $var <= $end; $var++)
      {
        $body
      }
    ]>
         | _ => <[()]>
     }
  }




        // Здесь ошибка разбора
    forAll i = [5 .. 7]
    {
        WriteLine($"$i");
    }
 
     // Здесь её нет
    forAllBad(i = [3, 6])
    {
        WriteLine($"$i");
    }



Error    1    parse error near '{...}' group: expecting '[' and some tokens inside. Parse error near '{...}' group: unexpected end of token sequence. Parse error near separator or closing bracket: expecting expression    F:\Prg\tmp\070524\NilListCheck\Main.n    33    2    NilListCheck
Error    2    unable to parse syntax rule, stopped at: ]. Parse error    F:\Prg\tmp\070524\NilListCheck\Main.n    32    2    NilListCheck
Error    5    parse error near `{...}' group: expecting `[' and some tokens inside    F:\Prg\tmp\070524\NilListCheck\Main.n    33    3    NilListCheck
Error    6    parse error near `{...}' group: unexpected end of token sequence    F:\Prg\tmp\070524\NilListCheck\Main.n    33    3    NilListCheck
Error    7    parse error near separator or closing bracket: expecting expression    F:\Prg\tmp\070524\NilListCheck\Main.n    33    3    NilListCheck
Error    8    parse error near `{...}' group: unexpected end of token sequence    F:\Prg\tmp\070524\NilListCheck\Main.n    33    3    NilListCheck
Error    9    parse error near separator or closing bracket: expecting operator `..'    F:\Prg\tmp\070524\NilListCheck\Main.n    33    3    NilListCheck
Error    10    parse error near `{...}' group: unexpected end of token sequence    F:\Prg\tmp\070524\NilListCheck\Main.n    33    3    NilListCheck
Error    11    parse error near separator or closing bracket: expecting expression    F:\Prg\tmp\070524\NilListCheck\Main.n    33    3    NilListCheck
Error    12    unable to parse syntax rule, stopped at: ]    F:\Prg\tmp\070524\NilListCheck\Main.n    32    3    NilListCheck





P.S. Я правильно понял что чтобы получить доступ к глобальной переменной из макроса её нужно просто указать внутри <[]> как обычный код,
например вызов глобальных функций Exec и т.п. и создание локальной переменной mutexs, видной только в области определения именно этого макроса, будет выглядеть как-то так

macro тры-ты-ты
{
       def mutexs = Nemerle.Macros.Symbol (Util.tmpname ("forAllPT_"));
<[
       if ($end - $begin >= 0)
       {
       def $(mutexs:name): array[object] = CreateWait($end - $begin + 1);

       for (mutable $var = $begin; $var <= $end; $var++)
         {
           Exec($(mutexs:name)[$var]);
         }
         Wait($(mutexs:name));
       }
    ]>
}

?
Re[10]: Можно ли это сделать с "="
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.05.07 19:56
Оценка:
Здравствуйте, FDSC, Вы писали:

Зачем так оверквотить?

FDS>Угу, тут слишком хитро... дело в том, что foreach( вполне может восприниматься компилятором как начало явного вызова макроса,

FDS>а вот forAll i = [0; 1] так восприниматься не будет, потому что в синтаксисе нет открывающей скобки

Ну, и что мешает добавит их? С ними стиль будет ближе к стандартным макросам.

Немерел разбирает код специальным образом разбивая лексемы на группы. Группы делятся в основном по скобкам. По этому без них будет жить тяжело.

FDS>P.S. Я правильно понял что чтобы получить доступ к глобальной переменной из макроса её нужно просто указать внутри <[]> как обычный код,


Не савсем. По умолчанию будет работать гигиена и все имена объявленные внутри макроса будут переименовываться (к ним будет добаляться номер "цвета"). Здесь
Автор: VladD2
Дата: 26.05.07
сказано как это обойти.

FDS>например вызов глобальных функций Exec


Вызовы будут рабтать и так. Тут речь идет только о вводимых в макросах переменных.

FDS> и т.п. и создание локальной переменной mutexs, видной только в области определения именно этого макроса, будет выглядеть как-то так


FDS>
FDS>macro тры-ты-ты
FDS>{
FDS>       def mutexs = Nemerle.Macros.Symbol (Util.tmpname ("forAllPT_"));
FDS><[
FDS>       if ($end - $begin >= 0)
FDS>       {
FDS>       def $(mutexs:name): array[object] = CreateWait($end - $begin + 1);

FDS>       for (mutable $var = $begin; $var <= $end; $var++)
FDS>         {
FDS>           Exec($(mutexs:name)[$var]);
FDS>         }
FDS>         Wait($(mutexs:name));
FDS>       }
FDS>    ]>
FDS>}
FDS>

FDS>?

В данном случае mutexs как раз будет превращаться в автоматически переименовываемую переменную (которая не пересечется с такой же из другого контекста). Так что можно было бы просто этого не делать, так как по умолчанию имена переменных и так уникальны. Если нужен доступ к переменным из области объявления, то их нужно передавать как переменные (т.е. mutexs должен был быть вычленен из переданного кода), объявляться с использованием $(... : usesite), или нужно модифицировать контес с помощью фунции Manager.MacroColors.PushUseSiteColor().
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Можно ли это сделать с "="
От: FDSC Россия consp11.github.io блог
Дата: 27.05.07 20:33
Оценка:
Здравствуйте, VladD2, Вы писали:

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


VD>Зачем так оверквотить?


Что, сильно? Я просто всегда забываю, что было до этого и когда убирают цитаты, меня обычно разражает сильно

VD>Ну, и что мешает добавит их? С ними стиль будет ближе к стандартным макросам.


А если мне хочется, что бы это была именно конструкция без скобок? Ещё одни скобки, лишние символы... просто удобнее было бы

В принципе, мне, например, вообще не хватает Matlab-овского (или хотя бы PL-евского) синтаксиса, когда можно написать k = A(1:6, 2:5) и в итоге из A скопируются данные с 1-ой по 6-ую строки со 2-ого по 5-ый столбец... всё-таки это было бы удобнее, в конце концов Nemerle не только функциональный язык
А как такое сделать, я вообще не представляю, опять, наверняка будут какие-нибудь заморочки и ничего нормально не получится


VD>Не савсем. По умолчанию будет работать гигиена и все имена объявленные внутри макроса будут переименовываться (к ним будет добаляться номер "цвета"). Здесь
Автор: VladD2
Дата: 26.05.07
сказано как это обойти.


А, спасибо, теперь дошло. Как раз использовать их дальше не нужно
Re[12]: Можно ли это сделать с "="
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.05.07 13:10
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>В принципе, мне, например, вообще не хватает Matlab-овского (или хотя бы PL-евского) синтаксиса, когда можно написать k = A(1:6, 2:5) и в итоге из A скопируются данные с 1-ой по 6-ую строки со 2-ого по 5-ый столбец... всё-таки это было бы удобнее, в конце концов Nemerle не только функциональный язык

FDS>А как такое сделать, я вообще не представляю,

По идее, создаешь макрос A с двумя параметарами и их уже паттерн-матчингом обрабатываешь. Тут делать нечего. Я бы скорее подумал насколько это нужно. Ведь не всем этот синтаксис будет очевидным.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Можно ли это сделать с "="
От: FDSC Россия consp11.github.io блог
Дата: 28.05.07 15:35
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>По идее, создаешь макрос A с двумя параметарами и их уже паттерн-матчингом обрабатываешь. Тут делать нечего. Я бы скорее подумал насколько это нужно. Ведь не всем этот синтаксис будет очевидным.


А — это не макрос, а массив... имени макроса тут нет

Если непонятно, могу пояснить подробнее.

Например, перемножение матриц A и B в MatLab может выглядеть так


i = 1:L;
j = 1:K;
C(i, j) = A(i, :) * B(:, j);



На Nemerle (без макросов) это выглядит так:

for (mutable i = 0; i < L; i++)
  for (mutable j = 0; j < K; j++)
  {
    C[i, j] = 0.0;
    for (mutable k = 0; k < M; k++)
      C[i, j] += A[i, k] * B[k, j];
  }


Ну, перемножение можно сделать и функцией, но бывают вещи по сложнее, которые с "векторным" синтаксисом выглядят гораздо лучше. Вот у меня впечатление, что сделать такую вещь с помощью макросов в Немерле невозможно...
Re[14]: Можно ли это сделать с "="
От: ie Россия http://ziez.blogspot.com/
Дата: 29.05.07 04:56
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Например, перемножение матриц A и B в MatLab может выглядеть так


FDS>
FDS>i = 1:L;
FDS>j = 1:K;
FDS>C(i, j) = A(i, :) * B(:, j);
FDS>


А на J так:
c =. a * b


Только вот делать из Nemerle J или Matlab, наверное, не стоит.

FDS>На Nemerle (без макросов) это выглядит так:

...
FDS>Ну, перемножение можно сделать и функцией, но бывают вещи по сложнее, которые с "векторным" синтаксисом выглядят гораздо лучше. Вот у меня впечатление, что сделать такую вещь с помощью макросов в Немерле невозможно...

Да, на Немерле далеко не все возможно, но так ли это плохо? Нужны мега-вычисления, возьми J или Matlab, нужны логические вычисления — пролог в руки, благо и то и то имеет возможность интегрироваться с .NET
... << RSDN@Home 1.2.0 alpha rev. 0>>
Превратим окружающую нас среду в воскресенье.
Re[15]: Можно ли это сделать с "="
От: FDSC Россия consp11.github.io блог
Дата: 29.05.07 10:44
Оценка:
Здравствуйте, ie, Вы писали:

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


FDS>>Например, перемножение матриц A и B в MatLab может выглядеть так


FDS>>
FDS>>i = 1:L;
FDS>>j = 1:K;
FDS>>C(i, j) = A(i, :) * B(:, j);
FDS>>


ie>А на J так:

ie>
ie>c =. a * b
ie>


В MatLab то же так можно, я показал суммирование в общем виде, когда можно брать только те столбцы, которые хочешь

ie>Только вот делать из Nemerle J или Matlab, наверное, не стоит.




ie>Да, на Немерле далеко не все возможно, но так ли это плохо? Нужны мега-вычисления, возьми J или Matlab, нужны логические вычисления — пролог в руки, благо и то и то имеет возможность интегрироваться с .NET


Хм. Это, конечно, можно, но мне Немерле понравился. Да и потом, J — совершенно незнакомый язык и, вполне возможно, там нет вложенных функций, а MatLab вообще страдает производительностью
Re[14]: Можно ли это сделать с "="
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.06.07 00:39
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>На Nemerle (без макросов) это выглядит так:


FDS>
FDS>for (mutable i = 0; i < L; i++)
FDS>  for (mutable j = 0; j < K; j++)
FDS>  {
FDS>    C[i, j] = 0.0;
FDS>    for (mutable k = 0; k < M; k++)
FDS>      C[i, j] += A[i, k] * B[k, j];
FDS>  }
FDS>


FDS>Ну, перемножение можно сделать и функцией, но бывают вещи по сложнее, которые с "векторным" синтаксисом выглядят гораздо лучше. Вот у меня впечатление, что сделать такую вещь с помощью макросов в Немерле невозможно...


Тут скорее не макросы нужны, а инкапсуляция матриц в абстрактном типе данных поддерживающем необъодимые операторы. Потипу DateTime.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Два дурацких вопроса по примеру реализации for
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.06.07 21:42
Оценка:
Здравствуйте, FDSC, Вы писали:

Может заинтересует...

Re[3]: Как добраться до реального типа PExpr?
Автор: VladD2
Дата: 20.06.07
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.