[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: kylix 2





Dmitry Astapov wrote:

Нет. В С нельзя создать и вернуть функцию как результат. Пример:

makeAdder x = map (+x)

makeAdder имеет тип:
forall a. (Num a) => a -> ([a] -> [a])
, т.е. (makeAdder 5) вернет функцию, которая принимает в качестве аргумента
список чисел, увеличивает каждое из них на 5, и возвращает в качестве
результата.

другой пример:
overloadFunctionAtSpecificPoint function point value =
  (\x -> if x == point then value else function(point))
Ее тип:
forall t a. (Eq a) => (a -> t) -> a -> t -> (a -> t)

Для данной функции function от одного аргумента (над которым определена
операция ==) возвращает новую функцию, значение которой совпадает со старой
во всех точках, кроме точки "point". В точке "point" новая функция имеет
значение "value". Пример:

Prelude> let overloadFunctionAtSpecificPoint function point value =
> 	(\x -> if x == point then value else function(point))
Prelude> let fun x = x+2
Prelude> fun 5
7
Prelude> let fun2 = overloadFunctionAtSpecificPoint fun 5 11
Prelude> fun2 5
11
Prelude> fun2 3
7

В c/c++ так сделать нельзя.


То есть, другими словами, Haskel позволяет перегружать функции таким вот странным (для человека, ранее кроме как с С, С++, Паскаль, Питон и пр. ни с чем больше не встречавшегося) образом. Сложно для понимания, по крайней мере сначала.

Аналогичный код на С:

#include <stdio.h>

#define POINT_V 64
#define VALUE_V 129

int function(int x, int (*what_to_do)(int pnt), int point, int value);
int function2(int x);

int main(int argc, char argv[]){

    printf("function2 does: VALUE_V + 365; VALUE is: 129\n");
printf("Function returned on x == POINT_V: %i\n", function(POINT_V, &function2, POINT_V, VALUE_V)); printf("Function returned on x != POINT_V: %i\n", function(POINT_V+34, &function2, POINT_V, VALUE_V));

    return 0;
}

int function(int x, int (*what_to_do)(), int point, int value){

    if(x == point){
	return value;
    } else {
	return (*what_to_do)(point);
    }	

}

int function2(int x){

    return VALUE_V + 365;

}

Разницу я только вижу в гибкости кода и его просте. Думаю, на ассемблере это выглядело бы еще сложнее... ;-)

Но этот код говорит о том, что все же совсем необязательно функции возвращать другую функцию. Можно вернуть ее возращаемое значение.

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


AS> functional programming
AS> This style of programming proceeds by computing new values from
AS> existing values without changing any of the existing values.
AS> imperative programming
AS> This style of programming proceeds by altering values stored in variables.
AS> Т.е. функциональное программирование - это вычисление новых
значений
AS> без изменения существующих переменных, императивное - посредством
Я бы сказал, что у чисто функциональных языков остуствует понятие
"переменной" вообще. Это было бы точнее.


 AS> А есть такие чисто функциональные языки?

Есть. Называются Haskell, Clean. Наверняка есть и другие.

Все примеры, которые я приводил до сих пор - на Haskell.

AS> Кстати, не свзяано ли это с понятием "чисто функции" (pure function)? AS> (Чтобы тут потом тоже не придумывать несуществующие связи)
pure abstract method из C++? Нет, совсем не связано.

Нет, именно "pure function". Объясняется как "функция, вычисляющая свое значение исключительно на основе данных аргументов", то есть гарантирующая один и тот же ответ при одних и тех же значениях аргументов при выполнении в разное время. Прочитал в одном из глоссариев (нашел в Гугле), там же где и про императивное и функциональное программирование.

--
Andrei Sosnin
http://zzx.ath.cx

 <!-- : it all depends on your vision : -->



Reply to: