Добрый день! Возник вопрос: как мне вывести на экран некоторый AST во всех деталях? Я видел, что в базовых классах выражений перегружен метод ToString(), но он дает слишком мало информации для моего случая. Хотелось бы получить что-то вроде E_call(E_ref("f"), [Parm(E_ref("x"))] (как в разделе 9.1 статьи Метапрограммирование в Nemerle
Здравствуйте, xeno.by, Вы писали:
XB>Добрый день! Возник вопрос: как мне вывести на экран некоторый AST во всех деталях? Я видел, что в базовых классах выражений перегружен метод ToString(), но он дает слишком мало информации для моего случая. Хотелось бы получить что-то вроде E_call(E_ref("f"), [Parm(E_ref("x"))] (как в разделе 9.1 статьи Метапрограммирование в Nemerle
Если нужны детали, то имеет смысл не печатеть АСТ, а рассматривать его под отладчиком. Там можно все что угодно увидеть. Вставляешь в макрос assert2(flase), жмешь Retry в появившемся окне делаешь шаг, чтобы выйти из контекста assert-а и в окне Locals или Watch1 смотришь что в переменных.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Иногда хочется просто дампнуть текст — у меня, например, студия не установлена, и я пишу в емаксе. В любом случае, я нафигачил простенькую реализацию на рефлекшне. Кстати, приятно писать на Немерле — все базовые привычки после сишарпа работают. А вот к Скале мне пришлось пару дней привыкать =)
using System;
using System.Linq;
using System.Text;
using System.Console;
using System.Reflection;
using System.Reflection.BindingFlags;
using Nemerle.Compiler;
using Nemerle.Compiler.Parsetree;
class Helper
{
public static Render(this exprs : list[PExpr]) : String
{
def buf = StringBuilder();
buf.Append("[");
mutable first = true;
foreach (expr in exprs)
{
if (first) { first = false; }
else { buf.Append(", "); }
buf.Append(expr.Render());
}
buf.Append("]");
buf.ToString();
}
public static Render(this expr : PExpr) : String
{
def buf = StringBuilder();
def t = expr.GetType();
buf.Append(t.Name);
buf.Append("(");
mutable first = true;
foreach (f in t.GetFields(Public | Instance | DeclaredOnly))
{
if (first) { first = false; }
else { buf.Append(", "); }
buf.Append(f.Name);
buf.Append(" = ");
def v = f.GetValue(expr);
if (v is PExpr) buf.Append((v :> PExpr).Render());
else if (v is list[PExpr]) buf.Append((v :> list[PExpr]).Render());
else buf.Append(v.ToString());
}
buf.Append(")");
buf.ToString();
}
public static Dump(this exprs : list[PExpr]) : void
{
WriteLine(exprs.Render());
}
public static Dump(this expr : PExpr) : void
{
WriteLine(expr.Render());
}
}
Здравствуйте, xeno.by, Вы писали:
XB>Иногда хочется просто дампнуть текст — у меня, например, студия не установлена, и я пишу в емаксе. В любом случае, я нафигачил простенькую реализацию на рефлекшне.
Можно и так. Еще погляди темы FDSC. Он тоже пытался так АСТ изучать. Там кроме рефлекшона еще было решение на лифтинге через макро-апи.
XB>Кстати, приятно писать на Немерле — все базовые привычки после сишарпа работают. А вот к Скале мне пришлось пару дней привыкать =)
Дык потому я в свое время за немерл и взялся. С одной стороны намного привычнее, а с другой есть те самые макросы (которые меня и интересовали тогда).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, xeno.by, Вы писали:
XB>Кстати, приятно писать на Немерле — все базовые привычки после сишарпа работают. А вот к Скале мне пришлось пару дней привыкать =)
Да... Кстати, отвыкай. Эффективность повысится раз в 10, если освоишь продвинутые методы. Например, вот этот кусок кода:
О! Крутота!! На сишарпе я бы написал просто exprs.StringJoin(expr => expr.Render()), но тут у меня нету моей библиотечки с хелперами. Впрочем, твой вариант еще круче.
Здравствуйте, xeno.by, Вы писали:
XB>Кстати, дословно твой пример не прокатил — выдает ошибку unbound name `expr'.
Окей, надо было просто написать $<#..$(exprs; ", "; Render)#>. А что будет, если вызываемый метод требует более одного параметра? Как в таком случае сослаться на переменную итерации?
Здравствуйте, xeno.by, Вы писали:
XB>О! Крутота!! На сишарпе я бы написал просто exprs.StringJoin(expr => expr.Render()),
И получил бы создание временного объекта (делегата) и косвенный вызов на ровном месте. Плюс, все равно не достиг бы той же выразительности.
XB>но тут у меня нету моей библиотечки с хелперами. Впрочем, твой вариант еще круче.
Это как раз не проблема. Подключай библиотеку и пользуйся. Дотент, однако .
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, xeno.by, Вы писали:
XB>>Кстати, дословно твой пример не прокатил — выдает ошибку unbound name `expr'.
Это я лохонулся. Надо было так:
$<#..$(exprs; ", "; _.Render())#>
Это так называемое частичное применение. В скале его тоже вроде бы ввели. Кстати, как я понимаю, содрали с немерла.
Частичное применение это сахар для лямбд, заменяющий отсутствие автоматического каррирования.
XB>Окей, надо было просто написать $<#..$(exprs; ", "; Render)#>. А что будет, если вызываемый метод требует более одного параметра? Как в таком случае сослаться на переменную итерации?
А, понятно. Я думал, что там магический синтаксис, а это просто лямбда. Кстати, справедливости ради, подчеркивания как плейсхолдеры в лямбдах в скале были с самого начала, а самое начало было за несколько лет до Немерле.
Здравствуйте, xeno.by, Вы писали:
XB>А, понятно. Я думал, что там магический синтаксис, а это просто лямбда. Кстати, справедливости ради, подчеркивания как плейсхолдеры в лямбдах в скале были с самого начала, а самое начало было за несколько лет до Немерле.
Когда в 2006-ом я смотрел на Скалу, то частичного применения там не было. В то же время, в немерле это появилось в 2005 году или раньше.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>Когда в 2006-ом я смотрел на Скалу, то частичного применения там не было. В то же время, в немерле это появилось в 2005 году или раньше.
Виноват, обязательно уточню.
VD>Когда в 2006-ом я смотрел на Скалу, то частичного применения там не было. В то же время, в немерле это появилось в 2005 году или раньше.
Мартин говорит, что эту штуку для Скалы они придумали самостоятельно. Она, действительно, была не с самого начала. Но когда точно ее добавили — он не помнит, а в логах пока не нашел.
Здравствуйте, xeno.by, Вы писали:
XB>Мартин говорит, что эту штуку для Скалы они придумали самостоятельно. Она, действительно, была не с самого начала. Но когда точно ее добавили — он не помнит, а в логах пока не нашел.
Ну, все так всегда говорят . Единственное доказательство первенства — это дата коммита в котором реализована фича.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>Ну, все так всегда говорят . Единственное доказательство первенства — это дата коммита в котором реализована фича.
Жесть какая... Хочешь сказать, что независимых открытий в принципе не существует?
Здравствуйте, xeno.by, Вы писали:
XB>Жесть какая... Хочешь сказать, что независимых открытий в принципе не существует?
Бывают конечно. Но тут есть два "но". Во-первых, при этом они, обычно, не являются похожи как две капли воды. Во-вторых, независимое открытие велосипеда — это доказательство недалекости и лени велосипедостроителя. Он должен был изначально изучить имеющиеся конкурирующие продукты и узнать что в них есть интересного. Так что, на мой взгляд, независимое открытие велосипеда хуже чем завимсовование фичи.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, xeno.by, Вы писали:
XB>>Жесть какая... Хочешь сказать, что независимых открытий в принципе не существует?
VD>Бывают конечно.
Я тут поразмахиваю Схемой из 2002 года, чтобы вы не ссорились.
Здравствуйте, gerrCrazzy, Вы писали:
XB>>>Жесть какая... Хочешь сказать, что независимых открытий в принципе не существует?
VD>>Бывают конечно.
C>Я тут поразмахиваю Схемой из 2002 года, чтобы вы не ссорились.
А можно узнать чем конкретно ты решил по размахивать?
Мы тут вообще-то говорили о использования синтаксиса используемого в скале и немерле. Твоя ссылка имеет мало общего с этим синтаксисом. Разве что сама идея частичного применения без каринга.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Мы тут вообще-то говорили о использования синтаксиса используемого в скале и немерле. Твоя ссылка имеет мало общего с этим синтаксисом. Разве что сама идея частичного применения без каринга.
Мопед в общем-то не мой, но люди недавно реализовали частичное применение в Erlang именно с синтаксисом Nemerle:
Cut: This adds support for cuts to Erlang. These are inspired by the Scheme form of cuts.
Cuts can be thought of as a light-weight form of abstraction, with similarities to partial application (or currying).
Разумеется, есть вероятность того, что нам не договаривают, и вовсе не Scheme был прообразом этой фичи. Разработчики тупо ночью подсмотрели и утащили к себе Немеролвую реализацию.
Здравствуйте, gerrCrazzy, Вы писали:
C>Разумеется, есть вероятность того, что нам не договаривают, и вовсе не Scheme был прообразом этой фичи. Разработчики тупо ночью подсмотрели и утащили к себе Немеролвую реализацию.
Что там тащить то? Информация гуглится на наз. Немерл и Скала используют этот синтаксис уже более пяти лет. Надо очень стараться, чтобы не найти ее .
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.