Тернарный оператор в императивных языках
От: igor-booch Россия  
Дата: 27.05.13 17:20
Оценка:
Тут в дотнетах развернулась жаркая дискуссия про функционалльной програмирование
http://rsdn.ru/forum/dotnet/5179867.1
Автор: igor-booch
Дата: 24.05.13


По ходе дискуссии у меня родился вопрос.
В Haskell есть if выражение. http://en.wikibooks.org/wiki/Haskell/Control_structures
Написано, что

If you programmed in C or Java, you will recognize Haskell's if/then/else as an equivalent to the ternary conditional operator ?


Смотрим документацию по оператору ? в C#

condition ? first_expression : second_expression;

Смотрим теперь документация по if-else в C#:

if (expression)
statement1
[else
statement2]

Я так понимаю, что в данных нотациях в expression я не могу использовать инструменты императивного языка позволяющие управлять потоком исполнения (flow control), а именно if, for. А в statement могу. Но это ограничение легко обойти. Я могу в expression вызвать метод, в котором уже if и for будут.

В связи с этим возникает вопрос насколько справедливо что if в Haskell равносильно тернарному оператору в императивных языках.
Возможно expression в императивных языках не эквивалентно expression в функциональных.
Если не эквивалентно, я тогда не понимаю разницы между expression и statement.





30.05.13 05:42: Перенесено модератором из 'Декларативное программирование' — VladD2
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Re: Тернарный оператор в императивных языках
От: samius Япония http://sams-tricks.blogspot.com
Дата: 27.05.13 17:40
Оценка:
Здравствуйте, igor-booch, Вы писали:

IB>Тут в дотнетах развернулась жаркая дискуссия про функционалльной програмирование

IB>http://rsdn.ru/forum/dotnet/5179867.1
Автор: igor-booch
Дата: 24.05.13

Жарите там в основном вы
Re: Тернарный оператор в императивных языках
От: _NN_ www.nemerleweb.com
Дата: 27.05.13 18:01
Оценка:
Здравствуйте, igor-booch, Вы писали:

IB>Если не эквивалентно, я тогда не понимаю разницы между expression и statement.


А что непонятного ?
Формула проста:
statement = expression возвращающий void.

В языках типа C# невозможно создать переменную из statement.
Вот и получается:

var a = true ? 1 : 2; // OK

var a = if(true) 1 else 2; // Error, if-else "возвращают" void.
void a = ... // Такое вообще нельзя


В функциональных языках и в гибридных языках понятие statement как отдельный элемент просто отсутствует.
В таких языка как правило отсутствует явное ключевое слово 'return' в понимании C (в Хаскелле это означает совсем другое если что),
И всегда последнее выражение используется как результат.
Это не отменяет возможность эмуляции 'return' стиля C.

Возьмем нефункциональный Ruby в котором, однако, все является выражением:
if true then 2 else 3 end; # Результат игнорируем

a = if true then 2 else 3 end; # Результат используем
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Тернарный оператор в императивных языках
От: igor-booch Россия  
Дата: 27.05.13 18:17
Оценка:
IB>>Тут в дотнетах развернулась жаркая дискуссия про функционалльной програмирование
IB>>http://rsdn.ru/forum/dotnet/5179867.1
Автор: igor-booch
Дата: 24.05.13

S>Жарите там в основном вы
Вы хотите сказать что я Вас жарю?
Не я не садист.
Я стремлюсь к совершенству, а Вы мне помогаете в этом
И сами чему-то учитесь (возможно).
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Re[3]: Тернарный оператор в императивных языках
От: samius Япония http://sams-tricks.blogspot.com
Дата: 27.05.13 18:23
Оценка:
Здравствуйте, igor-booch, Вы писали:

IB>>>Тут в дотнетах развернулась жаркая дискуссия про функционалльной програмирование

IB>>>http://rsdn.ru/forum/dotnet/5179867.1
Автор: igor-booch
Дата: 24.05.13

S>>Жарите там в основном вы
IB>Вы хотите сказать что я Вас жарю?
Нет, что вы Жарите в смысле "поддаете жару".

IB>Не я не садист.

IB>Я стремлюсь к совершенству, а Вы мне помогаете в этом
IB>И сами чему-то учитесь (возможно).
Не исключено
Re[2]: Тернарный оператор в императивных языках
От: Кодт Россия  
Дата: 27.05.13 19:42
Оценка: 1 (1) +2
Здравствуйте, _NN_, Вы писали:

IB>>Если не эквивалентно, я тогда не понимаю разницы между expression и statement.


_NN>А что непонятного ?

_NN>Формула проста:
_NN>statement = expression возвращающий void.

Грубое и, в общем случае, неверное утверждение.
statement — это утверждение. Например, определение переменной — это тоже statement.
Стейтменты, управляющие потоком (ветвления, циклы, переходы) проблематично рассматривать как выражения.
Кстати говоря, void-выражения можно утилизировать в операторе последовательности ",". Попробуйте туда мысленно подставить goto — и станет ясно, что не всякий стейтмент есть выражение.

_NN>В языках типа C# невозможно создать переменную из statement.

_NN>Вот и получается:

_NN>
_NN>var a = true ? 1 : 2; // OK

_NN>var a = if(true) 1 else 2; // Error, if-else "возвращают" void.
_NN>void a = ... // Такое вообще нельзя
_NN>


В С++ (стандарт 2003 и далее) можно делать return f() где void f().
В питоне тип None (аналог void) — обычное значение.

Так что это вопрос синтаксиса, в большей степени, нежели вопрос семантики.

_NN>Возьмем нефункциональный Ruby в котором, однако, все является выражением:


В руби и питоне "всё есть выражение" — это способ упрощения модели языка.
Там даже объявление класса — это не статическая конструкция, а интерпретируемая последовательность.
print "----1----"
class Foo :
  print "defclass"
  def __init__(self) :
    print "init"

print "----2----"
f = Foo()
print "----3----"

результат
----1----
defclass
----2----
init
----3----

Кстати, в питоне 2.x — print является не выражением, а стейтментом.
Написать x = (print "foo") нельзя.
Перекуём баги на фичи!
Re[3]: Тернарный оператор в императивных языках
От: Pzz Россия https://github.com/alexpevzner
Дата: 27.05.13 19:46
Оценка:
Здравствуйте, Кодт, Вы писали:

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


Строго говоря, как выражения проблематично использовать только циклы и операторы перехода. Потому что идея о том, что значением цикла является значение последнего прохода несколько контринтуитивна, IMHO.
Re[4]: Тернарный оператор в императивных языках
От: Кодт Россия  
Дата: 27.05.13 21:05
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Строго говоря, как выражения проблематично использовать только циклы и операторы перехода. Потому что идея о том, что значением цикла является значение последнего прохода несколько контринтуитивна, IMHO.


Она "несколько" контр-интуитивна постольку, поскольку у цикла может оказаться ноль проходов — и непонятно, что возвращать в этом случае.
Либо обёртывать в какой-то моноид с пустым элементом (например, nullable значение или список всех итераций);
либо вводить в синтаксис цикла ветку "иначе", как это сделано в питоне (там, правда, она отрабатывает всегда);
либо сделать теневой моноид: бросок исключения в качестве пустого элемента (и опять же, так сделано в питоне).

Если же мы рассмотрим цикл как некую свёртку, то ноль проходов — это ноль применений к исходному значению: вернём его; любое ненулевое количество проходов — вернём результат последнего прохода.
Но как это красиво в синтаксис оформить...
Скажем, так
x = 1234 and_for range(k) { |i| i*100 } # при k<1, x=1234; иначе, x=(k-1)*100
Перекуём баги на фичи!
Re[3]: Тернарный оператор в императивных языках
От: _NN_ www.nemerleweb.com
Дата: 28.05.13 06:18
Оценка:
Здравствуйте, Кодт, Вы писали:

_NN>>statement = expression возвращающий void.


К>Грубое и, в общем случае, неверное утверждение.

В большинстве случаев оно подходит.
Если statement возвращает void, то все просто и логично.
Просто языки не умеют или не хотят оперировать с 'void' типами.

К>statement — это утверждение. Например, определение переменной — это тоже statement.

Почему в этом случае нельзя рассматривать как выражение с результатом void ?
Скажем, в Nemerle как раз так и есть:
def a = def b = 1;
// b = 1
// a = ()


Возможно где-то в ML семействе есть такая фишка тоже.

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

В Nemerle аналогично определению переменной.
def a = foreach(x in []) {};
// a = ()


К>Кстати, в питоне 2.x — print является не выражением, а стейтментом.

Это не противоречит утверждению.
print возвращает void, а Python просто не умеет с ним работать.

К>Написать x = (print "foo") нельзя.

Также как и
a = if True:
      1
    else
      2

Зато можно
a = 1 if True else 2

Потому что тут это будет выражением.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: Тернарный оператор в императивных языках
От: Pzz Россия https://github.com/alexpevzner
Дата: 28.05.13 09:40
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Она "несколько" контр-интуитивна постольку, поскольку у цикла может оказаться ноль проходов — и непонятно, что возвращать в этом случае.


Согласен.

К>Но как это красиво в синтаксис оформить...

К>Скажем, так
К>
К>x = 1234 and_for range(k) { |i| i*100 } # при k<1, x=1234; иначе, x=(k-1)*100
К>


— Пане, як по вашему дупа?
— ...
— А, ну тоже красиво.
Re[5]: Тернарный оператор в императивных языках
От: Воронков Василий Россия  
Дата: 29.05.13 06:53
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Она "несколько" контр-интуитивна постольку, поскольку у цикла может оказаться ноль проходов — и непонятно, что возвращать в этом случае.

К>Либо обёртывать в какой-то моноид с пустым элементом (например, nullable значение или список всех итераций);
К>либо вводить в синтаксис цикла ветку "иначе", как это сделано в питоне (там, правда, она отрабатывает всегда);
К>либо сделать теневой моноид: бросок исключения в качестве пустого элемента (и опять же, так сделано в питоне).

К>Если же мы рассмотрим цикл как некую свёртку, то ноль проходов — это ноль применений к исходному значению: вернём его; любое ненулевое количество проходов — вернём результат последнего прохода.

К>Но как это красиво в синтаксис оформить...
К>Скажем, так
К>
К>x = 1234 and_for range(k) { |i| i*100 } # при k<1, x=1234; иначе, x=(k-1)*100
К>


Посмотри, как это в том же Немерле сделано. Цикл всегда возвращает Unit — и никаких проблем.
Re: Тернарный оператор в императивных языках
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 31.05.13 10:19
Оценка:
Здравствуйте, igor-booch, Вы писали:

IB>Я так понимаю, что в данных нотациях в expression я не могу использовать инструменты императивного языка позволяющие управлять потоком исполнения (flow control), а именно if, for.


Вместо if ты можешь использовать все тот же тернарный оператор, а for/foreach по своей сути — мутабельная конструкция, и заталкивать ее в выражение — крайне фиговая идея. Вместо for в функциональном стиле используют linq выражения.

IB>В связи с этим возникает вопрос насколько справедливо что if в Haskell равносильно тернарному оператору в императивных языках.


Справедливо.
... << RSDN@Home 1.2.0 alpha 5 rev. 99 on Windows 8 6.2.9200.0>>
AVK Blog
Re[5]: Тернарный оператор в императивных языках
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 31.05.13 10:23
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Она "несколько" контр-интуитивна постольку, поскольку у цикла может оказаться ноль проходов — и непонятно, что возвращать в этом случае.


Это если считать что цикл возвращает скалярное выражение. А если он возвращает итератор, то все становится предельно логично.

К>Если же мы рассмотрим цикл как некую свёртку


Не, это слишком узкая семантика для цикла.
... << RSDN@Home 1.2.0 alpha 5 rev. 99 on Windows 8 6.2.9200.0>>
AVK Blog
Re[2]: Тернарный оператор в императивных языках
От: igor-booch Россия  
Дата: 31.05.13 12:32
Оценка:
AVK>Вместо for в функциональном стиле используют linq выражения.
Жалко только что http://stackoverflow.com/questions/4814242/linq-recursion-function

IB>>В связи с этим возникает вопрос насколько справедливо что if в Haskell равносильно тернарному оператору в императивных языках.

AVK>Справедливо.
Если императивным языком считать C#, то
я для себя на этот вопрос ответил так:
если не считать, что в first_expression и second_expression в тернарном операторе можно вызвать императивный метод (грязную функцию), то да
если не считать, что в first_expression и second_expression в тернарном операторе не обладают всеми возможностями функциональных языков (напр. carring, lazy evaluation)
то справедливо
Возможно в других языках expressions более приближены к возможностям (и ограничениям) функциональных языков.

Зачем вообще expressions в императивных языках, если они такие "неполноценные" в свете функциональных языков?
— Без них компилятор (точнее парсер, не важно кого компилятора или интерпретатора) не построить
http://stackoverflow.com/questions/6754454/speed-difference-between-if-else-and-ternary-operator-in-c

Но концептуально expressions во всех языках означают означают одно.
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Re[3]: Тернарный оператор в императивных языках
От: C.A.B LinkedIn
Дата: 31.05.13 12:44
Оценка:
Здравствуйте, igor-booch, Вы писали:
IB>— Без них компилятор (точнее парсер, не важно кого компилятора или интерпретатора) не построить
То есть? Почему?
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Re[3]: Тернарный оператор в императивных языках
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 31.05.13 13:01
Оценка:
Здравствуйте, igor-booch, Вы писали:

IB>Жалко только что http://stackoverflow.com/questions/4814242/linq-recursion-function


Ну да, есть отдельные моменты, C# все таки не чисто функциональный язык.

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


Ну это в любом случае считать не надо, иначе сравнивать шарп с хаскелом просто бессмысленно.

IB>Зачем вообще expressions в императивных языках, если они такие "неполноценные" в свете функциональных языков?


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

IB>— http://stackoverflow.com/questions/6754454/speed-difference-between-if-else-and-ternary-operator-in-c


ИМХО бред какой то. Уже на уровне IL разницы быть не должно.
... << RSDN@Home 1.2.0 alpha 5 rev. 99 on Windows 8 6.2.9200.0>>
AVK Blog
Re[4]: Тернарный оператор в императивных языках
От: igor-booch Россия  
Дата: 31.05.13 13:56
Оценка: :)
CAB>Здравствуйте, igor-booch, Вы писали:
IB>>— Без них компилятор (точнее парсер, не важно кого компилятора или интерпретатора) не построить
CAB>То есть? Почему?

А вы представьте парсинг statement'а (императивного) if :


if (expression)
    statement1
[else
    statement2]




Если попустить, что в expression может быть другой if,
То есть это будет уже не expression, а statement,
то вплывут фундаментальные проблемы.

Не спрашивайте только какие именно, это все на уровне интуиции.
Если сам пойму сам напишу.
Единственно, то могу пока уточнить, опять же на уровне интуиции:
парсинг в принципе возможен,
невозможен парсинг в структуру данных, которую можно преобразовать в последовательности инструкций процессора.
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Re[5]: Тернарный оператор в императивных языках
От: C.A.B LinkedIn
Дата: 31.05.13 13:58
Оценка:
IB>>>— Без них компилятор (точнее парсер, не важно кого компилятора или интерпретатора) не построить
CAB>>То есть? Почему?
IB>А вы представьте парсинг statement'а (императивного) if :
IB>
IB>if (expression)
IB>    statement1
IB>[else
IB>    statement2]
IB>

Представляю, в результате получится AST вида:
          if_statement  
          /     |    \
expression statement1 statement2

IB>Если попустить, что в expression может быть другой if,
Если в вашем ЯП if это statement(т.е. не возвращает какого-то значения), то он не может быть там где требуется expression, это ошибка.
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Re[6]: Тернарный оператор в императивных языках
От: igor-booch Россия  
Дата: 01.06.13 08:55
Оценка:
По моему мы друг-друга не поняли.

IB>>— Без них (expression'ов) компилятор (точнее парсер, не важно кого компилятора или интерпретатора) не построить

CAB>То есть? Почему?

Я подумал, что Вы своим вопросом (Почему?) хотели сказать, что без expression'ов ЯП возможен.
Судя по Вашему предыдущему ответу вопрос "Почему?" касался чего-то другого.
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания
http://rsdn.ru/Info/rules.xml
Re[7]: Тернарный оператор в императивных языках
От: C.A.B LinkedIn
Дата: 01.06.13 09:15
Оценка:
IB>Я подумал, что Вы своим вопросом (Почему?) хотели сказать, что без expression'ов ЯП возможен.
Ассемблер?
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.