Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: RecursiveFarts 17. 08. 2018, 01:47:51

Název: Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: RecursiveFarts 17. 08. 2018, 01:47:51
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.
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Ivan Nový 17. 08. 2018, 07:35:54
Kód: [Vybrat]
fact = lambda x: C

nebo
Kód: [Vybrat]
def fun(x):
    return 1 if x == 0 else x * fact(x-1)
map(fun, [1, 2, 3, 4])
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Ivan Nový 17. 08. 2018, 07:36:57
Ten první způsob se neuložil celý, zde je kompletní
fact = lambda x: 1 if x == 0 else x * fact(x-1)
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Ivan Nový 17. 08. 2018, 07:38:23
A ten druhý je taky blbě, nyní správně
Kód: [Vybrat]
def fact(x):
    return 1 if x == 0 else x * fact(x-1)
map(fact, [1, 2, 3, 4])
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Trader 17. 08. 2018, 09:37:07
A ten druhý je taky blbě, nyní správně
Kód: [Vybrat]
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.
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: DK 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
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Trader 17. 08. 2018, 10:06:04
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).
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Ivan Nový 17. 08. 2018, 10:15:20
A ten druhý je taky blbě, nyní správně
Kód: [Vybrat]
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.
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Bacsa 17. 08. 2018, 11:21:30
A ten druhý je taky blbě, nyní správně
Kód: [Vybrat]
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”?
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Kojot 17. 08. 2018, 11:57:30
... a C++ už vůbec ne.
Ale dá se.
Kód: [Vybrat]
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);
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: ByCzech 17. 08. 2018, 12:38:57
Co je “erovsky”?

IMHO myslí způsob programování typický pro jazyk R
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Bacsa 17. 08. 2018, 12:43:43
... a C++ už vůbec ne.
Ale dá se.
Kód: [Vybrat]
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”?
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Kojot 17. 08. 2018, 13:19:18
... a C++ už vůbec ne.
Ale dá se.
Kód: [Vybrat]
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.
Kód: [Vybrat]
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);
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Bacsa 17. 08. 2018, 13:22:17
... a C++ už vůbec ne.
Ale dá se.
Kód: [Vybrat]
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.
Kód: [Vybrat]
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ě.
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Kojot 17. 08. 2018, 13:33:09
Furt blbě.
Je lepší psát k tématu, a ne jak se cítíš  ;D.
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Bacsa 17. 08. 2018, 13:53:44
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.
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Kojot 17. 08. 2018, 14:03:25
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  ;).
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: v 17. 08. 2018, 14:06:42
možná tohle http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0200r0.html ?
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Bacsa 17. 08. 2018, 14:12:28
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.
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: n 17. 08. 2018, 14:13:38
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... ;)
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Kojot 17. 08. 2018, 14:23:36
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.
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Kojot 17. 08. 2018, 14:27:35
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.
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: v 17. 08. 2018, 14:34:50
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
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: optimizer 17. 08. 2018, 14:47:34
clojure style rekurze v pythonu jde

Kód: [Vybrat]
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.
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Bacsa 17. 08. 2018, 14:53:30
clojure style rekurze v pythonu jde

Kód: [Vybrat]
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?)
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Kojot 17. 08. 2018, 14:59:48
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.
Kód: [Vybrat]
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.
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: mikrom 17. 08. 2018, 15:09:00
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
Kód: (python 2.7) [Vybrat]
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]
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: optimizer 17. 08. 2018, 15:14:17
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ší.
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: Bacsa 17. 08. 2018, 23:17: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.
Název: Re:Referenčně transparentní rekurzivní anonymní funkce v Pythonu a C++
Přispěvatel: optimizer 18. 08. 2018, 00:38:25
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

Kód: [Vybrat]
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]