Сахар перенесён весь?
От: matumba  
Дата: 06.12.10 22:06
Оценка:
Ребят, продолжаю осваивать Немерлю, тыкаюсь в отсутствие привычных удобств, а именно:
1. Не найду никак аналог "инициализации по месту":
var a = new Body { Hands = 2 }; // замечание: классы - дотнетовские

2. Какая-то беда с дженериками — объявляю поле класса:
mutable groupNodes : Hashtable[int, Node] = Hashtable.[int, Node] ();

БЕЗ подчёркнутого — не работает, ругаицца что нужен какой-то литеральный тип. А как же вывод типов?
Помогите советом, плиз, перерыл все доки — нету идей.
Re: Сахар перенесён весь?
От: hardcase Пират http://nemerle.org
Дата: 06.12.10 22:48
Оценка:
Здравствуйте, matumba, Вы писали:

M>Ребят, продолжаю осваивать Немерлю, тыкаюсь в отсутствие привычных удобств, а именно:

M>1. Не найду никак аналог "инициализации по месту":
var a = new Body { Hands = 2 }; // замечание: классы - дотнетовские


Инициализатор был в снипетах, в библиотеке макросов ObjectExpressions кажется.
1) В макро-референсы добавить NewObjectMacro.dll
2)
using Snippets;

...

def x = Body with { Hands = 2 };


Основное ограничение — не умеет инициализировать коллекции (в принципе легко докрутить).
Так как там используется ключевое слово with макрос может конфликтовать с другим кодом.
Если у кого-то есть идее по улучшению синтаксиса — велкам.

M>2. Какая-то беда с дженериками — объявляю поле класса:

M>
M>mutable groupNodes : Hashtable[int, Node] = Hashtable.[int, Node] ();
M>

M>БЕЗ подчёркнутого — не работает, ругаицца что нужен какой-то литеральный тип. А как же вывод типов?
M>Помогите советом, плиз, перерыл все доки — нету идей.

Без подчеркнутого работать не должен. А вывод типов, он да, есть:

mutable groupNodes : Hashtable[int, Node] = Hashtable();
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Сахар перенесён весь?
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 06.12.10 22:53
Оценка:
Здравствуйте, matumba, Вы писали:

M>2. Какая-то беда с дженериками — объявляю поле класса:


Вывод типов работает на локальных функциях и переменных.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[2]: Сахар перенесён весь?
От: hardcase Пират http://nemerle.org
Дата: 06.12.10 23:02
Оценка:
Здравствуйте, hardcase, Вы писали:

H>
H>using Snippets;

H>...

H>def x = Body with { Hands = 2 };
H>



Упс, опечатался:

using Snippets;

...

def x = Body() with { Hands = 2 };



Сейчас там два варианта:
def x = Body() with { Hands = 2; Legs = 2; };


def x = Body() with ( Hands = 2, Legs = 2 );



Альтернативой можно предложить такую конструкцию:
def bar = with(Bar())
{
  Hands = 2;
  Legs = 2;
  Other = with(Foo()) { X = 10; Y = 20 }
}
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Сахар перенесён весь?
От: matumba  
Дата: 07.12.10 08:13
Оценка:
Здравствуйте, hardcase, Вы писали:

H>using Snippets;

H>def x = Body with { Hands = 2 };

Ага, пасипки! Попробую дома. Вот эта страничка (http://nemerle.org/CsharpDiff) тогда нуждается в улучшениях. Если найду время, я смогу поправить?

H>Основное ограничение — не умеет инициализировать коллекции (в принципе легко докрутить).

H>Так как там используется ключевое слово with макрос может конфликтовать с другим кодом.
H>Если у кого-то есть идее по улучшению синтаксиса — велкам.

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

M>>2. Какая-то беда с дженериками — объявляю поле класса:

H>Без подчеркнутого работать не должен. А вывод типов, он да, есть:

H>
H>mutable groupNodes : Hashtable[int, Node] = Hashtable();
H>


Ой! А как же специализация дженерика?? Нелогичный вывод получается.
Re: Сахар перенесён весь?
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.12.10 08:19
Оценка: +1
Здравствуйте, matumba, Вы писали:

M>Ребят, продолжаю осваивать Немерлю, тыкаюсь в отсутствие привычных удобств, а именно:

M>1. Не найду никак аналог "инициализации по месту":
var a = new Body { Hands = 2 }; // замечание: классы - дотнетовские


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

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

В немерле вместо подобных инициализаторов пиринято пользоваться конструкторами типов. Упрощают жизнь две фичи:
1. Макрос [Record] позволяет автоматизировать формирование конструктора включающего все поля типа. При этом чтобы исключить некоторые поля можно воспользоваться сопутствующим макросом [RecordIgnore], который применяется к полям и приводит к тому, что макрос [Record] такие поля.
2. Возможность задавать значения по умолчанию для параметров методов и конструкторов и возможность явно указывать параметры (опуская те что имеют значения по умолчанию).

M>2. Какая-то беда с дженериками — объявляю поле класса:

M>
M>mutable groupNodes : Hashtable[int, Node] = Hashtable.[int, Node] ();
M>


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

M>БЕЗ подчёркнутого — не работает, ругаицца что нужен какой-то литеральный тип. А как же вывод типов?


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

M>Помогите советом, плиз, перерыл все доки — нету идей.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Сахар перенесён весь?
От: matumba  
Дата: 07.12.10 08:33
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Вывод типов работает на локальных функциях и переменных.


А что ему мешает работать на уровне класса? Там же ещё проще — посмотрел на инициализатор и вуаля!
Re[2]: Сахар перенесён весь?
От: matumba  
Дата: 07.12.10 08:50
Оценка:
Здравствуйте, VladD2, Вы писали:

M>>1. Не найду никак аналог "инициализации по месту":
var a = new Body { Hands = 2 }; // замечание: классы - дотнетовские


VD>Дело в том, что Немерл все таки функциональный язык.


Всё таки мультипарадигменный В этом-то и прелесть, что без функционизма головного мозга, можно писать красивые программки. "всё неизменяемое" для Дотнета — это всё же чуждая практика.

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


??? Не совсем понял. Вот выше создаётся неизменяемый объект Body, далее его члены (изменяемые, т.к. надо по логике работы класса) мы инициализируем. Сама архитектура класса уже не вписывается в ФП, тогда чего переживать? Пусть будет "чуток" (ага, весь Дотнет) императивным!

VD>В немерле вместо подобных инициализаторов пиринято пользоваться конструкторами типов.

VD>1. Макрос [Record]...

Уже читал, но как быть с готовыми классами?

VD>Вывод типов не работает для интерфейса типа (даже для приватного). Разрешается только опускать типы при инициализации поля литеральным типом.


А что такое "литеральный тип"?

VD>В свое время предлагалось разрешить вывод типов для приватных полей и методов, но это замедлило бы работу IDE.


эээ... но точно так же "локальный вывод" замедляет работу ИДЕ! Тем более, что большей частью правится именно код, а не состав класса.
Re[3]: Сахар перенесён весь?
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.12.10 08:53
Оценка: +1
Здравствуйте, matumba, Вы писали:

M>Ага, пасипки! Попробую дома. Вот эта страничка (http://nemerle.org/CsharpDiff) тогда нуждается в улучшениях. Если найду время, я смогу поправить?


Да, но сначала нужно получить логин под которым можно править. Проще всего для этого обратиться к кочеткову ( kochetkov.vladimir).

M>Эмм... а можно осветить проблему чуть подробнее, плиз? Коллекции у меня используются тоже часто, так что для меня это актуально.


С коллекциями обsчно проблем нет. Если нужны литералы, то проще использовать синтаксис литералов массивов или списков:
array[1, 2, 3]
[1, 2, 3]

А их уже можно передавать в конструкторы других коллекций (например, List[T]). Например:
def xs = List(array[1, 2, 3]);
def ys = List([1, 2, 3]);

Зачастую для генерации таких последовательностей вообще лучше использовать list comprehentions или ObjectExpressions. Но это уже следующий шаг в изучении зыка.

H>>
H>>mutable groupNodes : Hashtable[int, Node] = Hashtable();
H>>


M>Ой! А как же специализация дженерика?? Нелогичный вывод получается.


Что ты имеешь в виду? Пока что все получалось логично.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Сахар перенесён весь?
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.12.10 08:55
Оценка:
Здравствуйте, matumba, Вы писали:

M>А что ему мешает работать на уровне класса? Там же ещё проще — посмотрел на инициализатор и вуаля!


В инициализаторе может быть куча кода что будет тормозить работу и при этом тип может не выводиться только из него. Придется типизироваться все методы чтобы установить тип. А это очень накладно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Сахар перенесён весь?
От: hardcase Пират http://nemerle.org
Дата: 07.12.10 08:56
Оценка:
Здравствуйте, matumba, Вы писали:

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


H>>using Snippets;

H>>def x = Body with { Hands = 2 };

M>Ага, пасипки! Попробую дома. Вот эта страничка (http://nemerle.org/CsharpDiff) тогда нуждается в улучшениях. Если найду время, я смогу поправить?


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

H>>Основное ограничение — не умеет инициализировать коллекции (в принципе легко докрутить).

H>>Так как там используется ключевое слово with макрос может конфликтовать с другим кодом.
H>>Если у кого-то есть идее по улучшению синтаксиса — велкам.

M>Эмм... а можно осветить проблему чуть подробнее, плиз? Коллекции у меня используются тоже часто, так что для меня это актуально.


Докрутить можно очень просто: если правая часть with — это "список": [x, y, z], то сторим инициализатор коллекции (банально вызывем Add)
Словари можно будет инициализировать с помощью кортежей (это заработает автоматически):
Hashtable() with [(key1, value1), (key2, value2), (key3, value3)];
/* иЗвиНите зА неРовнЫй поЧерК */
Re[3]: Сахар перенесён весь?
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.12.10 09:11
Оценка:
Здравствуйте, matumba, Вы писали:

M>Всё таки мультипарадигменный


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

M>В этом-то и прелесть, что без функционизма головного мозга, можно писать красивые программки. "всё неизменяемое" для Дотнета — это всё же чуждая практика.


Дык никто не говорит про все. Но "акцент" есть. Скажем мы долго думали ввести ли в немерл ключевое слово val (вместо или вместе с) mutable. Тем кто только начинал осваивать язык очень нравилась эта идея. Но по прошествии времени практически все сходились на мысли, что mutable лучше просто потому что он длиннее, неудобнее и заметнее. Это подталкивает людей к использованию def в тех случаях когда он применим. А это, в свою очередь, делает программы проще и безопаснее.

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


M>??? Не совсем понял. Вот выше создаётся неизменяемый объект Body, далее его члены (изменяемые, т.к. надо по логике работы класса) мы инициализируем. Сама архитектура класса уже не вписывается в ФП, тогда чего переживать? Пусть будет "чуток" (ага, весь Дотнет) императивным!


Твой Body априори изменяемый, так как инициализаторы не могут работать с неизменяемыми объектами.
Неизменяемый объект — это тип который получает значения только при конструировании (путем вызова конструктора). Например, списки и кортежи в немерле не изменяемые типы. Когда ты добавляешь к списку значение, то на самом деле ты получаешь новый список который использует в своем хвосте старый.

VD>>В немерле вместо подобных инициализаторов пиринято пользоваться конструкторами типов.

VD>>1. Макрос [Record]...

M>Уже читал, но как быть с готовыми классами?


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

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

VD>>Вывод типов не работает для интерфейса типа (даже для приватного). Разрешается только опускать типы при инициализации поля литеральным типом.


M>А что такое "литеральный тип"?


Строковый литерал и числовой литерал: "строка", 123, 123.45.

VD>>В свое время предлагалось разрешить вывод типов для приватных полей и методов, но это замедлило бы работу IDE.


M>эээ... но точно так же "локальный вывод" замедляет работу ИДЕ! Тем более, что большей частью правится именно код, а не состав класса.


Локальный вывод типов работает строка в рамках отдельных методов (инициализаторы и эксесоры свойств тоже являются методами с точки зрения компилятора). Это позволяет при изменении одного тела метода типизироваться только его. Если же разрешить глобальный вывод типов, то придется перетипизировать весь проект.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Сахар перенесён весь?
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 07.12.10 09:15
Оценка:
Здравствуйте, matumba, Вы писали:

M>Ага, пасипки! Попробую дома. Вот эта страничка (http://nemerle.org/CsharpDiff) тогда нуждается в улучшениях. Если найду время, я смогу поправить?


Да, нужно только зарегистрироваться.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[4]: Сахар перенесён весь?
От: matumba  
Дата: 07.12.10 10:16
Оценка:
Здравствуйте, VladD2, Вы писали:

H>>>
H>>>mutable groupNodes : Hashtable[int, Node] = Hashtable();
H>>>


M>>Ой! А как же специализация дженерика?? Нелогичный вывод получается.


VD>Что ты имеешь в виду? Пока что все получалось логично.


Ну вот этот Hashtable() — мы ему не указали специализацию ([int, Node]) — с какой стати он будет присваиваться Hashtable[int, Node]? (и вообще создаваться)

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


Эх... отучились вы от удобного стиля! Влад, у меня такие "местные инициализации" сплошь и рядом, т.к. классу обычно делают пару наиболее употребимых конструкторов, остальное (в силу лени и бессмысленности всех сочетаний) дают на откуп ручному присвоению. И Дотнет, между прочим, не исключение. Так что макрос with я считаю must have.
--------------
Если чуть пофилософствовать, то я считаю Немерле лучше быть императивным, вбирая лучшее от ФП — это более естественный для многих тип мышления (и по развитию C# это тоже видно). Хаскель Головного Мозга — это всё же редкое явление
Мы, собсно, и так имеем достаточно: неизменяемые объекты, лямбды, ПМ, так что нажимать ФП-ием на юзера — только распугать зазря.
--------------

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


ОК, понял. Ну а без функций, поддерживая только явные типы?
public a = 7; // очевиднее некуда
private z = List[People]();// ditto
Re[5]: Сахар перенесён весь?
От: hardcase Пират http://nemerle.org
Дата: 07.12.10 10:26
Оценка:
Здравствуйте, matumba, Вы писали:

M>Ну вот этот Hashtable() — мы ему не указали специализацию ([int, Node]) — с какой стати он будет присваиваться Hashtable[int, Node]? (и вообще создаваться)


Его специализация выведется из использования — присваивания значения полю.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Сахар перенесён весь?
От: dotneter  
Дата: 07.12.10 10:44
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD> В свое время предлагалось разрешить вывод типов для приватных полей и методов, но это замедлило бы работу IDE.


А нельзя проблемы иде решать на ее уровне, а не на уровне языка? Может я все пишу в vimе и мне больше интересен язык нежели какое то там иде.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Talk is cheap. Show me the code.
Re[6]: Сахар перенесён весь?
От: matumba  
Дата: 07.12.10 11:12
Оценка:
Здравствуйте, hardcase, Вы писали:
H>Его специализация выведется из использования — присваивания значения полю.

Но как конструктор Hashtable() узнает, что он должен был быть хэшем [int, Node]? Мы ведь ничего не указывали:

mutable groupNodes : Hashtable[int, Node] = Hashtable();
Re[7]: Сахар перенесён весь?
От: hardcase Пират http://nemerle.org
Дата: 07.12.10 11:16
Оценка:
Здравствуйте, matumba, Вы писали:

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

H>>Его специализация выведется из использования — присваивания значения полю.

M>Но как конструктор Hashtable() узнает, что он должен был быть хэшем [int, Node]? Мы ведь ничего не указывали:


M>
mutable groupNodes : Hashtable[int, Node] = Hashtable();


Конструктор ничего не узнает.
А вот типизатор видит, что значение выражения Hashtable() присваивается полю с типом Hashtable[int, Node]. На основании этого он делает вывод о типах, которые подставляются в генерик: int+ и Node+.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[3]: Сахар перенесён весь?
От: matumba  
Дата: 07.12.10 11:16
Оценка:
Здравствуйте, dotneter, Вы писали:

D>Может я все пишу в vimе....


Не, такое мы не лечим!!
Очевидно, что без ИДЕ скорость падает в разы — придётся таки учитывать скорость разбора. Выше я предлагал упрощённый вывод — большинство случаев он покроет.
Re[8]: Сахар перенесён весь?
От: matumba  
Дата: 07.12.10 11:21
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Конструктор ничего не узнает.

H>А вот типизатор видит, что значение выражения Hashtable() присваивается полю с типом Hashtable[int, Node]. На основании этого он делает вывод о типах, которые подставляются в генерик: int+ и Node+.

Мать!! Не, ну я догадывался, что Немерля круто выводит, но чтобы настолько.... "звизда фшоке". А не приводит ли такой "умный" вывод к коллизиям или скрытым эффектам? Я считал, что вывод всегда делается по правой части, давая тип левой. А тут комбинация левой и правой части! Мне уже страшно
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.