Форум программистов, компьютерный форум, киберфорум
Lisp
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
91 / 58 / 8
Регистрация: 09.11.2011
Сообщений: 443
1

Функции высшего порядка

13.10.2014, 16:20. Просмотров 2092. Ответов 22
Метки нет (Все метки)

Читаю книгу
Lisp
1
2
3
4
(defun plot (fn min max step)
  (loop for i from min to max by step do
        (loop repeat (funcall fn i) do (format t "*"))
        (format t "~%")))
Что происходит, не могу понять?
Где тут тело функции fn и plot?
И растолкуйте, как это работает.

Добавлено через 4 минуты
а кажется тела функции FN нету в этом примере, его нужно передавать, как
Lisp
1
(plot #'exp 0 4 1/2)
но все равно, небольшие пояснения не помешают, может другими словами

Добавлено через 8 минут
Lisp
1
(format t "~%")
Это -то зачем тут?
2
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.10.2014, 16:20
Ответы с готовыми решениями:

Функции высшего порядка
Помогите пожалуйста решить задачу!!!

функции высшего порядка
Здравствуйте,срочно нужна ваша помощь т.к с ф-ями высшего порядка вообще не дружу((( Необходимо...

Функции высшего порядка
При решение не линейных уравнений вида f(x)=0, где f(x)-функция, не прерывная на интервале ,...

функции высшего порядка
Для определения равномерной сходимости функциональной последовательности {f}_{1}(x),{f}_{2}(x),......

__________________
22
Модератор
Эксперт Python
28529 / 15399 / 3043
Регистрация: 12.02.2012
Сообщений: 25,230
Записей в блоге: 4
13.10.2014, 16:25 2
На глаз - это табулирование функции построение гисторгаммы fn в пределах от min до max c шагом step. fn - функциональный параметр plot. На месте этого параметра может быть имя функции или безымянная функция:

Lisp
1
(plot #'(lambda (x) (* x x)) 0 10 0.1) ;; табулировать y=x^2 от 0 до 10 с шагом 0.1
1
91 / 58 / 8
Регистрация: 09.11.2011
Сообщений: 443
13.10.2014, 16:27  [ТС] 3
а как переделать пример выше с использованием APPLY?
Про безымянные я потом еще почитаю
0
Модератор
Эксперт Python
28529 / 15399 / 3043
Регистрация: 12.02.2012
Сообщений: 25,230
Записей в блоге: 4
13.10.2014, 16:30 4
Lisp
1
2
3
4
5
6
7
CL-USER 3 > (plot #'(lambda (x) (* x x)) 0 5 1)
 
*
****
*********
****************
*************************
Цитата Сообщение от Cheb Посмотреть сообщение
Это -то зачем тут?
- полагаю, это переход на новую строку.

Добавлено через 1 минуту
Цитата Сообщение от Cheb Посмотреть сообщение
а как переделать пример выше с использованием APPLY?
:

Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CL-USER 4 > (defun plot (fn min max step)
  (loop for i from min to max by step do
        (loop repeat (apply fn (list i)) do (format t "*"))
        (format t "~%")))
PLOT
 
CL-USER 5 > (plot #'(lambda (x) (* x x)) 0 5 1)
 
*
****
*********
****************
*************************
NIL
1
4343 / 3350 / 342
Регистрация: 12.03.2013
Сообщений: 5,838
13.10.2014, 16:35 5
"Тело"? Ну, defun plot - это объявление функции plot. А fn - это функция, которую надо передавать в качестве аргумента. Передавать надо не "тело", а саму функцию как она есть. Функции суть граждане первого класса, поэтому их можно хранить в переменных, передавать в качестве аргументов и получать в качестве значений, это всё просто.

Единственная заковыка - в funcall-е и в #'. Это из-за отдельного пространства имён для функций. Отдельное пространство не ущемляет их прав как граждан, но сказывается на обозначениях и затрудняет функциональное программирование. Упирается в правило вычисления списков. Программа же состоит из списков, и эти списки вычисляются. По умолчанию для первого символа в списке берётся значение из "функциональной ячейки", а для остальных - из "переменной ячейки".

Внутри функции plot переменная fn держит в себе функцию - в "переменной ячейке", потому что переменная. Поэтому мы не можем написать (fn i), потому что такая запись подразумевает, что мы хотим выковыривать функцию из "функциональной ячейки". Чтобы всё-таки можно было вызывать функции-значения переменных, существует funcall.

#'exp - это из-за того же, но в другом контексте. exp содержит показательную функцию в функциональной ячейке, чтобы можно было писать (exp (* pi #c(0 1))). Если же мы хотим использовать эту функцию не на первом месте списка, а в любых каких угодно целях, её можно вынуть из "функциональной ячейки" с помощью #'.

"Тело" функции никуда не надо передавать, надо саму функцию передавать.

Добавлено через 1 минуту
Цитата Сообщение от Cheb Посмотреть сообщение
Это -то зачем тут?
Чтобы строку переводить. На самом деле надо было написать (terpri). А вообще, наверно, можно было бы всю функцию внутрь одного format-а засунуть.

Добавлено через 2 минуты
Цитата Сообщение от Cheb Посмотреть сообщение
а как переделать пример выше с использованием APPLY?
А зачем? apply - это для применения функции к списку аргументов. Если списка аргументов нет, apply не нужен.

Цитата Сообщение от Cheb Посмотреть сообщение
Про безымянные я потом еще почитаю
Безымянная функция - это то же самое, что безымянное число. Чтобы использовать число 5, необязательно же его записывать в переменную?
2
Модератор
Эксперт Python
28529 / 15399 / 3043
Регистрация: 12.02.2012
Сообщений: 25,230
Записей в блоге: 4
13.10.2014, 16:35 6
Цитата Сообщение от helter Посмотреть сообщение
Если же мы хотим использовать эту функцию не на первом месте списка, а в любых каких угодно целях, её можно вынуть из "функциональной ячейки" с помощью #'.
- мне эта фраза представляется не очень удачной. Получается, что, употребляя exp вот в такой конструкции - (+ 5 exp), мы "оставляем ее в функциональной ячейке"...
0
4343 / 3350 / 342
Регистрация: 12.03.2013
Сообщений: 5,838
13.10.2014, 16:38 7
Цитата Сообщение от Catstail Посмотреть сообщение
Получается, что употребляя exp вот в такой конструкции (+ 5 exp) мы "оставляем ее в функциональной ячейке"...
Я говорил про использование самой функции. В конструкции (+ 5 exp) участвует символ exp в качестве переменной, но экспоненциальная функция в вычисление не вовлечена.
0
91 / 58 / 8
Регистрация: 09.11.2011
Сообщений: 443
13.10.2014, 16:43  [ТС] 8
Цитата Сообщение от Catstail Посмотреть сообщение
CL-USER 4 > (defun plot (fn min max step)
* (loop for i from min to max by step do
* * * * (loop repeat (apply fn (list i)) do (format t "*"))
* * * * (format t "~%")))
PLOT
CL-USER 5 > (plot #'(lambda (x) (* x x)) 0 5 1)
нет что бы так вызвать (без лямбды пока)
(apply #'plot #'exp.......

Добавлено через 1 минуту
вообщем это все важно и надо переварить...

Добавлено через 1 минуту
Цитата Сообщение от helter Посмотреть сообщение
А зачем? apply - это для применения функции к списку аргументов. Если списка аргументов нет, apply не нужен.
пытаюсь понять пример в учебнике и просто научиться пользоваться

Добавлено через 1 минуту
Цитата Сообщение от helter Посмотреть сообщение
Безымянная функция - это то же самое, что безымянное число
да это понятно, такое и в других языках тоже есть.
0
4343 / 3350 / 342
Регистрация: 12.03.2013
Сообщений: 5,838
13.10.2014, 16:56 9
Цитата Сообщение от Cheb Посмотреть сообщение
нет что бы так вызвать (без лямбды пока)
(apply #'plot #'exp.......
apply - чтобы применять к списку. (apply #'plot (list #'exp ...)), если в этом есть какой-то смысл.

Цитата Сообщение от Cheb Посмотреть сообщение
да это понятно, такое и в других языках тоже есть.
Ага, я о том же.
0
Модератор
Эксперт Python
28529 / 15399 / 3043
Регистрация: 12.02.2012
Сообщений: 25,230
Записей в блоге: 4
13.10.2014, 17:26 10
Цитата Сообщение от Cheb Посмотреть сообщение
нет что бы так вызвать (без лямбды пока)
(apply #'plot #'exp.......
- а зачем здесь apply? Лишний бантик. Вызывайте так: (plot #'exp ...)
0
91 / 58 / 8
Регистрация: 09.11.2011
Сообщений: 443
13.10.2014, 17:57  [ТС] 11
Цитата Сообщение от Catstail Посмотреть сообщение
- а зачем здесь apply? Лишний бантик. Вызывайте так: (plot #'exp ...)
да, я пример пытаюсь понять в книжке

Добавлено через 16 секунд
как apply пользоваться
0
Модератор
Эксперт Python
28529 / 15399 / 3043
Регистрация: 12.02.2012
Сообщений: 25,230
Записей в блоге: 4
13.10.2014, 18:09 12
Apply использовать просто:

Lisp
1
(apply Функция список_аргументов)
Вот когда это нужно и полезно? Например, когда список аргументов уже сформирован. Пример - вычислить сумму элементов произвольного одноуровнего числового списка. Можно рекурсией или итерацией... А можно просто:

Lisp
1
(defun sum-list (lst) (apply '+ lst))
Правда, у apply (по имеющимся сведениям) есть ограничение на размер списка. Для больших списков пример может завершиться аварийно.

Функция apply играет фундаментальную роль в ядре классического Лиспа (см., например, в финском двухтомнике "Лисп на Лиспе")
2
helter
13.10.2014, 18:17
  #13

Не по теме:


Цитата Сообщение от Catstail Посмотреть сообщение
Вот когда это нужно и полезно? Например, когда список аргументов уже сформирован. Пример - вычислить сумму элементов произвольного одноуровнего числового списка. Можно рекурсией или итерацией... А можно просто:
Lisp
1
(defun sum-list (lst) (apply '+ lst))
Правда, у apply (по имеющимся сведениям) есть ограничение на размер списка.
На всякий случай напомню, что для переносимого года это ограничение составляет 50 элементов.

0
91 / 58 / 8
Регистрация: 09.11.2011
Сообщений: 443
15.10.2014, 16:40  [ТС] 14
Цитата Сообщение от helter Посмотреть сообщение
Правда, у apply (по имеющимся сведениям) есть ограничение на размер списк
это ограничение можно узнать используя константу CALL-ARGUMENTS-LIMIT
А как её посмотреть? Или может поменять (хотя константа же)

Что бы разобраться с FUNCALL написал тестовый пример
Кликните здесь для просмотра всего текста
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
(format t "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++~%")
(format t "++++++ ПРОГРАММА демонстрирует пример работы с оператором FUNCALL ++++++~%")
(format t "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++~%")
 
;;; опредеоим несколько простых функций
;;определим функцию умножения
(defun умножение (x1 x2)
    (format t "Умножение чисел ~a и ~a = " x1 x2)
    (* x1 x2))
 
;;определим функцию сложения
(defun сумма (x1 x2)
    (format t "Сумма чисел ~a и ~a = " x1 x2)
    (+ x1 x2))
 
;;определим функцию деления
(defun деление (x1 x2)
    (format t "Деление чисел ~a и ~a = " x1 x2)
    (/ x1 x2))
 
;;определим функцию вычитания
(defun разность (x1 x2)
    (format t "Разность чисел ~a и ~a = " x1 x2)
    (- x1 x2))
 
;;опишем главную функцию вызова
(defun глав-fn (fn a b)
    (format t "~a~%" (funcall fn a b)))
 
;;начало программы
(глав-fn #'умножение 2 9)
(глав-fn #'сумма 2 9)
(глав-fn #'разность 2 9)
(глав-fn #'деление 2 9)


Ха ! можно писать по-русски, даже часть слова. Эдак "ОдинЭС" можно в вебе заварганить для бухов
0
Модератор
Эксперт Python
28529 / 15399 / 3043
Регистрация: 12.02.2012
Сообщений: 25,230
Записей в блоге: 4
15.10.2014, 16:49 15
Цитата Сообщение от Cheb Посмотреть сообщение
А как её посмотреть?
- очень просто:

Lisp
1
2
CL-USER 1 > CALL-ARGUMENTS-LIMIT
2047
0
91 / 58 / 8
Регистрация: 09.11.2011
Сообщений: 443
15.10.2014, 17:07  [ТС] 16
у меня
Lisp
1
2
3
4
  
* CALL-ARGUMENTS-LIMIT
 
4611686018427387903
0
4343 / 3350 / 342
Регистрация: 12.03.2013
Сообщений: 5,838
15.10.2014, 17:28 17
Цитата Сообщение от Cheb Посмотреть сообщение
у меня
В разных реализациях - по-разному. Не зависит от реализации только минимум - 50.

Добавлено через 2 минуты
Цитата Сообщение от Cheb Посмотреть сообщение
Ха ! можно писать по-русски, даже часть слова. Эдак "ОдинЭС" можно в вебе заварганить для бухов
Ну на самом деле это тоже от реализации зависит. (На самом деле даже соответствие символ<->числовой код зависит от реализации. Хотя понятно, что зрелые, так сказать, реализации, достаточно хорошо владеют юникодом.)

Добавлено через 5 минут
Цитата Сообщение от Cheb Посмотреть сообщение
тестовый пример
Гм, "левая" строка выводится, а результат - нет.
Lisp
1
(умножение (сумма 2 2) 2)
будет странно выглядеть.
0
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,354
16.10.2014, 02:12 18
Цитата Сообщение от helter Посмотреть сообщение
Гм, "левая" строка выводится, а результат - нет.
Тут гельтер намекает, что лучше оформить так
Lisp
1
2
(defun глав-fn (fn a b)
  (funcall fn a b))
То же касается и всех остальных функций.

Добавлено через 8 минут
lw
Lisp
1
2
3
4
5
CL-USER 2 > (умножение (сумма 3 4) 4)
Сумма чисел 3 и 4 = Умножение чисел 7 и 4 = 
28
 
CL-USER 3 >
0
4493 / 4203 / 354
Регистрация: 12.05.2012
Сообщений: 2,959
16.10.2014, 08:09 19
как вариант:

Функция apply применяет функцию к одному и более аргументу, последним из которых должен быть список:
Lisp
1
2
3
4
> (apply #'* '(8 9 10))        
720
> (apply #'* 8 9 '(10))
720
Функция funcall вызывает функцию с аргументами:
Lisp
1
2
> (funcall #'* 8 9 10)
720
Добавлено через 5 минут
в CLISP до 4096 элементов:
Lisp
1
2
3
4
> (apply #'min '(7 4 6 4 5))
4
> call-arguments-limit
4096
можно заменить на reduce:
Lisp
1
2
> (reduce #'max '(7 4 6 4 5))
7
2
91 / 58 / 8
Регистрация: 09.11.2011
Сообщений: 443
16.10.2014, 16:18  [ТС] 20
Цитата Сообщение от _sg Посмотреть сообщение
(apply #'min '(7 4 6 4 5))
Э, зачем ты, уважаемый, вот эту ' (апостроф) поставил? я вчера целый вечер из-за неё мучился

вот так с apply у меня заработало.
Lisp
1
(format t "~a" (apply #'сумма a)) )
вот полный код
Кликните здесь для просмотра всего текста

Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
;;определим функцию умножения
(defun умножение (x1 x2)
    (format t "Умножение чисел ~a и ~a = " x1 x2)
    (* x1 x2))
 
;;определим функцию сложения
(defun сумма (x1 x2)
    (format t "Сумма чисел ~a и ~a = " x1 x2)
    (+ x1 x2))
 
;;определим функцию деления
(defun деление (x1 x2)
    (format t "Деление чисел ~a и ~a = " x1 x2)
    (/ x1 x2))
 
;;определим функцию вычитания
(defun разность (x1 x2)
    (format t "Разность чисел ~a и ~a = " x1 x2)
    (- x1 x2))
 
;;опишем главную функцию вызова
(defun foo (a) 
(format t "~a" (apply #'сумма a)) )
 
(foo '(3 4))


в этих черточках совсем запутался! и еще #', я думал это одно и тоже что funcall
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.10.2014, 16:18

Заказываю контрольные, курсовые, дипломные работы и диссертации здесь.

Функции высшего порядка
Дана такая задача...помогите...

Рекурсивные функции, функции высшего порядка, преобразование императивных программ в функциональные
Простые рекурсивные функции для обработки списков: А) (ATOM-LIST x) проверяет, является ли х ...

Определить функции высшего порядка
1.Даны списки x и y. В списке y все элементы различные. Определить функцию высшего порядка (rep f y...

Тема: функции высшего порядка (apply, funcall, mapcar, maplist)
(Common Lisp) Даны два списка x и y. Список y является упорядоченным по некоторому правилу....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.