Re[17]: "LINQ как шаг к ФП". Стиль изложения.
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.02.09 13:23
Оценка:
Здравствуйте, FR, Вы писали:
FR>
FR>let rec power5 x =
FR>    let rec aux acc n = if n=0 then acc else aux (acc * x) (n - 1) in aux 1 5;;
FR>

Прекрасный пример выхода за пределы императивного мышления. Именно этим трюкам и пытается научить Влад в своей статье
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[16]: "LINQ как шаг к ФП". Стиль изложения.
От: EvilChild Ниоткуда  
Дата: 12.02.09 13:28
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Очень просто. Вот у нас простейшая процедурная программа по возведению числа в 5ю степень:

S>
S>public int Power5(int x)
S>{
S>  int power5 = x;
S>  power5 = power11*x;
S>  power5 = power11*x;
S>  power5 = power11*x;
S>  power5 = power11*x;
S>  return power5;
S>}
S>

S>Обрати внимание, что у нас есть некая переменная power5, состояние которой последовательно меняется. Результат последнего оператора напрямую, но неявно, зависит от того, что положил в эту переменную первый оператор. Это и есть глобальное, с точки зрения отдельных операторов, состояние.
S>Вся локальность power5 сводится к тому, что мы запрещаем вмешиваться в ее состояние другим процедурам.
S>Стоит также отметить, что уже здесь мы пользуемся процедурой умножения, которая тоже может быть записана как определенная последовательность ветвлений и присваиваний. То, что в реальных архитектурах такая операция доступна "из коробки", для теории значения не имеет.
Глобальное, с точки зрения отдельных операторов, состояние — это весьма странный зверь.
Под глобальными переменными, обычно, понимают переменные доступные в любой области видимости.
Конструкция, описанная тобой какая-то совершенно искуственная.
Какая от неё польза?

EC>>Мне вот неочевидно почему в нём обязательно должно быть глобальное состояние.

S>А куда же оно денется, это состояние? Вот попробуй переписать Power5 так, чтобы в ней не было состояния.
Глобального состояния (в традиционном его понимании) там нет.
Re[17]: "LINQ как шаг к ФП". Стиль изложения.
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.02.09 13:37
Оценка: -1 :)
Здравствуйте, EvilChild, Вы писали:

EC>Конструкция, описанная тобой какая-то совершенно искуственная.

EC>Какая от неё польза?
Не понимаю вопроса. Польза от чего? От этой убогой программы? Ну, она умеет возводить числа в пятую степень.

S>>А куда же оно денется, это состояние? Вот попробуй переписать Power5 так, чтобы в ней не было состояния.

EC>Глобального состояния (в традиционном его понимании) там нет.

Достаточно того, что есть состояние, изменяющееся во времени. Даже если написать эту же программу в виде
return x*x*x*x*x;

Всё равно будет состояние, хоть и неявное. Потому, что спецификация императивного ЯП подразумевает вот такую семантику:
temp1 = x;
temp2 = temp1*x;
temp3 = temp2*x;
temp4 = temp3*x;
temp5 = temp4*x;
return temp5;

И никуда ты от этого не денешься, пока не начнешь искать не способ представить алгоритм в виде последовательных трансформаций некоего состояния, а как способ описания зависимостей.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: "LINQ как шаг к ФП". Стиль изложения.
От: EvilChild Ниоткуда  
Дата: 12.02.09 13:54
Оценка:
Здравствуйте, Sinclair, Вы писали:

EC>>Конструкция, описанная тобой какая-то совершенно искуственная.

EC>>Какая от неё польза?
S>Не понимаю вопроса. Польза от чего? От этой убогой программы? Ну, она умеет возводить числа в пятую степень.
Не прикидывайся, ты даже верно процитировал.
Имелось в виду твоё изобретение под названием глобальное, с точки зрения отдельных операторов, состояние.

S>Достаточно того, что есть состояние, изменяющееся во времени. Даже если написать эту же программу в виде

S>
S>return x*x*x*x*x;
S>

S>Всё равно будет состояние, хоть и неявное. Потому, что спецификация императивного ЯП подразумевает вот такую семантику:
S>
S>temp1 = x;
S>temp2 = temp1*x;
S>temp3 = temp2*x;
S>temp4 = temp3*x;
S>temp5 = temp4*x;
S>return temp5;
S>

S>И никуда ты от этого не денешься, пока не начнешь искать не способ представить алгоритм в виде последовательных трансформаций некоего состояния, а как способ описания зависимостей.
Совсем недавно ты настаивал на глобальности состояния, это меня и удивило.
Re[18]: "LINQ как шаг к ФП". Стиль изложения.
От: Gajdalager Украина  
Дата: 12.02.09 14:15
Оценка: +2
Здравствуйте, Sinclair, Вы писали:

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


EC>>Конструкция, описанная тобой какая-то совершенно искуственная.

EC>>Какая от неё польза?
S>Не понимаю вопроса. Польза от чего? От этой убогой программы? Ну, она умеет возводить числа в пятую степень.

S>>>А куда же оно денется, это состояние? Вот попробуй переписать Power5 так, чтобы в ней не было состояния.

EC>>Глобального состояния (в традиционном его понимании) там нет.

S>Достаточно того, что есть состояние, изменяющееся во времени. Даже если написать эту же программу в виде

S>
S>return x*x*x*x*x;
S>

S>Всё равно будет состояние, хоть и неявное. Потому, что спецификация императивного ЯП подразумевает вот такую семантику:
S>
S>temp1 = x;
S>temp2 = temp1*x;
S>temp3 = temp2*x;
S>temp4 = temp3*x;
S>temp5 = temp4*x;
S>return temp5;
S>

S>И никуда ты от этого не денешься, пока не начнешь искать не способ представить алгоритм в виде последовательных трансформаций некоего состояния, а как способ описания зависимостей.
Подожди-подожди... Почему это вдруг эти переменные стали состоянием, да ещё и глобальным? Давай напишем так:
[c#]
return x * (\x -> x * x (x)); // Упростили к кубу
[c#]
Умножаем х на результат вычисления лямбды. Где состояние? В регистрах? А они здесь при чём? Это детали реализации.
<< RSDN@Home 1.2.0 alpha 4 rev. 1128>>
Сейчас играет Оргия праведников — С.М.С.
Re[50]: "LINQ как шаг к ФП". Стиль изложения.
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 12.02.09 16:22
Оценка: 4 (1)
Здравствуйте, FR, Вы писали:


G>>Причем вы можете свой аналогичный сахар в F# делать в любых количествах.

FR>Интересно как?

Вот так http://www.infoq.com/articles/pickering-fsharp-workflow
Re[51]: "LINQ как шаг к ФП". Стиль изложения.
От: thesz Россия http://thesz.livejournal.com
Дата: 12.02.09 17:05
Оценка:
G>>>Причем вы можете свой аналогичный сахар в F# делать в любых количествах.
FR>>Интересно как?
G>Вот так http://www.infoq.com/articles/pickering-fsharp-workflow

"Не надо путать причину и следствие. Особенно не надо путать следствие." (C) Кнышев

Це ж описание монад. Как следствие, не надо его путать с ленивыми вычислениями.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[52]: "LINQ как шаг к ФП". Стиль изложения.
От: FR  
Дата: 12.02.09 17:09
Оценка:
Здравствуйте, thesz, Вы писали:

T>"Не надо путать причину и следствие. Особенно не надо путать следствие." (C) Кнышев


T>Це ж описание монад. Как следствие, не надо его путать с ленивыми вычислениями.


Мы уже с ленивости на сахар переключились
Re[19]: "LINQ как шаг к ФП". Стиль изложения.
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.02.09 04:26
Оценка:
Здравствуйте, Gajdalager, Вы писали:
G>Подожди-подожди... Почему это вдруг эти переменные стали состоянием, да ещё и глобальным?
Переменные == состояние. По определению.
G>Давай напишем так:
G>
G>return x * (\x -> x * x (x)); // Упростили к кубу
G>[c#]
Не понял, что это за синтаксис. Можно пояснить, где здесь что? Имеется в виду вот это:
[c#]
return x * ((int a) => a*a) (x);

Так что ли?
G>Умножаем х на результат вычисления лямбды. Где состояние? В регистрах? А они здесь при чём? Это детали реализации.
Ну давайте разберемся. Семантика C# такова, что мы получим примерно вот это:
var square = Func<int, int>(a => a*a);
var temp = square(x);
var temp2 = temp*x;
return x;

Введением императивной лямбды ты ничего не добьешься — это по-прежнему тот же самый пример с x*x*x*x. Такая лямбда — всего лишь еще один, более компактный способ описания процедур. Ровно с тем же успехом ты мог ее описать заранее, как Power2(x) и вызвать по месту. По-прежнему связь результата power5 и аргумента выражена неявно, через цепочку трансформаций.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[20]: "LINQ как шаг к ФП". Стиль изложения.
От: FR  
Дата: 13.02.09 04:57
Оценка: +2
Здравствуйте, Sinclair, Вы писали:

S>Введением императивной лямбды ты ничего не добьешься — это по-прежнему тот же самый пример с x*x*x*x. Такая лямбда — всего лишь еще один, более компактный способ описания процедур. Ровно с тем же успехом ты мог ее описать заранее, как Power2(x) и вызвать по месту. По-прежнему связь результата power5 и аргумента выражена неявно, через цепочку трансформаций.


По моему ты зря нажимаешь на реализацию. Тот код на Ocaml который я выше привел тоже транслируется в очень даже императивное:

_camlKjljl__aux_60:
L101:
    cmp    ebx, 1
    jne    L100
    ret
L100:
    add    ebx, -2
    mov    edx, DWORD PTR [ecx+12]
    sar    edx, 1
    dec    eax
    imul    eax, edx
    inc    eax
    jmp    L101
Re[21]: "LINQ как шаг к ФП". Стиль изложения.
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.02.09 07:46
Оценка:
Здравствуйте, FR, Вы писали:

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


S>>Введением императивной лямбды ты ничего не добьешься — это по-прежнему тот же самый пример с x*x*x*x. Такая лямбда — всего лишь еще один, более компактный способ описания процедур. Ровно с тем же успехом ты мог ее описать заранее, как Power2(x) и вызвать по месту. По-прежнему связь результата power5 и аргумента выражена неявно, через цепочку трансформаций.


FR>По моему ты зря нажимаешь на реализацию.

Я нажимаю не на реализацию, а на семантику.
Я не виноват, что в императивном языке она именно такая. Есть понятия ассоциативности операций и порядка вычисления аргументов.
Это в таком простом случае программа выглядит похожей на функциональную.

Тот код на Ocaml который я выше привел тоже транслируется в очень даже императивное:
Совершенно неважно, во что именно он транслируется. Понятно, что внутре у ней неонка... тьфу, то есть императивный процессор, у которого неизбежно есть состояние.
Но завтра ты скачаешь новый компилятор, и код будет транслироваться во что-то другое. Речь именно о семантике программы.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[22]: "LINQ как шаг к ФП". Стиль изложения.
От: FR  
Дата: 13.02.09 07:53
Оценка:
Здравствуйте, Sinclair, Вы писали:

FR>>По моему ты зря нажимаешь на реализацию.

S>Я нажимаю не на реализацию, а на семантику.
S>Я не виноват, что в императивном языке она именно такая. Есть понятия ассоциативности операций и порядка вычисления аргументов.
S>Это в таком простом случае программа выглядит похожей на функциональную.

Вот этот код на D
int power5(int x) pure
{
    return x * x * x * x *x;
}


Уже непросто выглядит функциональным, но и семантически чистый.
В общем по моему грань слишком тонкая.
Re[23]: "LINQ как шаг к ФП". Стиль изложения.
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.02.09 08:17
Оценка:
Здравствуйте, FR, Вы писали:

FR>Уже непросто выглядит функциональным, но и семантически чистый.

FR>В общем по моему грань слишком тонкая.
Между чем и чем? Между декларативным и императивным? Не вижу никакой тонкости грани.
То, что существует полная эквивалентность туда и обратно — ну так это опять же еще Черч показал.
То, что можно внедрять в императивный в целом язык декларативные элементы — тоже нифига не новость.
Вот я на SQL пишу:

update employee set salary = salary +200 where lastname like 'D%'
update employee set salary = salary*1.2 where firstname like 'J%'

Каждый из стейтментов по существу вполне декларативен; он не навязывает никакого внутреннего порядка выполнения. Но они меняют глобальное состояние, и программа остается целиком императивной.

Поэтому мы возвращаемся к вопросу мышления — императивному программисту претит вот эта декларативная неопределенность; он инстинктивно стремится к переменным и циклам.
А декларативному программисту напротив, не нравится вот эта вот зависимость результата от порядка выполнения.
Ему комфортнее работать с
create view Salary2009 as select id, salary+200 as salary from employee where lastname like 'D%'
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[16]: "LINQ как шаг к ФП". Стиль изложения.
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 13.02.09 08:22
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Ну, то есть если мы откажемся от концепции return как таковой


От концепции return не отказываются даже в функциональных языках, там просто отказываются от ключевого слова return. В том же примере FR:
let rec power5 x =
    let rec aux acc n = if n=0 then acc else aux (acc * x) (n - 1) in aux 1 5;;

уши этой концепции торчат наружу.

S>Никаких присваиваний нет; никакого состояния тоже нет — программа описывает только непреложные факты.


Состояние просто перенесно из изменяемых переменных на стек, но оно все равно в явном виде присутствует -- при организации рекурсивного вызова sum_impl программист должен явно его определять (вычисляя аргументы рекурсивного вызова). Более того, программист должен специальным образом заботится об этом состоянии -- чтобы рекурсия была хвостовой.

S>Вроде того, что сумма всех чисел в массиве — это сумма одного числа с суммой всех остальных. Этот факт истинен всё время, а не только в момент выхода из подпрограммы.


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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[17]: "LINQ как шаг к ФП". Стиль изложения.
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.02.09 08:58
Оценка:
Здравствуйте, eao197, Вы писали:

E>От концепции return не отказываются даже в функциональных языках, там просто отказываются от ключевого слова return. В том же примере FR:

E>
E>let rec power5 x =
E>    let rec aux acc n = if n=0 then acc else aux (acc * x) (n - 1) in aux 1 5;;
E>

E>уши этой концепции торчат наружу.
Не вижу никаких ушей. Это не return, это тождество. Вот в учебнике математики за пятый класс, когда мы говорим "пусть x равно y+z", мы что, что-то куда-то вернули?

E>Состояние просто перенесно из изменяемых переменных на стек, но оно все равно в явном виде присутствует -- при организации рекурсивного вызова sum_impl программист должен явно его определять (вычисляя аргументы рекурсивного вызова).

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

E>Более того, программист должен специальным образом заботится об этом состоянии -- чтобы рекурсия была хвостовой.

Это артефакты конкретных реализаций. С точки зрения частично вычислимых функций, совершенно неважно, является ли рекурсия хвостовой.

E>Ерунда. На любом произвольном шаге исполнения функциональной версии sum (с рекурсивными вызовами sum_impl) есть только текущее значение, которое станет результатом (т.е. истинным фактом) только после завершения всего вычисления.

О каком еще "шаге" мы говорим? С учетом того, что у функций нет побочных эффектов, компилятор имеет полное право вообще отказаться от шагов вычисления и брать результат напрямую из таблицы. "Шаг" может появиться только после преобразования декларативной программы в императивную. То, что тебе очевиден ровно один такой способ преобразования, не означает, что применяться будет именно он.
В частности, хитрый компилятор может раскрыть скобки и получить, что power 5 =1 * x * x * x * x * x, воспользоваться ассоциативностью умножения и получить эквивалент
let rec power5 x =
let rec aux a = a * a in x * aux aux x
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: "LINQ как шаг к ФП". Стиль изложения.
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 13.02.09 09:35
Оценка: -1 :)
Здравствуйте, Sinclair, Вы писали:

E>>От концепции return не отказываются даже в функциональных языках, там просто отказываются от ключевого слова return. В том же примере FR:

E>>
E>>let rec power5 x =
E>>    let rec aux acc n = if n=0 then acc else aux (acc * x) (n - 1) in aux 1 5;;
E>>

E>>уши этой концепции торчат наружу.
S>Не вижу никаких ушей. Это не return, это тождество.

Ага, тождество.
В OCaml, на котором FR привел пример, значением функции будет значение последнего выражения, которое было выполнено в этой функции. И тип этого выражения должен совпадать с типом функции. А это означает, что в обоих ветках if-а нужно заботиться о выражениях, которые должны иметь одинаковый тип. Поэтому в OCaml запись:
if n=0 then acc ...

полностью соответствует аналогу в императивных языках:
if(n=0) return acc; ...


S>Вот в учебнике математики за пятый класс, когда мы говорим "пусть x равно y+z", мы что, что-то куда-то вернули?


Программирование -- это не математика. Если бы было по другому, то запись 'a=b' разражала бы всех программистов, а не только Вирта с Мейром.

E>>Состояние просто перенесно из изменяемых переменных на стек, но оно все равно в явном виде присутствует -- при организации рекурсивного вызова sum_impl программист должен явно его определять (вычисляя аргументы рекурсивного вызова).

S>Не вижу никаких вычислений. Вижу определение функции aux, которая совершенно неизменна, хоть и ссылается сама на себя.
aux (acc * x) (n - 1)

Посмотри внимательнее. И стоит только переписать вычисление вот так:
acc * (aux x (n-1))

как все очень и очень серьезно меняется. Хотя смысл остается тем же самым.

А на счет изменности функций:
int sum( int[] a ) {
  int r = 0;
  for( int i = 0; i != a.length; ++i )
    r += a[ i ];
  return r;
}

Чем эта функция изменна?

E>>Более того, программист должен специальным образом заботится об этом состоянии -- чтобы рекурсия была хвостовой.

S>Это артефакты конкретных реализаций.

Еще раз, программирование -- это не математика. Нет никакого толка от функции sum, если она не может вычислить сумму элементов массива из 10M элементов из-за нехватки стека.

Еще одно серьезное различие между программированием и математикой в том, что числа в программировании имеют размерность. В математике выражение (a-b) имеет смысл всегда. А в программировании -- нет.

E>>Ерунда. На любом произвольном шаге исполнения функциональной версии sum (с рекурсивными вызовами sum_impl) есть только текущее значение, которое станет результатом (т.е. истинным фактом) только после завершения всего вычисления.

S>О каком еще "шаге" мы говорим?

Например, об очередном вызове sum_impl.

S>С учетом того, что у функций нет побочных эффектов


Какие побочные эффекты у приведенной выше императивной функции sum?

S>компилятор имеет полное право вообще отказаться от шагов вычисления и брать результат напрямую из таблицы.


Из какой таблицы? Из какой таблицы компилятор может подставить значение функции sum для произвольного массива?

S>"Шаг" может появиться только после преобразования декларативной программы в императивную.


Ну да, конечно. Шаг рекурсии в ФП -- это, определенно, совсем другое дело, чем шаг цикла в ИП.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[12]: "LINQ как шаг к ФП". Стиль изложения.
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 13.02.09 09:37
Оценка:
Здравствуйте, Sinclair, Вы писали:

ГВ>>Честно говоря, после "стиль мышления" я выпал в настолько плотный осадок, что остальное уже было несущественным.

S>Наличие осадка вижу. Причин считать остальное несущественным — не вижу.

Да как тебе сказать, ИМХО, этот самый "стиль мышления" — причина настолько могучая, что встретив такое в околотехническом тексте остальное можно смело не читать.

ГВ>>То есть "плавный" переход от субъекта к объекту остался незамеченным. То есть ты называешь способ декомпозиции стилем мышления.

S>Хорошо. Речь идет о стиле мышления, для которого типичен именно указанный способ декомпозиции.

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

S>Суть беседы пока что сводится к тому, что выражение "У Мэри есть ягненок" тебя не устраивает, а самостоятельно выполнить переход к "гражданка Мария Джонс осуществляет ограниченное право владения объектом животноводства, не достигшим репродуктивного возраста" ты не хочешь.


Я против того, чтобы узнав о том, что у Мэри есть ягнёнок, в её адрес фыркали: "Глупая пастушка, фи!" А у Влада, в отличие от других авторов аналогичных пассажей, именно так и получается. Ты льёшь воду на ту же мельницу.

ГВ>>Не дела ради, а курьёзу для, попробуем обсудить означенный тобой способ декомпозиции и возможность его существования.

S>Отлично. Достаточно подробно вопрос существования такого способа декомпозиции программ освещен в работах Тьюринга, Поста, Чёрча, и многих других.

Я имел в виду практическое существование, то есть факты того, что такой способ используется людьми в повседневной деятельности для разработки ПО. Понятно, что память, например, она вообще глобальна и едина для всех программ.

ГВ>>И здесь вопросов снова больше, чем ответов. Например, так ли уж любой алгоритм подвергается привязке только к глобальным данным?

S>Данные, которыми оперирует машина Тьюринга, вполне себе глобальны. Есть какие-то вопросы о возможности реализации любого алгоритма машиной Тьюринга?

Я не о теоретической возможности, а о практике. На практике императивный подход в абсолютном большинстве случаев комбинируется с другими способами декомпозиции, в т.ч. — и с функциональной декомпозицией. Ни для кого это, по большому счёту не секрет, не новость и не открытие нового мира. А выбор способа декомпозиции диктуется совсем не одним только "стилем мышления".

ГВ>>Кроме того, если набор императивных конструкций ограничен модификацией, переходом и ветвлением (условным переходом), то по логике вещей, и вся программа должна представлять собой сплошной спагетти из if/goto.

S>Совершенно верно. См. например алгоритм Евклида. Есть какие-то сомнения в том, что он представляет собой сплошное спагетти из if/goto и присваиваний?

Нет сомнний, но это же и есть та самая короткая программа, о которой я сказал.

ГВ>>Если это так, то напрашивается мысль о том, что "императивный программист" — это либо сферический конь в вакууме,

S>Ага, похоже начинаются проблески понимания.



ГВ>>либо, в крайнем случае, очень-очень начинающий, поскольку на практике такие программы хоть и бывают, но они либо весьма ограничены в размерах, либо встречаются крайне редко.

S>Совершенно верно. Расширим модель "императивного программиста" до "процедурного программиста".

Зачем? Речь шла об императивном программисте.

S>У него в арсенале появляются новые конструкции, в частности процедуры.

S>Это даёт ему более богатые возможности декомпозиции алгоритма, но принципиально ничего не меняется — по-прежнему есть разделяемое состояние, с которым идет работа. По-прежнему основным инструментом является if, иногда замаскированный под while/for/until. Даже итерация по массиву/списку выполняется при помощи явной модификации переменной.

Сиречь, имеем комбинацию императивного и какого-то другого подхода.

ГВ>>Оба предполагаемых явления не слишком достойны того, чтобы с ними бороться. Либо я чего-то в твоих рассуждениях не понимаю.

S>Не вижу ничего особенно редкого в императивном программировании. Вон по соседству Павел Дворкин постоянно съезжает на то, что декларативное программирование мешает ему точно указать, в каком порядке в какие регистры складывать данные.

Я тоже не вижу ничего редкого в императивном программировании самом по себе (то есть в использовании приёмов, классифицируемых как ИП). Если ты не понял, то я говорил о "чистом императивном программировании", которым, якобы, занимается пресловутый "императивный программист".

ГВ>>P.S.: Вопрос о мышлении по-прежнему остаётся открытым.

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

Мда. Чудесатее и чудесатее. Антон, ты хоть понимаешь, о чём я толкую?
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[19]: "LINQ как шаг к ФП". Стиль изложения.
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.02.09 10:52
Оценка:
Здравствуйте, eao197, Вы писали:

E>Программирование -- это не математика. Если бы было по другому, то запись 'a=b' разражала бы всех программистов, а не только Вирта с Мейром.

Есть разные виды программирования.

E>как все очень и очень серьезно меняется. Хотя смысл остается тем же самым.

Это артефакт поведения конкретного компилятора конкретного языка.

E>А на счет изменности функций:

E>
E>int sum( int[] a ) {
E>  int r = 0;
E>  for( int i = 0; i != a.length; ++i )
E>    r += a[ i ];
E>  return r;
E>}
E>

E>Чем эта функция изменна?
Не понял вопрос. Вам непонятно, что r является изменчивым состоянием? что i является изменчивым состоянием, и даже банальное доказательство того факта, что ни одно из обращений не выходит за пределы границ массива является нетривиальным?

E>Еще раз, программирование -- это не математика. Нет никакого толка от функции sum, если она не может вычислить сумму элементов массива из 10M элементов из-за нехватки стека.

Еще раз: для чистой функции никаких причин жрать стек такими объемами нету вообще. Если компилятор неспособен свести ее потребление памяти к двум регистрам — это проблемы компилятора, а не ФП.

E>Еще одно серьезное различие между программированием и математикой в том, что числа в программировании имеют размерность.

Вот этого не понял.
E>В математике выражение (a-b) имеет смысл всегда. А в программировании -- нет.
Смысл этого выражения существенно зависит от того, о какой именно математике мы говорим. Если a и b являются членами конечной группы размером 2^32, то в программировании и в математике выражение будет иметь совершенно одинаковый смысл.

E>Например, об очередном вызове sum_impl.

Вы путаете два различных мира. Концепция "вызова" — это процедурное программирование. От императивного программирования в нём есть понятие "instruction pointer" — инструкции, выполняемой в данный момент. Плюс паттерн "вызов с возвратом", который строится из запоминания текущего ip, последующего goto, и восстановления ip+1 в будущем.

E>Какие побочные эффекты у приведенной выше императивной функции sum?

У приведенной выше — никаких. Поэтому хороший компилятор избавляется от излишней императивности в меру своих возможностей.
E>Из какой таблицы? Из какой таблицы компилятор может подставить значение функции sum для произвольного массива?
В функции power5 никакого массива не было.

E>Ну да, конечно. Шаг рекурсии в ФП -- это, определенно, совсем другое дело, чем шаг цикла в ИП.

Воот. Начинаешь понимать.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[19]: "LINQ как шаг к ФП". Стиль изложения.
От: Курилка Россия http://kirya.narod.ru/
Дата: 13.02.09 10:59
Оценка: -1
Здравствуйте, eao197, Вы писали:

E>Еще одно серьезное различие между программированием и математикой в том, что числа в программировании имеют размерность. В математике выражение (a-b) имеет смысл всегда. А в программировании -- нет.


a и b — логические предикаты (или ещё лучше прямые на плоскости), объясни математический смысл выражения a-b
Re[20]: "LINQ как шаг к ФП". Стиль изложения.
От: Gajdalager Украина  
Дата: 13.02.09 11:16
Оценка: +2
Здравствуйте, Sinclair, Вы писали:

E>>А на счет изменности функций:

E>>
E>>int sum( int[] a ) {
E>>  int r = 0;
E>>  for( int i = 0; i != a.length; ++i )
E>>    r += a[ i ];
E>>  return r;
E>>}
E>>

E>>Чем эта функция изменна?
S>Не понял вопрос. Вам непонятно, что r является изменчивым состоянием? что i является изменчивым состоянием, и даже банальное доказательство того факта, что ни одно из обращений не выходит за пределы границ массива является нетривиальным?

Не знаю, что такое изменная-неизменная функция; однако думаю, что данную функцию можно назвать чистой, ведь она возвращает одно и то же значение для того самого аргумента и не имеет побочных эффектов. Если эффекты есть — укажите мне их. А то, что функция записана в императивном стиле — это уже детали.
<< RSDN@Home 1.2.0 alpha 4 rev. 1128>>
Сейчас играет Оргия праведников — Сицилийский виноград
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.