У мене вправа в Python наступна:
поліном задається у вигляді множини коефіцієнтів, таким чином, що потужність визначається за показниками, наприклад: (9,7,5) означає 9 + 7 * x + 5 * x ^ 2
написати функцію для обчислення її значення для заданого x
Оскільки я останнім часом займаюся функціональним програмуванням, я писав
def evaluate1(poly, x):
coeff = 0
power = 1
return reduce(lambda accu,pair : accu + pair[coeff] * x**pair[power],
map(lambda x,y:(x,y), poly, range(len(poly))),
0)
що я вважаю нечитабельним, тому написав
def evaluate2(poly, x):
power = 0
result = 1
return reduce(lambda accu,coeff : (accu[power]+1, accu[result] + coeff * x**accu[power]),
poly,
(0,0)
)[result]
що принаймні як нечитабельне, так я написав
def evaluate3(poly, x):
return poly[0]+x*evaluate(poly[1:],x) if len(poly)>0 else 0
що може бути менш ефективним (редагувати: я помилявся!), оскільки він використовує безліч множень замість експоненції, в принципі мені тут не байдуже вимірювання (редагувати: Як глупо! все ще не настільки читабельні (можливо), як ітераційне рішення:
def evaluate4(poly, x):
result = 0
for i in range(0,len(poly)):
result += poly[i] * x**i
return result
Чи є чисте функціональне рішення таке читабельне, як імперативне і близьке до нього за ефективністю?
Щоправда, зміна представництва допоможе, але це було надано вправою.
Це може бути Хаскелл або Лісп, а не лише Пітон.
lambda
, порівняно з мовами з легшою функцією анонімного синтаксису. Частина цього, ймовірно, сприяє "нечистому" вигляду.
for
циклів) є поганою метою, на яку слід прагнути в Python. Повторне зв’язування змінних з розумним та не мутуючим об'єктом дає вам майже всі переваги та робить код нескінченно більш читабельним. Оскільки об'єкти чисел незмінні і він лише відновлює дві локальні назви, ваше "імперативне" рішення краще реалізує функціональні чесноти програмування, ніж будь-який "суворо чистий" код Python.