Hi Alex,

> The current implementation of 'do' is not well suited to grant access to
> the internal counter to the application level.
> Because 32bit PicoLisp has no short numbers, incrementing a number
> always results in the allocation of a new cell (turning the old cell
> into garbage). To avoid this, 'do' creates a copy of its first argument
> at the beginning, and destructively increments it at each pass through
> the loop. If we make this value available to an application, strange
> things would happen (modifying values as side effects).
> As there is the 'for' function which handles similar cases, I never
> really missed such a feature.
> Should we think about it again for the 64bit version? Then we'll have
> 60bit short numbers which will probably not be exceeded for most loops.

I see that you take big pain to optimize things a lot.  I would
actually prefer the convenience of powerful programming interface and
would not mind to sacrifice a bit of performance.  'do' could stay the
way it is except there could be a new execution path to handle the
case where the first argument is a cons cell as above.  It might be
slower than ideal in the meantime but maybe we could put it on the
list of postponed TODO optimizations which could be implemented later
(or never depending on other priorities)?

I simply find saying

  (do (I . 5) (print I) "finished")

much better than saying

  (for (I 1 (<= I 5) (inc I)) (print I) "finished")

and the performance would be the same, wouldn't it?

I guess it is a matter of taste, anyway;-)

> To go one level up always '1' should be enough. You simply count the
> levels of functional bindings, e.g.:
>    (de foo (Lst . Prg)
>       (mapcar
>          '((X) (eval X 2))
>          Lst ) )
> Here we must use '2', as we want to eval the expression 'X' in the scope
> outside of 'foo', and between that is another function '((X) ..)'.

It's clear now, thank you.


Reply via email to