Помогите чайнику понять пример из функицонального программирования
Уважаемое сообщество, вынужден обратиться к вам за помощью, прошу не судить строго, изучаю Python. В начале раздела по ООП, есть небольшая глава про функциональное программирование. Как всегда, весь код который подается набираю в PyCharm. Вот собственно что меня заинтересовало:
С первой функцией мне все понятно. А вот при попытке вывести функцию со второго примера:
def increment(a):
return a + 1
increment(a)
получаю сообщение с ошибкой что переменная а не определена. В связи с этим первый вопрос: где определять переменную, если по определению в функциональном программировании функция не пологается на данные за ее пределами и не изменяет их? А в этом примере я не вижу что бы данные определялись внутри функции.
Второй вопрос возник после изучения и тестирования все той же функции:
почему данный код:
def increment(a):
return a + 1
print(a)
increment(1)
ничего не выводит(даже ошибки), у нас же есть инструкция print...
а код:
def increment(a):
return a + 1
print(increment(1))
выведет значение (что вообщем-то верно).
Ответы (4 шт):
def increment(a):
return a + 1
increment(a)
вы вызываете метод в глобальном окружении в котором не определенна переменная "a" и при этом вы пытаетесь ее передать, определите ее до вызова метода
def increment(a):
return a + 1
print(a)
increment(1)
return вызывает выход из метода, поэтому функция print не вызывается
def increment(a):
return a + 1
print(increment(1))
все верно потому что вы возвращаете результат функции из метода в метод Print
UPD для первого вариант вот так можно определить переменную
a = 7
def increment(a):
return a + 1
increment(a)
или вот так
def increment(a):
return a + 1
a = 7
increment(a)
главное чтобы она была в той же области видимости и до вызова функции
Вот так определить переменную:
def increment(a):
return a + 1
a = 1
print(f"До использования функции а={a}")
a = increment(a)
print(f"После использования функции а={a}")
А здесь у вас ошибка:
def increment(a):
return a + 1
print(a)
Нужно print(a) поставить над return - поскольку по сути это команда завершает выполнение функции и функция print уже не выполняется (из-за отступов, которые заменяют форматирование скобками в других языках):
def increment(a):
result = a + 1
print(result)
return result
UPD. У вас на листинге из книги в вопросе, кстати, в первом случае объявлена переменная а=0 до функции, и передается она в функцию не через аргументы, а через global, а во втором случае уже как аргумент.
По второму вопросу:
Переменную можно нигде не определять.
Если в языке есть поддержка хвостовой рекурсии (в python в коробке нет), то будет работать такой динамичный мир:
def world_iteration(a,b):
will_a = increment(a)
will_b = increment(b)
world_iteration(will_a,will_b)
world_iteration(0,0)
где определять переменную
Именно переменную, в том смысле, который вкладывают в это слово императивные языки – желательно нигде.
В терминах функционального программирования, переменная это имя, которое может быть связано с произвольным значением, но не может быть переназначено в рамках одного вычисления. Т.е. имеется в виду переменная величина в математическом смысле.
t = 3x
это типичное действие в математике, а
x = x + 1
нонсенс, так как
x - x = 1
0 = 1
А функциональное программирование построено на математических законах.
В python нет явного механизма, запрещающего переопределение переменных, это на совести программиста. Если он не переназначает переменные и не меняет их содержимое иным способом, то это никак не противоречат принципами функционального программирования, и такие переменные нужны и даже необходимы.
по определению в функциональном программировании функция не полагается на данные за ее пределами и не изменяет их
Чистая функция не полагается на внешние изменяемые данные и не изменяет их сама, это так. Но никто не мешает ей обращаться к внешним неизменяемым данным, например:
def circumference(r):
return 2 * math.pi * r
Эта функция чистая, опять же с оговоркой, если кто-нибудь захочет переназначить значение math.pi, язык этому никак не воспрепятствует, он подразумевает, что пользователю хватит здравомыслия не делать этого.
И даже в следующем примере обе функции f и g – чистые
def f(x):
def g(y):
return 2 * x + 3 * y
return g(1) * g(2)
Хотя g и полагается на внешний параметр x, в рамках вычисления значения f(x) он неизменен, и g для разных значений x это разные функции, а не одна и та же функция, дающая разные результаты.
