Re[24]: "LINQ как шаг к ФП". Стиль изложения.
От: LaPerouse  
Дата: 16.02.09 15:44
Оценка: 1 (1)
Здравствуйте, Sinclair, Вы писали:

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


S>А вот эта "неуловимость" ФП связана как раз с ФП/ИП дуализмом: если избегать деструктивных присваиваний в процедурной программе, то она будет совпадать с некоторой функциональной программой с точностью до синтаксиса. А если ввести компонент "состояние" в результаты, над которыми оперируют функции в ФП программе, получим императивный алгоритм.


Состояние — она такая хитрая штука, что даже когда его типа нет, на самом деле оно вполне себе есть.
Вот например, возьмем все тот же пример, — в обеих случаях, приведенных eao, состояние присутствует. В первом случае оно нагло торчит в переменной r и не заметить его, мягко говоря, тяжело:

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

Во-втором случае состояние не присутствует в явном виде, но хранится на стеке. Но тем не менее оно есть, просто замаскировано.

int sum( int[] a ) {
  int sum_impl( int[] a, int index, int result ) {
    if( index != a.length )
      return sum_impl( a, i + 1, result + a[ index ] );
    else
      return result;
  }
  return sum_impl( a, 0, 0 );
}


result отличается от r только тем, что обновление значения не происходит путем деструктивного присваивания
r+=a[i]
, но происходит запись нового значения в стек: например, в стек первого рекурсивного вызова записывается a[0], второго вызова — a[0] + a[1] и т. д. Да, нет присваивания, однако суть процесса не меняется. Он останется итеративным и ему присуще состояние как описатель вычислительного процесса в данный момент времени.

Наконец, третий случай, это когда состояние в принципе отсутствует.

int sum( int[] a ) {
    int sum_impl( int[] a, int index ) {
            if( index != a.length )
                return a[ index ] + sum_impl( a, i + 1);
            else
                return a[ index ];
    }
    return sum_impl( a, 0);
}


Здесь на очередном витке рекурсии алгоритм не знает, на каком уровне он находится и действует так, будто ему надо посчитать сумму чисел от n от a.length, где n — номер рекурсивного вызова. Здесь состояния в принципе нет, это чисто рекурсивный процесс (линейная рекурсия)!

Так что видя, что нет явного деструктивного присваивания, нельзя утверждать, что состояния нет. Оно вполне себе может жить неявно на стеке и от этого не перестанет быть состоянием.

А теперь, внимание, вернемся к твоему

S>А если ввести компонент "состояние" в результаты, над которыми оперируют функции в ФП программе, получим императивный алгоритм.


То, что первый вариант — чистый ИП, а третий — чистый ФП, сомнений, наверное, ни у кого нет. А вот со вторым посложнее.

Возможны варианты
1. Случай 2 — это уже не ФП, так как там есть состояние на стеке
2. Случай 2 — это ФП, так как ФП отрицает не любое состояние, а лишь то, которое меняется путем деструктивного присваивания.

Некоторые размышления привели меня к мысли о том, что все таки справедливо второе устверждение.
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[25]: "LINQ как шаг к ФП". Стиль изложения.
От: VoidEx  
Дата: 16.02.09 16:16
Оценка:
Здравствуйте, LaPerouse, Вы писали:

LP>Некоторые размышления привели меня к мысли о том, что все таки справедливо второе устверждение.


Например мысли о fold (собственно второй вариант и есть)? Который суть заменяет конструкторы списка на константу и функцию и потому точно функционален. Это уж как смотреть
Re[47]: "LINQ как шаг к ФП". Стиль изложения.
От: FR  
Дата: 16.02.09 16:17
Оценка:
Здравствуйте, LaPerouse, Вы писали:

FR>>По штанге хоть и жуткий оффтоп, это такая штука и калечит и лечит


LP>Все хорошо в меру. Если физические кондиции позволяют, можно и под 100 кг штангой полежать. Но если скажем вес у тебя 50 килограмм, то какого хрена пытаться это делать? А ведь некоторые пытаются. "Каждый сверчок знай свой шесток". Один знакомый грыжу себе так заработал.


Дело не в этом, я имел в виду что одним из самых эффективных способов лечения того же остехондроза как раз является лечебная физкультура в которой большая часть упражнений заимствована из тяжелой атлетики
Re[25]: "LINQ как шаг к ФП". Стиль изложения.
От: FR  
Дата: 16.02.09 16:22
Оценка:
Здравствуйте, LaPerouse, Вы писали:

LP>Возможны варианты

LP>1. Случай 2 — это уже не ФП, так как там есть состояние на стеке
LP>2. Случай 2 — это ФП, так как ФП отрицает не любое состояние, а лишь то, которое меняется путем деструктивного присваивания.

LP>Некоторые размышления привели меня к мысли о том, что все таки справедливо второе устверждение.


Вообще даже первая функция именно как функция чистая хотя и реализованна конечно нечисто. А так да, можно было вместо размышлений почитать хотя бы первую главу Филда — Харрисона
Кстати случай 2 это весьма распространенный паттерн в ФП, те же потоковые вычисления оно и есть.
Re[4]: "LINQ как шаг к ФП". Стиль изложения.
От: Vamp Россия  
Дата: 19.02.09 21:02
Оценка: :))) :)
I>Для кого не сложен, для новичка или топа ?
Вообще ни для кого не сложен. Мне стало интересно, что это за ЭЛИТА такая, ФП — прочел статью и понял за 10 минут. Как всегда, много шума из ничего. Стандартный алгоритмы над последовательностями в С++ живут уже больше 10 лет. И лямбды есть, тоже давно уже.
Да здравствует мыло душистое и веревка пушистая.
Re[5]: "LINQ как шаг к ФП". Стиль изложения.
От: IT Россия linq2db.com
Дата: 19.02.09 21:13
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Стандартный алгоритмы над последовательностями в С++ живут уже больше 10 лет. И лямбды есть, тоже давно уже.


Ты лямбды с указателями на функции случайно не путаешь?
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: "LINQ как шаг к ФП". Стиль изложения.
От: Vamp Россия  
Дата: 19.02.09 21:16
Оценка: :)
IT>Ты лямбды с указателями на функции случайно не путаешь?
А как их можно спутать? Под лямбдами я имею в виду бюстовские.
Да здравствует мыло душистое и веревка пушистая.
Re[7]: "LINQ как шаг к ФП". Стиль изложения.
От: IT Россия linq2db.com
Дата: 19.02.09 21:20
Оценка:
Здравствуйте, Vamp, Вы писали:

IT>>Ты лямбды с указателями на функции случайно не путаешь?

V>А как их можно спутать? Под лямбдами я имею в виду бюстовские.

А как они реализованы в плюсах? В частности как реализован захват контекста?
Если нам не помогут, то мы тоже никого не пощадим.
Re[8]: "LINQ как шаг к ФП". Стиль изложения.
От: Vamp Россия  
Дата: 19.02.09 21:31
Оценка: :)
IT>А как они реализованы в плюсах? В частности как реализован захват контекста?
Я сам, честно говоря, не пользовался. Наверняка замыкания там как-то сделаны, но как?
Вот тут все есть:
http://www.boost.org/doc/libs/1_38_0/doc/html/lambda.html
Да здравствует мыло душистое и веревка пушистая.
Re[9]: "LINQ как шаг к ФП". Стиль изложения.
От: Qbit86 Кипр
Дата: 19.02.09 22:35
Оценка: +1
Здравствуйте, Vamp, Вы писали:

V>>>И лямбды есть, тоже давно уже.

V>Вот тут все есть:
V>http://www.boost.org/doc/libs/1_38_0/doc/html/lambda.html

Ты что, шутишь? Бустовские лямбды — это жалкое подобие никчемной пародии на нормальные лямбды.
Глаза у меня добрые, но рубашка — смирительная!
Re[8]: "LINQ как шаг к ФП". Стиль изложения.
От: CreatorCray  
Дата: 20.02.09 23:35
Оценка:
Здравствуйте, IT, Вы писали:

Да уже и C++0x подтянулся с лямбдами
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: "LINQ как шаг к ФП". Стиль изложения.
От: criosray  
Дата: 21.02.09 11:30
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Да уже и C++0x подтянулся с лямбдами


Уже есть компилляторы?
Re[10]: "LINQ как шаг к ФП". Стиль изложения.
От: CreatorCray  
Дата: 21.02.09 12:16
Оценка: 1 (1)
Здравствуйте, criosray, Вы писали:

CC>>Да уже и C++0x подтянулся с лямбдами

C>Уже есть компилляторы?
Да
GCC ICC
Поддержка фич не 100% по кол-ву, но постепенно вводятся
Например в ICC лямбды уже есть.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: "LINQ как шаг к ФП". Стиль изложения.
От: criosray  
Дата: 21.02.09 12:34
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>>>Да уже и C++0x подтянулся с лямбдами

C>>Уже есть компилляторы?
CC>Да
CC>GCC ICC
CC>Поддержка фич не 100% по кол-ву, но постепенно вводятся
CC>Например в ICC лямбды уже есть.
Судя по всему новый Intel C++ Compiler 11.0 тоже поддерживает лямба-выражения.
http://www.intel.com/cd/software/products/asmo-na/eng/compilers/clin/277618.htm
Re[10]: "LINQ как шаг к ФП". Стиль изложения.
От: nikov США http://www.linkedin.com/in/nikov
Дата: 21.02.09 15:30
Оценка:
Здравствуйте, criosray, Вы писали:

CC>>Да уже и C++0x подтянулся с лямбдами


C>Уже есть компилляторы?


Насколько я понял из демонстрации на презентации, компилятор из Microsoft Visual Studio 2010 Beta их поддерживает.
Re[9]: "LINQ как шаг к ФП". Стиль изложения.
От: IT Россия linq2db.com
Дата: 21.02.09 17:55
Оценка:
Здравствуйте, Vamp, Вы писали:

IT>>А как они реализованы в плюсах? В частности как реализован захват контекста?

V>Я сам, честно говоря, не пользовался. Наверняка замыкания там как-то сделаны, но как?

Не увидел ни одного. Да это и не удивительно. Без GC такие вещи не делаются. А без замыканий лямбды — это пародия, что мы и наблюдаем в бусте.
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: "LINQ как шаг к ФП". Стиль изложения.
От: IT Россия linq2db.com
Дата: 21.02.09 17:55
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Да уже и C++0x подтянулся с лямбдами


А как в нём реализован захват контекста?
Если нам не помогут, то мы тоже никого не пощадим.
Re[10]: "LINQ как шаг к ФП". Стиль изложения.
От: VoidEx  
Дата: 21.02.09 18:07
Оценка:
Здравствуйте, IT, Вы писали:

IT>Не увидел ни одного. Да это и не удивительно. Без GC такие вещи не делаются. А без замыканий лямбды — это пародия, что мы и наблюдаем в бусте.


Замыкания там делаются ручками. Хочешь — копируй, хочешь — ссылку, хочешь — хоть shared_ptr, хочешь — весь стек. В общем, в стиле Си++.
Называть это полноценными лямбдами, конечно, нельзя. Но double = power 2 написать можно.
И уж гораздо удобнее, чем структурки временные воротить, чтобы в for_each передать.
Кстати.
Можно даже
function<int (int)> fact = [&fact] (int n) { if (n == 0) return 1; return n * fact(n - 1); }

Re[12]: "LINQ как шаг к ФП". Стиль изложения.
От: CreatorCray  
Дата: 21.02.09 21:44
Оценка:
Здравствуйте, criosray, Вы писали:

CC>>Например в ICC лямбды уже есть.

C>Судя по всему новый Intel C++ Compiler 11.0 тоже поддерживает лямба-выражения.
C>http://www.intel.com/cd/software/products/asmo-na/eng/compilers/clin/277618.htm
Так про него и речь.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: "LINQ как шаг к ФП". Стиль изложения.
От: CreatorCray  
Дата: 21.02.09 21:44
Оценка:
Здравствуйте, IT, Вы писали:

IT>А как в нём реализован захват контекста?


Из документации к ICC 11.0

Understanding Lambda-Capture
A lambda expression can refer to identifiers declared outside the lambda expression. If the identifier is a local variable or a reference with automatic storage duration, it is an up-level reference and must be "captured" by the lambda expression. Such a lambda expression must be introduced by [lambda-captureopt], where lambda-captureopt specifies whether identifiers are captured by reference or by copy. The table below summarizes forms of lambda-captureopt.

Symbol
Indicates

[]
Nothing to capture: an up-level reference is an error

[&x, y, ...]
Capture as specified: identifiers prefixed by & are captured by reference; other identifiers are captured by copy. An up-level reference to any variable not explicitly listed is an error

[&]
Capture by reference: an up-level reference implicitly captures the variable by reference

[=]
Capture by copy: an up-level reference implicitly captures the variable by copy

[&, x, y, ...]
Capture by reference with exceptions: listed variables are captured by value/copy (no listed variable may be prefixed by &)

[=, &x, &y, ...]
Capture by copy with exceptions: listed variables are captured by reference only (every listed variable must be prefixed by &)


No identifier may appear twice in the list. In the following code that sets area to the sum of the areas of four circles, the notation [&area,pi] specifies that area is captured by reference and pi by copy.

float radius[] = {2,3,5,7};
float area=0;
float pi = 3.14f;
for_each(radius, radius+4, [&area,pi](float r) {
    return area+=pi*r*r;)
}


Specifying Default Capture
When a default capture is specified, the list must specify only the other kind of capture. In other words, if you specify that the default capture is by reference, then you must list (and only list) the variables that should be captured by copy. For example, if your intent is to capture x by reference and y by copy, and both x and y appear in the function body, the following code illustrates what is correct and incorrect code:

[&,&x,y] // ERROR - default is capture-by-reference; you must list only capture by copy
[&,y]  // CORRECT
[=,&x,y]  // ERROR - default is capture-by-copy; you must list only capture by reference
[=,&x]  // CORRECT - default capture is by copy and so you must list x to be captured by reference
[&x]   // ERROR - since there is no default capture, you must list y
[y]    // ERROR - again no default capture is specified, so you must list &x
[&x,y]   // CORRECT - since no default is specified, every variable is listed with its capture mode.


Default Binding Modes
The following lambda expressions demonstrate default binding modes. All three expressions are semantically equivalent. Each captures x and y by reference, and captures a and b by copy.

[&x,&y,a,b](float r) {x=a; y=b;}
[&,a,b](float r) {x=a; y=b;}
[=,&x,&y](float r) {x=a; y=b;}


Referring to this
If a lambda expression occurs inside a member function, it can refer to this. Because this is not a variable, it cannot be captured by reference. Even when it is captured implicitly in a lambda expression introduced by [&], it is captured by copy.

Formal Grammar for Lambda Expressions in "Lambda Expressions and Closures: Wording for Monomorphic Lambdas (Revision 4)" available at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/N2550.pdf

... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.