[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