-
1. Data: 2011-10-15 10:38:37
Temat: lambda, clojures
Od: " " <f...@g...SKASUJ-TO.pl>
Umialby ktos mi wytlumaczyć o co z tym chodzi, i np jak
ewentalnie mogloby to sie przydac na gruncie c? Juz kiedys
dwa razy probowalem załapac co to jest ale jakos trafialem
jakby na dosyc niekomunikatywne teksty albo cos bo nie udalo
mi sie pojac co to jest i o co w tym chodzi...
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
-
2. Data: 2011-10-15 19:57:29
Temat: Re: lambda, clojures
Od: Maciej Sobczak <s...@g...com>
On Oct 15, 12:38 pm, " " <f...@g...SKASUJ-TO.pl> wrote:
> Umialby ktos mi wytlumaczy o co z tym chodzi, i np jak
> ewentalnie mogloby to sie przydac na gruncie c?
Na gruncie C nie mogłoby i dlatego nie umiałby.
> Juz kiedys
> dwa razy probowalem za apac co to jest ale jakos trafialem
> jakby na dosyc niekomunikatywne teksty
Teksty były na pewno dobre, ale one nie były o C. Musisz w końcu
zrobić ten krok naprzód i wydostać się z pułapki jaką jest Twoje
bardzo sztywne założenie, że C jest ostatecznym etapem w rozwoju
języków programowania.
--
Maciej Sobczak * http://www.msobczak.com * http://www.inspirel.com
-
3. Data: 2011-10-15 20:16:51
Temat: Re: lambda i clojures
Od: " " <f...@g...SKASUJ-TO.pl>
> na gruncie c nie moglby
pod iosem jest cos co sie nazywa blocks, i jest to
wlasnie applowskie rozszerzenie c ktore zdaje sie
ze implementuje wlasnie te clojures - ale opisy sa
dla mnie tak metne ze nie rozumiem za bardzo o co z
tym chodzi
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
-
4. Data: 2011-10-15 23:18:17
Temat: Re: lambda i clojures
Od: Piotr Chamera <p...@p...onet.pl>
W dniu 2011-10-15 22:16, f...@g...SKASUJ-TO.pl pisze:
>> na gruncie c nie moglby
>
> pod iosem jest cos co sie nazywa blocks, i jest to
> wlasnie applowskie rozszerzenie c ktore zdaje sie
> ze implementuje wlasnie te clojures - ale opisy sa
> dla mnie tak metne ze nie rozumiem za bardzo o co z
> tym chodzi
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
-
5. Data: 2011-10-16 05:25:53
Temat: Re: lambda i clojures
Od: " " <f...@g...SKASUJ-TO.pl>
Piotr Chamera <p...@p...onet.pl> napisał(a):
> W dniu 2011-10-15 22:16, f...@g...SKASUJ-TO.pl pisze:
> >> na gruncie c nie moglby
> >
> > pod iosem jest cos co sie nazywa blocks, i jest to
> > wlasnie applowskie rozszerzenie c ktore zdaje sie
> > ze implementuje wlasnie te clojures - ale opisy sa
> > dla mnie tak metne ze nie rozumiem za bardzo o co z
> > tym chodzi
>
> 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
a czym sie rozni od zwyklej normalnej 'niepowiazanej' funkcji?
w tym prztkladzie wyzej nie rozumiem co to jest i co
to ma ilustrowac:
> CL-USER> licznik
> Unbound variable: LICZNIK
> [Condition of type UNBOUND-VARIABLE]
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
-
6. Data: 2011-10-16 08:05:00
Temat: Re: lambda i clojures
Od: Piotr Chamera <p...@p...onet.pl>
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
>
> a czym sie rozni od zwyklej normalnej 'niepowiazanej' funkcji?
> w tym prztkladzie wyzej nie rozumiem co to jest i co
> to ma ilustrowac:
>
>> CL-USER> licznik
>> Unbound variable: LICZNIK
>> [Condition of type UNBOUND-VARIABLE]
Ż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.
Po rozszerzeniu pierwszego przykładu o drugą operację na
liczniku mamy najprostszy obiekt z dwiema operacjami na nim
i enkapsulacją jego wewnętrznego stanu.
(let ((licznik 0))
(defun następny () (setf licznik (1+ licznik)))
(defun poprzedni () (setf licznik (1- licznik))))
-
7. Data: 2011-10-16 09:01:00
Temat: Re: lambda i clojures
Od: " " <f...@g...SKASUJ-TO.pl>
Piotr Chamera <p...@p...onet.pl> napisał(a):
> 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
> >
> > a czym sie rozni od zwyklej normalnej 'niepowiazanej' funkcji?
> > w tym prztkladzie wyzej nie rozumiem co to jest i co
> > to ma ilustrowac:
> >
> >> CL-USER> licznik
> >> Unbound variable: LICZNIK
> >> [Condition of type UNBOUND-VARIABLE]
>
> Ĺť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.
>
> Po rozszerzeniu pierwszego przykĹadu o drugÄ operacjÄ na
> liczniku mamy najprostszy obiekt z dwiema operacjami na nim
> i enkapsulacjÄ jego wewnÄtrznego stanu.
>
> (let ((licznik 0))
> (defun nastÄpny () (setf licznik (1+ licznik)))
> (defun poprzedni () (setf licznik (1- licznik))))
>
denerwuje mnie to niepowiernie bo nic z tego nie rozumiem,
np w c funkcja jest definiowana tylko raz i dotego w globalnym
kontekscie wiec powiedzmy ze to c nie dotyczy
ale czy tam gdzie tego sie uzywa taka funkcje definiuje sie kilka
razy w roznych kontekstach? czy kazda z nich przechwytuje ten kontekst
raczej przez referencje czy przez wartosc? czy np jesli jest 5 definicji
to te wspolne przechwycine dane sa wspolne dla tych definicji?
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/
-
8. Data: 2011-10-16 10:09:07
Temat: Re: lambda i clojures
Od: Piotr Chamera <p...@p...onet.pl>
W dniu 2011-10-16 11:01, f...@g...SKASUJ-TO.pl pisze:
> Piotr Chamera<p...@p...onet.pl> napisał(a):
>
>> (let ((licznik 0))
>> (defun nastÄpny () (setf licznik (1+ licznik)))
>> (defun poprzedni () (setf licznik (1- licznik))))
>>
>
> denerwuje mnie to niepowiernie bo nic z tego nie rozumiem,
> np w c funkcja jest definiowana tylko raz i dotego w globalnym
> kontekscie wiec powiedzmy ze to c nie dotyczy
>
> ale czy tam gdzie tego sie uzywa taka funkcje definiuje sie kilka
> razy w roznych kontekstach? czy kazda z nich przechwytuje ten kontekst
> raczej przez referencje czy przez wartosc? czy np jesli jest 5 definicji
> to te wspolne przechwycine dane sa wspolne dla tych definicji?
Przez referencję. W przykładzie powyżej obie funkcje korzystają
z tego samego licznika, bo zostały zdefiniowane w tym samym środowisku
i przechwyciły tą samą zmienną.
CL-USER> (następny)
1
CL-USER> (następny)
2
CL-USER> (poprzedni)
1
CL-USER> (poprzedni)
0
CL-USER> (następny)
1
...
Gdybym napisał to tak:
(let ((licznik 0))
(defun następny () (setf licznik (1+ licznik))))
(let ((licznik 0))
(defun poprzedni () (setf licznik (1- licznik))))
to każda z funkcji miałaby osobny licznik
CL-USER> (następny)
1
CL-USER> (następny)
2
CL-USER> (poprzedni)
-1
CL-USER> (następny)
3
CL-USER> (poprzedni)
-2
...
Mógłbym chcieć też móc ustawiać krok inkrementacji dla obu
liczników jednocześnie i napisać tak:
(let ((krok 1))
(defun krok (x) (setf krok x))
(let ((licznik 0))
(defun następny () (setf licznik (+ licznik krok)))
)
(let ((licznik 0))
(defun poprzedni () (setf licznik (- licznik krok)))
)
)
wtedy krok jest wspólny dla obu funkcji a liczniki oddzielne
CL-USER> (następny)
1
CL-USER> (krok 10)
10
CL-USER> (następny)
11
CL-USER> (poprzedni)
-10
CL-USER> (krok 4)
4
CL-USER> (poprzedni)
-14
CL-USER> (następny)
15
...
W językach takiego typu jak lisp bardzo ważne jest, żeby
przestać utożsamiać funkcję z nazwą, która ją aktualnie
reprezentuje. Nazwy to tylko etykietki dowiązane do obiektów
języka (funkcji, zmiennych itd.) - obiekt może mieć jedną,
wiele lub nie mieć żadnej dowiązanej nazwy.
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
-
9. Data: 2011-10-16 11:19:24
Temat: Re: lambda i clojures
Od: Piotr Chamera <p...@p...onet.pl>
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.
-
10. Data: 2011-10-16 12:24:06
Temat: Re: lambda i clojures
Od: " " <f...@g...SKASUJ-TO.pl>
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
--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/