А почему &= и им подобные реализованы, а &&= нет?
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 21.12.10 19:55
Оценка:
Сегодня с _nn_ во время традиционного замера пиписек с ультракоротким языком заметили. Присваивание с bitwise-логикой реализовано, а с булевой — нет. Набросал макры с этими операциями по аналогии с bitwise — все вроде работает, ничего ни с чем не конфликтует.

Просто забыли, нафиг не было нужно или есть причины? А то как-то нелогично получается
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re: А почему &= и им подобные реализованы, а &&= нет?
От: catbert  
Дата: 21.12.10 20:01
Оценка: +1 :)
А нафиг оно нужно?
Re[2]: А почему &= и им подобные реализованы, а &&= нет?
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 21.12.10 20:16
Оценка: +2
Здравствуйте, catbert, Вы писали:

C>А нафиг оно нужно?


Код сокращает аж на целое имя переменной и пару операторов пробела Мне просто кажется, что оно нужно так же, как и уже реализованные bitwise-присваивания, т.е. либо они есть все (и bitwise и булевы), либо их нет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re: А почему &= и им подобные реализованы, а &&= нет?
От: RomikT Германия  
Дата: 21.12.10 20:32
Оценка: 1 (1) +1
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Сегодня с _nn_ во время традиционного замера пиписек с ультракоротким языком заметили. Присваивание с bitwise-логикой реализовано, а с булевой — нет. Набросал макры с этими операциями по аналогии с bitwise — все вроде работает, ничего ни с чем не конфликтует.


KV>Просто забыли, нафиг не было нужно или есть причины? А то как-то нелогично получается


А &&=, как и &&, не вычисляет выражение если значение переменной false? Не будет ли это удивлять?
mutable x = false;
x &&= functionWithSideEffectsTheWillNotBeCalled()
Re[2]: А почему &= и им подобные реализованы, а &&= нет?
От: _nn_ www.nemerleweb.com
Дата: 21.12.10 20:49
Оценка:
Здравствуйте, RomikT, Вы писали:

RT>А &&=, как и &&, не вычисляет выражение если значение переменной false? Не будет ли это удивлять?


А здесь будет вызов функции ? Не будет ли это удивлять ?
mutable x = false;
x = x && functionWithSideEffectsTheWillNotBeCalled()
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: А почему &= и им подобные реализованы, а &&= нет?
От: catbert  
Дата: 21.12.10 20:58
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Код сокращает аж на целое имя переменной и пару операторов пробела Мне просто кажется, что оно нужно так же, как и уже реализованные bitwise-присваивания, т.е. либо они есть все (и bitwise и булевы), либо их нет.


Не понимаю... && это ведь тот же самый оператор, что и &, только ленивый?
Re[3]: А почему &= и им подобные реализованы, а &&= нет?
От: catbert  
Дата: 21.12.10 21:00
Оценка: :))
Здравствуйте, _nn_, Вы писали:

__>x = x && functionWithSideEffectsTheWillNotBeCalled()


Так наверное даже Бриан Керниган на Си не пишет
Re[2]: А почему &= и им подобные реализованы, а &&= нет?
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 21.12.10 21:07
Оценка: +1
Здравствуйте, RomikT, Вы писали:

RT>Здравствуйте, kochetkov.vladimir, Вы писали:


KV>>Сегодня с _nn_ во время традиционного замера пиписек с ультракоротким языком заметили. Присваивание с bitwise-логикой реализовано, а с булевой — нет. Набросал макры с этими операциями по аналогии с bitwise — все вроде работает, ничего ни с чем не конфликтует.


KV>>Просто забыли, нафиг не было нужно или есть причины? А то как-то нелогично получается


RT>А &&=, как и &&, не вычисляет выражение если значение переменной false? Не будет ли это удивлять?

RT>
RT>mutable x = false;
RT>x &&= functionWithSideEffectsTheWillNotBeCalled()
RT>


Хороший вопрос. Да, по логике, являясь сахаром для x = x && functionWithSideEffectsTheWillNotBeCalled(), в приведенном примере значение ф-ции не должно вычисляться, но WTF'ы на эту тему будут обязательно. Ну, тогда можно пойти по пути шарпа и, оставив все как есть, просто реализовать operator_bitwiseAnd(bool, bool). А то получается и не так (симметричная реализация) и не эдак (как в шарпе).
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[4]: А почему &= и им подобные реализованы, а &&= нет?
От: kochetkov.vladimir Россия https://kochetkov.github.io
Дата: 21.12.10 21:32
Оценка:
Здравствуйте, catbert, Вы писали:

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


KV>>Код сокращает аж на целое имя переменной и пару операторов пробела Мне просто кажется, что оно нужно так же, как и уже реализованные bitwise-присваивания, т.е. либо они есть все (и bitwise и булевы), либо их нет.


C>Не понимаю... && это ведь тот же самый оператор, что и &, только ленивый?


Нет. По крайней мере, на практике. В шарпе они действительно отличаются только ленивостью, т.к. оба определены как над целыми, так и над булевыми типами. В немерле, & определен только над целыми, а && только над булевыми (установил эмпирически, в исходники не смотрел). Т.е. вот такой код не скомпилируется:

mutable A = 0;
A = A && 1; // ошибка "expected bool, got int- in matched value: System.Int32 is not a subtype of System.Boolean [simple require]"
mutable B = true;
B = B & true; // ошибка "typing fails on finding the operator op_BitwiseAnd(bool, bool)"


Т.е. в немерле & и && это один и тот же оператор для различных типов, но при этом еще и первый энергичный, а второй ленивый, судя по всему. И &= есть, а &&= нет
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>

[Интервью] .NET Security — это просто
Автор: kochetkov.vladimir
Дата: 07.11.17
Re[5]: А почему &= и им подобные реализованы, а &&= нет?
От: _nn_ www.nemerleweb.com
Дата: 22.12.10 07:21
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

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


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


KV>>>Код сокращает аж на целое имя переменной и пару операторов пробела Мне просто кажется, что оно нужно так же, как и уже реализованные bitwise-присваивания, т.е. либо они есть все (и bitwise и булевы), либо их нет.


C>>Не понимаю... && это ведь тот же самый оператор, что и &, только ленивый?


KV>Нет. По крайней мере, на практике. В шарпе они действительно отличаются только ленивостью, т.к. оба определены как над целыми, так и над булевыми типами.

Не совсем так.
&& и || определены только для bool.

KV>В немерле, & определен только над целыми, а && только над булевыми (установил эмпирически, в исходники не смотрел). Т.е. вот такой код не скомпилируется:

А вот тут надо бы добавить & и | для bool.

Полным набором для bool:
&, &=, &&, &&=
|, |=, ||, ||=

http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: А почему &= и им подобные реализованы, а &&= нет?
От: _FRED_ Черногория
Дата: 24.12.10 05:21
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Сегодня с _nn_ во время традиционного замера пиписек с ультракоротким языком заметили. Присваивание с bitwise-логикой реализовано, а с булевой — нет. Набросал макры с этими операциями по аналогии с bitwise — все вроде работает, ничего ни с чем не конфликтует.


KV>Просто забыли, нафиг не было нужно или есть причины? А то как-то нелогично получается


Видимо, сделали по аналогии с шарпом.
Help will always be given at Hogwarts to those who ask for it.
Re: А почему &= и им подобные реализованы, а &&= нет?
От: _NN_ www.nemerleweb.com
Дата: 25.12.11 05:58
Оценка:
Pull Request для фичи готов.

Собственно, для bool операции "&" и "|" также как "&=" и "|=" энергичные, а "&&", "||", "&&=", "||=" ленивые.

Осталось только поддержать.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: А почему &= и им подобные реализованы, а &&= нет?
От: Rival Таиланд
Дата: 25.12.11 16:04
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Да, по логике, являясь сахаром для x = x && functionWithSideEffectsTheWillNotBeCalled(), в приведенном примере значение ф-ции не должно вычисляться, но WTF'ы на эту тему будут обязательно.


Может в таком случае ворнинги стоит выдавать? Хотя макрос тогда наверное будет много сложнее.
«История жизни – это, по существу, развитие сознания, которое завуалировано морфологией.» Пьер Тейяр де Шарден
Re[4]: А почему &= и им подобные реализованы, а &&= нет?
От: _NN_ www.nemerleweb.com
Дата: 27.12.11 21:22
Оценка:
Здравствуйте, Rival, Вы писали:

R>Здравствуйте, kochetkov.vladimir, Вы писали:


KV>>Да, по логике, являясь сахаром для x = x && functionWithSideEffectsTheWillNotBeCalled(), в приведенном примере значение ф-ции не должно вычисляться, но WTF'ы на эту тему будут обязательно.


R>Может в таком случае ворнинги стоит выдавать? Хотя макрос тогда наверное будет много сложнее.

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

Просто запомнить, что двойные символы дают ленивое вычисление.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: А почему &= и им подобные реализованы, а &&= нет?
От: Rival Таиланд
Дата: 27.12.11 21:58
Оценка:
Здравствуйте, _NN_, Вы писали:

R>>Может в таком случае ворнинги стоит выдавать? Хотя макрос тогда наверное будет много сложнее.

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

_NN>Просто запомнить, что двойные символы дают ленивое вычисление.


Ну для меня это не проблема и ворнинги мне не нужны но kochetkov.vladimir написал опасение что:

KV>>>в приведенном примере значение ф-ции не должно вычисляться, но WTF'ы на эту тему будут обязательно.


Ворнинги вариант решения этой проблемы.
«История жизни – это, по существу, развитие сознания, которое завуалировано морфологией.» Пьер Тейяр де Шарден
Re[6]: А почему &= и им подобные реализованы, а &&= нет?
От: Ziaw Россия  
Дата: 28.12.11 15:02
Оценка:
Здравствуйте, Rival, Вы писали:

R>Ворнинги вариант решения этой проблемы.


Ворнинг плохой вариант, если программист желает именно ленивого поведения.
Re: А почему &= и им подобные реализованы, а &&= нет?
От: hardcase Пират http://nemerle.org
Дата: 28.12.11 15:51
Оценка: +1
Здравствуйте, kochetkov.vladimir, Вы писали:

Предлагаю просто ничего не делать.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[7]: А почему &= и им подобные реализованы, а &&= нет?
От: Rival Таиланд
Дата: 28.12.11 15:56
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Ворнинг плохой вариант, если программист желает именно ленивого поведения.


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

Насколько много в Немерле мест, где поведение Немерле расходится или может расходиться с ожидаемым поведением для С# программиста?
«История жизни – это, по существу, развитие сознания, которое завуалировано морфологией.» Пьер Тейяр де Шарден
Re: А почему &= и им подобные реализованы, а &&= нет?
От: CodingUnit Россия  
Дата: 28.12.11 21:07
Оценка:
Здравствуйте, kochetkov.vladimir, Вы писали:

KV>Сегодня с _nn_ во время традиционного замера пиписек с ультракоротким языком заметили. Присваивание с bitwise-логикой реализовано, а с булевой — нет. Набросал макры с этими операциями по аналогии с bitwise — все вроде работает, ничего ни с чем не конфликтует.


KV>Просто забыли, нафиг не было нужно или есть причины? А то как-то нелогично получается


Похоже действительно вряд ли найдутся случаи использования этого оператора, наверное у создателей С# тоже были причины не включать их. Вообще не очень хороший стиль производить булевое выражение и его присваивать результату, это и не функциональный стиль, получается слева должно быть обязательно mutable переменная.
Пулл реквест был отклонен, пока полного согласия сообщества еще не видно, он создан поспешно. Надо серьезно подумать чтобы что то добавлять, чтобы язык не превратился в реализацию множества чьих то хотелок. Для таких случаев даже в boost библиотеки проходят долгий период обсуждения и проверок. Если кому то очень хочется иметь такие операторы, то можно в собственных библиотеках их реализовывать, но в стандартную над 100 раз подумать.
Re[2]: А почему &= и им подобные реализованы, а &&= нет?
От: _NN_ www.nemerleweb.com
Дата: 02.01.12 08:43
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Здравствуйте, kochetkov.vladimir, Вы писали:


KV>>Сегодня с _nn_ во время традиционного замера пиписек с ультракоротким языком заметили. Присваивание с bitwise-логикой реализовано, а с булевой — нет. Набросал макры с этими операциями по аналогии с bitwise — все вроде работает, ничего ни с чем не конфликтует.


KV>>Просто забыли, нафиг не было нужно или есть причины? А то как-то нелогично получается


CU>Похоже действительно вряд ли найдутся случаи использования этого оператора, наверное у создателей С# тоже были причины не включать их.

То, что они не включены в C# еще не повод не включать в Nemerle.
Примеры: ** , %&&, %||, %^^, <-> .

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

Функциональность стиля у "&&=" точно такая же как и у "+=".

CU> Пулл реквест был отклонен, пока полного согласия сообщества еще не видно, он создан поспешно. Надо серьезно подумать чтобы что то добавлять, чтобы язык не превратился в реализацию множества чьих то хотелок. Для таких случаев даже в boost библиотеки проходят долгий период обсуждения и проверок. Если кому то очень хочется иметь такие операторы, то можно в собственных библиотеках их реализовывать, но в стандартную над 100 раз подумать.

На мой взгляд есть просто потеря симметрии.

С Новым Годом
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: А почему &= и им подобные реализованы, а &&= нет?
От: CodingUnit Россия  
Дата: 04.01.12 00:03
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>То, что они не включены в C# еще не повод не включать в Nemerle.

_NN>Примеры: ** , %&&, %||, %^^, <-> .

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

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

_NN>Функциональность стиля у "&&=" точно такая же как и у "+=".
и это императивный стиль, когда язык в первую очередь функциональный чем императивный, императивность чисто для совместимости со старым стилем, но мы идем в область более безопасного программирования (функционального), где нет присваивания той же области памяти, это еще один аргумент в сторону не использовать такие операторы

_NN>На мой взгляд есть просто потеря симметрии.

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

_NN>С Новым Годом

С Новым Годом!
Re[4]: А почему &= и им подобные реализованы, а &&= нет?
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 04.01.12 00:15
Оценка:
Здравствуйте, CodingUnit, Вы писали:

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


Я что-то пропустил? Немерле всегда был равноправно мультипарадигмальным.
Ce n'est que pour vous dire ce que je vous dis.
Re[5]: А почему &= и им подобные реализованы, а &&= нет?
От: CodingUnit Россия  
Дата: 04.01.12 00:20
Оценка:
Здравствуйте, Don Reba, Вы писали:

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


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


DR>Я что-то пропустил? Немерле всегда был равноправно мультипарадигмальным.


Да Nemerle равноправно мультипарадигмный, но в обыденной жизни все же стараются использовать функциональный стиль и не советуют использовать императивные возможности типа return, do, += и им подобные. Это эволюция языков в целом и Nemerle все же хорош таким мостом от императивных языков (типа C#, C++, Java) к функциональным. Конечной об императивности Немерле можно долго дискутировать, но тема у нас о включении операторов &&=, ||= в библиотеку, поэтому это был лишь один из аргументов непринятия их.
Re[6]: А почему &= и им подобные реализованы, а &&= нет?
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 04.01.12 01:13
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Да Nemerle равноправно мультипарадигмный, но в обыденной жизни все же стараются использовать функциональный стиль и не советуют использовать императивные возможности типа return, do, += и им подобные. Это эволюция языков в целом и Nemerle все же хорош таким мостом от императивных языков (типа C#, C++, Java) к функциональным. Конечной об императивности Немерле можно долго дискутировать, но тема у нас о включении операторов &&=, ||= в библиотеку, поэтому это был лишь один из аргументов непринятия их.


Думаю, эволюция идёт не к чистой функциональности, а к некому разумному компромису. Я согласен с _NN_, что императивность операторов &&= и ||= такая же как и у других аналогичных операторов и поэтому не делает язык менее функциональным. Вместе с тем, пользы от них совсем немного, поэтому лучше последовать правилу "не навреди" и воздержаться от введения в язык ленивых операторов присваивания.
Ce n'est que pour vous dire ce que je vous dis.
Re[7]: А почему &= и им подобные реализованы, а &&= нет?
От: CodingUnit Россия  
Дата: 04.01.12 02:14
Оценка:
Здравствуйте, Don Reba, Вы писали:

DR>Думаю, эволюция идёт не к чистой функциональности, а к некому разумному компромису. Я согласен с _NN_, что императивность операторов &&= и ||= такая же как и у других аналогичных операторов и поэтому не делает язык менее функциональным. Вместе с тем, пользы от них совсем немного, поэтому лучше последовать правилу "не навреди" и воздержаться от введения в язык ленивых операторов присваивания.


Императивность это то что мне бросается в глаза, почему бы я никогда не стал бы использовать эти операторы, но и в других случаях я согласен что очень мало случаев их полезного применения.
Re[4]: А почему &= и им подобные реализованы, а &&= нет?
От: _NN_ www.nemerleweb.com
Дата: 04.01.12 08:16
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>В моей библиотеке тоже есть много замечательных вещей намного более необходимых чем операторы &&=, но пока эта вещь не стандартная и не принята сообществом, то они так и лежат в моей библиотеке.

А что за библиотека если не секрет ?

Если не жалко поделиться кодом, то возможно стоит библиотеку поместить в snippets .
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: А почему &= и им подобные реализованы, а &&= нет?
От: CodingUnit Россия  
Дата: 04.01.12 09:33
Оценка:
Здравствуйте, _NN_, Вы писали:

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


CU>>В моей библиотеке тоже есть много замечательных вещей намного более необходимых чем операторы &&=, но пока эта вещь не стандартная и не принята сообществом, то они так и лежат в моей библиотеке.

_NN>А что за библиотека если не секрет ?

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

NeedChange — который автоматически создает методы для изменения неизменяемых полей через конструктор
Traversable — сейчас работаю над макросом, который в унифицированной манере позволяет обходить неизменяемые деревья (в нерекурсивной манере, не требующей стэка), перестраивать их, изменять с помощью операций Fold, Reduce. Я хотел описать его на форуме, как будет возможность и может быть добавить в стандартную библиотеку


_NN>Если не жалко поделиться кодом, то возможно стоит библиотеку поместить в snippets .

свежая версию Nemerle.Statechart всегда будет в сниппетах, после испытания некоторые полезные инструменты постараюсь описать и внести в стандартную библиотеку
Re[6]: А почему &= и им подобные реализованы, а &&= нет?
От: _NN_ www.nemerleweb.com
Дата: 04.01.12 10:03
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>NeedChange — который автоматически создает методы для изменения неизменяемых полей через конструктор


Что-то я тут не понял идею . Можно пример ?

CU>Traversable

Это будет синтаксический макрос я понимаю.
Похоже нужны макросы методы расширения..
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[7]: А почему &= и им подобные реализованы, а &&= нет?
От: CodingUnit Россия  
Дата: 04.01.12 11:13
Оценка: 15 (2)
Здравствуйте, _NN_, Вы писали:

CU>>NeedChange — который автоматически создает методы для изменения неизменяемых полей через конструктор


_NN>Что-то я тут не понял идею . Можно пример ?


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


class Object
{
[NeedChange] public field1 : int;
public field2 : string;
public field3 : string;

// этот метод генерируется автоматически макросом
ChangeField1(fld1 : int) : Object
{
 if (field1 != fld1) Object(field1 = fld1, field2 = field2, field3 = field3) else this
}
}


Это просто незаменимая вещь если нужно работать с неизменяемыми объектами

CU>>Traversable

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


class Op
{ 
    | Plus
    | Minus
    | Multiply
    | Divide
    ToString() : string
{
 match (this)
 {
  | Plus => "+"
  | Minus => "-"
  | Multiply => "*"
  | Divide  => "/"
 }
}
 }

[Traversable] // этот аттрибут создает методы для обхода дерева
class Expr
{
    | Literal {lit : int;}
    | BinaryOp {left : Expr; oper : Op; right : Expr;}     // left, op, right
    | IfThenElse {cond : Expr; then : Expr; els : Expr;} // cond, then, else; 0=false in cond
    | Print {expr : Expr;}                    // prints, then returns that value
}


в нем создаются методы Fold, Reduce с разными перегрузками и аккумуляторами, например:
Fold[T](literal : Literal -> T, binary_op : BinaryOp * T * T -> T, if_then_else : IfThenElse * T * T * T -> T, print : Print * T -> T) : T
{
... тут создается код для обхода
}


 // выражение примерного языка программирования if (42) print(1 + 1) else 0;
def expr = Expr.IfThenElse(Literal(42), Print(BinaryOp(Literal(1), Op.Plus, Literal(1))), Print(Literal(0)));

expr.Fold(<[]>, x => <[ $(x.lit) ]>, (t, l, r) => <[ $l $(t.oper.ToString() : usesite) $r]>, (t, e) => <[ WriteLine($e);$e]>);


на выходе получается выражение представляющее дерево

можно например посчитать результат выражения, или свертку констант:

def expr = BinaryOp(Literal(4), Op.Plus, BinaryOp(Literal(3), Multiply, Literal(5));

def process_op(a, op, b)
{
 match (op)
 {
    | Plus     => a + b
    | Minus    => a - b
    | Multiply => a * b
    | Divide   => a / b
 }
}



def result = expr.Fold(0, _.lit, (t, l, r) => process_op(l, t.oper, r));

на выходе результат выражения.

или изменение неизменямого дерева

def new_tree = expr.Reduce(x => x.ChangeLit(x.lit * 10), (t, _, _) => t.ChangeOper(Multiply())); // Reduce - Fold без начального значения, у которого аккумулятор это тот же тип (название взято из f#)

на выходе дерево с измененными значениями

Как видите вещь обобщенная, это катаморфизм в функциональных терминах или Fold над деревьями, которая очень пригождается в жизни, если нужно что то подсчитывать в деревьях, создавать новые, генерировать код на основе их. Этот макрос использует методы расширения, что такое макросы методы расширения не совсем понятно.
Re[8]: А почему &= и им подобные реализованы, а &&= нет?
От: CodingUnit Россия  
Дата: 04.01.12 11:26
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>в нем создаются методы Fold, Reduce с разными перегрузками и аккумуляторами, например:

CU>Fold[T](literal : Literal -> T, binary_op : BinaryOp * T * T -> T, if_then_else : IfThenElse * T * T * T -> T, print : Print * T -> T) : T
CU>{
CU>... тут создается код для обхода
CU>}

Тут ошибочка, сигнатура такая:

Fold[T](init : T, literal : Literal -> T, binary_op : BinaryOp * T * T -> T, if_then_else : IfThenElse * T * T * T -> T, print : Print * T -> T) : T
{
}

init — начальное значение, остальные части генерируются на основе дерева
Re[8]: А почему &= и им подобные реализованы, а &&= нет?
От: _NN_ www.nemerleweb.com
Дата: 04.01.12 13:01
Оценка:
Здравствуйте, CodingUnit, Вы писали:


>Это просто незаменимая вещь если нужно работать с неизменяемыми объектами

CU>>>Traversable



Вместо макроаттрибута на класс использовать примерно такой код (сейчас так нельзя).
Это позволяет добавлять интерфейс не меняя код класса.
macro PrintMe(this l)
{
  <[ System.Console.WriteLine("{0}", $(l : usesite)); ]>
}

Main() : void
{
  1.PrintMe();
  "a".PrintMe();
}

Во время компиляции развернется в:
Main() : void
{
  System.Console.WriteLine("{0}", 1);
  System.Console.WriteLine("{0}", "a");
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[9]: А почему &= и им подобные реализованы, а &&= нет?
От: CodingUnit Россия  
Дата: 04.01.12 18:53
Оценка:
Здравствуйте, _NN_, Вы писали:

>Это просто незаменимая вещь если нужно работать с неизменяемыми объектами

CU>>>Traversable
Здравствуйте, CodingUnit, Вы писали:


>>Это просто незаменимая вещь если нужно работать с неизменяемыми объектами

CU>>>>Traversable
_NN>
согласен, в функциональных языках FoldTree пытаются реализовать, но не реализуют в стандартном виде, якобы потому что деревья все разные, потому что у них нет макросов

_NN>
_NN>macro PrintMe(this l)
_NN>{
_NN>  <[ System.Console.WriteLine("{0}", $(l : usesite)); ]>
_NN>}
_NN>

_NN>

_NN>Main() : void
_NN>{
_NN>  1.PrintMe();
_NN>  "a".PrintMe();
_NN>}
_NN>


да такое поведение сейчас можно получить если сильно изгольнуться, например релизовать PrintMe в типе принадлежащем 1 то есть int, с помощью метода расширения, по идее должно прокатить, сначала надо запустить макрос который генерирует этот метод, можно и уровня выражения и он генерирует заглушку модуль с реализацией нужного метода в типе принадлежащем выражению справа, если такое решение будет достаточно. А еще можно макросом тупо переписывать тело метода, где найдет выражение PrintMe заменяет на твой код печати. Это можно делать этим же макросом PrintMe, тупо но прокатит. Но о полной поддержке таких супер вещей лучше помечтать о Н2, за чашкой чаю.
Re[8]: А почему &= и им подобные реализованы, а &&= нет?
От: CodingUnit Россия  
Дата: 04.01.12 20:10
Оценка:
Здравствуйте, CodingUnit, Вы писали:


CU> // выражение примерного языка программирования if (42) print(1 + 1) else 0;

CU>def expr = Expr.IfThenElse(Literal(42), Print(BinaryOp(Literal(1), Op.Plus(), Literal(1))), Print(Literal(0)));

CU>expr.Fold(<[]>, x => <[ $(x.lit) ]>, (t, l, r) => <[ $l $(t.oper.ToString() : usesite) $r]>, (t, e) => <[ WriteLine($e);$e]>);

CU>[/nemerle]

CU>на выходе получается выражение представляющее дерево


здесь еще одна ошибочка, пропустил самое интересное ветку if_then_else


[Traversable] // этот аттрибут создает методы для обхода дерева
class Expr
{
    | Literal {lit : int;}
    | BinaryOp {left : Expr; oper : Op; right : Expr;}     // left, op, right
    | IfThenElse {cond : Expr; then : Expr; els : Expr;} // cond, then, else; 0=false in cond
    | Print {expr : Expr;}                    // prints, then returns that value
}

def expr = Expr.IfThenElse(Literal(42), Print(BinaryOp(Literal(1), Op.Plus(), Literal(1))), Print(Literal(0)));

def res = expr.Fold(<[]>, x             => <[ $(x.lit) ]>, 
                         (t, l, r)      => <[ $l $(t.oper.ToString() : usesite) $r]>, 
                         (t, c, th, el) => <[ if ($c) $th else $el ]>,
                         (t, e)         => <[ WriteLine($e);$e]>);


здесь в if и в других местах берется аккумулятор для каждой из ветвей, в данном случае это PExpr, чтобы они были дерево должно обходится в Post-order манере это все делает Fold за кулисами. Как видите генерация получается очень декларативной, FoldTree удивительная вещь в алгебре типов.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.