[nem-pl] in_tail_position
Kamil Skalski
nazgul at omega.pl
Thu Mar 11 16:42:58 CET 2004
Thursday 11 of March 2004 15:50, Lukasz Kaiser wrote:
> Taka funkcje da sie policzyc "od dolu" ogonowo w nastepujacy sposob:
> def f (x) {
Nie zrozumiałem na jakiej podstawie chciałbyć rozpoznać jakich akumulatorów
trzeba użyć, przecież matching może być skomplikowany i obudowany w różne nic
nie znaczące "śmieci". No ale nic, pewnie dla jednego przypadku, który się
zaimplementuje to będzie działać.
Więc odpowiedź jest taka, że nie da się jeszcze pisać żadnych makr na typach
czy metodach [accumulable] f (..) { .. }
Myślę, że będzie się dało za jakieś 2-3 tygodnie, bo już się wszyscy na nie
napalamy.
Dałoby się raczej zrobić to jako wywołanie funkcji, ew. jakąś składnią
wprowadzoną przez 'syntax' (patrz regexp):
regexp match (..) { ... }
czyli możesz sobie napisać makro
accumulable (match (..) { .... })
albo
accumulable (def f (...) { .... })
(lub ulepszone o 'syntax')
> f = | 0 => Cons ( B, B ) | x => Cons ( f (x-1), B )
> to pewnie ta druga galaz sie przeklada na
> x => { y <- f(x-1) ; z <- Cons (x, 1) ; Cons ( y, z ) }.
co to za Cons(x, 1)? nie ma tego w oryginalnym kodzie....
> def f_ptr ( ptr, n ) { match n with
>
> | O => { ptr <- ConsM ( BM, BM ) }
> | x => { def mutable nptr = NULL ;
>
> ptr <- ConsM ( nptr, BM ) ;
> f_ptr ( nptr, x-1 ) }
miałeś na myśli
mutable nptr <- null;
ptr <- ConsM ( ref nptr, BM);
f_prt (ref nptr, x-1)
?
Pamiętaj, że u ciebie nptr jest przekazany jako wartość. (refów jeszcze nie
mamy)
Natomiast to i tak nie będzie działać, bo przecież konstruktory mają to do
siebie, że najczęściej kopiują wartość parametru, czyli w tym przypadku
konstruktor ConsM posłusznie skopiuje sobie nulla.
To musiałoby wyglądać jakoś tak
ptr <- ConsM (null, BM);
f_ptr (ref ptr.a, x -1)
i teraz może miałoby jakiś sens, ale jest to raczej dość nieeleganckie
hakowanie przekazywaniem przez referencję.
Natomiast różnego rodzaju optymalizacje dotyczące podobnej tematyki
omawialiśmy w kontekscie rekordów:
https://nemerle.org/mailman/pipermail/devel-en/2004-February/000003.html
> Mozliwe zastosowanie:
> Mozna wtedy zrobic zeby np. taka funkcja nie byla rekurencyjna:
> insertTree ( n, t ) { match t with
>
> | Leaf => Tree ( n, Leaf, Leaf )
> | Tree ( i, l, r ) => if (i < n)
>
> Tree ( i, l, insertTree ( n, r ) )
> else
> Tree ( i, insertTree ( n, l ), r )
> }
> }
>
Z tego co zrozumiałem, twoja propozycja opiera się na dość imperatywnym
podejściu z przekazywaniem wskaźników, które ktoś może zmodyfikować. Jaki
jest zatem sens robienia powyższej funkcji i optymalizowania jej w ten
sposób, skoro można napisać
match (x) {
| Leaf => x <- Tree (n, Leaf, Leaf)
| Tree (i, l, r) => if (i < n) f (n, ref l) else f (n, ref r)
(no jakoś tak, pewnie nie można pattern variable przekazać tak, więc trzeba ją
wziąć bezpośrednio z x)
Kamil
More information about the devel-pl
mailing list