Jde nějak napsat v Pythonu a C++ rekurzivní anonymní funkce? Mám například [1, 2, 3, 4, 5].fmap(fact) pro faktoriál, ale místo zvlášť definované funkce fact chci mít jako argument fmapu jen lambda výraz. V podstatě něco jako Recall v R, ale to zjevně Python nemá a C++ už vůbec ne.
fact = lambda x: C
nebo
def fun(x):
return 1 if x == 0 else x * fact(x-1)
map(fun, [1, 2, 3, 4])
Ten první způsob se neuložil celý, zde je kompletní
fact = lambda x: 1 if x == 0 else x * fact(x-1)
A ten druhý je taky blbě, nyní správně
def fact(x):
return 1 if x == 0 else x * fact(x-1)
map(fact, [1, 2, 3, 4])
Citace od: Ivan Nový kdy 17. 08. 2018, 07:38:23
A ten druhý je taky blbě, nyní správně
def fact(x):
return 1 if x == 0 else x * fact(x-1)
map(fact, [1, 2, 3, 4])
To není anonymní, otázka zněla, jak dát ten lambda výraz přímo do volání mapu jako parametr.
Mozne to je, ale nevim, zda tohle zrovna v Pythonu chces delat
https://stackoverflow.com/questions/481692/can-a-lambda-function-call-itself-recursively-in-python
Citace od: DK kdy 17. 08. 2018, 09:42:11
Mozne to je, ale nevim, zda tohle zrovna v Pythonu chces delat
https://stackoverflow.com/questions/481692/can-a-lambda-function-call-itself-recursively-in-python
To Y jde taky udělat jako callable. V tom C++ jako funktor (ve dvou ze tři smyslů tohoto slova).
Citace od: Trader kdy 17. 08. 2018, 09:37:07
Citace od: Ivan Nový kdy 17. 08. 2018, 07:38:23
A ten druhý je taky blbě, nyní správně
def fact(x):
return 1 if x == 0 else x * fact(x-1)
map(fact, [1, 2, 3, 4])
To není anonymní, otázka zněla, jak dát ten lambda výraz přímo do volání mapu jako parametr.
To je zvěrstvo, nepythonické :-) Lambdy nepoužívat. V Pythonu by se mělo programovat pythonicky, to hlavní výhoda Pythonu, vlastní odlišná filosofie, a ne erovsky. Navíc rekurzi raději obcházet.
Citace od: Ivan Nový kdy 17. 08. 2018, 10:15:20
Citace od: Trader kdy 17. 08. 2018, 09:37:07
Citace od: Ivan Nový kdy 17. 08. 2018, 07:38:23
A ten druhý je taky blbě, nyní správně
def fact(x):
return 1 if x == 0 else x * fact(x-1)
map(fact, [1, 2, 3, 4])
To není anonymní, otázka zněla, jak dát ten lambda výraz přímo do volání mapu jako parametr.
To je zvěrstvo, nepythonické :-) Lambdy nepoužívat. V Pythonu by se mělo programovat pythonicky, to hlavní výhoda Pythonu, vlastní odlišná filosofie, a ne erovsky. Navíc rekurzi raději obcházet.
To je otázka na samodružný bod funkce vyššího řádu. V dynamickém jazyce to je vskutku zvěrstvo. Ale v tom C++ to už smysl má. Co je "erovsky"?
Citace od: RecursiveFarts kdy 17. 08. 2018, 01:47:51
... a C++ už vůbec ne.
Ale dá se.
constexpr auto fact = [](unsigned int i) {
constexpr auto recursive = [](unsigned int i, auto &self) -> unsigned int {
return i ? i * self(i - 1, self) : 1;
};
return recursive(i, recursive);
};
static_assert(fact(3) == 6);
static_assert(fact(4) == 24);
Citace od: Bacsa kdy 17. 08. 2018, 11:21:30
Co je "erovsky"?
IMHO myslí způsob programování typický pro jazyk R
Citace od: Kojot kdy 17. 08. 2018, 11:57:30
Citace od: RecursiveFarts kdy 17. 08. 2018, 01:47:51
... a C++ už vůbec ne.
Ale dá se.
constexpr auto fact = [](unsigned int i) {
constexpr auto recursive = [](unsigned int i, auto &self) -> unsigned int {
return i ? i * self(i - 1, self) : 1;
};
return recursive(i, recursive);
};
static_assert(fact(3) == 6);
static_assert(fact(4) == 24);
Ano, dá se, ale jinak, tohle není anonymní. Jak to bude bez použití "recursive"?
Citace od: Bacsa kdy 17. 08. 2018, 12:43:43
Citace od: Kojot kdy 17. 08. 2018, 11:57:30
Citace od: RecursiveFarts kdy 17. 08. 2018, 01:47:51
... a C++ už vůbec ne.
Ale dá se.
constexpr auto fact = [](unsigned int i) {
constexpr auto recursive = [](unsigned int i, auto &self) -> unsigned int {
return i ? i * self(i - 1, self) : 1;
};
return recursive(i, recursive);
};
static_assert(fact(3) == 6);
static_assert(fact(4) == 24);
Ano, dá se, ale jinak, tohle není anonymní. Jak to bude bez použití "recursive"?
Dobře, tak anonymně a bez použití recursive ;D.
static_assert([](unsigned int i) {
constexpr auto not_recursive = [](unsigned int i, auto &self) -> unsigned int {
return i ? i * self(i - 1, self) : 1;
};
return not_recursive(i, not_recursive);
}(3) == 6);
Citace od: Kojot kdy 17. 08. 2018, 13:19:18
Citace od: Bacsa kdy 17. 08. 2018, 12:43:43
Citace od: Kojot kdy 17. 08. 2018, 11:57:30
Citace od: RecursiveFarts kdy 17. 08. 2018, 01:47:51
... a C++ už vůbec ne.
Ale dá se.
constexpr auto fact = [](unsigned int i) {
constexpr auto recursive = [](unsigned int i, auto &self) -> unsigned int {
return i ? i * self(i - 1, self) : 1;
};
return recursive(i, recursive);
};
static_assert(fact(3) == 6);
static_assert(fact(4) == 24);
Ano, dá se, ale jinak, tohle není anonymní. Jak to bude bez použití "recursive"?
Dobře, tak anonymně a bez použití recursive ;D.
static_assert([](unsigned int i) {
constexpr auto not_recursive = [](unsigned int i, auto &self) -> unsigned int {
return i ? i * self(i - 1, self) : 1;
};
return not_recursive(i, not_recursive);
}(3) == 6);
Furt blbě.
Citace od: Bacsa kdy 17. 08. 2018, 13:22:17
Furt blbě.
Je lepší psát k tématu, a ne jak se cítíš ;D.
Citace od: Kojot kdy 17. 08. 2018, 13:33:09
Je lepší psát k tématu
Tak to dělej, někdo chce anonymní funkci a ty píšeš kód mimo mísu.
Citace od: Bacsa kdy 17. 08. 2018, 13:53:44
Citace od: Kojot kdy 17. 08. 2018, 13:33:09
Je lepší psát k tématu
Tak to dělej, někdo chce anonymní funkci a ty píšeš kód mimo mísu.
Vždyť je anonymní. To spíš mimo mísu jsi ty ;).
možná tohle http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0200r0.html ?
Citace od: Kojot kdy 17. 08. 2018, 14:03:25
Citace od: Bacsa kdy 17. 08. 2018, 13:53:44
Citace od: Kojot kdy 17. 08. 2018, 13:33:09
Je lepší psát k tématu
Tak to dělej, někdo chce anonymní funkci a ty píšeš kód mimo mísu.
Vždyť je anonymní. To spíš mimo mísu jsi ty ;).
Není. Máš ta pojmenovanou lokální proměnnou. Až se jí zbavíš, tak to bude řešením. Ale vzhledem k tomu, žes ani nebyl schopen pochopit zadání, těžko přijdeš s řešením.
Citace od: Bacsa kdy 17. 08. 2018, 14:12:28
Citace od: Kojot kdy 17. 08. 2018, 14:03:25
Citace od: Bacsa kdy 17. 08. 2018, 13:53:44
Citace od: Kojot kdy 17. 08. 2018, 13:33:09
Je lepší psát k tématu
Tak to dělej, někdo chce anonymní funkci a ty píšeš kód mimo mísu.
Vždyť je anonymní. To spíš mimo mísu jsi ty ;).
Není. Máš ta pojmenovanou lokální proměnnou. Až se jí zbavíš, tak to bude řešením. Ale vzhledem k tomu, žes ani nebyl schopen pochopit zadání, těžko přijdeš s řešením.
Ty ses dobrej mamlas, clovece, poposkoc si... ;)
Citace od: Bacsa kdy 17. 08. 2018, 14:12:28
Není. Máš ta pojmenovanou lokální proměnnou. Až se jí zbavíš, tak to bude řešením. Ale vzhledem k tomu, žes ani nebyl schopen pochopit zadání, těžko přijdeš s řešením.
Tak bez pojmenování lokálních proměnných, nebo dokonce parametrů, jsem to ještě nezkoušel. Snad na tuto úroveň jednou dospěju ;D.
Citace od: v kdy 17. 08. 2018, 14:06:42
možná tohle http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0200r0.html ?
Podle mě je to v zásadě to samé. Do auto paramteru lambdy se předává požadovaná funkce. V tomto případě objekt třídy y_combinator_result, který zavolá uloženou funkci.
Citace od: Kojot kdy 17. 08. 2018, 14:27:35
Citace od: v kdy 17. 08. 2018, 14:06:42
možná tohle http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0200r0.html ?
Podle mě je to v zásadě to samé. Do auto paramteru lambdy se předává požadovaná funkce. V tomto případě objekt třídy y_combinator_result, který zavolá uloženou funkci.
almost_gcd se tam použije jenom jednou, to bych řekl, že je docela rozdíl
clojure style rekurze v pythonu jde
import types, inspect
def recur(*args, **kwargs):
return types.FunctionType(inspect.stack()[1][0].f_code, globals())(*args, **kwargs)
fact = lambda x: x * recur(x - 1) if x > 1 else x
v praxi to použije jen dement.
Citace od: optimizer kdy 17. 08. 2018, 14:47:34
clojure style rekurze v pythonu jde
import types, inspect
def recur(*args, **kwargs):
return types.FunctionType(inspect.stack()[1][0].f_code, globals())(*args, **kwargs)
fact = lambda x: x * recur(x - 1) if x > 1 else x
v praxi to použije jen dement.
To bezpochyby, protože to je dementní řešení. Žes to sem dal, hanba by tě měla fackovat. (P.S. Proč tu není zvracející smajlík?)
Citace od: v kdy 17. 08. 2018, 14:34:50
Citace od: Kojot kdy 17. 08. 2018, 14:27:35
Citace od: v kdy 17. 08. 2018, 14:06:42
možná tohle http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0200r0.html ?
Podle mě je to v zásadě to samé. Do auto paramteru lambdy se předává požadovaná funkce. V tomto případě objekt třídy y_combinator_result, který zavolá uloženou funkci.
almost_gcd se tam použije jenom jednou, to bych řekl, že je docela rozdíl
Tak protože to předávání funkce se dějě v operátoru volání objektu y_combinator_result.
template<class ...Args>
decltype(auto) operator()(Args &&...args) {
return fun_(std::ref(*this), std::forward<Args>(args)...);
}Auto parametr gcd v lambdě je pak reference na objekt y_combinator_result. Výhoda je, že si to předávání nemusíš psát sám, ale udělá to ten objekt y_combinator_result.
Citace od: DK kdy 17. 08. 2018, 09:42:11
Mozne to je, ale nevim, zda tohle zrovna v Pythonu chces delat
https://stackoverflow.com/questions/481692/can-a-lambda-function-call-itself-recursively-in-python
je to dost nepekne
Python 2.7.6 (default, Nov 23 2017, 15:49:48)
[GCC 4.8.4] on linux2
Type "copyright", "credits" or "license()" for more information.
>>> map(lambda n: (lambda f, *a: f(f, *a))(lambda rec, n: 1 if n == 0 else n*rec(rec, n-1), n), [1, 2, 3, 4, 5])
[1, 2, 6, 24, 120]
>>>
[code python 3.4]
Python 3.4.3 (default, Nov 28 2017, 16:41:13)
[GCC 4.8.4] on linux
Type "copyright", "credits" or "license()" for more information.
>>> map(lambda n: (lambda f, *a: f(f, *a))(lambda rec, n: 1 if n == 0 else n*rec(rec, n-1), n), [1, 2, 3, 4, 5])
<map object at 0x7f3c31f384a8>
>>> list(map(lambda n: (lambda f, *a: f(f, *a))(lambda rec, n: 1 if n == 0 else n*rec(rec, n-1), n), [1, 2, 3, 4, 5]))
[1, 2, 6, 24, 120]
>>>
[/code]
Citace od: Bacsa kdy 17. 08. 2018, 14:53:30
To bezpochyby, protože to je dementní řešení. Žes to sem dal, hanba by tě měla fackovat. (P.S. Proč tu není zvracející smajlík?)
Na dementní otázku dementní řešení. Zatím jsem neviděl lepší.
Citace od: optimizer kdy 17. 08. 2018, 15:14:17
Citace od: Bacsa kdy 17. 08. 2018, 14:53:30
To bezpochyby, protože to je dementní řešení. Žes to sem dal, hanba by tě měla fackovat. (P.S. Proč tu není zvracející smajlík?)
Na dementní otázku dementní řešení. Zatím jsem neviděl lepší.
Ty jsi ale kretén. Ta otázka je normální a zajímavá, akorát že ty vůbec nevíš, která bije. Vrať se do zvláštní školy.
Citace od: Bacsa kdy 17. 08. 2018, 23:17:30
Ty jsi ale kretén. Ta otázka je normální a zajímavá, akorát že ty vůbec nevíš, která bije. Vrať se do zvláštní školy.
recall z R v Pythonu, přesně jak tazatel chtěl
import types, inspect
def recall(*args, **kwargs):
return types.FunctionType(inspect.stack()[1][0].f_code, globals())(*args, **kwargs)
list(map(lambda x: x * recall(x - 1) if x > 1 else x, [1, 2, 3, 4, 5]))
# [1, 2, 6, 24, 120]