Re[7]: Nemerle Enhancement Proposal 1
От: hi_octane Беларусь  
Дата: 22.11.10 10:12
Оценка: 3 (1)
__>Раз get свойство всегда создает readonly переменную, которую можно изменять только в конструкторе.
__>Мне кажется логичным подстановка поля вместо свойства там.
__>Надо только понять если не приведет это к каким-нибудь проблемам.
Ну например в макросах разбирая AST метода по-разному работать с автосвойствами, которые заменяются на поля и с обычными свойствами совсем не хочется. А если макрос ещё захочет обратиться к аттрибутам свойства, вместо которого подставилось поле — то ещё больший лишний гемор. Получается эта оптимизация должна идти на самых последних этапах, когда макросы уже отработали, т.е. хардкод в компилятор одного особенного случая.

И главное, какой профит с этого? Минимальная оптимизация которую должен jit делать, но вручную? Может лучше вложить время в поддержку WPF?
Re[6]: Nemerle Enhancement Proposal 1
От: catbert  
Дата: 24.11.10 09:51
Оценка: 1 (1)
Здравствуйте, matumba, Вы писали:

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


__>>Если бы все согласны были, то по умолчнию _j это хорошо, но не все согласны.


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


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

Вариант 1:

class Foo
{
    public Blah { get; } // компилятор генерирует get { _N_Blah_189273; }
    private _N_Blah_189273; // поле генерируется компилятором

    public this()
    {
        Blah = DateTime.Now.Seconds; // Blah подменяется на _N_Blah_189273
        InitializeField(out Blah); // Blah подменяется на _N_Blah_189273, все работает
    }
}


Вариант 2:

class Bar
{
    public Blah { get; } // компилятор генерирует get { _N_Blah_189273; }
    private _N_Blah_189273; // поле генерируется компилятором

    public this()
    {
        field(Blah) = DateTime.Now.Seconds; // макрос field магически возвращает нужное поле для свойства
        InitializeField(out field(Blah)); // все опять же магически работает
    }
}
Re: Nemerle Enhancement Proposal 1
От: _nn_ www.nemerleweb.com
Дата: 28.11.10 14:58
Оценка: 1 (1)
Nemerle Enhancement Proposal 1 Revision 2

Цель
Заменить макрос Accessor на автосвойства.
Некоторые возможности на сегодня недоступны при использовании макроса Accessor: указание модификаторов internal, protected, new.
Можно доделать макрос, но его использование неинтуитивно и неуклюже.


Автосвойства для чтения
Разрешить создания автосвойств только для чтения. (get only)
Наряду с автосвойством для чтения-записи (get set)

class MyClass
{
  public MyGetProperty : int { get; }
}


Доступ к полю
Предоставить специальный макрос для доступа к полям автосвойств.
Это позволит:
1. Инициализировать автосвойства только для чтения.
2. Добраться до поля автосвойства, что не представляется возможным сегодня.

class MyClass
{
  public MyGetProperty : int { get; }

  public this()
  {
    fieldof(MyGetProperty) = 1;
  }
}


Макрос Record
Описанный метод позволит описывать классы понятней:
class Immutable
{
  public Prop1 : string { get; }
  public Prop2 : int { get; }
}


Пример
Полный пример с учетом всех предложенией:

[AttributeUsage(AttributeTargets.Property)]
class SpecialAttribute : Attribute { }

interface ISome
{
  StringGetSet : string { get; set; }
  StringGet : string { get; }
}

abstract class Base
{
  public virtual PublicIntGetSet : int { get; set; } 
  public abstract PublicIntGet : int { get; }

  internal virtual InternalIntGetSet : int { get; set; } 
  protected abstract ProtectedIntGet : int { get; }
}

[Record]
class Derived : Base, ISome
{
  #region ISome
  
  [Special] public StringGetSet : string { get; set; }
  
  public StringGet : string { get; }
  
  #endregion
    
  #region Base
  
  [Special] public override PublicIntGetSet : int { get; set; }  
  public override PublicIntGet : int { get; }
  
  internal new InternalIntGetSet : int { get; set; }  
  protected override ProtectedIntGet : int { get; }
  
  #endregion Base
  
  #region Derived
  
  public virtual OtherProp : int { get; }
  
  #endregion
  
  public this()
  {
    fieldof(StringGsetSet) = "a";
    InitValueOut(out fieldof(StringGet), "b");
      
    fieldof(PublicIntGetSet) = 1;
    InitValueRef(ref fieldof(PublicIntGet) = 2;
    fieldof(InternalIntGetSet) = 3;
    InitValueOut(out fieldof(ProtectedIntGet), 4);
    
    fieldof(OtherProp) = 10;
  }
  
  static InitValueRef[T](s : ref T, value : T) : void { s = value; }  
  static InitValueOut[T](s : out T, value : T) : void { s = value; }
}

module Program
{
    Main() : void
    {
        def d1 = Derived();
        def d2 = Derived("a", "b", 1, 2, 3, 4, 10);
    }
}


Variant
В variant вместо задания полей, будут задаваться свойства.
Значение будет таким же как и автосвойства только для чтения (get only).
Для доступа к переменной следует использовать макрос fieldof:

variant A
{
  | X
    {
      i : int; j : int; // Определение свойств
      public new this(i : int, j : int)
      {
        fieldof(i) = i;
        fieldof(j) = j;
      }
    }
  | Y
    {
      K : int; L : int; // Определение свойств
      public new this(k : int, l : int)
      {
        fieldof(K) = k;
        fieldof(L) = l;
      }
    }
}

def x = A.X(1, 2);
def i = x.i;
def j = x.j;

def y = A.Y(1, 2);
def k = y.K;
def l = y.L;


Надеюсь учел все пожелания участников дискуссии.
Пишите.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[8]: Nemerle Enhancement Proposal 1
От: Denom Украина  
Дата: 22.11.10 10:24
Оценка: +1
Здравствуйте, hi_octane, Вы писали:

> Может лучше вложить время в поддержку WPF?

Да, однозначно — лучше... (а так же silverlight, vs 2010, WP7)
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Re[3]: Nemerle Enhancement Proposal 1
От: matumba  
Дата: 22.11.10 13:44
Оценка: +1
Здравствуйте, _nn_, Вы писали:

__>Так синтаксис J : int { get; set; } и так уже рабочий.


га Почувствуй себя кэпом! (это я про свои инновации) Ну и хорошо! А какое имя даётся хранилищу проперти J?

__>Мое предложение было в унифицировании имен полей.

__>Но все же видится мне более правильным решением указывать их явно.

Мне кажется, вы хотите сделать что-то смешное: сначала сократить объявление проперти, а потом его же и раздуть всякими прибамбасами доступа, именем хранилища... а смысл? Уже есть полный синтаксис описания проперти, сахар нужен лишь тем, кто согласен с дефолтовыми настройками. Вот по дефолту и сделайте _j — вполне нормальное имя (тем более, что ему не с чем пересекаться — другой проперти J не будет, а поля класса будут с другими именами.
Nemerle Enhancement Proposal 1
От: _nn_ www.nemerleweb.com
Дата: 16.11.10 10:30
Оценка:
Nemerle Enhancement Proposal 1

Проблема:
В C# и в Nemerle мы имеем возможность определить свойства похожим образом включая автосвойства.
Но ни в C# ни в Nemerle нет возможности задать в автосвойстве только getter. (или только setter, кому оно надо не знаю )

Для этой цели в C# надо писать поле и свойство, а в Nemerle можно сократить работу за счет макроатрибута:
_i : int;
I : int { get { _i } };

mutable _j : int;
J : int { get { _j } set { _j = value } };

mutable _k : int;
K : int { set { _k = value } };


[Accessor]
_i : int;

[Accessor(WantSetter = true)]
_j : int;


Accessor неинтуитивен для программистов C#.

Предложение:
Вместо этого предлагаю обратный Accessor-у стиль.
Описываем свойство, а поле генерируется по имени свойства:

I : int { get };
// _i : int;
// I : int { get { _i } };

[MutableField] I : int { get };
// mutable _i : int;
// I : int { get { _i } };

J : int { get; set; };
// mutable _j : int;
// J : int { get { _j } set { _j = value } };

K : int { set };
// mutable _k : int;
// K : int { set { _k = value } };


Не нужен сложный атрибут Accessor, код более понятен.
Также это не ломает старый код, а лишь дополняет функционал.
Если имя уже занято, ошибка компиляции.

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

Старый вариант:
variant A
{
  | X
    {
      i : int; j : int; // Определение полей
      public new this(i : int, j : int)
      {
        this.i = i;
        this.j = j;
      }
    }
  | Y
    {
      K : int; L : int; // Определение полей
      public new this(k : int, l : int)
      {
        this.K = k;
        this.L = l;
      }
    }
}

def x = A.X(1, 2);
def i = x.i;
def j = x.j;

def y = A.Y(1, 2);
def k = y.K;
def l = y.L;


Новый вариант:
variant A
{
  | X
    {
      // Создаются поля _i, _j
      i : int; j : int; // Определение свойств
      public new this(i : int, j : int)
      {
        this._i = i;
        this._j = j;
      }
    }
  | Y
    {
      // Создаются поля _k, _l
      K : int; L : int; // Определение свойств
      public new this(k : int, l : int)
      {
        this._k = k;
        this._l = l;
      }
    }
}

def x = A.X(1, 2);
def i = x.i;
def j = x.j;

def y = A.Y(1, 2);
def k = y.K;
def l = y.L;


Заключение:
Предложенный способ позволит улучшить код и привлечь больше программистов C#.
Изменение variant улучшает взаимодействие с C#.

Высказываемся
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Nemerle Enhancement Proposal 1
От: catbert  
Дата: 16.11.10 12:37
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Nemerle Enhancement Proposal 1


__>Новый вариант:

variant A
{
  | X
    {
      // Создаются поля _i, _j
      i : int; j : int; // Определение свойств
      public new this(i : int, j : int)
      {
        this._i = i;
        this._j = j;
      }
    }
  | Y
    {
      // Создаются поля _k, _l
      K : int; L : int; // Определение свойств
      public new this(k : int, l : int)
      {
        this._k = k;
        this._l = l;
      }
    }
}


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

Если удастся как-то решить эту проблему, я за.
Re[2]: Nemerle Enhancement Proposal 1
От: SergASh  
Дата: 16.11.10 15:50
Оценка:
Здравствуйте, catbert, Вы писали:

C>То есть программисту необходимо знать про поля, которые генерирует компилятор. Это мне не нравится.

C>К тому же, соглашения о том, как именовать member-переменные, разные в разных конторах (в отличии от соглашений о том, как именовать свойства).

C>Если удастся как-то решить эту проблему, я за.


Пару лет назад я предлагал ввести в API макросов механизм, который бы позволял абстрагироваться от стиля именования, и чтобы все макросы, генерирующие разные члены класса, при создании имен этих членов опирались на данный механизм. Если программиста не устроит стиль по умолчанию, то он один раз на проект или солюшен настроит под себя и больше об этом не волнуется. Правда, тогда мой голос не был услышан. Возможно, сейчас самое время что-то такое сделать.
Re[2]: Nemerle Enhancement Proposal 1
От: _nn_ www.nemerleweb.com
Дата: 16.11.10 16:27
Оценка:
Здравствуйте, catbert, Вы писали:

C>То есть программисту необходимо знать про поля, которые генерирует компилятор. Это мне не нравится.

C>К тому же, соглашения о том, как именовать member-переменные, разные в разных конторах (в отличии от соглашений о том, как именовать свойства).

C>Если удастся как-то решить эту проблему, я за.


Вы о классах или о вариантах ?

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

Если о вариантах, то интерес на наименования поля появляется только в одном случае, когда переопределяется конструктор.
Из всего кода компилятора данная возможность используется только в 2-х файлах.
Кстати, вы знали что это возможно до этого поста ?
Т.е. в большинстве случаев нас не интересует какие поля создает компилятор.
Зато это даст лучший интероп с C#, где у варианта будут видны свойства, а не поля.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Nemerle Enhancement Proposal 1
От: _nn_ www.nemerleweb.com
Дата: 17.11.10 07:38
Оценка:
Здравствуйте, catbert, Вы писали:

C>То есть программисту необходимо знать про поля, которые генерирует компилятор. Это мне не нравится.


Сейчас можно вручную все указать и нет проблем.
Можно конечно придумать какой-то макрос типа такого:
[Field(Name = "otherName")] X : int { get };

otherName : int;
X : int { get { otherName } };


[Field(Name = "otherName2")] Y : int { get; set; };

mutable otherName2 : int;
Y : int { get { otherName2 } set { otherName2 = value } };

(После написания, возник вопрос, почему его нет сейчас ? )

Для автосвойств типа get и для свойств variant вместо этого макроса можно разрешить использовать имя свойства и вместо него компилятор подставит поле.
В любом случае кроме как конструктора мы не можем их инциализировать.
Таким образом нам не нужно знать имени генерируемого поля.

I : int { get }

public this()
{
  Initialize(out I); // out I_Generated_Name
  Initialize2(ref I); // ref I_Generated_Name
  I = 1; // I_Generated_Name = 1
}


variant A
{
  | X
    {
      I : int;
      public new this(i : int)
      {
        I = 1; // I_Generated_Name = 1
        // ..
      }
    }
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Nemerle Enhancement Proposal 1
От: catbert  
Дата: 17.11.10 10:45
Оценка:
Здравствуйте, catbert, Вы писали:

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


C>Если удастся как-то решить эту проблему, я за.


Мое решение — макрос field(PropertyName), который возвращает PExpr-референс на сгенерированное автополе.
Re[3]: Nemerle Enhancement Proposal 1
От: catbert  
Дата: 17.11.10 10:48
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Если о вариантах, то интерес на наименования поля появляется только в одном случае, когда переопределяется конструктор.

__>Из всего кода компилятора данная возможность используется только в 2-х файлах.

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

Вообще, автосвойство с геттером нужно лишь одном случае — когда возвращаемое значение задается в конструкторе. В результате, нужен лишь способ задать в конструкторе это самое значение.
Re[4]: Nemerle Enhancement Proposal 1
От: _nn_ www.nemerleweb.com
Дата: 17.11.10 11:54
Оценка:
Здравствуйте, catbert, Вы писали:

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


__>>Если о вариантах, то интерес на наименования поля появляется только в одном случае, когда переопределяется конструктор.

__>>Из всего кода компилятора данная возможность используется только в 2-х файлах.

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


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


Что насчет автоматической подстановки поля вместо свойства в get свойствах ?
http://rsdn.ru/forum/nemerle/4041734.1.aspx
Автор: _nn_
Дата: 17.11.10
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Nemerle Enhancement Proposal 1
От: catbert  
Дата: 17.11.10 21:38
Оценка:
Здравствуйте, _nn_, Вы писали:

__>
__>[Field(Name = "otherName2")] Y : int { get; set; };

__>mutable otherName2 : int;
__>Y : int { get { otherName2 } set { otherName2 = value } };
__>

__>(После написания, возник вопрос, почему его нет сейчас ? )

Это круто.

__>Для автосвойств типа get и для свойств variant вместо этого макроса можно разрешить использовать имя свойства и вместо него компилятор подставит поле.

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

__>
__>I : int { get }

__>public this()
__>{
__>  Initialize(out I); // out I_Generated_Name
__>  Initialize2(ref I); // ref I_Generated_Name
__>  I = 1; // I_Generated_Name = 1
__>}
__>


__>
__>variant A
__>{
__>  | X
__>    {
__>      I : int;
__>      public new this(i : int)
__>      {
__>        I = 1; // I_Generated_Name = 1
__>        // ..
__>      }
__>    }
__>


Если замена I на I_Generated_Name в конструкторах не вызовет всяких странностей при попытке обращения к свойству именно как свойству, можно и так сделать.
Re: Nemerle Enhancement Proposal 1
От: matumba  
Дата: 21.11.10 09:09
Оценка:
Здравствуйте, _nn_, Вы писали:

nn>J : int { get; set; };

nn>// mutable _j : int;
nn>// J : int { get { _j } set { _j = value } };

Всесторонне поддерживаю! На мой взгляд, если под каждую команду пытаться затачивать компилятор (ах, какие капризные разрабы — им не нравится подчёркивание!), то в результате из-за 10% извращенцев будут страдать 90% остальных (извращенцев) . В ЛЮБОМ языке есть фичи, которые не нравятся той или иной группе — надо принимать решение, оптимальное для большинства.
Мне кажется предложенный nn метод самым практичным — голова должна думать об алгоритмах, а не плюшках в названиях переменных.
И вот ещё что бы добавил:

J : int { get; set; } = 7;
// mutable _j : int = 7;
// J : int { get { _j } set { _j = value } };


Т.е. статическая инициализация проперти.
Re[2]: Nemerle Enhancement Proposal 1
От: catbert  
Дата: 21.11.10 11:46
Оценка:
Здравствуйте, matumba, Вы писали:

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


nn>>J : int { get; set; };

nn>>// mutable _j : int;
nn>>// J : int { get { _j } set { _j = value } };

M> В ЛЮБОМ языке есть фичи, которые не нравятся той или иной группе — надо принимать решение, оптимальное для большинства.


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

А большинство станет еще больше, если не привязывать язык к какому-то конкретному стилю именования. Поэтому варианты, где такой привязки нет, имхо ценнее. А уже есть два варианта: макрос field(...) и подстановка поля вместо свойства в конструкторах.

M>
M>J : int { get; set; } = 7;
M>// mutable _j : int = 7;
M>// J : int { get { _j } set { _j = value } };
M>


M>Т.е. статическая инициализация проперти.


Плюсадин
Re[3]: Nemerle Enhancement Proposal 1
От: matumba  
Дата: 21.11.10 15:12
Оценка:
Здравствуйте, catbert, Вы писали:

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


"Напоказа" не будет — она же приватная! Кроме того, она необходима, если логика доступа нетривиальная:

Hour : int { get; set; };// тут-то всё легко!
Minute : int {
    get;// ожидаемо, get { _minute; }
    set {
        if (value > 60) _hour = value / 60;// здесь нет смысла дёргать Hour, т.к. это внутренние разборки
        _minute = value % 60;// а как тут присвоить, не зная имени?
    }
};


C>Поэтому варианты, где такой привязки нет, имхо ценнее.


Нет смысла возить весь чемодан ключей, если у колеса один единственный размер гаек. Зато неудобств — море. Никто же не парится, что в идентификаторах нельзя ставить пробелы? Хотя куда приятнее читать "Загрузить(Отчёт за месяц)", чем "Загрузить(ОтчётЗаМесяц)". "Где-то приходится быть злым, чтобы всё вокруг стало добрее".
Re[4]: Nemerle Enhancement Proposal 1
От: catbert  
Дата: 21.11.10 15:57
Оценка:
Здравствуйте, matumba, Вы писали:

M>"Напоказа" не будет — она же приватная! Кроме того, она необходима, если логика доступа нетривиальная:


M>
M>Hour : int { get; set; };// тут-то всё легко!
M>Minute : int {
M>    get;// ожидаемо, get { _minute; }
M>    set {
M>        if (value > 60) _hour = value / 60;// здесь нет смысла дёргать Hour, т.к. это внутренние разборки
M>        _minute = value % 60;// а как тут присвоить, не зная имени?
M>    }
M>};
M>


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

M>Нет смысла возить весь чемодан ключей, если у колеса один единственный размер гаек. Зато неудобств — море. Никто же не парится, что в идентификаторах нельзя ставить пробелы? Хотя куда приятнее читать "Загрузить(Отчёт за месяц)", чем "Загрузить(ОтчётЗаМесяц)". "Где-то приходится быть злым, чтобы всё вокруг стало добрее".


В данном случае злым быть не приходится, нужно просто чуточку больше подумать.
Re: Nemerle Enhancement Proposal 1
От: matumba  
Дата: 21.11.10 17:16
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Предложение:

__>Описываем свойство, а поле генерируется по имени свойства:

J : int { get; set; };
// mutable _j : int;
// J : int { get { _j } set { _j = value } };


Ребят, пните начинающего, хотел вот попробовать реализовать это (в сильно упрощённом виде), но чую, сделал совсем не то и не так.
Для начала, я не нашёл как втиснуться в класс под видом объявления проперти — решил просто через синтаксис "prop ИмяСвойства Тип;", но хотелось бы именно как у _нн_ — "Джи : инт {get;set;}" (а то и вообще "J : int R;" / "J : int RW;"). Вторая грабля — это правильно достучаться к названию переменной. Моя storage_name — строка, а компилер ругаицца "in argument #1 (expr), needed a Nemerle.Compiler.Parsetree.PExpr, got string: System.String is not a subtype of Nemerle.Compiler.Parsetree.PExpr [simple require]" (это он на строку с mutable).
Теперь я догадываюсь, почему это КВАЗИцитирование — потому что, блин, всё так сложно, что Макросы становятся вообще высшим дзеном, хотя по идее, ничего сверхсложного из себя не представляют — взял исходник, преобразовал, выдал AST или вообще тупую строку-подстановку.
Вот мои мозолистые 3-часовые труды (где мозоль — не скажу ) :

public macro prop (prop_type, name)
  syntax ("prop", prop_type, name)
  {
      def storage_name = "_" + name.ToString().ToLower();
      <[
          mutable $storage_name : $prop_type;
      ]>
  }
Re[5]: Nemerle Enhancement Proposal 1
От: hi_octane Беларусь  
Дата: 21.11.10 18:20
Оценка:
__>Что насчет автоматической подстановки поля вместо свойства в get свойствах ?
__>http://rsdn.ru/forum/nemerle/4041734.1.aspx
Автор: _nn_
Дата: 17.11.10

Совсем свойство не выкинуть, т.к. оно может быть частью реализации интерфейса, оно может понадобиться через рефлексию, может использоваться каким-либо макросом для чего-то. Экономия на get несущественная, да и оптимизация доступа к свойствам — вроде как работа jit'a, и он вроде даже с ней в релизе справляется... короче оно того стоит? Какое преимущество ожидается от этой фичи?
Re[2]: Nemerle Enhancement Proposal 1
От: catbert  
Дата: 21.11.10 19:31
Оценка:
Здравствуйте, matumba, Вы писали:

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


__>>Предложение:

__>>Описываем свойство, а поле генерируется по имени свойства:

M>
M>J : int { get; set; };
M>// mutable _j : int;
M>// J : int { get { _j } set { _j = value } };
M>


M>Ребят, пните начинающего, хотел вот попробовать реализовать это (в сильно упрощённом виде), но чую, сделал совсем не то и не так.

M>Для начала, я не нашёл как втиснуться в класс под видом объявления проперти — решил просто через синтаксис "prop ИмяСвойства Тип;", но хотелось бы именно как у _нн_ — "Джи : инт {get;set;}" (а то и вообще "J : int R;" / "J : int RW;"). Вторая грабля — это правильно достучаться к названию переменной. Моя storage_name — строка, а компилер ругаицца "in argument #1 (expr), needed a Nemerle.Compiler.Parsetree.PExpr, got string: System.String is not a subtype of Nemerle.Compiler.Parsetree.PExpr [simple require]" (это он на строку с mutable).
M>Теперь я догадываюсь, почему это КВАЗИцитирование — потому что, блин, всё так сложно, что Макросы становятся вообще высшим дзеном, хотя по идее, ничего сверхсложного из себя не представляют — взял исходник, преобразовал, выдал AST или вообще тупую строку-подстановку.
M>Вот мои мозолистые 3-часовые труды (где мозоль — не скажу ) :

M>
M>public macro prop (prop_type, name)
M>  syntax ("prop", prop_type, name)
M>  {
M>      def storage_name = "_" + name.ToString().ToLower();
M>      <[
M>          mutable $storage_name : $prop_type;
M>      ]>
M>  }
M>


Ты создаешь макрос уровня выражения. Он может использоваться только внутри методов.
Макросы уровня класса (не уверен, что они именно так называются) писать чуть сложнее. Насколько я понимаю, твой синтаксис в Nemerle 1 вообще невозможно реализовать.

Менее глобально, надо вместо $storage_name написать $(storage_name : usesite). (не проверял, к сожалению, но копать надо в эту сторону)
Re[3]: Nemerle Enhancement Proposal 1
От: matumba  
Дата: 21.11.10 20:14
Оценка:
catbert, спасибо, ХОТЯ БЫ СКОМПИЛИРОВАЛОСЬ!

C>Ты создаешь макрос уровня выражения.


Это-то и пугает! Разве не унифицированным должен быть подход к макросам? Сейчас-то я уже нашёл волшебные строчки, но от них ещё страшнее:

def ctx = Nemerle.Macros.ImplicitCTX ();
def builder = ctx.Env.Define (<[ decl:
builder.Define (<[ decl: foo : int;
builder.Compile ();
builder.CannotFinalize = true;


(это я надёргал из примера) Что-то мне подсказывает, что всех этих ImplicitCTX/Define/Compile вообще не должно быть — макрос должен писаться одинаково везде.
Re[2]: Nemerle Enhancement Proposal 1
От: _nn_ www.nemerleweb.com
Дата: 22.11.10 08:19
Оценка:
Здравствуйте, matumba, Вы писали:

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


__>>Предложение:

__>>Описываем свойство, а поле генерируется по имени свойства:

M>
M>J : int { get; set; };
M>// mutable _j : int;
M>// J : int { get { _j } set { _j = value } };
M>


M>Ребят, пните начинающего, хотел вот попробовать реализовать это (в сильно упрощённом виде), но чую, сделал совсем не то и не так.

M>Для начала, я не нашёл как втиснуться в класс под видом объявления проперти — решил просто через синтаксис "prop ИмяСвойства Тип;", но хотелось бы именно как у _нн_ — "Джи : инт {get;set;}" (а то и вообще "J : int R;" / "J : int RW;"). Вторая грабля — это правильно достучаться к названию переменной. Моя storage_name — строка, а компилер ругаицца "in argument #1 (expr), needed a Nemerle.Compiler.Parsetree.PExpr, got string: System.String is not a subtype of Nemerle.Compiler.Parsetree.PExpr [simple require]" (это он на строку с mutable).

Так синтаксис J : int { get; set; } и так уже рабочий.
Там ничего не нужно менять.

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

Еслия я правильно понимаю тут разбор "get", "set", а значит там можно повлиять на генерируемое поле:
http://code.google.com/p/nemerle/source/browse/nemerle/trunk/ncc/parsing/MainParser.n#1486
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: Nemerle Enhancement Proposal 1
От: _nn_ www.nemerleweb.com
Дата: 22.11.10 08:22
Оценка:
Здравствуйте, hi_octane, Вы писали:

__>>Что насчет автоматической подстановки поля вместо свойства в get свойствах ?

__>>http://rsdn.ru/forum/nemerle/4041734.1.aspx
Автор: _nn_
Дата: 17.11.10

_>Совсем свойство не выкинуть, т.к. оно может быть частью реализации интерфейса, оно может понадобиться через рефлексию, может использоваться каким-либо макросом для чего-то. Экономия на get несущественная, да и оптимизация доступа к свойствам — вроде как работа jit'a, и он вроде даже с ней в релизе справляется... короче оно того стоит? Какое преимущество ожидается от этой фичи?

Так я и не предлагаю его выкинуть
Для get свойство придется всегда устанавливать имя поля, что сводит все преимущество на нет:
[Field(Name = "x")] X : int { get; }
[Accessor] x : int;


Раз get свойство всегда создает readonly переменную, которую можно изменять только в конструкторе.
Мне кажется логичным подстановка поля вместо свойства там.
Надо только понять если не приведет это к каким-нибудь проблемам.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Nemerle Enhancement Proposal 1
От: _nn_ www.nemerleweb.com
Дата: 22.11.10 14:35
Оценка:
Здравствуйте, matumba, Вы писали:

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


__>>Так синтаксис J : int { get; set; } и так уже рабочий.


M>га Почувствуй себя кэпом! (это я про свои инновации) Ну и хорошо! А какое имя даётся хранилищу проперти J?


__>>Мое предложение было в унифицировании имен полей.

__>>Но все же видится мне более правильным решением указывать их явно.

M>Мне кажется, вы хотите сделать что-то смешное: сначала сократить объявление проперти, а потом его же и раздуть всякими прибамбасами доступа, именем хранилища... а смысл? Уже есть полный синтаксис описания проперти, сахар нужен лишь тем, кто согласен с дефолтовыми настройками. Вот по дефолту и сделайте _j — вполне нормальное имя (тем более, что ему не с чем пересекаться — другой проперти J не будет, а поля класса будут с другими именами.


Если бы все согласны были, то по умолчнию _j это хорошо, но не все согласны.
Хотя наиболее распростанненые случаи когда поле называется _j или j, и очень редки когда называется по другому.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: Nemerle Enhancement Proposal 1
От: matumba  
Дата: 22.11.10 19:56
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Если бы все согласны были, то по умолчнию _j это хорошо, но не все согласны.


А какие варианты "несогласных" уже озвучены и чем они лучше текущего? (я именно про именование, а не ввод кучи атрибутов, вводящих те же яйца, но в профиль)
Re[4]: Nemerle Enhancement Proposal 1
От: catbert  
Дата: 24.11.10 09:52
Оценка:
Здравствуйте, matumba, Вы писали:

M>catbert, спасибо, ХОТЯ БЫ СКОМПИЛИРОВАЛОСЬ!


C>>Ты создаешь макрос уровня выражения.


M>Это-то и пугает! Разве не унифицированным должен быть подход к макросам?


Ну, по-хорошему оно вроде как и да. Но Nemerle (как бы нам того не хотелось) не совершенен.
Re[7]: Nemerle Enhancement Proposal 1
От: _nn_ www.nemerleweb.com
Дата: 24.11.10 10:37
Оценка:
Здравствуйте, catbert, Вы писали:

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


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


__>>>Если бы все согласны были, то по умолчнию _j это хорошо, но не все согласны.


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


C>Абстрагироваться от именования вообще, так как в get-only свойствах переменные нужны лишь один раз — в конструкторе.


C>Вариант 1:


Должна быть возможность отделить поле от свойства.
Хотя бы для атрибутов как указал hi_octane.

C>Вариант 2:


+1
Это выглядит хорошим решением.

[AttributeUsage(AttributeTargets.Property)]
class SpecialAttribute : Attribute { }

abstract class Base
{
  [Special] public virtual PublicIntGetSet : int { get; set; } 
  public abstract PublicIntGet : int { get; }

  internal virtual InternalIntGetSet : int { get; set; } 
  protected abstract ProtectedIntGet : int { get; }
}

class Derived : Base
{
  [Special] public override PublicIntGetSet : int { get; set; }
  
  public override PublicIntGet : int { get; }

  internal override InternalIntGetSet : int { get; set; }
  
  protected override ProtectedIntGet : int { get; }
  
  public this()
  {
    field(PublicIntGetSet) = 1;
    field(PublicIntGet) = 2;
    field(InternalIntGetSet) = 3;
    field(ProtectedIntGet) = 4;
  }  
}


Я попытался сделать Derived на основе макроса Accessor, но увы не получилось.
Если кто-то сможет сделать для сравнения, будет очень показательным.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Nemerle Enhancement Proposal 1
От: nCdy http://nCdy.org/
Дата: 01.12.10 09:01
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Nemerle Enhancement Proposal 1 Revision 2


Ну выглядит удобно. Мне нравится.
But I don't really mean it
Re[9]: Nemerle Enhancement Proposal 1
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 15:02
Оценка:
Здравствуйте, Denom, Вы писали:

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


>> Может лучше вложить время в поддержку WPF?

D>Да, однозначно — лучше... (а так же silverlight, vs 2010, WP7)

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