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...
Пока на собственное сообщение не было ответов, его можно удалить.