-
11. Data: 2011-10-16 12:52:31
Temat: Re: lambda i clojures
Od: Piotr Chamera <p...@p...onet.pl>
W dniu 2011-10-16 14:24, f...@g...SKASUJ-TO.pl pisze:
> Piotr Chamera<p...@p...onet.pl> napisał(a):
>
>> W dniu 2011-10-16 12:09, Piotr Chamera pisze:
>>> Można np. napisać to
>>>
>>> >> (let ((licznik 0))
>>> >> (defun następny () (setf licznik (1+ licznik)))
>>> >> (defun poprzedni () (setf licznik (1- licznik))))
>>>
>>> tak:
>>>
>>> (defvar *licz*
>>> (let ((licznik 0))
>>> (list
>>> (lambda ()
>>> (setf licznik (1+ licznik)))
>>> (lambda ()
>>> (setf licznik (1- licznik))))))
>>>
>>> taka konstrukcja zwraca listę funkcji (którym nie nadano nazw)
>>>
>>> CL-USER> *licz*
>>> (#<COMPILED-LEXICAL-CLOSURE #xC9E7EC6> #<COMPILED-LEXICAL-CLOSURE
>>> #xC9E7E9E>)
>>>
>>> i korzystać z licznika tak:
>>>
>>> CL-USER> (funcall (first *licz*))
>>> 1
>>> CL-USER> (funcall (first *licz*))
>>> 2
>>> CL-USER> (funcall (second *licz*))
>>> 1
>>> CL-USER> (funcall (second *licz*))
>>> 0
>>
>> Dodam może jeszcze, że w tym przykładzie możemy zrobić
>> coś takiego:
>>
>> CL-USER> (setf (symbol-function 'następny) (first *licz*))
>> #<COMPILED-LEXICAL-CLOSURE #xC83E976>
>>
>> CL-USER> (setf (symbol-function 'poprzedni) (second *licz*))
>> #<COMPILED-LEXICAL-CLOSURE #xC83E94E>
>>
>> CL-USER> (następny)
>> 1
>> CL-USER> (funcall (first *licz*))
>> 2
>> CL-USER> (następny)
>> 3
>> CL-USER> (funcall (first *licz*))
>> 4
>> ....
>>
>> Wywołujemy teraz tę samą funkcję, ale raz przez nazwę,
>> a drugi raz uruchamiając obiekt przechowywany na liście.
>
> nadal nie rozumiem tego cholerstwa, cos takirgo jak
> z tym licznikiem mozna zrobic na statycznych zmiennych
> wewnatrz funkcji, nie wiem jaka jest roznica miedzy tym
> co moznazrobic na tych zm statycznych a tym czego nie mozna
> zrobic i potrzebne sa te closures i wogole do czego
> moze sie to przydac - te przyklady jakie widza w wiki sa jakos
> totalnie dziwne
Nie znam na tyle C, żeby powiedzieć jaka jest różnica - mogę
prosić o przykład realizacji tego w C?
-
12. Data: 2011-10-16 13:15:56
Temat: Re: lambda i clojures
Od: " " <f...@g...SKASUJ-TO.pl>
> >
> > nadal nie rozumiem tego cholerstwa, cos takirgo jak
> > z tym licznikiem mozna zrobic na statycznych zmiennych
> > wewnatrz funkcji, nie wiem jaka jest roznica miedzy tym
> > co moznazrobic na tych zm statycznych a tym czego nie mozna
> > zrobic i potrzebne sa te closures i wogole do czego
> > moze sie to przydac - te przyklady jakie widza w wiki sa jakos
> > totalnie dziwne
>
> Nie znam na tyle C, Ĺźeby powiedzieÄ jaka jest róşnica â mogÄ
> prosiÄ o przykĹad realizacji tego w C?
>
>
przyklad na statiki w c nie za bardzo pomoze w zrozumieniu po
co sluzyc moga te closures (poki co mnie to tylko denerwuje)
nie wiem czy jest w tym cos co naprawde moze sie przydac i
czego nie ma da sie zrobic tymi statikami
int nastepny()
{
static int licznik = 0;
return ++licznik;
}
powyzej zmienna statyczna licznik jest podobna do zmiennej globalnej
tylko ze jej widzialnosc jest ograniczona do wnetrza funkcji, jest tylko
raz inicjalizowana przy starcie programu, a pozniej kazde wywolanie po
prostu zwieksza ja o jeden i zwraca, tak ze gdyby wypisaywac logiem
for(int i=0; i<10l i++)
log( nastepny() );
to bedzie wynik:
1
2
3
4
5
6
7
8
9
nie wiem na czym ma polegac to 'przechwytywanie' kontekstow w
closures itd i czemu ma to sluzyc w stosunku do zwyklych wywolan,
przyklady sa naprawde dziwaczne
np przyklad z pythonem z wiki
http://pl.wikipedia.org/wiki/Domknięcie_(programowan
ie)
co to ma byc?
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
-
13. Data: 2011-10-16 13:37:20
Temat: Re: lambda i clojures
Od: Edek <e...@g...com>
On 10/16/2011 03:15 PM, f...@g...SKASUJ-TO.pl wrote:
[...]
> nie wiem na czym ma polegac to 'przechwytywanie' kontekstow w
> closures itd i czemu ma to sluzyc w stosunku do zwyklych wywolan,
> przyklady sa naprawde dziwaczne
>
> np przyklad z pythonem z wiki
>
> http://pl.wikipedia.org/wiki/Domknięcie_(programowan
ie)
>
> co to ma byc?
To ma być polska strona. Ty kliknąć, po lewej, "English" i czytać.
Potem pytać ;)
Na angielskiej sporo z tych rzeczy jest wytłumaczone. Możesz
zamiast tego zainwestować w poznanie języka funkcyjnego,
bo elementy funkcyjne są w C++, Pythonie, Javie (od biedy,
niejawnie). Ja bym proponował taką kolejność:
- lambda w pythonie (minimal, wyrażenie)
- lambda w C++
- anonymous classes w Javie i dlaczego niektóre zmienne muszą
być final
- wracając do Pythona, poguglać na temat bindowania symboli,
bo reguły nie są banalne
Edek
-
14. Data: 2011-10-16 13:46:03
Temat: Re: lambda i clojures
Od: Piotr Chamera <p...@p...onet.pl>
W dniu 2011-10-16 15:15, f...@g...SKASUJ-TO.pl pisze:
>>>
>>> nadal nie rozumiem tego cholerstwa, cos takirgo jak
>>> z tym licznikiem mozna zrobic na statycznych zmiennych
>>> wewnatrz funkcji, nie wiem jaka jest roznica miedzy tym
>>> co moznazrobic na tych zm statycznych a tym czego nie mozna
>>> zrobic i potrzebne sa te closures i wogole do czego
>>> moze sie to przydac - te przyklady jakie widza w wiki sa jakos
>>> totalnie dziwne
>>
>> Nie znam na tyle C, Ĺźeby powiedzieÄ jaka jest róşnica â mogÄ
>> prosiÄ o przykĹad realizacji tego w C?
>>
>>
> przyklad na statiki w c nie za bardzo pomoze w zrozumieniu po
> co sluzyc moga te closures (poki co mnie to tylko denerwuje)
> nie wiem czy jest w tym cos co naprawde moze sie przydac i
> czego nie ma da sie zrobic tymi statikami
>
> int nastepny()
> {
> static int licznik = 0;
>
> return ++licznik;
> }
>
> powyzej zmienna statyczna licznik jest podobna do zmiennej globalnej
> tylko ze jej widzialnosc jest ograniczona do wnetrza funkcji, jest tylko
> raz inicjalizowana przy starcie programu, a pozniej kazde wywolanie po
> prostu zwieksza ja o jeden i zwraca, tak ze gdyby wypisaywac logiem
>
> for(int i=0; i<10l i++)
> log( nastepny() );
>
> to bedzie wynik:
> 1
> 2
> 3
Ok mamy jedną funkcję, która korzysta ze statycznego licznika.
Teraz potrzebujemy dwie funkcje, które korzystają z tego samego
licznika - jedna go zwiększa, druga zmniejsza. W C to będzie
wyglądało... ?
-
15. Data: 2011-10-16 14:17:00
Temat: Re: lambda i clojures
Od: "Stachu 'Dozzie' K." <d...@g...eat.some.screws.spammer.invalid>
On 2011-10-16, Piotr Chamera <p...@p...onet.pl> wrote:
[...]
> Ok mamy jedną funkcję, która korzysta ze statycznego licznika.
> Teraz potrzebujemy dwie funkcje, które korzystają z tego samego
> licznika - jedna go zwiększa, druga zmniejsza. W C to będzie
> wyglądało... ?
Da się. Wydziela się takie funkcje do osobnej jednostki kompilacji,
a tam umieszcza zmienną static.
Na prostych przykładach nie wyjaśnisz firowi jaka jest różnica między
domknięciem i funkcją z zestawem statycznych zmiennych, a bardziej
skomplikowanych nie pojmie, bo jest za głupi. W ogóle nie rozumiem czemu
z nim dyskutujesz.
--
Secunia non olet.
Stanislaw Klekot
-
16. Data: 2011-10-16 14:27:35
Temat: Re: lambda i clojures
Od: " " <f...@g...SKASUJ-TO.pl>
Piotr Chamera <p...@p...onet.pl> napisał(a):
> W dniu 2011-10-16 15:15, f...@g...SKASUJ-TO.pl pisze:
> >>>
> >>> nadal nie rozumiem tego cholerstwa, cos takirgo jak
> >>> z tym licznikiem mozna zrobic na statycznych zmiennych
> >>> wewnatrz funkcji, nie wiem jaka jest roznica miedzy tym
> >>> co moznazrobic na tych zm statycznych a tym czego nie mozna
> >>> zrobic i potrzebne sa te closures i wogole do czego
> >>> moze sie to przydac - te przyklady jakie widza w wiki sa jakos
> >>> totalnie dziwne
> >>
> >> Nie znam na tyle C, Ĺźeby powiedzieÄ jaka jest róşnica â mogÄ
> >> prosiÄ o przykĹad realizacji tego w C?
> >>
> >>
> > przyklad na statiki w c nie za bardzo pomoze w zrozumieniu po
> > co sluzyc moga te closures (poki co mnie to tylko denerwuje)
> > nie wiem czy jest w tym cos co naprawde moze sie przydac i
> > czego nie ma da sie zrobic tymi statikami
> >
> > int nastepny()
> > {
> > static int licznik = 0;
> >
> > return ++licznik;
> > }
> >
> > powyzej zmienna statyczna licznik jest podobna do zmiennej globalnej
> > tylko ze jej widzialnosc jest ograniczona do wnetrza funkcji, jest tylko
> > raz inicjalizowana przy starcie programu, a pozniej kazde wywolanie po
> > prostu zwieksza ja o jeden i zwraca, tak ze gdyby wypisaywac logiem
> >
> > for(int i=0; i<10l i++)
> > log( nastepny() );
> >
> > to bedzie wynik:
> > 1
> > 2
> > 3
>
> Ok mamy jedną funkcję, która korzysta ze statycznego licznika.
> Teraz potrzebujemy dwie funkcje, które korzystają z tego samego
> licznika - jedna go zwiększa, druga zmniejsza. W C to będzie
> wyglądało... ?
>
trzebaby zrobic 'wspoldzielone statiki' pisalem na ten temat
z rok temu (albo zrobic modul itd) ale na pewno nie o to chodzi
w tych cholernych closures
w tym przykladzie z pytona
mnozenie_przez_5 = mnozenie_przez(5)
print mnoezenie_przez_5(12)
niby mozna zrobic pewna nowa rzecz tj setupnac sobie niejako 'szablonową'
funkcje by mnozyla przez 5, w c mozna to samo zrobic z tym
ze ta 5ka musialaby byc globalna lub trzebeby miec mozliwosc
odnoszenia sie do statkow w funkcji (tez kiedys proponowalem)
itp, ale nie wiem o co im tam konkretnie chodzi
czy np w ten sposob
mnozenie_przez_5 = mnozenie_przez(5)
mnozenie_przez_7 = mnozenie_przez(7)
mnozenie_przez_9 = mnozenie_przez(9)
chca tworzyc trzy rozne czy jedna 'przełaczaną' i czy
wogole ta mozliwosc chwytania tych liczb 5,7,9 lub innych
z kontekstow ma byc uzywana w jakis wyrafinowany sposob
- np z roznych kontekstow - i czy to ma dawac jakies
nietrywialne mozliwosci, poki co jest to jakies dziwne
i zakrecone ( obecnie kandydat numer 1 w konkursie na rzeczy
irytujace oraz denerwujące )
}
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
-
17. Data: 2011-10-16 14:49:26
Temat: Re: lambda i clojures
Od: Piotr Chamera <p...@p...onet.pl>
W dniu 2011-10-16 16:17, Stachu 'Dozzie' K. pisze:
> On 2011-10-16, Piotr Chamera<p...@p...onet.pl> wrote:
> [...]
>> Ok mamy jedną funkcję, która korzysta ze statycznego licznika.
>> Teraz potrzebujemy dwie funkcje, które korzystają z tego samego
>> licznika - jedna go zwiększa, druga zmniejsza. W C to będzie
>> wyglądało... ?
>
> Da się. Wydziela się takie funkcje do osobnej jednostki kompilacji,
> a tam umieszcza zmienną static.
>
> Na prostych przykładach nie wyjaśnisz firowi jaka jest różnica między
> domknięciem i funkcją z zestawem statycznych zmiennych, a bardziej
> skomplikowanych nie pojmie, bo jest za głupi. W ogóle nie rozumiem czemu
> z nim dyskutujesz.
Słyszałem kiedyś coś takiego ,,nie ma głupich uczniów, są tylko
nieodpowiedni nauczyciele" - próbuję siebie w roli nauczyciela :)
A tak serio - siedzę nad nudną robotą i od czasu do czasu muszę sobie
zrobić przerwę... Programistą nie jestem, robię to tylko hobbystycznie,
C nie znam prawie wcale, ostatnio w wolnym czasie uczę się Lispu
i pomyślałem, że może spróbuję podać jakiś prosty przykład a dyskusja
się rozwinie i pojawią się jakieś ciekawsze przykłady albo nowe dla
mnie zagadnienia.
-
18. Data: 2011-10-16 15:26:11
Temat: Re: lambda i clojures
Od: bartekltg <b...@o...pl>
W dniu 2011-10-16 10:05, Piotr Chamera pisze:
> W dniu 2011-10-16 07:25, f...@g...SKASUJ-TO.pl pisze:
>> Piotr Chamera<p...@p...onet.pl> napisał(a):
>>> Closure to taka funkcja powiązana ze środowiskiem, w którym została
>>> zdefiniowana. N.p.:
>>>
>>> (let ((licznik 0))
>>> (defun następny () (setf licznik (1+ licznik))))
>>>
>>> CL-USER> (następny)
>>> 1
>>>
>>> CL-USER> licznik
>>> Unbound variable: LICZNIK
>>> [Condition of type UNBOUND-VARIABLE]
>>>
>>> CL-USER> (następny)
>>> 2
>>>
>>> W Wikipedii jest to całkiem dobrze opisane:
>>> http://en.wikipedia.org/wiki/Closure_%28computer_sci
ence%29
>
> Że ,,licznik" nie jest dostępny globalnie - po wyjściu z zasięgu
> konstrukcji ,,let" przestał być widoczny, ale po wywołaniu funkcji
> nadal jest dostępny - to fragment środowiska, w którym funkcja była
> definiowana, który został przez nią przechwycony. Nie może być
> odłożony na stosie, jest zewnętrzny w stosunku do ciała funkcji i może
> przenosić informację pomiędzy jej wywołaniami.
> Żeby to zrobić w C
> trzeba by pewnie zaalokować jakiś obiekt na stercie i przekazać
> do funkcji wskaźnik do niego.
Zmienne statyczne w funkcji?
http://en.wikipedia.org/wiki/Static_variable
#include <stdio.h>
void func() {
static int x = 0; // x is initialized only once across three
calls of func()
printf("%d\n", x); // outputs the value of x
x = x + 1;
}
int main(int argc, char * const argv[]) {
func(); // prints 0
func(); // prints 1
func(); // prints 2
return 0;
}
Robi dokładnie to, co Twój przykład.
pzdr
bartekltg
-
19. Data: 2011-10-16 16:22:02
Temat: Re: lambda i clojures
Od: Piotr Chamera <p...@p...onet.pl>
W dniu 2011-10-16 16:27, f...@g...SKASUJ-TO.pl pisze:
> Piotr Chamera<p...@p...onet.pl> napisał(a):
(...)
>> Ok mamy jedną funkcję, która korzysta ze statycznego licznika.
>> Teraz potrzebujemy dwie funkcje, które korzystają z tego samego
>> licznika - jedna go zwiększa, druga zmniejsza. W C to będzie
>> wyglądało... ?
>>
> trzebaby zrobic 'wspoldzielone statiki' pisalem na ten temat
> z rok temu (albo zrobic modul itd) ale na pewno nie o to chodzi
> w tych cholernych closures
A dlaczego nie? MZ chodzi właśnie o taki mechanizm - wiązanie
obiektów z pewnej lokalnej przestrzeni nazw z działającymi na nich
funkcjami w taki sposób, że są one dla tych funkcji nadal dostępne
po wyjściu z tej przestrzeni. I żeby to było proste w stosowaniu...
i to chyba tyle... Pozostaje znaleźć zastosowania...
-
20. Data: 2011-10-16 16:43:49
Temat: Re: lambda i clojures
Od: Bronek Kozicki <b...@s...net>
On 16/10/2011 16:26, bartekltg wrote:
> Zmienne statyczne w funkcji?
> http://en.wikipedia.org/wiki/Static_variable
>
> #include <stdio.h>
>
> void func() {
> static int x = 0; // x is initialized only once across three calls of
> func()
> printf("%d\n", x); // outputs the value of x
> x = x + 1;
> }
>
> int main(int argc, char * const argv[]) {
> func(); // prints 0
> func(); // prints 1
> func(); // prints 2
> return 0;
> }
>
> Robi dokładnie to, co Twój przykład.
... pod warunkiem że uruchomisz to tylko raz.
Closure można utworzyć wiele razy, z jednego wyrażenia lambda, za każdym
razem będzie miało nowy stan. To jest szczególnie pożyteczne w wątkach.
B.