Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Closures

44 views
Skip to first unread message

none albert

unread,
Aug 14, 2023, 4:20:02 AM8/14/23
to
I finally understood what closures mean.
In Forth parlance it is a search order that is kept with an
Forth word. Each time the Forth word is invoked, the search
order is obeyed on top of the parameters that are passed.
It puzzled me that the search order need not be restored after
calling a lisp word, but it is build in.
Restoring seemed to be a stumbling block for implementing
tail optimisation, but it is not needed.

In implementing lisp the lisp search order has to be separate
from the Forth search order, that is naturally be present,
because Forth is the implementation language.
Traditional Forth implementation have a voc link, that points
to a previous wordlist, and allows Forth to print a list of
VOCABULARY's. It can be put to good use to implement the
chain of nested environments that lisp requires.

An environment is a wordlist, and a Forth mechanism can be used
to store lisp function in the wordlist.
That ties up the name field (to identify) and the link field (to
search).
Because it is a function defined in a high level Forth,
the code field contain docol, and the data field contains
a pointer to high level code.
The flag field is put to good use in identifying lisp
objects like numbers string symbols.

So the CDFLN fields are tied up, lisp functions run out of Forth header
fields.
Comes ciforth. The implementor of ciforth had the foresight to define
an extra field (>XFA) , free to use.

The bottom line is you can have a lisp closure call as follows:
\ Execute a lisp execution-token .
: EXECUTE-LISP DUP >XFA @ ENVIR ! EXECUTE ;

Groetjes Albert
--
Don't praise the day before the evening. One swallow doesn't make spring.
You must not say "hey" before you have crossed the bridge. Don't sell the
hide of the bear until you shot it. Better one bird in the hand than ten in
the air. First gain is a cat spinning. - the Wise from Antrim -

Anton Ertl

unread,
Aug 14, 2023, 10:31:51 AM8/14/23
to
albert@cherry.(none) (albert) writes:
>I finally understood what closures mean.
>In Forth parlance it is a search order that is kept with an
>Forth word.

That view leads down to boy compilers (in Knuth's man-or-boy test),
and at best (if you save and restore the variables on function entry
and exit) dynamically-scoped Lisp.

>An environment is a wordlist,

A wordlist has only one instance of each word in a wordlist.

An environment in a statically-scoped language is a set of local
frames, where each local frame is created dynamically when the
function to which the frame belongs is called. So if a function has
two instances at the same time (e.g., in recursion), a wordlist is
insufficient.

You can use wordlists to store the offsets of variable within the
frames, but you have to manage the frames separately.

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: https://forth-standard.org/
EuroForth 2023: https://euro.theforth.net/2023

Kaz Kylheku

unread,
Aug 14, 2023, 11:27:31 AM8/14/23
to
On 2023-08-14, albert@cherry.(none) (albert) <albert@cherry> wrote:
> I finally understood what closures mean.
> In Forth parlance it is a search order that is kept with an
> Forth word.

It seems as if you emigrated to Forth Island decades ago and now you
need everything translated into Forthese.

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazi...@mstdn.ca

dxforth

unread,
Aug 14, 2023, 6:10:45 PM8/14/23
to
On 15/08/2023 1:27 am, Kaz Kylheku wrote:
> On 2023-08-14, albert@cherry.(none) (albert) <albert@cherry> wrote:
>> I finally understood what closures mean.
>> In Forth parlance it is a search order that is kept with an
>> Forth word.
>
> It seems as if you emigrated to Forth Island decades ago and now you
> need everything translated into Forthese.

Some concepts that abound are baffling and need translating.
OTOH forth afficionados come up with novelties too :)

Kaz Kylheku

unread,
Aug 14, 2023, 8:20:50 PM8/14/23
to
Large numbers of more or less empty heads that don't know anything other
than Javascript are able to grok closures.

Relating things to what you know is a useful crutch, but at
some point you have to just walk.

none albert

unread,
Aug 15, 2023, 2:45:03 AM8/15/23
to
In article <2023Aug1...@mips.complang.tuwien.ac.at>,
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>albert@cherry.(none) (albert) writes:
>>I finally understood what closures mean.
>>In Forth parlance it is a search order that is kept with an
>>Forth word.
>
>That view leads down to boy compilers (in Knuth's man-or-boy test),
>and at best (if you save and restore the variables on function entry
>and exit) dynamically-scoped Lisp.
I'm an amateur. I implement MAL. I don't know whether that is a
dynamically-scoped Lisp. Actually my goal is to prove that
Forth is capable of parsing lisp itself, with a modular parser
in the style of BEGIN WHILE REPEAT words.
For example the rule that comma is to be treated as blank space
translate to the rule:
: , ; PREFIX

>
>>An environment is a wordlist,
>
>A wordlist has only one instance of each word in a wordlist.
Okay, so we have multiple instance of a wordlist.

>
>An environment in a statically-scoped language is a set of local
>frames, where each local frame is created dynamically when the
>function to which the frame belongs is called. So if a function has
>two instances at the same time (e.g., in recursion), a wordlist is
>insufficient.
That would mean that
(def! fib (fn* (N) (if (= N 0) 1
(if (= N 1) 1 (+ (fib (- N 1))
(fib (- N 2)))))))
would fail, but it isn't:
(fib 10)
89

Also the quine tests succeeds. It was commented out of the tests,
because the line was too long. (and it is too long for a usenet post,
sorry). That was not a restriction in my implementation.

;;;;; Test quine
((fn* [q] (quasiquote ((unquote q) (quote (unquote q))))) (quote (fn* [q] (quasiquote ((unquote q) (quote (unquote q)))))))
;=>((fn* [q] (quasiquote ((unquote q) (quote (unquote q))))) (quote (fn* [q] (quasiquote ((unquote q) (quote (unquote q)))))))

What fails is:
( ( (fn* (a) (fn* (b) (+ a b))) 5) 7)
(b) (+ a b))) 5) 7) ? ciforth ERROR # 8010
Error 8010 means that a symbol is not found in the nested environments.
`` a '' is not found.
The phrase clearly means that in the environment that `a has the
value 7, a new instance of the function has to be generated.
>
>You can use wordlists to store the offsets of variable within the
>frames, but you have to manage the frames separately.
I think I do with the proposed mechanism.
We shall see.

>
>- anton

Kaz Kylheku

unread,
Aug 15, 2023, 3:33:21 AM8/15/23
to
On 2023-08-15, albert@cherry.(none) (albert) <albert@cherry> wrote:
> That would mean that
> (def! fib (fn* (N) (if (= N 0) 1
> (if (= N 1) 1 (+ (fib (- N 1))
> (fib (- N 2)))))))
> would fail, but it isn't:
> (fib 10)

fib is not capturing lexical closures. There are multiple instances, but
they are not accessible at the same time. In particular, once any
activation of fib terminates, nothing accesses that instance of N any
more.

We can write fib in C, whose local variables turn to pixie dust when the
block scope ends, allowing a simple stack to be used for locals.

Lexical closures mean that the variables visible in any activation of a
function can live indefinitely. Lexical closures are objects that can
escape from the context where they are created, and be invoked after
that context has terminated.

none albert

unread,
Aug 15, 2023, 4:41:05 AM8/15/23
to
In article <202308150...@kylheku.com>,
Kaz Kylheku <864-11...@kylheku.com> wrote:
>On 2023-08-15, albert@cherry.(none) (albert) <albert@cherry> wrote:
>> That would mean that
>> (def! fib (fn* (N) (if (= N 0) 1
>> (if (= N 1) 1 (+ (fib (- N 1))
>> (fib (- N 2)))))))
>> would fail, but it isn't:
>> (fib 10)
>
>fib is not capturing lexical closures. There are multiple instances, but
>they are not accessible at the same time. In particular, once any
>activation of fib terminates, nothing accesses that instance of N any
>more.

Obviously not, I observed that. The test for capturing lexical closures
fails, but fib is not.

<SNIP>
>Lexical closures mean that the variables visible in any activation of a
>function can live indefinitely. Lexical closures are objects that can
>escape from the context where they are created, and be invoked after
>that context has terminated.
This is lisp parlance. The concept of lexical closures is present
in algol 68, but the term is not used.
Any language that supports functions within functions, functions as
first order objects and persistance (items created in a function that
have a life span longer than the function call) has this feature.

>Mastodon: @Kazi...@mstdn.ca

Groetjes Albert
0 new messages