Сообщающиеся макросы
От: _Claus_  
Дата: 19.11.11 13:11
Оценка:
Недавно была дискуссия и ее фрагмент:

_С_ >> В Boo вложенный макрос видит своего содержателя через переменную с его именем, и соответственно может там менять дописывать все что вздумается.

VladD2 >> В немерле просто не понадобится вложенный макрос.
Тут другие принципы. Обычно в Н для таких случае создают макро-атрибут который вешают на сборку или тип и он распознает нужный синтаксис и формирует нужный код.

Прочитав статьи расширенного курса о макросах так и не смог понять, как мне решить одну из своих задач.
Опишу задачу, чтобы всем понятно, зачем оно такое..

Самый быстрый механизм работы СУБД через MemoryMapped Files. в net 4.0 появилась возможность напрямую с ними работать, ессно с ограничениями,
но все же. Обмен данных возможен только структурами. У меня классы. Задача: по описанию класса сгенерить структуру + вспомогательный код.

У меня было в Boo так:
Persist X
{  
   VAL a as int
   REF b as string
   REFVAL values as SortList of X
   ..
}


Вложенные макросы VAL, REF,.. создавали защищенные свойства,
добавляли о себе инфу макросу Persist, который потом разворачивал ее в структуру с такими или другими полями и методы.

Теперь в Н я не вижу как сделать то же самое. Макросы отметаем, берем макроатрибуты. Имеет проблемы:
явно объявленное поле (избыточное объявление имеем сразу — mutable оно всегда) надо трансформировать в property
c кодом. вероятно возможно, но дальше, куда кидать информацию о себе ? — если Persist макрос отработал, она уже бесполезна,
если нет, то как ему передать нужные данные? Если все же возможно, все равно есть явная проблема,
если вложенные макроатрибуты работают до атрибута Persist, им некуда регистрировать информацию о себе, если после,
она уже бесполезна.

Что робыть?
Re: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.11.11 20:45
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>У меня было в Boo так:

_C_>Persist X
_C_>{  
_C_>   VAL a as int
_C_>   REF b as string
_C_>   REFVAL values as SortList of X
_C_>   ..
_C_>}


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

[Persist]
class X
{  
   public [VAL]    a      : int         { get; set; }
   public [REF]    b      : string      { get; set; }
   public [REFVAL] values : SortList[X] { get; set; }
   ...
}


_C_>Вложенные макросы VAL, REF,.. создавали защищенные свойства,

_C_>добавляли о себе инфу макросу Persist, который потом разворачивал ее в структуру с такими или другими полями и методы.

Тут вариантов может быть масса.
1. VAL, REF и REFVAL могут быть обычными атрибутами. Макрос Persist может читать информацию о полях, и за одно, информацию об атрибутах VAL, REF и REFVAL.
2. VAL, REF и REFVAL можно сделать марками работающими на ранних стадиях. Они могут делать что вам надо плюс добавлять в UserData TypeBuilder-а для типа X необходимую информацию. Persist, работающий на более поздней стадии, сможет прочесть эту информацию и сгенерировать то что нужно (структуру и что угодно еще).

_C_>Теперь в Н я не вижу как сделать то же самое. Макросы отметаем, берем макроатрибуты. Имеет проблемы:

_C_>явно объявленное поле (избыточное объявление имеем сразу — mutable оно всегда) надо трансформировать в property c кодом.

Объявляй сразу свойства. Можешь и mutable сам подставить, если нужно. Только это может запутать других.

_C_>вероятно возможно, но дальше, куда кидать информацию о себе ?


В свойство UserData объекта в котором объявляются свойства и применяется атрибут Persist.

_C_>- если Persist макрос отработал, она уже бесполезна,

_C_>если нет, то как ему передать нужные данные?

Реализуй Persist на более поздней стадии и все будет ОК. Он сможет читать информацию из UserData. Засунь в UserData хэш-таблицу в которой заложи нужную информацию (ключ имя свойства, значение — нужная информация).

_C_> Если все же возможно, все равно есть явная проблема,

_C_>если вложенные макроатрибуты работают до атрибута Persist, им некуда регистрировать информацию о себе, если после,
_C_>она уже бесполезна.

Ну, я уже выше описал два подхода.
1. Сделать VAL обычными атрибутами и разбираться со всем в макросе Persist.
2. Выполнять Persist на более поздней стадии и передовать данные через TypeBuilder.UserData.
Выбор за тобой.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Сообщающиеся макросы
От: _Claus_  
Дата: 19.11.11 21:58
Оценка:
VD>Можно даже воспроизвести 1 в 1 (с учетом синтаксических различий).

Это как? простые макросы на уровне классов и полей не работают(кстати будет ли это устранено в Nemerle2?). а так конечно хочу.для полей это более адекватно, чем атрибуты.
VD>Но проще и привычнее было бы сделать все на базе макро-атрибутов. Тогда это выглядело бы так:

VD>
VD>[Persist]
VD>class X
VD>{  
VD>   public [VAL]    a      : int         { get; set; }
VD>   public [REF]    b      : string      { get; set; }
VD>   public [REFVAL] values : SortList[X] { get; set; }
VD>   ...
VD>}
VD>


так не очень подойдет, насколько я понимаю, у меня на get set вешается код, зависящий от типа переменной + тип внутренней переменной как правило не
совпадает с объявленным и вычисляется от типа(обычно — смещение в базе, но не всегда) + для некоторых типов доп. поле, отслеживающие была ли модификация. поэтому желательно чистое объявление, которое сделает все что нужно для поля. только вот не понял я как простым макросом..


VD>2. VAL, REF и REFVAL можно сделать марками работающими на ранних стадиях. Они могут делать что вам надо плюс добавлять в UserData TypeBuilder-а для типа X необходимую информацию. Persist, работающий на более поздней стадии, сможет прочесть эту информацию и сгенерировать то что нужно (структуру и что угодно еще).


именно так и нужно.

_C_>>Теперь в Н я не вижу как сделать то же самое. Макросы отметаем, берем макроатрибуты. Имеет проблемы:

_C_>>явно объявленное поле (избыточное объявление имеем сразу — mutable оно всегда) надо трансформировать в property c кодом.

VD>Объявляй сразу свойства. Можешь и mutable сам подставить, если нужно. Только это может запутать других.


поэтому и не стоит явно свойства объявлять. это внутреннее дело.

еще вот не получается трансформация, Н упорно подставляет лишние скобки ( в контексте выражения), как от них избавиться?

macro @REF (var) 
  syntax("REF",  var)
  {     
    <[mutable $var ]>     
  }


может проще показать boo макрокод, чтобы было яснее? там много разных моментов. если получится его умно портировать, у общества
будет резвая embedded db. а может еще и статья.
Re[3]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.11.11 23:20
Оценка:
Здравствуйте, _Claus_, Вы писали:


VD>>Можно даже воспроизвести 1 в 1 (с учетом синтаксических различий).


_C_>Это как?


Можно прикрутить синтаксис к макросам верхнего уровня. Не уверен, что это без проблем будет работать в IDE (никто не проверял). Смотри макрос abrakadabra и его применение.

_C_>простые макросы на уровне классов и полей не работают(кстати будет ли это устранено в Nemerle2?).


В Немерле другая идеология. Устранять тут нечего. К этому придется привыкнуть.

_C_>а так конечно хочу.для полей это более адекватно, чем атрибуты.


На мой взгляд, более адекватно не удивлять людей которые, в последствии, будут читать и править код написанный с использованием макросов. По сему, если описывается класс, то лучше чтобы он выглядел как класс, пусть даже и размеченный атрибутами. Лишний синтаксис — лишнее время на изучения. Все должно быть оправданным.

_C_>так не очень подойдет, насколько я понимаю, у меня на get set вешается код, зависящий от типа переменной + тип внутренней переменной как правило не совпадает с объявленным и вычисляется от типа(обычно — смещение в базе, но не всегда) + для некоторых типов доп. поле, отслеживающие была ли модификация. поэтому желательно чистое объявление, которое сделает все что нужно для поля. только вот не понял я как простым макросом..


Макрос работающий на ранних стадиях (т.е. VAL, REF и REFVAL) может заменить тело геттеров и сеттеров и сгенерировать все что угодно. Если тела окажутся не пустыми, то преобразование в авто-ствойство произведено не будет. Так что это не проблема.

_C_>поэтому и не стоит явно свойства объявлять. это внутреннее дело.


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

В немерле есть макрос Accessor. Он создает свойства-эксессоры для полей. Можешь поглядеть его реализацию. Но в последнее время его используют редка, так как автосвойства банально удобнее и красивее.

_C_>еще вот не получается трансформация, Н упорно подставляет лишние скобки ( в контексте выражения), как от них избавиться?


_C_>
_C_>macro @REF (var) 
_C_>  syntax("REF",  var)
_C_>  {     
_C_>    <[mutable $var ]>     
_C_>  }
_C_>


Что за скобки?

_C_>может проще показать boo макрокод, чтобы было яснее? там много разных моментов. если получится его умно портировать, у общества будет резвая embedded db. а может еще и статья.


Получится или нет — это зависит от тебя.
В макросах Бу я не силен. Но поглядеть можно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Сообщающиеся макросы
От: _Claus_  
Дата: 20.11.11 00:37
Оценка:
VD>На мой взгляд, более адекватно не удивлять людей которые, в последствии, будут читать и править код написанный с использованием макросов. По сему, если описывается класс, то лучше чтобы он выглядел как класс, пусть даже и размеченный атрибутами. Лишний синтаксис — лишнее время на изучения. Все должно быть оправданным.

Если трансформация атрибутом поля в свойство удивляет Н-программистов, тогда оправдано, иначе — лишний код, в котором можно ошибиться.
Эта трансформация абсолютно невидима для прикладника.


_C_>>еще вот не получается трансформация, Н упорно подставляет лишние скобки ( в контексте выражения), как от них избавиться?


_C_>>
_C_>>macro @REF (var) 
_C_>>  syntax("REF",  var)
_C_>>  {     
_C_>>    <[mutable $var ]>     
_C_>>  }
_C_>>


VD>Что за скобки?


выдает mutable (z : int)
причем не исправляется если раскладываю на var.exp, var.type, все равно вылазят.

_C_>>может проще показать boo макрокод, чтобы было яснее? там много разных моментов. если получится его умно портировать, у общества будет резвая embedded db. а может еще и статья.


VD>Получится или нет — это зависит от тебя.



Не только от меня. например я плохо понимаю как добраться из макроса REF до макроса Persist.
перечень функций для подъема в дереве не видел в описании. массив блоков кода AST как умно сцепить в один, — не знаю.
элементарные вещи вроде тех, которые описаны выше работают с "особенностями". которые непонятно как преодолеть.
код макросов смотрю, но пока ясности в голове нет.
так что сам может и напишу, но показывать постесняюсь.

VD>В макросах Бу я не силен. Но поглядеть можно.

синтакс похож. макрокода немного. коменты есть еще добавлю. куда кидать?
Re[5]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.11.11 01:45
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>Если трансформация атрибутом поля в свойство удивляет Н-программистов, тогда оправдано, иначе — лишний код, в котором можно ошибиться.


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

_C_>выдает mutable (z : int)


Значит ты туда суешь "z : int". Тебе нужно усложнить макрос, чтобы он распознавал случай "z : int" и обрабатывал его отдельно. Скобок там, скорее всего, нет. Просто при преобразовании в строку оно так отображается.

_C_>Не только от меня. например я плохо понимаю как добраться из макроса REF до макроса Persist.


Я же раз пять уже объяснил.

_C_>перечень функций для подъема в дереве не видел в описании.


Не понял этой фразы.

_C_> массив блоков кода AST как умно сцепить в один, — не знаю.


Преобразовать в список (list[T]) и в нужном месте подставить в квазицитату:
<[ { ..$exprs } ]>

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

_C_>элементарные вещи вроде тех, которые описаны выше работают с "особенностями". которые непонятно как преодолеть.

_C_>код макросов смотрю, но пока ясности в голове нет.
_C_> так что сам может и напишу, но показывать постесняюсь.

Стесняться тут нечего. Если возникают вопросы, мы поможем. Тут главное пробовать. Ну, почитать имеет смысл.

VD>>В макросах Бу я не силен. Но поглядеть можно.

_C_>синтакс похож. макрокода немного. коменты есть еще добавлю. куда кидать?

Если не много, то можешь просто прямо в сообщении показывать. Если там все же не мало кода, то можно закинуть на какой-нить http://pastebin.com.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.11.11 01:52
Оценка:
Здравствуйте, _Claus_, Вы писали:

Да... очень советую почитать это
Автор: VladD2
Дата: 04.09.11
. Там как раз даются примеры создания нетривиальных макросов.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Сообщающиеся макросы
От: catbert  
Дата: 20.11.11 07:05
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>>>еще вот не получается трансформация, Н упорно подставляет лишние скобки ( в контексте выражения), как от них избавиться?


_C_>>>
_C_>>>macro @REF (var) 
_C_>>>  syntax("REF",  var)
_C_>>>  {     
_C_>>>    <[mutable $var ]>     
_C_>>>  }
_C_>>>



_C_>выдает mutable (z : int)

_C_>причем не исправляется если раскладываю на var.exp, var.type, все равно вылазят.

Приоритеты правильно задали?
Re: Сообщающиеся макросы
От: catbert  
Дата: 20.11.11 07:12
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>Вложенные макросы VAL, REF,.. создавали защищенные свойства,

_C_>добавляли о себе инфу макросу Persist, который потом разворачивал ее в структуру с такими или другими полями и методы.

_C_>все равно есть явная проблема,

_C_>если вложенные макроатрибуты работают до атрибута Persist, им некуда регистрировать информацию о себе, если после,
_C_>она уже бесполезна.

_C_>Что робыть?


Посмотреть на код макросов Record или StructuralEquality, в которых есть похожий паттерн:

https://github.com/rsdn/nemerle/blob/master/macros/StructuralEquality.n
https://github.com/rsdn/nemerle/blob/master/macros/core.n#L864 (почему бы все макросы не разложить наконец по отдельным файлам?)

Там есть макроатрибуты RecordIgnore и, соответственно, EqualsIgnore, которые делают то, что вам нужно: выполняются до своих "родителей" и сообщают им про свои поля.
Re[6]: Сообщающиеся макросы
От: _Claus_  
Дата: 20.11.11 08:43
Оценка:
VD>Немерле-программист не обязан знать все ДСЛ-и на свете. Если можно обойтись штатным синтаксисом, то я предпочитаю так и поступать. ДСЛ должен давать явные приемущества. Здесь я таковых не вижу.

Здесь REF, REFVAL, .. это такие же описатели как mutable и def. Наличие последних просто избыточно, потому что описатели базы являются производными от mutable. но держаться за это не буду (в одном месте ты восхищенно рассказывал о том, что можно ; в конце метода не писать, а тут экономии больше).

_C_>>выдает mutable (z : int)


VD>Значит ты туда суешь "z : int". Тебе нужно усложнить макрос, чтобы он распознавал случай "z : int" и обрабатывал его отдельно. Скобок там, скорее всего, нет. Просто при преобразовании в строку оно так отображается.


От это не легче — код не компилируется.

_C_>>Не только от меня. например я плохо понимаю как добраться из макроса REF до макроса Persist.


VD>Я же раз пять уже объяснил.

VD>Не понял этой фразы.

Про DataUser я понял, не понял как до макроса добраться.

_C_>> массив блоков кода AST как умно сцепить в один, — не знаю.


VD>Стесняться тут нечего. Если возникают вопросы, мы поможем. Тут главное пробовать. Ну, почитать имеет смысл.


VD>Если не много, то можешь просто прямо в сообщении показывать. Если там все же не мало кода, то можно закинуть на какой-нить http://pastebin.com.


макросы — http://pastebin.com/4uikZiTA
back-end database для макросов — http://pastebin.com/DDcsGX7G

вместе они представляют завершенный комплект, позволяющий написать вот такой код:


Persist my_root:
    
    REFBLOCK words as List of iword
            
        ..
    
datamap_ = datamap_file(fname_datamap, size_datamap)
        
if datamap_.root_obj
            
     Instance = datamap_.root_obj
else
     datamap_.root_obj = my_root(datamap_ )

     datamap_.save_root()

my_root.x_obj = Obj(datamap_)
 
my_root.list_obj = List[Obj]()

my_root.list_obj.AddRange(..)

my_root.save()



и дальше работать с кодом почти так же как без СУБД, при изменении объектов, находящихся вне контейнеров, надо им
вызывать save. транзакций нет, их не поддерживает .Net для memmapfiles. но в конце изменений надо вызывать save_root,
там хранится смещение на блоки свободной памяти, которое может измениться.
основное и главное достоинство — скорость. она в десяток раз больше, чем у быстрейшей встроенной .Net субд Perst.
вторичное достоинство — предельная простота, расширяемость и бесплатность.
Re[6]: Сообщающиеся макросы
От: _Claus_  
Дата: 20.11.11 09:23
Оценка:
Здравствуйте, catbert, Вы писали:

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


_C_>>>>еще вот не получается трансформация, Н упорно подставляет лишние скобки ( в контексте выражения), как от них избавиться?


_C_>>>>
_C_>>>>macro @REF (var) 
_C_>>>>  syntax("REF",  var)
_C_>>>>  {     
_C_>>>>    <[mutable $var ]>     
_C_>>>>  }
_C_>>>>



_C_>>выдает mutable (z : int)

_C_>>причем не исправляется если раскладываю на var.exp, var.type, все равно вылазят.

C>Приоритеты правильно задали?


а какие? я пишу

REF x : int

и ожидаю

mutable x : int

вместо этого имею

mutable (x : int)
Re[2]: Сообщающиеся макросы
От: _Claus_  
Дата: 20.11.11 09:25
Оценка:
Здравствуйте, catbert, Вы писали:

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


_C_>>Вложенные макросы VAL, REF,.. создавали защищенные свойства,

_C_>>добавляли о себе инфу макросу Persist, который потом разворачивал ее в структуру с такими или другими полями и методы.

_C_>>все равно есть явная проблема,

_C_>>если вложенные макроатрибуты работают до атрибута Persist, им некуда регистрировать информацию о себе, если после,
_C_>>она уже бесполезна.

_C_>>Что робыть?


C>Посмотреть на код макросов Record или StructuralEquality, в которых есть похожий паттерн:


C>https://github.com/rsdn/nemerle/blob/master/macros/StructuralEquality.n

C>https://github.com/rsdn/nemerle/blob/master/macros/core.n#L864 (почему бы все макросы не разложить наконец по отдельным файлам?)

C>Там есть макроатрибуты RecordIgnore и, соответственно, EqualsIgnore, которые делают то, что вам нужно: выполняются до своих "родителей" и сообщают им про свои поля.


Ух ты.. премного благодарны!
Re[7]: Сообщающиеся макросы
От: catbert  
Дата: 20.11.11 10:57
Оценка: +1
Здравствуйте, _Claus_, Вы писали:

C>>Приоритеты правильно задали?


_C_>а какие? я пишу


_C_>REF x : int


_C_>и ожидаю


_C_>mutable x : int


_C_>вместо этого имею


_C_>mutable (x : int)


Ну да, это потому что REF захватывает все выражение x : int и подставляет его как имя переренной для mutable. Не знаю, зачем вам указывать тип после REF (ведь он все равно выведется), но если очень надо, советую сделать вот так:

  macro @REF (var)
    syntax ("REF", var)
  {
      match (var)
      {
      | <[ $x : $y ]> => <[mutable $x : $y; ]>
      | <[ $x = $y ]> => <[mutable $x = $y; ]>
      | _ => <[ mutable $var; ]>
      }
  }


Макрос будет расковыривать var и заковыривать его назад в mutable.

Более "кошерный" подход в том, чтобы задать приоритет связывания оператора REF выше чем у двоеточия.
Re[2]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.11.11 17:27
Оценка:
Здравствуйте, catbert, Вы писали:

C>почему бы все макросы не разложить наконец по отдельным файлам?


Займись.

ЗЫ

Почему все говорят о том, что нужно сделать что-то полезное, а не делают?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.11.11 18:05
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>>>выдает mutable (z : int)


VD>>Значит ты туда суешь "z : int". Тебе нужно усложнить макрос, чтобы он распознавал случай "z : int" и обрабатывал его отдельно. Скобок там, скорее всего, нет. Просто при преобразовании в строку оно так отображается.


_C_>От это не легче — код не компилируется.


Ну, дык, если ничего не менять, то ничего и не изменится .

Покажи код. В прочем, здесь
Автор: catbert
Дата: 20.11.11
уже дан верный ответ.

_C_>Про DataUser я понял, не понял как до макроса добраться.


Я раз пять объяснял. Одни макросы выполняются на более ранней стадии, например, BeforeInherence. Пишут нужную информацию в в свойство UserData объекта TypeBuilder (передаваемый им в качестве параметра). Другой выполняется на более поздней стадии. Он читает данные из UserData и формирует нужный код.

_C_>макросы — http://pastebin.com/4uikZiTA

_C_>back-end database для макросов — http://pastebin.com/DDcsGX7G

Поглядел бегло. Конечно же не все понятно. Но в общем сложилось впечатление, что это какой-то сериализатор списка объектов в файл. На СУБД это мало похоже. Возможно, конечно, что я что-то пропустил. Букв много...
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.11.11 19:16
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>Про DataUser я понял, не понял как до макроса добраться.


Проще показать чем объяснять. Ниже приведен пример. Он только выводит информацию в виде предупреждений компилятора, но основную идею он демонстрирует. Вместо строки, в качестве значения, у тебя будет какая-то более сложная структура (или кортеж).

Helpers.n — тут описана извлекающая (и инициализирующая) значение из typeBuilder.UserData["Persist_FieldsMap"]:
  Скрытый текст
using Nemerle.Collections;
using Nemerle.Compiler;
using Nemerle.Imperative;

namespace MacroLibrary
{
  type MapType = Hashtable[Parsetree.ClassMember.Property, string];
  
  module Helpers
  {
   public GetFieldsMap(typeBuilder : TypeBuilder) : MapType
    {
      def fieldsMap = typeBuilder.UserData["Persist_FieldsMap"] :> MapType;
      
      when (fieldsMap != null)
        return fieldsMap;
        
      def fieldsMap = MapType();
      typeBuilder.UserData["Persist_FieldsMap"] = fieldsMap;
      fieldsMap
    }
  }
}


Ref.n — содержит реализацию макро-атрибута Ref. Он вешается на свойство и закладывает информацию в typeBuilder.UserData["Persist_FieldsMap"]:
  Скрытый текст
using Nemerle;
using Nemerle.Collections;
using Nemerle.Compiler;
using Nemerle.Compiler.Parsetree;
using Nemerle.Compiler.Typedtree;
using Nemerle.Text;
using Nemerle.Utility;

using System;
using System.Collections.Generic;
using System.Linq;

namespace MacroLibrary
{
  [MacroUsage(MacroPhase.BeforeInheritance, MacroTargets.Property)]
  macro Ref(typeBuilder : TypeBuilder, property : ClassMember.Property)
  {
    RefImpl.DoTransform(Macros.ImplicitCTX(), typeBuilder, property)
  }
  
  module RefImpl
  {
    public DoTransform(typer : Typer, typeBuilder : TypeBuilder, property : ClassMember.Property) : void
    {
      Macros.DefineCTX(typer);
      def fieldsMap = Helpers.GetFieldsMap(typeBuilder);
      fieldsMap[property] = "REF"; // запоминаем, что к данному свойству был применен макрос Ref
    }
  }
}


Persist.n — основной макрос Persist. В нем выводится информация о всех свойствах. Если есть дополнительная информация, то выводится и она:
  Скрытый текст
using Nemerle;
using Nemerle.Collections;
using Nemerle.Compiler;
using Nemerle.Compiler.Parsetree;
using Nemerle.Compiler.Typedtree;
using Nemerle.Text;
using Nemerle.Utility;

using System;
using System.Collections.Generic;
using System.Linq;

using BF = System.Reflection.BindingFlags;

namespace MacroLibrary
{
  [MacroUsage(MacroPhase.WithTypedMembers, MacroTargets.Class)]
  macro Persist(typeBuilder : TypeBuilder)
  {
    PersistImpl.DoTransform(Macros.ImplicitCTX(), typeBuilder)
  }
  
  module PersistImpl
  {
    public DoTransform(typer : Typer, typeBuilder : TypeBuilder) : void
    {
      Macros.DefineCTX(typer);
      
      def props = typeBuilder.GetProperties(BF.DeclaredOnly | BF.Public | BF.NonPublic | BF.Instance);
      
      foreach (prop is PropertyBuilder in props)
      {
        def fieldsMap = Helpers.GetFieldsMap(typeBuilder);
        def kind = fieldsMap.Get(prop.Ast) ?? "none"; // Получаем доп.информацию о свойстве или "none".
        
        Message.Hint(prop.NameLocation, $"Property $(prop.Name) : $(prop.Getter?.ReturnType) ($kind)");
      }
    }
  }
}


Использование:
  Скрытый текст
using System;
using MacroLibrary;

[Persist]
class TestClass
{
        public Prop1 : int      { get; set; }
  [Ref] public Prop2 : string   { get; set; }
        public Prop3 : DateTime { get; set; }
}
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Сообщающиеся макросы
От: _Claus_  
Дата: 21.11.11 07:07
Оценка:
ух! спасибо!

При переписывании наткнулся на проблему, с которой гугление не помогло.
демокод:
class x
  public load[ T](delta : int) : List[T]                         
    List[T]()

module Program

  Main() : void
        
    mutable f = x()
    
    def s = f.load[int](2) //вариант 1
    
    def s : List[int]  = f.load(2) //вариант 2


оба не помогают
некоторые методы, например load в datamap принимают шаблон struct, который в параметрах метода не обозначен.
компилятор обзывается:
cannot find any suitable indexer in 'List' (type is ? -> ?)
и еще всякое по мелочи..
Re[9]: Сообщающиеся макросы
От: _nn_ www.nemerleweb.com
Дата: 21.11.11 08:28
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>ух! спасибо!


_C_>При переписывании наткнулся на проблему, с которой гугление не помогло.

_C_>демокод:
_C_>class x
_C_>  public load[ T](delta : int) : List[T]                         
_C_>    List[T]()

_C_>module Program

_C_>  Main() : void
        
_C_>    mutable f = x()
    
_C_>    def s = f.load[int](2) //вариант 1
    
_C_>    def s : List[int]  = f.load(2) //вариант 2

_C_>оба не помогают
_C_>некоторые методы, например load в datamap принимают шаблон struct, который в параметрах метода не обозначен.
_C_>компилятор обзывается:
_C_>cannot find any suitable indexer in 'List' (type is ? -> ?)
_C_>и еще всякое по мелочи..

В Nemerle синтаксис a[b] это вызов индексера, а генерик тип это будет a.[b] (обратить внимание на точку).

В некоторых случаях эту точку можно не писать и компилятор сам определяет, что это не индексер, а в некоторых случаях писать нужно.
Точка в генерик типе
Автор: _nn_
Дата: 21.09.11


В данном случае нужно просто указать точку либо не писать тип:
// Самый предпочтительный
def s = f.load(2);

// Указание генерика
def s : List.[int] = f.load.[int](2); 
def s  = f.load.[int](2); 
def s  : List.[int] = f.load(2);
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[10]: Сообщающиеся макросы
От: _Claus_  
Дата: 21.11.11 08:42
Оценка:
__>// Указание генерика
__>def s : List.[int] = f.load.[int](2);
__>def s = f.load.[int](2);
__>def s : List.[int] = f.load(2);
__>[/nemerle]

спасибо, помогло!
Re[11]: Сообщающиеся макросы
От: _nn_ www.nemerleweb.com
Дата: 21.11.11 09:22
Оценка:
Здравствуйте, _Claus_, Вы писали:

__>>// Указание генерика

__>>def s : List.[int] = f.load.[int](2);
__>>def s = f.load.[int](2);
__>>def s : List.[int] = f.load(2);
__>>[/nemerle]

_C_>спасибо, помогло!


А чем плох вариант: "def s = f.load(2)" ?
Писать меньше и типы автоматически выводятся.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[10]: Сообщающиеся макросы
От: _Claus_  
Дата: 21.11.11 09:32
Оценка:
Есть вопросы, проясните, плз

пытаюсь из экземпляра читать статическое поле, получаю
trying to access static member (field: static delta : int through an instance
с каких пор это стало ошибкой?

в сравнениях не поддерживается короткая запись?
if (x) ..
when (!obj) ..
это почемуйто? вроде не сложно определить value оно или нет и сравнить с 0 или null..

в struct объявленные поля не public по умолчанию, но вообще-то на то он и struct, что у него все public.
или здесь особый struct?


в макросе с аттрибутом

[MacroUsage(MacroPhase.BeforeInheritance, MacroTargets.Property)] 
macro Ref(typeBuilder : TypeBuilder, property : ClassMember.Property)
  
    RefImpl.DoTransform(Macros.ImplicitCTX(), typeBuilder, property)


компилятор в режиме отступов не желает компилировать, только в одну строку если вытянуть.


[MacroUsage(MacroPhase.BeforeInheritance, MacroTargets.Property)] macro Ref(typeBuilder : TypeBuilder, property : ClassMember.Property)

какой знак продолжения строки нужно вставить или не заморачиваться?
Re[12]: Сообщающиеся макросы
От: _Claus_  
Дата: 21.11.11 09:34
Оценка:
Здравствуйте, _nn_, Вы писали:

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


__>>>// Указание генерика

__>>>def s : List.[int] = f.load.[int](2);
__>>>def s = f.load.[int](2);
__>>>def s : List.[int] = f.load(2);
__>>>[/nemerle]

_C_>>спасибо, помогло!


__>А чем плох вариант: "def s = f.load(2)" ?

__>Писать меньше и типы автоматически выводятся.

У меня тип шаблона не совпадает с типом параметра.
Re[11]: Сообщающиеся макросы
От: _nn_ www.nemerleweb.com
Дата: 21.11.11 09:55
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>Есть вопросы, проясните, плз


Я так понимаю вы из среды С++.
Язык Nemerle старается придерживаться правил С# и здравого смысла.
Поэтому поведение некоторых вещей отличается от С++.

_C_>пытаюсь из экземпляра читать статическое поле, получаю

_C_>trying to access static member (field: static delta : int through an instance
_C_>с каких пор это стало ошибкой?

В C# это является ошибкой, и в Nemerle тоже.
Статические методы нужно вызывать напрямую через тип.

_C_>в сравнениях не поддерживается короткая запись?

_C_>if (x) ..
_C_>when (!obj) ..
_C_>это почемуйто? вроде не сложно определить value оно или нет и сравнить с 0 или null..

Что означает запись
if (x)
if (x != null) или if (x != 0) ?

В С# так нельзя и в Nemerle тоже.

Вообще, ничего сложно в написании "!= null" , "!= 0" совершенно нет.
А если использовать Pattern Matching то вообще практически не нужно.

_C_>в struct объявленные поля не public по умолчанию, но вообще-то на то он и struct, что у него все public.

_C_>или здесь особый struct?

Все как в C#, public нужно всегда объявлять.
Кстати struct в .Net это не struct в С++ понимании

_C_>в макросе с аттрибутом


_C_>
_C_>[MacroUsage(MacroPhase.BeforeInheritance, MacroTargets.Property)] 
_C_>macro Ref(typeBuilder : TypeBuilder, property : ClassMember.Property)
  
_C_>    RefImpl.DoTransform(Macros.ImplicitCTX(), typeBuilder, property)

_C_>


_C_>компилятор в режиме отступов не желает компилировать, только в одну строку если вытянуть.


_C_>

_C_>[MacroUsage(MacroPhase.BeforeInheritance, MacroTargets.Property)] macro Ref(typeBuilder : TypeBuilder, property : ClassMember.Property)

_C_>

_C_>какой знак продолжения строки нужно вставить или не заморачиваться?

Знак "\"

[MacroUsage(MacroPhase.BeforeInheritance, MacroTargets.Property)] \
macro Ref(typeBuilder : TypeBuilder, property : ClassMember.Property)
  
    RefImpl.DoTransform(Macros.ImplicitCTX(), typeBuilder, property)


На мой взгляд это недочет, но режим с отступами не является основным режимом языка на сегодня.
Поэтому есть недочеты, но их всегда можно устранить если есть время и желания
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[9]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.11.11 10:00
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>
_C_>    def s = f.load[int](2) //вариант 1
_C_>    def s : List[int]  = f.load(2) //вариант 2
_C_>


_C_>оба не помогают

_C_>некоторые методы, например load в datamap принимают шаблон struct, который в параметрах метода не обозначен.
_C_>компилятор обзывается:
_C_>cannot find any suitable indexer in 'List' (type is ? -> ?)
_C_>и еще всякое по мелочи..

С первым вариантом все ясно. Тут неоднозначность между индексером и параметром типов. Нужно просто подставить точку:
def s = f.load.[int](2)

А вот второй вариант должен работать.
Какую версию ты используешь? В 1.1 бэта такой код должен компилироваться.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.11.11 10:07
Оценка:
Здравствуйте, VladD2, Вы писали:

_C_>>
_C_>>    def s = f.load[int](2) //вариант 1
_C_>>    def s : List[int]  = f.load(2) //вариант 2
_C_>>


VD>А вот второй вариант должен работать.

VD>Какую версию ты используешь? В 1.1 бэта такой код должен компилироваться.

Сори, заметил проблему только после второго прочтения. Просто не нежно задавать параметры типов явно. В Немерле очень мощный вывод типов. Он разруливает типы в 99% случаев. Так что указывать параметры типов явно нужно очень редко.

Более того, вывод типов возможен из использования. Так что если за строчкой:
def s = f.load(2);

будет идти что-то вроде:
s.Add(42);

то компилятор все равно корректно выведет тип.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.11.11 10:10
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>У меня тип шаблона не совпадает с типом параметра.


Ну, а дальше эту переменную s как используешь? Почти уверен, что немерловый компилятор без труда выведет типы из дальнешего использования. Попробуй выбросить параметры типов полностью и поглядеть что будет.

И вообще, привыкай больше доверять выводу типов. По сравнению с Boo или F# в немерле, он намного совершеннее.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.11.11 10:25
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>в сравнениях не поддерживается короткая запись?

_C_>if (x) ..
_C_>when (!obj) ..
_C_>это почемуйто? вроде не сложно определить value оно или нет и сравнить с 0 или null..

Потому что это потенциальный багодром. Это ведь не просто сокращения в when или if — это неявные приведения между bool и числами. В некоторых комбинациях это приводит к трудно уловимым ошибкам. Например, мотерые С++-ники обычно пишут проверки раком: "null == x", только для того чтобы не нарваться на случайные гралши.

По тем же причинам "=" не возвращает значения и их нельзя связать в последовательность: "a = b = c;".

_C_>в struct объявленные поля не public по умолчанию, но вообще-то на то он и struct, что у него все public.

_C_>или здесь особый struct?

Есть только один тип в котором по умолчанию поля public — это вхождение вариантов. Во всех стальных местах по умолчанию все члены являются private. Это соглашение всех без исключения C-подобных языков.

_C_>в макросе с аттрибутом


_C_>
_C_>[MacroUsage(MacroPhase.BeforeInheritance, MacroTargets.Property)] 
_C_>macro Ref(typeBuilder : TypeBuilder, property : ClassMember.Property)
_C_>    RefImpl.DoTransform(Macros.ImplicitCTX(), typeBuilder, property)
_C_>

_C_>компилятор в режиме отступов не желает компилировать, только в одну строку если вытянуть.
_C_>
_C_>[MacroUsage(MacroPhase.BeforeInheritance, MacroTargets.Property)] macro Ref(typeBuilder : TypeBuilder, property : ClassMember.Property)
_C_>

_C_>какой знак продолжения строки нужно вставить или не заморачиваться?

Слеш:
macro Ref(typeBuilder : TypeBuilder, property : ClassMember.Property) \
    RefImpl.DoTransform(Macros.ImplicitCTX(), typeBuilder, property)


ЗЫ

Очень советую поглядеть исходники стандартной библиотеки макросов. И вообще, код компилятора и библиотек дает 99% ответов связанных с написанием макросов. Лично я учил немерл, в основном, на его основе. Например, вот код макроса написанный в индент-стиле.

В прочем, если можешь себя перебороть, то лучше перейти на скобочный стиль, так как только он поддерживается в IDE. Иначе с комплитом и другими сервисами IDE будут проблемы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.11.11 11:29
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Я так понимаю вы из среды С++.


Скорее из Питона. Он же говорил, что Boo использует. В Питоне много спорных решений было сделано. Одно объявление переменных первым присвоением чего стоит.

_C_>>пытаюсь из экземпляра читать статическое поле, получаю

_C_>>trying to access static member (field: static delta : int through an instance
_C_>>с каких пор это стало ошибкой?

__>В C# это является ошибкой, и в Nemerle тоже.

__>Статические методы нужно вызывать напрямую через тип.

Не совсем так. Из экземплярного метода можно обращаться к статическому без квалификации имени. Ну, что-то типа:
private static Foo() : void {}
public         Bar() : void
{
  Foo(); // OK
}

Происходит это потому, что внутри типа его тип является текущим.
А вот доступ через this действительно запрещен:
private static Foo() : void {}
public         Bar() : void
{
  this.Foo(); // Error
}

Это очевидная ошибка о которой нужно сообщать программисту. Ведь, скорее всего, он не ошибается думая, что Foo экземплярный метод. Вместо this тут может быть свойство или поле.

Короче, человек привык к багодромному языку и теперь строгость малость напрягает. Тут ничего не поделаешь, придется немного привыкнуть. Зато потом куча ошибок просто не сможет появиться, а значит будет меньше отладки.

__>Вообще, ничего сложно в написании "!= null" , "!= 0" совершенно нет.

__>А если использовать Pattern Matching то вообще практически не нужно.

Скажу больше. Есть операторы .? и ??. Если их грамотно использовать, то код станет в разы короче, безопаснее и понятнее.
А еще лучше не допускать появления null используя макро-атрибут для параметров [NotNull]. Ну, а для выражения отсутствия значения использовать option[T] или ValueOption[T].

Пока писал, понял, что для ValueOption[T] нужно добавить ExtensionPattern и открыть тип содержащий его псевдо-конструкторы. Тогда его будет так же удобно использовать как и option[T]. Учитывая, что накладные расходы для ValueOption[T] минимальны (так как это структура) его можно использовать где угодно не опасаясь потери производительности.

__>Все как в C#, public нужно всегда объявлять.


Во вхождениях вариантов поля по умолчанию public.

__>На мой взгляд это недочет, но режим с отступами не является основным режимом языка на сегодня.

__>Поэтому есть недочеты, но их всегда можно устранить если есть время и желания

Ну, дык соберите команду тех кого интересует этот режим и устраните этот недочет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Сообщающиеся макросы
От: _nn_ www.nemerleweb.com
Дата: 21.11.11 11:54
Оценка:
Здравствуйте, VladD2, Вы писали:

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


__>>Я так понимаю вы из среды С++.


VD>Скорее из Питона. Он же говорил, что Boo использует. В Питоне много спорных решений было сделано. Одно объявление переменных первым присвоением чего стоит.

В Питоне нет автоматического приведения типов в целое для if. Это из С/C++.

VD>Не совсем так. Из экземплярного метода можно обращаться к статическому без квалификации имени. Ну, что-то типа:

VD>Это очевидная ошибка о которой нужно сообщать программисту. Ведь, скорее всего, он не ошибается думая, что Foo экземплярный метод. Вместо this тут может быть свойство или поле.
+1

VD>Короче, человек привык к багодромному языку и теперь строгость малость напрягает. Тут ничего не поделаешь, придется немного привыкнуть. Зато потом куча ошибок просто не сможет появиться, а значит будет меньше отладки.



__>>Вообще, ничего сложно в написании "!= null" , "!= 0" совершенно нет.

__>>А если использовать Pattern Matching то вообще практически не нужно.

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

VD>А еще лучше не допускать появления null используя макро-атрибут для параметров [NotNull]. Ну, а для выражения отсутствия значения использовать option[T] или ValueOption[T].
А NotNull нельзя приделать к методу ? Чтобы одним махом все проверять на null:
[NotNull] public F(a : int, b : string, c : object, d : long) : void { ... }

Превращается в ==>
public F(a : int, [NotNull] b : string, [NotNull] c : object, d : long) : void { ... }


VD>Пока писал, понял, что для ValueOption[T] нужно добавить ExtensionPattern и открыть тип содержащий его псевдо-конструкторы. Тогда его будет так же удобно использовать как и option[T]. Учитывая, что накладные расходы для ValueOption[T] минимальны (так как это структура) его можно использовать где угодно не опасаясь потери производительности.

А этот VariantOption когда стоит использовать вместо option ?
Только для производительности ? Ведь для юзер кода option должно хватить.

__>>На мой взгляд это недочет, но режим с отступами не является основным режимом языка на сегодня.

__>>Поэтому есть недочеты, но их всегда можно устранить если есть время и желания

VD>Ну, дык соберите команду тех кого интересует этот режим и устраните этот недочет.


Можно попробовать, только боюсь ни у кого на это нет времени
Да и для меня скобочки не смертельный вариант.
В С-подобных языках вообще выбора нет
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[12]: Сообщающиеся макросы
От: _Claus_  
Дата: 21.11.11 12:08
Оценка:
Здравствуйте, VladD2, Вы писали:

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


_C_>>в сравнениях не поддерживается короткая запись?

_C_>>if (x) ..
_C_>>when (!obj) ..
_C_>>это почемуйто? вроде не сложно определить value оно или нет и сравнить с 0 или null..

VD>Потому что это потенциальный багодром.


Слишком вы тут осторожные, однако. Не хватает воображения, чтобы это давало какие-то проблемы.
У меня так точно не было, несмотря на многие годы интенсивного использования.
а вот вместо сравнения написать присваивание — это сколько угодно.
Так что не согласен я с Каутским.

VD>По тем же причинам "=" не возвращает значения и их нельзя связать в последовательность: "a = b = c;".


_C_>>в struct объявленные поля не public по умолчанию, но вообще-то на то он и struct, что у него все public.

_C_>>или здесь особый struct?

VD>Есть только один тип в котором по умолчанию поля public — это вхождение вариантов. Во всех стальных местах по умолчанию все члены являются private. Это соглашение всех без исключения C-подобных языков.


в С++ открытые. значит в С# стали чудить, но я на нем не пишу. но это потому что в Майкрософте народу много, чтобы всех занять придумывают раздутый синтаксис, из пальца высосанные ограничения и низкий уровень языков.

VD>Очень советую поглядеть исходники стандартной библиотеки макросов. И вообще, код компилятора и библиотек дает 99% ответов связанных с написанием макросов. Лично я учил немерл, в основном, на его основе. Например, вот код макроса написанный в индент-стиле.

Смотрю регулярно, хорошо написано, но понятно не все.

VD>В прочем, если можешь себя перебороть, то лучше перейти на скобочный стиль, так как только он поддерживается в IDE. Иначе с комплитом и другими сервисами IDE будут проблемы.

что-нибудь милое и знакомое оставить надо. для психики лучше. и для кода тоже.

еще вот не понял как простые стандартные фиксированные массивы создаются (которые в шарпе типа System.Int32[])
есть ли короткая запись для такого типа?
Re[12]: Сообщающиеся макросы
От: _Claus_  
Дата: 21.11.11 12:18
Оценка:
__>В C# это является ошибкой, и в Nemerle тоже.
__>Статические методы нужно вызывать напрямую через тип.
Может я наивен, но смысла в этом никакого, а вред вполне ощутимый.
нафига использующей стороне знать детали реализации моего класса?
Я могу изменить экземплярное на статическое или наоборот — вызывающий код зачем переделывать?
потому что в Майкрософте им виднее ..
Re[13]: Сообщающиеся макросы
От: _nn_ www.nemerleweb.com
Дата: 21.11.11 12:23
Оценка:
Здравствуйте, _Claus_, Вы писали:

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


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


_C_>>>в сравнениях не поддерживается короткая запись?

_C_>>>if (x) ..
_C_>>>when (!obj) ..
_C_>>>это почемуйто? вроде не сложно определить value оно или нет и сравнить с 0 или null..

VD>>Потому что это потенциальный багодром.


_C_>Слишком вы тут осторожные, однако. Не хватает воображения, чтобы это давало какие-то проблемы.

_C_>У меня так точно не было, несмотря на многие годы интенсивного использования.
А зачем тогда в С++ придумали Safe-Bool Idiom, explicit operator cast ? Не от хорошей жизни наверное

_C_>а вот вместо сравнения написать присваивание — это сколько угодно.

_C_>Так что не согласен я с Каутским.

VD>>По тем же причинам "=" не возвращает значения и их нельзя связать в последовательность: "a = b = c;".


_C_>>>в struct объявленные поля не public по умолчанию, но вообще-то на то он и struct, что у него все public.

_C_>>>или здесь особый struct?

VD>>Есть только один тип в котором по умолчанию поля public — это вхождение вариантов. Во всех стальных местах по умолчанию все члены являются private. Это соглашение всех без исключения C-подобных языков.


_C_>в С++ открытые. значит в С# стали чудить, но я на нем не пишу. но это потому что в Майкрософте народу много, чтобы всех занять придумывают раздутый синтаксис, из пальца высосанные ограничения и низкий уровень языков.

В C# не стали чудить, а просто требуют указания публичного контракта.
И правильно делают.

Кстати, в Boo и Java так тоже

VD>>Очень советую поглядеть исходники стандартной библиотеки макросов. И вообще, код компилятора и библиотек дает 99% ответов связанных с написанием макросов. Лично я учил немерл, в основном, на его основе. Например, вот код макроса написанный в индент-стиле.

_C_>Смотрю регулярно, хорошо написано, но понятно не все.
Вопросы в студию.

VD>>В прочем, если можешь себя перебороть, то лучше перейти на скобочный стиль, так как только он поддерживается в IDE. Иначе с комплитом и другими сервисами IDE будут проблемы.

_C_>что-нибудь милое и знакомое оставить надо. для психики лучше. и для кода тоже.

_C_>еще вот не понял как простые стандартные фиксированные массивы создаются (которые в шарпе типа System.Int32[])

_C_>есть ли короткая запись для такого типа?
Статьи Nemerle читали?

C#Nemerle

var ary = new int[1];
ary[0] = 42;

var ary = new int[] { 42 };
var ary = new [] { 42 };

// явное указание типа переменной
int[] ary = new [] { 42 };

// массив массивов (вложенный массив)
int[][] ary = new[] { new[] { 42 } };
var ary = new[] { new[] { 42 }, new[] { 33, 1 } };

// многомерные массивы
var ary = new[,] { { 42, 1 }, { 33, 2 } };
Console.WriteLine(ary[0, 0]);


def ary = array(1);
ary[0] = 42; // тип выводится из использования

def ary = array[42];


// явное указание типа переменной
def ary : array[int] = array[1];

// массив массивов (вложенный массив)
def ary : array[array[int]] = array[array[42]];
def ary = array[array[42], array[33, 1]];

// многомерные массивы
def ary = array.[2][[42, 1], [33, 2]];
Console.WriteLine(ary[0, 0]);

Еще есть Новое Вики и Старое Вики.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[14]: Сообщающиеся макросы
От: catbert  
Дата: 21.11.11 12:31
Оценка:
Здравствуйте, _nn_, Вы писали:

__>А этот VariantOption когда стоит использовать вместо option ?

__>Только для производительности ? Ведь для юзер кода option должно хватить.

Тогда же, когда стоит использовать структуры вместо классов — то есть когда нету боксинга.
Re[13]: Сообщающиеся макросы
От: _Claus_  
Дата: 21.11.11 12:35
Оценка:
__>>Вообще, ничего сложно в написании "!= null" , "!= 0" совершенно нет.
__>>А если использовать Pattern Matching то вообще практически не нужно.
я бы предпочел не писать, это может компилятор. а то типы выводит, а "!= null" сами напишем!
пожалеем, дадим отдохнуть.

VD>Пока писал, понял, что для ValueOption[T] нужно добавить ExtensionPattern и открыть тип содержащий его псевдо-конструкторы. Тогда его будет так же удобно использовать как и option[T]. Учитывая, что накладные расходы для ValueOption[T] минимальны (так как это структура) его можно использовать где угодно не опасаясь потери производительности.


я б про это почитал бы.
Re[14]: Сообщающиеся макросы
От: _Claus_  
Дата: 21.11.11 13:08
Оценка:
__>Кстати, в Boo и Java так тоже

В Воо все поля в структуре public по умолчанию, в классах private.

VD>>>Очень советую поглядеть исходники стандартной библиотеки макросов. И вообще, код компилятора и библиотек дает 99% ответов связанных с написанием макросов. Лично я учил немерл, в основном, на его основе. Например, вот код макроса написанный в индент-стиле.

_C_>>Смотрю регулярно, хорошо написано, но понятно не все.
__>Вопросы в студию.

вот это что дает и что за global ?

($("_N_continue" : global)

вот это непонятно что в match получается


match (cases)
      {
        | <[ match ($_) { ..$cases } ]> =>



за array спасибо. у меня Array в голове был
Re[15]: Сообщающиеся макросы
От: _nn_ www.nemerleweb.com
Дата: 21.11.11 13:20
Оценка:
Здравствуйте, _Claus_, Вы писали:

__>>Кстати, в Boo и Java так тоже


_C_>В Воо все поля в структуре public по умолчанию, в классах private.

Да, все таки структурах публичные.
Похоже и в F# также.

VD>>>>Очень советую поглядеть исходники стандартной библиотеки макросов. И вообще, код компилятора и библиотек дает 99% ответов связанных с написанием макросов. Лично я учил немерл, в основном, на его основе. Например, вот код макроса написанный в индент-стиле.

_C_>>>Смотрю регулярно, хорошо написано, но понятно не все.
__>>Вопросы в студию.

_C_>вот это что дает и что за global ?


_C_> ($("_N_continue" : global)


Это создает метку. Если не ошибаюсь global нам поможет создать уникальное имя.
Это тут к статьям о макросах и цитировании.

В Nemerle есть уникальный способ решения выхода из множества циклов и нет необходимости в операции goto.
Работает на базе блоков:

  macro Break () syntax ("break")
  {
    <[ $("_N_break" : global) () ]>
  }

  macro Continue () syntax ("continue")
  {
    <[ $("_N_continue" : global) () ]>
  }

  macro @while (cond, body)
  syntax ("while", "(", cond, ")", body)
  {
    <[
      ($("_N_break" : global) : {
        def loop () : void
        {
          when ($cond)
          {
            ($("_N_continue" : global) : {
              $body
            }) : void;
            loop ()
          }
        }

        loop ();
      }) : void
    ]>
  }


Тут все просто.
Создаем блок _N_break, и вызываем локальную функцию, в которой есть блок _N_continue.
Если вызовем "break" то выйдем из блока, т.е. из цикла.
Если вызовем "continue", то выйдем из внутреннего блока, а потом снова вызовем локальную функцию, т.е. следующую итерацию цикла.


_C_>вот это непонятно что в match получается



_C_>
_C_>match (cases)
_C_>      {
_C_>        | <[ match ($_) { ..$cases } ]> =>
_C_>


Это разбирает блок match, т.е. этот код:
{
  | A(x, y) => ...
  | B => ..
  | _ => ...
}




_C_>за array спасибо. у меня Array в голове был
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Сообщающиеся макросы
От: _Claus_  
Дата: 21.11.11 16:36
Оценка:
VD>Да... очень советую почитать это
Автор: VladD2
Дата: 04.09.11
. Там как раз даются примеры создания нетривиальных макросов.


а как этот XML как текст читать, чем?
Re[5]: Сообщающиеся макросы
От: _nn_ www.nemerleweb.com
Дата: 21.11.11 17:05
Оценка:
Здравствуйте, _Claus_, Вы писали:

VD>>Да... очень советую почитать это
Автор: VladD2
Дата: 04.09.11
. Там как раз даются примеры создания нетривиальных макросов.


_C_>а как этот XML как текст читать, чем?


MS Word его умеет открывать.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[14]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.11.11 17:17
Оценка:
Здравствуйте, _nn_, Вы писали:

VD>>Пока писал, понял, что для ValueOption[T] нужно добавить ExtensionPattern и открыть тип содержащий его псевдо-конструкторы. Тогда его будет так же удобно использовать как и option[T]. Учитывая, что накладные расходы для ValueOption[T] минимальны (так как это структура) его можно использовать где угодно не опасаясь потери производительности.

__>А этот VariantOption когда стоит использовать вместо option ?
__>Только для производительности ? Ведь для юзер кода option должно хватить.

Для нее, для родной. Лично я по причине оверхэда option[T] использую редко.
ValueOption[T] дает совсем незаметный оверхэд. Так что его можно использовать где угодно.
Я тут подумал... ValueOption[T] можно попробовать усовершенстовать еще сильнее. Создать версию для объектов, которая в качестве признака null будет использовать самое поле со значением. Тогда оверхэда по памяти вообще не будет. Вот только придется называть ее по другому. Например ObjectOption[T]. Жаль типы нельзя перегружать.

VD>>Ну, дык соберите команду тех кого интересует этот режим и устраните этот недочет.


__>Можно попробовать, только боюсь ни у кого на это нет времени \


Ну, а что же вы хотите? У меня тоже не было времени. Но было желание. Я сел и начал делать. На все у меня тоже времени не хватит.

__>Да и для меня скобочки не смертельный вариант.

__>В С-подобных языках вообще выбора нет

Вот и я о том же. Так что тот кому не нравятся скобочки может или смириться с ними, или засучить рукова и допилить интеграцию так, чтобы она поддерживала и бесскобочный синтаксис.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.11.11 17:32
Оценка:
Здравствуйте, _Claus_, Вы писали:

__>>В C# это является ошибкой, и в Nemerle тоже.

__>>Статические методы нужно вызывать напрямую через тип.
_C_>Может я наивен, но смысла в этом никакого, а вред вполне ощутимый.

Смысл в этом очевидный. Компилятор выявляет ошибки и указывает программисту на это. Это из той же оперы что и необходимость объявления переменной. Физически без этого обойтись можно, но это провоцирует ошибки.

_C_>нафига использующей стороне знать детали реализации моего класса?


Статические методы не являются частью реализации класса. Выражение идущее до точки (при вызове метода) — это дополнительный параметр. Не находишь, что странно передавать функции лишний параметр?

_C_>Я могу изменить экземплярное на статическое или наоборот — вызывающий код зачем переделывать?


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

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

_C_>потому что в Майкрософте им виднее ..


В МС тоже не идиоты сидят. Проектируя C# в МС сделали многое чтобы сделать язык более безопасным (не допускающим случайных ошибок). К сожалению, без проблем тоже не обошлось и косяки в язык добавили. Например, оператор as. Но в целом дизайн C# лучший из мэйстрим-языков.

При проектировании Nemerle концепция недопущения случайных ошибок была поставлена во главу угла. В процессе работы над языком было выкинуто ряд решений которые могли приводить к случайным ошибкам. На сегодня немерл один из самых устойчивых к ошибкам языков из практически применимых ЯП.

Ломать это с какими либо целями никто не будет. Почти уверен, что со временем ты сам согласишься, что в Немреле все очень продумано.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: Сообщающиеся макросы
От: _nn_ www.nemerleweb.com
Дата: 21.11.11 17:34
Оценка:
Здравствуйте, VladD2, Вы писали:

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


VD>>>Пока писал, понял, что для ValueOption[T] нужно добавить ExtensionPattern и открыть тип содержащий его псевдо-конструкторы. Тогда его будет так же удобно использовать как и option[T]. Учитывая, что накладные расходы для ValueOption[T] минимальны (так как это структура) его можно использовать где угодно не опасаясь потери производительности.

__>>А этот VariantOption когда стоит использовать вместо option ?
__>>Только для производительности ? Ведь для юзер кода option должно хватить.

VD>Для нее, для родной. Лично я по причине оверхэда option[T] использую редко.

VD>ValueOption[T] дает совсем незаметный оверхэд. Так что его можно использовать где угодно.
VD>Я тут подумал... ValueOption[T] можно попробовать усовершенствовать еще сильнее. Создать версию для объектов, которая в качестве признака null будет использовать самое поле со значением. Тогда оверхэда по памяти вообще не будет. Вот только придется называть ее по другому. Например ObjectOption[T]. Жаль типы нельзя перегружать.

Нужен тип-макрос который преобразуется в правильный тип во время компиляции.
Везде пишем option[T], а компилятор подставит лучший тип в зависимости от T.
В С++ такое сделать вполне возможно.

А нельзя сделать variant, который сгенерировал бы структуру, а не класс чтобы еще и сопоставления работали для ValueOption?

Кстати, а почему не разделить option на 2 класса:
ValueOption[T] where T : struct
ObjectOption[T] where T : class

И используй класс по назначению.

VD>>>Ну, дык соберите команду тех кого интересует этот режим и устраните этот недочет.


__>>Можно попробовать, только боюсь ни у кого на это нет времени \


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


Можно попробовать собрать людей, но у меня сейчас больше желания использовать Nemerle для написания программ, а не заниматься компилятором.

__>>Да и для меня скобочки не смертельный вариант.

__>>В С-подобных языках вообще выбора нет

VD>Вот и я о том же. Так что тот кому не нравятся скобочки может или смириться с ними, или засучить рукова и допилить интеграцию так, чтобы она поддерживала и бесскобочный синтаксис.


Чем больше людей будут переходить с Boo , тем больше шансов на это. Ждем вас программисты на Boo.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[13]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.11.11 18:19
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>Слишком вы тут осторожные, однако. Не хватает воображения, чтобы это давало какие-то проблемы.

_C_>У меня так точно не было, несмотря на многие годы интенсивного использования.

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

В прочем, на С++ я тоже не мало писал и даже привык к этому багодромногму языки. Я наплодил себе кучу правил "хорошего тона" и придерживался их. В итоге объем ошибок был не велик, но вот объем кода, требуемого для решения задач, был слишком велик, а моя производительность напротив слишком мала. C# поднял ее в несколько раз. Nemerle еще в несколько раз. При этом объем кода который требуется написать на немреле для решения той же задачи в разы меньше чем на C# и во много раз меньше чем при работе на C++. Потому я и полюбил этот язык.

_C_>а вот вместо сравнения написать присваивание — это сколько угодно.

_C_>Так что не согласен я с Каутским.

Ты не верно смотришь на проблему. Очевидно, что лишний контроль не помешает. Если бы это приводило к заметному раздуванию кода, то это могло бы породить другие проблемы. Однако на практике кода на Немерле нужно значительно меньше чем на C++ или даже Boo, так как язык обладает кучей возможностей поднимающих производительность программистов не на копейки (как какие-то там присвоения или умолчания при объявлении полей), а в разы (паттерн-матчинг, варианты, макросы).

_C_>>>в struct объявленные поля не public по умолчанию, но вообще-то на то он и struct, что у него все public.

_C_>>>или здесь особый struct?

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

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

Потом какая разница структура это или класс? В дотнтете (а значит и Немерле) структура — это "значимый объект", т.е. объект который передается по значению. Все остальное у структур и классов одинаковое. И точно так же имеет смысл скрывать реализацию выставляя наружу только свойства и методы.

Вот почему свойства по умолчанию private действительно не ясно. Они ведь придуманы именно чтобы использоваться в интерфейсе. Вот их имеет смысл сделать публичными. Лично я, в последнее время, в основном использую именно свойства.

Кстати, немерл открытый язык. Ты без труда создашь макрос который меняет умолчания для типа. Создай макрос PablicByDefault и сможешь регулировать это дело самостоятельно. А в параметрах макроса еще можно будет указать для чего нужно public по умолчанию задавать.

VD>>Есть только один тип в котором по умолчанию поля public — это вхождение вариантов. Во всех стальных местах по умолчанию все члены являются private. Это соглашение всех без исключения C-подобных языков.


_C_>в С++ открытые. значит в С# стали чудить, но я на нем не пишу. но это потому что в Майкрософте народу много, чтобы всех занять придумывают раздутый синтаксис, из пальца высосанные ограничения и низкий уровень языков.


С++ — это пример безграмотного проектирования. На него лучше не ссылаться. В нем все через зад.
В Яве и Шарпе не зря пошли другим путем.

Потом в С++ структура и класс вообще различий почти не имеют. Вот дефолт для доступа пришпандорили. В дотнете же структура — это значимый тип. В общем, совсем другая сущность. Более подходящая по названию.

_C_>Смотрю регулярно, хорошо написано, но понятно не все.


К сожалению, не все там хорошо написано. Ну, а то что по началу не понятно, так это нормально. На то он и новый язык. Я вот твои макросы читал и тоже не все понимал .

_C_>что-нибудь милое и знакомое оставить надо. для психики лучше. и для кода тоже.


Ну, тогда пиши и отлаживай со скобками, а потом преобразуй в отступный синтаксис. Читать и компилировать его можно.

_C_>еще вот не понял как простые стандартные фиксированные массивы создаются (которые в шарпе типа System.Int32[])

_C_>есть ли короткая запись для такого типа?

Дык просто пишешь array[1, 2, 3] и все. Или array(размер) (если нужен незаполенный).
Внутри тел методов типы им указывать не надо. Сами выведутся. А при описании полей и свойств указываешь тип array[тип_элемента].
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.11.11 18:21
Оценка:
Здравствуйте, _Claus_, Вы писали:

VD>>Да... очень советую почитать это
Автор: VladD2
Дата: 04.09.11
. Там как раз даются примеры создания нетривиальных макросов.


_C_>а как этот XML как текст читать, чем?


Это вордовский файл.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.11.11 18:25
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Кстати, а почему не разделить option на 2 класса:

__>ValueOption[T] where T : struct
__>ObjectOption[T] where T : class

__>И используй класс по назначению.


Потому что иногда нужно реализовывать обобщенные алогритмы которые могут принимать любое T. С Nullable уже эту глупость сделали, ограничив типы структурами. Так что сделать
ObjectOption[T] where T : class

можно. Это будет оптимизация.
А вот
ValueOption[T]  where T : struct

это глупость уже.
Нужен Option[T] который будет принимать любой тип и при этом будет структурой (не будет создавать сильного оверхэда).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.11.11 18:33
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>вот это что дает и что за global ?


Прочитай статью на которую я ссылку дал. Там все описано.

_C_> ($("_N_continue" : global)


Это значит, что имя созданное с помощью сплайса будет относиться к глобальному контексту. По умолчанию макросы гигиеничны и имя созданное в макросе не будет видно за его приделами. А вот чтобы сослаться на глобальное имя надо делать так как показано выше.

_C_>вот это непонятно что в match получается


_C_>
_C_>match (cases)
_C_>      {
_C_>        | <[ match ($_) { ..$cases } ]> =>
_C_>


Это распознование оператора match с любым содержимым. При этом проверяемое в match значение значение игнорируется ("_" — это символ игнорирующий значения), а входждения match-а помещаются в переменную cases, которая является списком выражений (о чем говорит сплайс "..$").
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.11.11 21:03
Оценка:
Здравствуйте, _Claus_, Вы писали:

VD>>Пока писал, понял, что для ValueOption[T] нужно добавить ExtensionPattern и открыть тип содержащий его псевдо-конструкторы. Тогда его будет так же удобно использовать как и option[T]. Учитывая, что накладные расходы для ValueOption[T] минимальны (так как это структура) его можно использовать где угодно не опасаясь потери производительности.


_C_>я б про это почитал бы.


Про что конкретно? Про ValueOption[T] или про ExtensionPattern-ы?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: Сообщающиеся макросы
От: _Claus_  
Дата: 21.11.11 22:57
Оценка:
Здравствуйте, VladD2, Вы писали:

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


VD>>>Пока писал, понял, что для ValueOption[T] нужно добавить ExtensionPattern и открыть тип содержащий его псевдо-конструкторы. Тогда его будет так же удобно использовать как и option[T]. Учитывая, что накладные расходы для ValueOption[T] минимальны (так как это структура) его можно использовать где угодно не опасаясь потери производительности.


_C_>>я б про это почитал бы.


VD>Про что конкретно? Про ValueOption[T] или про ExtensionPattern-ы?


да про все. слова незнакомые, чувствую, что-то стоящее.
Re[14]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.11.11 23:14
Оценка:
Здравствуйте, _nn_, Вы писали:

__>А NotNull нельзя приделать к методу ? Чтобы одним махом все проверять на null:

__>
__>[NotNull] public F(a : int, b : string, c : object, d : long) : void { ... }
__>

__>Превращается в ==>
__>
__>public F(a : int, [NotNull] b : string, [NotNull] c : object, d : long) : void { ... }
__>


Ты как маленький прямо. Заходишь в директорию макросов и делаешь поиск по NotNull...

В общем, на сегодня он применим только к параметрам. Даже к возвращаемому значению не применим. Хотя можно использовать макросы Design by Contract для тех же целей.

В общем, если тебе хочется, то можешь добавить макрос на метод и даже на класс (а то и на пространство имен).

__>А этот VariantOption когда стоит использовать вместо option ?


Ага.

__>Только для производительности ? Ведь для юзер кода option должно хватить.


Ну, вот в парсере использовать option[T] очень не выгодно, например. И в компиляторе тоже. Думаю замена с option[T] на ValueOption[T], а еще лучше на ObjectOption[T] даст заметное ускорение компилятора.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Сообщающиеся макросы
От: _Claus_  
Дата: 21.11.11 23:31
Оценка:
VD>Смысл в этом очевидный. Компилятор выявляет ошибки и указывает программисту на это. Это из той же оперы что и необходимость объявления переменной. Физически без этого обойтись можно, но это провоцирует ошибки.

Да все провоцирует на ошибки. Но это в наименьшей степени.

_C_>>нафига использующей стороне знать детали реализации моего класса?


VD>Статические методы не являются частью реализации класса. Выражение идущее до точки (при вызове метода) — это дополнительный параметр. Не находишь, что странно передавать функции лишний параметр?



_C_>>Я могу изменить экземплярное на статическое или наоборот — вызывающий код зачем переделывать?


VD>Если хочешь чтобы вызовы статических методов выглядели как экзеплярные, делай их методами-расширениями.

VD>Только при этом логично было бы, чтобы статический метод получал бы значение объекта в первом параметре. Иначе будет лишний (неиспользуемый параметр).

я так скажу, если даже идти на поводу у параноиков из Майкрософта, это может быть предупреждением, но никак не ошибкой.

VD>Ну, а если метод не обращается к типу к которому он объявлен, то с огромной вероятностью этот метод лежит не там где следовало бы. Таким методам место в отдельных модулях.


_C_>>потому что в Майкрософте им виднее ..


VD>В МС тоже не идиоты сидят. Проектируя C# в МС сделали многое чтобы сделать язык более безопасным (не допускающим случайных ошибок). К сожалению, без проблем тоже не обошлось и косяки в язык добавили. Например, оператор as. Но в целом дизайн C# лучший из мэйстрим-языков.


не идиоты. но ничего умного по части языков / компиляторов ими не было придумано / внедрено. Идеи .Net датируются серединой 80-х, идея C# и реализация .Net -беглых из Borland, и т. д. Вот и Nemerle им кость в горле. а вы говорите — ну нет, вряд ли они тупые, вот скопируем вот это, не зря же они
тут лохмотьев намотали. а вот и зря. нет там гениев. или их к программированию не допускали.

VD>При проектировании Nemerle концепция недопущения случайных ошибок была поставлена во главу угла. В процессе работы над языком было выкинуто ряд решений которые могли приводить к случайным ошибкам. На сегодня немерл один из самых устойчивых к ошибкам языков из практически применимых ЯП.


Да много лишних слов и конструкций, которые вызывают откровенное недоумение, потому что реально Nemerle крут, но рябые C# уши торчат во многих местах.

Вот например нафига при вызове функций с ref out каждый раз его явно указывать. я уже сказать компилятору что там ref,
чего я как попугай должен это постоянно повторять. или вдруг это может стать по-другому? но время я на этом теряю. вижу ошибки, начинаю пугаться, править.

или typeof для шаблонного параметра, если я его передаю в функцию требующую System.Type, почему я должен писать typeof(T), хотя
коню понятно что речь о типе, о чем же еще? где тут устойчивость к ошибкам? нету, но есть лишний маразматический код, любезно перенятый у мелкомягких.
Re[16]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.11.11 23:45
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>да про все. слова незнакомые, чувствую, что-то стоящее.


ExtensionPattern — это способ дать возможность использовать более простой паттерн (при паттерн-матчинге).

ValueOption[T] — это структура — аналог типа optin[T]. ValueOption[T] банально быстрее optin[T] так как optin[T] — ссылочный тип, а ValueOption[T] структура.

optin[T] — это принятый в мире ФП паттерн представления необязательного значения. Вместо того чтобы допускать null в качестве значения мы описываем тип переменной как option[T] (option[T] — это вариантный тип). Далее, если есть значение, то мы его оборачивам в значение optin[T].Some(42), а если нет, то используем optin[T].None() который не имеет значения.

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

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

При этом у таких оберток есть развитый интерфейс для работы с ними. Так с ними работают операторы ?. и ??. Первый вовращает дефволт-значнеие, если ссылка нулевая. Второй позволяет задать конкретное дефолтное значение, если ссылка нулевая.

Но у option[T] есть еще одно преимущество. Так как option[T] вариант, то его значения можно распознавать с помощью сопоставления с образцом.

Например:
def Plus(x : optin[int], y : optin[int])
{
  | (Some(x), None)    => x
  | (None,    Some(y)) => y
  | (Some(x), Some(y)) => x + y
}


Для ValueOption[T] так не сделаешь, так как ValueOption[T] не вариантный тип. Можно конечно использовать его в сопоставлении с образцом следующим образом (с использованием паттерна where):
def Plus(x : ValueOption[int], y : ValueOption[int])
{
  | (ValueOption where(HasValue=true, Value=x), ValueOption where(HasValue=false))         => x
  | (ValueOption where(HasValue=false),         ValueOption where(HasValue=true, Value=y)) => y
  | (ValueOption where(HasValue=true, Value=x), ValueOption where(HasValue=true, Value=y)) => x + y
}

Но это слишком громоздко.

Так вот можно написать ExtensionPattern который опишет более простой паттерн и отобразит его в более сложный, но применимый к структуре.

Вот как выглядят ExtensionPattern-атрибуты для типа ValueOption[T]:
  [ExtensionPattern(VSome(value) = ValueOption where(HasValue=true, Value=value))]
  [ExtensionPattern(VNone()      = ValueOption where(HasValue=false))]
  public struct ValueOption[T]
  {
    ...

Теперь в сопоставлении с образцом можно использовать следующий код:

def Plus(x : ValueOption[int], y : ValueOption[int])
{
  | (VSome(x), VNone)    => x
  | (VNone,    VSome(y)) => y
  | (VSome(x), VSome(y)) => x + y
}

то есть, код, практически аналогичный тому что был с вариантами. Но при этом ValueOption — это структура, а значим мы получаем повышенную производительность.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.11.11 00:09
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>Да все провоцирует на ошибки. Но это в наименьшей степени.


Примеры в студию! Тогда и обсудим.

_C_>я так скажу, если даже идти на поводу у параноиков из Майкрософта, это может быть предупреждением, но никак не ошибкой.


По-моему все очевидно. Не нужен функции лишний праметр, но его передают. Это может быть ошибка ил небрежность. Такого допускать нельзя. Не нужен параметр — не передавай. Там в ведь может быть не хилое вычисление a.f(42, "ss").Y.Foo(); Зачем его высчитывать, если Foo даже не имеет такого параметра?

Другой вопрос. А нужно ли вообще производить это вычисление? Ведь "a.f(42, "ss").Y" испоьзуется только для вычисления типа. Что бы он не вернул тип будет один и тем же. Но этот код может создать побочные эффекты и выкидывать его нельзя.

В общем, вопросов выше крыши.

А с запретом проблем нет.

_C_>Вот и Nemerle им кость в горле.


Они упорно делают вид, что не замечают Nemerle. Какая тут кость?

_C_> а вы говорите — ну нет, вряд ли они тупые, вот скопируем вот это, не зря же они

_C_>тут лохмотьев намотали. а вот и зря. нет там гениев. или их к программированию не допускали.

Ну, мы то как раз ничего бездумно не копируем. Все ошибки Хейльсберга мы выбросили.

_C_>Да много лишних слов и конструкций, которые вызывают откровенное недоумение, потому что реально Nemerle крут, но рябые C# уши торчат во многих местах.


Хорошие уши торчат. Плохие нет. Надо говорить конкретно. Пока что тебе не нравится то, что другим очень даже нравится.

_C_>Вот например нафига при вызове функций с ref out каждый раз его явно указывать.


Откровенно говоря сама идея передачи значений по ссылкам мне не нравится. Будь возврат кортежей эффективне, я бы советовал вообще не использовать ref/out-параметров, так как они неудобны и императивны.

Но раз уж они есть — этот синтаксис самый удобный и безопасный. Он заставляет человека четко понимать что происходит. Читая код видно, что я передал ссылку.

В С++ как раз это было сделано до безобразия бездарно. Тут нужно отдать должное Хельсбергу. Хотя лучше бы он изучил что такое кортежи. Они куда лучше подходят для возврата значений. А ссылки в любом случае зло.

_C_>я уже сказать компилятору что там ref,

_C_>чего я как попугай должен это постоянно повторять.

Чтобы понимать, что происходит. Что значение переменной переданной в параметр может измениться.

_C_>или вдруг это может стать по-другому?


Ага. Поменял описание метода и вдруг нежданно не гадагно переменная которая раньше не изменялась вдруг начала изменяться. И фиг поймешь где и как. Короче — грабли. А тут тебя заставляют такие места явно описать и обвесить флажками (как волчий загон).

_C_>но время я на этом теряю. вижу ошибки, начинаю пугаться, править.


_C_>или typeof для шаблонного параметра, если я его передаю в функцию требующую System.Type, почему я должен писать typeof(T), хотя коню понятно что речь о типе, о чем же еще? где тут устойчивость к ошибкам? нету, но есть лишний маразматический код, любезно перенятый у мелкомягких.


Тут ты чего-то странное говоришь. typeof() возвращает рантайм-тип (объект описывающий тип). В качестве параметра он получает имя типа времени компиляции. Как typeof() узнает, что ты хочешь получить информацию о типе T, а не о каком-то другом?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Сообщающиеся макросы
От: _Claus_  
Дата: 22.11.11 04:03
Оценка:
VD>Другой вопрос. А нужно ли вообще производить это вычисление? Ведь "a.f(42, "ss").Y" испоьзуется только для вычисления типа. Что бы он не вернул тип будет один и тем же. Но этот код может создать побочные эффекты и выкидывать его нельзя.
Побочные эффекты можно создать любым кодом. Ошибки в вызове по ссылке на экземпляр нет логически. Я не могу вспомнить ни одного языка с таким диким ограничением. поэтому зацепило..

VD>В общем, вопросов выше крыши.

VD>А с запретом проблем нет.

Вот многовато запретов. Человек заходит с С++ или Питона (первые ищут жизнь полегче, вторые — скорости) к примеру, а ему тут запреты. дайте хоть путь обойти. "вот модуль, пишите почти как раньше. получите бонусы. но учтите, что истина где-то рядом" — было бы разумно.
Ценность Nemerle не в текущей спецификации языка (хороша, но есть сильные конкуренты), а в его потенциальной мимикрии к чему угодно, в архитектуре Core (конкурентов нет).
Приди в голову кому-нибудь написать систему макросов для того же Python — и большинство Питон-кода получат 20x ускорения. (для этого правда вывод типов должен быть и для возвращаемых значений, но уверен, это искусственное ограничение).
Или Ruby, CoffeeScript, .. то же самое. текущий синтакс с его ограничениями может впечатлить выходцев с С# и Java, остальные будут постоянно
натыкаться на строгости, которые, увы, оценят только шарписты. чего стоит недружелюбность — отсутствие Imperative в генерируемых в проекте фалах.
некто хочет попробовать, пишет незамысловатый цикл с return или break и получает плюху. после кинется читать мануалы? сильно наврядли. не хотят люди новых ограничений. хотят старые сбагрить. педантичные требования раздражают. если к ним не привык конечно. вот Scala — не хотите не пишите точку для доступа к члену, скобки вызова и т.п. и там нет протестов "запретите а то мы ошибемся, руки прочь от скобок!" — хотите пишите, не хотите не пишите. Одерски вместе со мной считаем, если компилятор может разрулить,пусть этим и занимается. и чем меньше я напишу и чем больше получу- тем ясно лучше. а для контроля юнит-тесты в помощь.
умный язык должен предоставлять разумную систему умолчаний на все. а там, если мало, пиши ограничения, уточняй, наяривай.
и платформу скрывать на которой работает с ее косяками. потому что человек может прийти с другой, и эти С# "инновации" ему не нужны даже бесплатно.
Dart вот идет по этому пути. А в Google не идиоты сидят. или и тут поспорим


VD>Хорошие уши торчат. Плохие нет. Надо говорить конкретно. Пока что тебе не нравится то, что другим очень даже нравится.


_C_>>Вот например нафига при вызове функций с ref out каждый раз его явно указывать.


VD>Откровенно говоря сама идея передачи значений по ссылкам мне не нравится. Будь возврат кортежей эффективне, я бы советовал вообще не использовать ref/out-параметров, так как они неудобны и императивны.


VD>Но раз уж они есть — этот синтаксис самый удобный и безопасный. Он заставляет человека четко понимать что происходит. Читая код видно, что я передал ссылку.


да нету такого нигде (C# не в счет). раз объявил и все. а тут — "мы не тупой, но повторяю снова"

VD>Тут ты чего-то странное говоришь. typeof() возвращает рантайм-тип (объект описывающий тип). В качестве параметра он получает имя типа времени компиляции. Как typeof() узнает, что ты хочешь получить информацию о типе T, а не о каком-то другом?


вот код:
def delta : int = Marshal.SizeOf(typeof(memblock)) //memblock — struct
если я напишу
def delta : int = Marshal.SizeOf(memblock)
это ошибка, но что еще в данном контексте может значить memblock? кроме типа.. строку? число?
Re[17]: Сообщающиеся макросы
От: Ziaw Россия  
Дата: 22.11.11 04:34
Оценка:
Здравствуйте, _Claus_, Вы писали:

VD>>Другой вопрос. А нужно ли вообще производить это вычисление? Ведь "a.f(42, "ss").Y" испоьзуется только для вычисления типа. Что бы он не вернул тип будет один и тем же. Но этот код может создать побочные эффекты и выкидывать его нельзя.


Влад, тут нужен просто ворнинг. Программист уже сам решит, нужно там вычисление или нет.

_C_>Побочные эффекты можно создать любым кодом. Ошибки в вызове по ссылке на экземпляр нет логически. Я не могу вспомнить ни одного языка с таким диким ограничением. поэтому зацепило..


Вот тут я согласен. Особых проблем от вызова статических методов у экземпляра быть не должно.

_C_>некто хочет попробовать, пишет незамысловатый цикл с return или break и получает плюху. после кинется читать мануалы? сильно наврядли. не хотят люди новых ограничений. хотят старые сбагрить. педантичные требования раздражают. если к ним не привык конечно. вот Scala — не хотите не пишите точку для доступа к члену, скобки вызова и т.п. и там нет протестов "запретите а то мы ошибемся, руки прочь от скобок!" — хотите пишите, не хотите не пишите. Одерски вместе со мной считаем, если компилятор может разрулить,пусть этим и занимается. и чем меньше я напишу и чем больше получу- тем ясно лучше. а для контроля юнит-тесты в помощь.

_C_>умный язык должен предоставлять разумную систему умолчаний на все. а там, если мало, пиши ограничения, уточняй, наяривай.
_C_>и платформу скрывать на которой работает с ее косяками. потому что человек может прийти с другой, и эти С# "инновации" ему не нужны даже бесплатно.
_C_>Dart вот идет по этому пути. А в Google не идиоты сидят. или и тут поспорим

В nemerle 2 можно будет подумать о диалекте без скобок и точек с запятой. Диалекты там будут делаться и подключаться проще. Реализовать это в первом немерле имеющимися силами просто нереально.

_C_>>>Вот например нафига при вызове функций с ref out каждый раз его явно указывать.


_C_>да нету такого нигде (C# не в счет). раз объявил и все. а тут — "мы не тупой, но повторяю снова"


А мне нравится. Именно тем, что я не гадаю, как там передается параметр. Не хватает только возможности автоматического объявления переменной в out по месту. Иммутабельной.

_C_>вот код:

_C_>def delta : int = Marshal.SizeOf(typeof(memblock)) //memblock — struct
_C_>если я напишу
_C_>def delta : int = Marshal.SizeOf(memblock)
_C_>это ошибка, но что еще в данном контексте может значить memblock? кроме типа.. строку? число?

В Nemerle memblock это конструктор. Было бы странно, если бы в некоторых, ничем не выделяющихся контекстах он означал что-то другое.
Re[17]: Сообщающиеся макросы
От: _Claus_  
Дата: 22.11.11 04:49
Оценка:
спасибо! впечатлило!
Re[18]: Сообщающиеся макросы
От: _Claus_  
Дата: 22.11.11 05:04
Оценка:
Z>В nemerle 2 можно будет подумать о диалекте без скобок и точек с запятой. Диалекты там будут делаться и подключаться проще. Реализовать это в первом немерле имеющимися силами просто нереально.

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

_C_>>>>Вот например нафига при вызове функций с ref out каждый раз его явно указывать.


_C_>>да нету такого нигде (C# не в счет). раз объявил и все. а тут — "мы не тупой, но повторяю снова"


Z>А мне нравится. Именно тем, что я не гадаю, как там передается параметр. Не хватает только возможности автоматического объявления переменной в out по месту. Иммутабельной.


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

_C_>>вот код:

_C_>>def delta : int = Marshal.SizeOf(typeof(memblock)) //memblock — struct
_C_>>если я напишу
_C_>>def delta : int = Marshal.SizeOf(memblock)
_C_>>это ошибка, но что еще в данном контексте может значить memblock? кроме типа.. строку? число?

Z>В Nemerle memblock это конструктор. Было бы странно, если бы в некоторых, ничем не выделяющихся контекстах он означал что-то другое.


не знал. так конечно. я ж то думал .. а так да, согласен.
Re[15]: Сообщающиеся макросы
От: _nn_ www.nemerleweb.com
Дата: 22.11.11 08:25
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>В общем, если тебе хочется, то можешь добавить макрос на метод и даже на класс (а то и на пространство имен).


Попробую, думаю, макрос будет полезен

__>>А этот VariantOption когда стоит использовать вместо option ?


VD>Ага.


__>>Только для производительности ? Ведь для юзер кода option должно хватить.


VD>Ну, вот в парсере использовать option[T] очень не выгодно, например. И в компиляторе тоже. Думаю замена с option[T] на ValueOption[T], а еще лучше на ObjectOption[T] даст заметное ускорение компилятора.


Почему не заменить ? Учитывая возможности ExtensionPattern, можно получить вполне удобное применение без проигрыша производительности.
Если это еще улучшает скорость компилятора, то вообще
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[17]: Сообщающиеся макросы
От: _nn_ www.nemerleweb.com
Дата: 22.11.11 08:39
Оценка: +1
Здравствуйте, _Claus_, Вы писали:

_C_>Вот многовато запретов. Человек заходит с С++ или Питона (первые ищут жизнь полегче, вторые — скорости) к примеру, а ему тут запреты. дайте хоть путь обойти. "вот модуль, пишите почти как раньше. получите бонусы. но учтите, что истина где-то рядом" — было бы разумно.


Как раз в Python много запретов и это считается хорошим тоном.
Как же Python Zen: "There should be one—and preferably only one—obvious way to do it" ?

_C_>да нету такого нигде (C# не в счет). раз объявил и все. а тут — "мы не тупой, но повторяю снова"


Вот в С++ если есть указатель не вполне ясно что код делает:
void f(int* a) { }

int x;
f(&x);

Тут меняем переменную, инициализируем или просто работаем со значением ?

Как раз в C# правильно сделали. Позволяет легче понимать код.
А вообще ref/out в Nemerle практически не нужны, разве что в местах критичных для производительности.
Кортежи и variant-ы решают проблему возврата множества значений.
Если у вас в Nemerle коде много ref/out , то замените их на более удобные фичи языка.

Скажем стандартный паттерн TryParse:
// C#
class My
{
  public static bool TryParse(string s, out My m) { ... }
}

// Nemerle
class My
{
  public static TryParse(s : string) : option[My] { ... }
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[18]: Сообщающиеся макросы
От: _nn_ www.nemerleweb.com
Дата: 22.11.11 08:51
Оценка: 49 (1)
Здравствуйте, Ziaw, Вы писали:

Z>Вот тут я согласен. Особых проблем от вызова статических методов у экземпляра быть не должно.


Calling static methods on type parameters is illegal, part one
Calling static methods on type parameters is illegal, part two
Calling static methods on type parameters is illegal, part three

Вкратце, тип для вызова статического метода определяется во время компиляции и поэтому в генерик классе знать что реально нужно вызвать невозможно.

P.S.
Woraround:
typeof(<type name>).GetMethod("<method name>").Invoke(null, new object[]{<list of parameters if any>});
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[17]: Сообщающиеся макросы
От: artelk  
Дата: 22.11.11 09:08
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>ValueOption[T] — это структура — аналог типа optin[T]. ValueOption[T] банально быстрее optin[T] так как optin[T] — ссылочный тип, а ValueOption[T] структура.


А почему бы сам option[T] не переделать в структуру? Сделать Extension Pattern с теми же именами Some(value) и None, чтобы внешне все выглядело так же и существующий код нормально компилировался.
Или где-то требуется, чтобы он был ссылочным типом?
Re[19]: Сообщающиеся макросы
От: Ziaw Россия  
Дата: 22.11.11 12:53
Оценка: 1 (1) +1
Здравствуйте, _Claus_, Вы писали:


Z>>А мне нравится. Именно тем, что я не гадаю, как там передается параметр. Не хватает только возможности автоматического объявления переменной в out по месту. Иммутабельной.


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

_C_>но появись двуглазая альтернатива- исход будет решен.

Да ладно. Рассказывай такие сказки тем, у кого действительно нет альтернатив. Я знаком с достаточно большим количеством языков. ref и out это редко используемые костыли, низкоуровневые оптимизации. Очень хорошо, что они видны в коде. В С++ глядя на вызов можно легко предположить, что передается ссылка, они там чаще чем по значению ходят. А вот в дотнете ref/out настолько редкая птица, что мозг без подсказок этот вариант просчитывать не будет.

Z>>В Nemerle memblock это конструктор. Было бы странно, если бы в некоторых, ничем не выделяющихся контекстах он означал что-то другое.


_C_>не знал. так конечно. я ж то думал .. а так да, согласен.


В отличии от C#, конструктор в nemerle не оператор (new typename(..)), а функция typename(...). Она может быть использована как любая другая функция в качестве ФВП.
Re[18]: Сообщающиеся макросы
От: WolfHound  
Дата: 22.11.11 14:02
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Влад, тут нужен просто ворнинг. Программист уже сам решит, нужно там вычисление или нет.

И что дальше? Будешь держать проект с ворнингом?

Z>А мне нравится. Именно тем, что я не гадаю, как там передается параметр. Не хватает только возможности автоматического объявления переменной в out по месту. Иммутабельной.

Тут возникает куча вопросов с областью видимости данной переменной.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[20]: Сообщающиеся макросы
От: _nn_ www.nemerleweb.com
Дата: 22.11.11 14:03
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>В отличии от C#, конструктор в nemerle не оператор (new typename(..)), а функция typename(...). Она может быть использована как любая другая функция в качестве ФВП.


Как-то не задумывался об этом.
Однако да, 1-0 в пользу отброса 'new' :

using System.Console;
 
class A { public P : int { get { 0 } } }
 
def f(g)
{
  def x = g();
  WriteLine($"x.P - $(x.P)");
}
 
f(A)

x.P — 0


http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[18]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.11.11 14:57
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Влад, тут нужен просто ворнинг. Программист уже сам решит, нужно там вычисление или нет.


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

Зафиг вообще нужен ворнинг? Какая-то странная позиция. Вроде как считаем поведение ненормальным, но боимся назвать вещи своими именами.

_C_>>Побочные эффекты можно создать любым кодом. Ошибки в вызове по ссылке на экземпляр нет логически. Я не могу вспомнить ни одного языка с таким диким ограничением. поэтому зацепило..


Z>Вот тут я согласен. Особых проблем от вызова статических методов у экземпляра быть не должно.


Давайте вы покажите хотя бы одно обсуждение, где кто-то критиковал бы поведение принятое в C#.
Люди не даром ввели это требование. Это грабли и им не место в языке.

Z>А мне нравится. Именно тем, что я не гадаю, как там передается параметр. Не хватает только возможности автоматического объявления переменной в out по месту. Иммутабельной.


Очень смешно. Надеюсь ты просто очепятался и имелось в виду "мутабельной" (по русски говоря — изменяемой).

Не хватает? Ну, так сделай. Задачка не сложная.
Я вот почти не использую эти ref/out. Так что и проблем не испытываю.


_C_>>вот код:

_C_>>def delta : int = Marshal.SizeOf(typeof(memblock)) //memblock — struct
_C_>>если я напишу
_C_>>def delta : int = Marshal.SizeOf(memblock)
_C_>>это ошибка, но что еще в данном контексте может значить memblock? кроме типа.. строку? число?

Z>В Nemerle memblock это конструктор. Было бы странно, если бы в некоторых, ничем не выделяющихся контекстах он означал что-то другое.


Причем тут конструктор? memblock имеет тип memblock. В SizeOf требуется тип System.Type. Что странного что такое преобразование осуществляется не магически, а с помощью функции? На оборот, отлично видно что происходит в коде.

В общем, товарищ нашел к чему докопаться. Если нечего делать пусть сделает макрос SizeOf который будет принимать имя типа и возвращать System.Type.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[19]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.11.11 15:04
Оценка:
Здравствуйте, _Claus_, Вы писали:

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

_C_>но появись двуглазая альтернатива- исход будет решен.

Ну, да. Только одноглазой бабой является С++. Причем не только одноглазой, но еще кривой и страшной как смерть. Ты вот влез из леса увидел других и давай у них в глазу песчинку искать, чтобы за свою, одноглазую, не было стыдно.

_C_>не знал. так конечно. я ж то думал .. а так да, согласен.


Тут такой вопрос. Весь дизайн (ну, за исключением отдельных вопросов вроде точек в параметрах типов) серьезно продуман. Все сделано не с дури. Глупого копирования не было. Везде где в языках (из которых производилось заимствование) было что-то криво, кривые решения не брались. Из того же Шарпа много чего выикинули. Это и оператор as, и разрешение пегрузок при наличии виртульных членов, и много чего еще.

Кому не нравится что-то, может (в большинстве случаев) создать макросы которые это дело обходят. Так не сложно создать макросы которые сократят синтаксис того же SizeOf. Но это уже будут ваши личные, и что очень важно, локальные изыски.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.11.11 15:05
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Почему не заменить ? Учитывая возможности ExtensionPattern, можно получить вполне удобное применение без проигрыша производительности.

__>Если это еще улучшает скорость компилятора, то вообще

Потому что это не малый объем работы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.11.11 15:15
Оценка:
Здравствуйте, artelk, Вы писали:

A>А почему бы сам option[T] не переделать в структуру? Сделать Extension Pattern с теми же именами Some(value) и None, чтобы внешне все выглядело так же и существующий код нормально компилировался.

A>Или где-то требуется, чтобы он был ссылочным типом?

Боюсь, что кое-где код может поломаться.

У кого есть время может попробовать на клоне.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[19]: Сообщающиеся макросы
От: Ziaw Россия  
Дата: 22.11.11 15:36
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Давайте вы покажите хотя бы одно обсуждение, где кто-то критиковал бы поведение принятое в C#.

VD>Люди не даром ввели это требование. Это грабли и им не место в языке.

Лана, фик с ним. Убедили.

Z>>А мне нравится. Именно тем, что я не гадаю, как там передается параметр. Не хватает только возможности автоматического объявления переменной в out по месту. Иммутабельной.


VD>Очень смешно. Надеюсь ты просто очепятался и имелось в виду "мутабельной" (по русски говоря — изменяемой).


Нет, я хочу именно иммутабельную. Ибо out это аналог инициализации переменной.

Хочется чего-то типа:
when (dict.TryGetValue(key, def out val))
{
  // use immutable val
}

сейчас приходится делать:
mutable val; // оно мне не надо в этой области видимости
when (dict.TryGetValue(key, def out val))
{
  // оно мне не надо мутабельное здесь
}



VD>Не хватает? Ну, так сделай. Задачка не сложная.


Задача сложная. Как правильно заметил Wolfhound не очень очевидна даже область видимости. Боюсь даже, что макрами это решить будет сложнее, чем компилятор править.

VD>Я вот почти не использую эти ref/out. Так что и проблем не испытываю.


Я тоже редко.
Re[20]: Сообщающиеся макросы
От: _nn_ www.nemerleweb.com
Дата: 22.11.11 15:49
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Нет, я хочу именно иммутабельную. Ибо out это аналог инициализации переменной.


Предлагаю initonce:
initonce val;
// Тут mutable

when (dict.TryGetValue(key, out val))
{
  // Тут immutable
}
// Тут immutable


Как реализовать не знаю.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[17]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.11.11 16:09
Оценка:
Здравствуйте, _Claus_, Вы писали:


_C_>Вот многовато запретов. Человек заходит с С++ или Питона (первые ищут жизнь полегче, вторые — скорости) к примеру, а ему тут запреты. дайте хоть путь обойти. "вот модуль, пишите почти как раньше. получите бонусы. но учтите, что истина где-то рядом" — было бы разумно.


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

Я вот когда переходил на C# с С++ тоже испытывал неудовольствие, но совсем по другим поводам. Меня угнетало отсутствие шаблонов (тогда еще был C# 1.0 в котором даже дженериков не было) и множественного наследования (МН). Со временем понял, что без МН можно отлично жить. Есть другие подходы, а от МН не только польза, но и вред был не малый. А вот шаблоны — это уже бесспорный и объективный недостаток. Дженерики смогли снизить потребность, но устранить ее не смогли. В немерле я нашел отличную замену шаблонам. На них можно сделать все что угодно. Шаблонам такая гибкость и не снилось. И, главное, что все делается как следует, а не через задницу, как это часто бывало в плюсах.

_C_>некто хочет попробовать, пишет незамысловатый цикл с return или break и получает плюху. после кинется читать мануалы? сильно наврядли.


Не давай все пространства имен откроем, все макросы впихнем и будем удивляться почему это люди функциональные возможности не используют, а все долбят for-ы и while-ы.

На практике таких проблем нет. Если кто-то умудрился не прочтя ни одной статьи сесть писать код на немерле, то он полезет на форумы или поглядит в чужой код. Пока что такую претензию только ты и высказал. Причем сам же признался, что решение проблемы тебе уже известно. Вот и другим известно. Лично я пишу return раз в месяц. А continue или break использую еще реже. Да что уж там? Практически не использую.

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

_C_> не хотят люди новых ограничений. хотят старые сбагрить.


Ну, а что мы будем рассказывать тем кто с C# или Java-ы переходить? Мол, извиняйте добры молодцы. К нам тут до вас С++-ник заходил и мы под него язык поднастроили, чтобы ему привычнее по первой было? Ну, смешно же!

_C_>педантичные требования раздражают. если к ним не привык конечно. вот Scala


А что Scala в ней как раз ограничений и запретов выше крыши.

_C_> — не хотите не пишите точку для доступа к члену,


Да ладно! Там есть соврешенно непродуманное решение использовать методы как операторы. Проблем от него куда больше чем пользы. Приоритеты и ассоциативность ведь задать нельзя. В результате получается бардак. А осуществить доступ к члену без точки там точно так же нельзя. В С++, кстати, тоже. Ну, а в немерле ты можешь описать нужные тебе операторы в виде макросов. При этом для них можно задать приоритет и ассоциативность. А можешь и полноценный ДСЛ. Причем без приседений и ужимок.

Это как в плюсах. Есть вот метапрограммирование на шаблонах. Но через задницу, на другом языке, медленно, убого и с кучей ограничений. Ну, давай теперь немерл поругаем что он и это говнище не впихнул в себя. Зачем только? Ведь вместо этого есть полноценное прямое решение — макросы. Они гибче, быстрее и их можно писать на том же языке что они расширяют.

_C_>скобки вызова и т.п. и там нет протестов "запретите а то мы ошибемся, руки прочь от скобок!" — хотите пишите, не хотите не пишите.


В Скале ограничений куча. И после С++ на Скале уж точно не будешь себя в своей тарелке чувствовать.

Многие навороты в Скале были сделаны чтобы не вводя макросы позволить создавать ДСЛ-и и расширять язык. Итог фееричный — Одесски пришел к выводу, что нужно добавлять в Скалу макросы. Пока что, прада, без синтаксического расширения. Но если они что-то сделают, то это это будет только делом времени.

Короче, делают ошибки и ходят по граблям. И все из-за отсутствия дальновидности.

Результат плачевыный. Скала давно превратилась в лингивистическую помойку. Вот ДжетБрэйнс делает свою упрощенную скалу, так как простые смертные с этими наворотами уже справиться не могут.

_C_> Одерски вместе со мной считаем, если компилятор может разрулить,пусть этим и занимается.


Компилятор то многое может разрулить. А вот человек — нет. Язык делается в первую очередь для человека.
И дизайн языка — это очень не простой вопрос. Каждую его деталь надо обкатывать на практике. Так что огульно сувать в язык разную хрень только ради того чтобы быть привычным все подряд — это не подход. Он приведет к превращению языка в помойку.

В Н2 мы планируем сделать языковый конструктор. Разработка языков и их модификаций на нем будет существенно упрощена. Кто хочет может попытать счастье в создании своего супер-языка. А немерл останется тем чем он есть сейчас — скрещиванием C#, ML и макросов.

Менять если что-то и будем, то только после продолжительного обсуждения в результате которого не будет серьезных голосов против.

Из всех твоих предложений я бы, пожалуй, пошел только на изменение дефолтных прав доступа для свойств (а не для структур, что смысла не имеет). Вот зачем каждый раз писать public к свойствам я действительно не понимаю. Ведь 99.9% свойств являются публичными, а для 0.1% можно и явно указать.

Но и это будем обсуждать и смотреть на реакцию народа. Ни то можно такого накуралисить...

_C_>юнит-тесты в помощь.


Ну, дык пиши на Жабаскрипте. Ограничений минимум. Без юнит-тестов вообще жить нельзя. Самое то. И МП есть (динамика ведь).

_C_>умный язык должен предоставлять разумную систему умолчаний на все. а там, если мало, пиши ограничения, уточняй, наяривай.


Ну, дык так и старались сделать. Ничего разумного в public-е для изменяемых полей в структурах нет. А вот проблем от этого точно будет не мало.

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

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

_C_>Dart вот идет по этому пути. А в Google не идиоты сидят. или и тут поспорим


Очень смешно. Пока что Гугль занимается откровенной херней. Лучше бы нас поддержали.

VD>>Но раз уж они есть — этот синтаксис самый удобный и безопасный. Он заставляет человека четко понимать что происходит. Читая код видно, что я передал ссылку.


_C_>да нету такого нигде (C# не в счет). раз объявил и все. а тут — "мы не тупой, но повторяю снова"


Мало что до этого не было? Теперь будет. Решение хорошее. А то что этого не было в недоязыках вроде С++, меня это мало интересует. Его дизайн только первопроходчеством можно оправдать.

VD>>Тут ты чего-то странное говоришь. typeof() возвращает рантайм-тип (объект описывающий тип). В качестве параметра он получает имя типа времени компиляции. Как typeof() узнает, что ты хочешь получить информацию о типе T, а не о каком-то другом?


_C_>вот код:

_C_>def delta : int = Marshal.SizeOf(typeof(memblock)) //memblock — struct
_C_>если я напишу
_C_>def delta : int = Marshal.SizeOf(memblock)
_C_>это ошибка, но что еще в данном контексте может значить memblock? кроме типа.. строку? число?

Это выглядит как передача ссылки на конструктор. Вот это вполне корреткный код для немерла:
module Marshal
{
  public SizeOf[T](func : void -> T) : T { func() }
}
...
Marshal.SizeOf(memblock) // передаем ссылку на конструктор

Да и в любом случае memblock — это конкретный тип. А SizeOf требует другой тип System.Type. Как при этом получить тип для самого System.Type?

Вот и выходит, что это не дурь, а очень даже логичное решение. Псевдо-фукнция преобразующая статический типов в его рантайм-представление. В С++, кстати, РТТИ похожим образом сделано.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[21]: Сообщающиеся макросы
От: WolfHound  
Дата: 22.11.11 16:17
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Предлагаю initonce:

Тогда уж просто def без инициализатора.
Ты пойми тут проблема не в синтаксисе, а в куче работы по отслеживанию потока исполнения.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[22]: Сообщающиеся макросы
От: _nn_ www.nemerleweb.com
Дата: 22.11.11 16:37
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


__>>Предлагаю initonce:

WH>Тогда уж просто def без инициализатора.
Тоже вариант
WH>Ты пойми тут проблема не в синтаксисе, а в куче работы по отслеживанию потока исполн\ения.
Это я как раз понимаю.

В Nemerle до сих пор есть баг с отслеживанием out аргументов
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[20]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.11.11 22:55
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Нет, я хочу именно иммутабельную. Ибо out это аналог инициализации переменной.

Z>Хочется чего-то типа:
Z>
Z>when (dict.TryGetValue(key, def out val))
Z>{
Z>  // use immutable val
Z>}
Z>

Z>сейчас приходится делать:
Z>
Z>mutable val; // оно мне не надо в этой области видимости
Z>when (dict.TryGetValue(key, def out val))
Z>{
Z>  // оно мне не надо мутабельное здесь
Z>}
Z>


Ах вот ты о чем?... Забавно. Ну, а что делать с ref?

Тогда лучше взять решение из F# — виртуально преобразовывать функции с ref/out-параметрами в функции возвращающие кортеж. Скажем функция:
Foo(a : int, b : ref string, c : out long) : bool

преобразуется в:
Foo(a : int, b : string) : string * long * bool

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

Реализовать будет не просто, правда.

VD>>Не хватает? Ну, так сделай. Задачка не сложная.


Z>Задача сложная. Как правильно заметил Wolfhound не очень очевидна даже область видимости. Боюсь даже, что макрами это решить будет сложнее, чем компилятор править.


Я думал ты о поддержке в IDE говоришь. Ну, типа автоматом создавать переменную по кнопке.

VD>>Я вот почти не использую эти ref/out. Так что и проблем не испытываю.


Z>Я тоже редко.


Так стоит тогда копья ломать?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[21]: Сообщающиеся макросы
От: _Claus_  
Дата: 23.11.11 06:44
Оценка:
VD>>>Не хватает? Ну, так сделай. Задачка не сложная.

Z>>Задача сложная. Как правильно заметил Wolfhound не очень очевидна даже область видимости. Боюсь даже, что макрами это решить будет сложнее, чем компилятор править.


VD>Я думал ты о поддержке в IDE говоришь. Ну, типа автоматом создавать переменную по кнопке.


VD>>>Я вот почти не использую эти ref/out. Так что и проблем не испытываю.


Использование ref out это от недоразвитости функциональных фич языка.

но в импортируемом коде такое бывает.

и.. в Nemerle если при возврате создается объект-кортеж, а функция крутится в долгом цикле, это может замедлить
код на порядок-два. и вот это проблема, почему даже здесь имеет смысл это использовать.
или есть козырьоптимизация в рукаве?
Re[18]: Сообщающиеся макросы
От: _Claus_  
Дата: 23.11.11 08:03
Оценка:
VD>В прочем, можно специально создать парочку шаблонов для начинающих с большим императивным стажем. Назвать только как-то, чтобы было понятно. Или сделать визард в котором чекбоксами предлагать нужные возможности выбрать.

Если язык смешанного типа, как утверждается, по логике императивные инструкции поддерживаются по умолчанию.
а если уж быть последовательным, то надо и for — while отключить, — чистейший императив.
логика должна быть превыше всего. а не догмы.

_C_>>педантичные требования раздражают. если к ним не привык конечно. вот Scala

VD>А что Scala в ней как раз ограничений и запретов выше крыши.
Да там компилятор рулит и разруливает, все что можно.

_C_>> — не хотите не пишите точку для доступа к члену,


VD>Да ладно! Там есть соврешенно непродуманное решение использовать методы как операторы. Проблем от него куда больше чем пользы. Приоритеты и ассоциативность ведь задать нельзя. В результате получается бардак. А осуществить доступ к члену без точки там точно так же нельзя.


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

VD>Многие навороты в Скале были сделаны чтобы не вводя макросы позволить создавать ДСЛ-и и расширять язык.

Согласен!
VD>Итог фееричный — Одесски пришел к выводу, что нужно добавлять в Скалу макросы. Пока что, прада, без синтаксического расширения. Но если они что-то сделают, то это это будет только делом времени.
ссылку посмотрел бы. он противник, но идет навстречу пожеланиям масс.

VD>Компилятор то многое может разрулить. А вот человек — нет. Язык делается в первую очередь для человека.

VD>И дизайн языка — это очень не простой вопрос. Каждую его деталь надо обкатывать на практике. Так что огульно сувать в язык разную хрень только ради того чтобы быть привычным все подряд — это не подход. Он приведет к превращению языка в помойку.

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

VD>В Н2 мы планируем сделать языковый конструктор. Разработка языков и их модификаций на нем будет существенно упрощена. Кто хочет может попытать счастье в создании своего супер-языка. А немерл останется тем чем он есть сейчас — скрещиванием C#, ML и макросов.


Главное, чтобы вы учли возможность создания на основе новой Core других языков.

VD>Из всех твоих предложений я бы, пожалуй, пошел только на изменение дефолтных прав доступа для свойств (а не для структур, что смысла не имеет). Вот зачем каждый раз писать public к свойствам я действительно не понимаю. Ведь 99.9% свойств являются публичными, а для 0.1% можно и явно указать.


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

VD>Но для меня еще огромный вопрос можно ли делать разные дефолты. Язык тем проще изучается, чем меньше в нем частных случаев.

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

_C_>>Dart вот идет по этому пути. А в Google не идиоты сидят. или и тут поспорим

VD>Очень смешно. Пока что Гугль занимается откровенной херней. Лучше бы нас поддержали.

вы с .Net. А вот почему вы не бомбите открытыми воззваниями через телевидение и газеты сколковскую шайку, это непонятно.
тут в конце конце серьезное дело, а не выпрямитель лобковых волос.

VD>Мало что до этого не было? Теперь будет. Решение хорошее. А то что этого не было в недоязыках вроде С++, меня это мало интересует. Его дизайн только первопроходчеством можно оправдать.


постоянно спрашивать человека, в своем ли он уме, нетактично.

VD>Вот и выходит, что это не дурь, а очень даже логичное решение. Псевдо-фукнция преобразующая статический типов в его рантайм-представление. В С++, кстати, РТТИ похожим образом сделано.


я уже покаялся, кто ж знал что дефолтный конструктор у вас без скобок
Re[18]: Сообщающиеся макросы
От: _Claus_  
Дата: 23.11.11 14:22
Оценка:
в своем ответе на этот пост я мог быть неправильно понят:

VD>Мало что до этого не было? Теперь будет. Решение хорошее. А то что этого не было в недоязыках вроде С++, меня это мало интересует. Его дизайн только первопроходчеством можно оправдать.


Я:постоянно спрашивать человека, в своем ли он уме, нетактично.

Имел ввиду со стороны компилятора, когда он постоянно спрашивает меня о ref и out требуя их явного указания.
Re[19]: Сообщающиеся макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.11.11 15:00
Оценка:
Здравствуйте, _Claus_, Вы писали:

VD>>Мало что до этого не было? Теперь будет. Решение хорошее. А то что этого не было в недоязыках вроде С++, меня это мало интересует. Его дизайн только первопроходчеством можно оправдать.


_C_>Имел ввиду со стороны компилятора, когда он постоянно спрашивает меня о ref и out требуя их явного указания.


Ну, и правильно делают. Ты один раз пишешь код и 100500 раз его читаешь. Так что лучше чуть-чуть покорячиться написав ref, но потом понимать, что переменная по ссылке передается.

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