Rocksolid Light

Welcome to Rocksolid Light

mail  files  register  newsreader  groups  login

Message-ID:  

Everyone has a purpose in life. Perhaps yours is watching television. -- David Letterman


devel / comp.lang.forth / Re: tail call optimisation, lisp implemented in Forth

SubjectAuthor
* tail call optimisation, lisp implemented in Forthnone
+* Re: tail call optimisation, lisp implemented in Forthminforth
|`- Re: tail call optimisation, lisp implemented in Forthnone
`- Re: tail call optimisation, lisp implemented in Forthnone

1
tail call optimisation, lisp implemented in Forth

<nnd$7d844dab$52db8b4e@a0541ff0868dc0dd>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=24033&group=comp.lang.forth#24033

  copy link   Newsgroups: comp.lang.forth comp.lang.lisp
Newsgroups: comp.lang.forth,comp.lang.lisp
Subject: tail call optimisation, lisp implemented in Forth
X-Newsreader: trn 4.0-test77 (Sep 1, 2010)
From: albert@cherry (none)
Originator: albert@cherry.(none) (albert)
Message-ID: <nnd$7d844dab$52db8b4e@a0541ff0868dc0dd>
Organization: KPN B.V.
Date: Mon, 17 Jul 2023 10:56:19 +0200
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!feeder1.feed.usenet.farm!feed.usenet.farm!peer01.ams4!peer.am4.highwinds-media.com!news.highwinds-media.com!feed.abavia.com!abe004.abavia.com!abp002.abavia.com!news.kpn.nl!not-for-mail
Lines: 72
Injection-Date: Mon, 17 Jul 2023 10:56:19 +0200
Injection-Info: news.kpn.nl; mail-complaints-to="abuse@kpn.com"
X-Received-Bytes: 3515
 by: none - Mon, 17 Jul 2023 08:56 UTC

I'm following the instructions of mal (clojure)
https://github.com/kanaka/mal

The instruction in mal step 5 :
Several of the special forms that you have defined in EVAL end up
calling back into EVAL. For those forms that call EVAL as the last
thing that they do before returning (tail call) you will just loop
back to the beginning of eval rather than calling it again.

I come to realize that an implementation of a lisp without tail cal
optimisation is a joke. So this is all but mandatory.

In the context of my Forth implementation a function, say `` if ''
is looked up in the environment, it is special, so it leaves
evaluation of the rest of the list to the discretion of `` if ''.
The bottom line is that there is no way to construct an infinite
loop around special functions, as proposed, in the vein of
"
while true: // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
if not list?(ast): return eval_ast(ast, env)
if empty?(ast): return ast
switch ast[0]:
'def!: return env.set(ast[1], EVAL(ast[2], env))
'let*: env = ...; ast = ast[2] // TCO
'do: ast = eval_ast(ast[1..-1], env)[-1] // TCO
'if: EVAL(ast[1], env) ? ast = ast[2] : ast = ast[3] // TCO
'fn*: return new MalFunc(...)
_default_: f, args = eval_ast(ast, env)
if malfunc?(f): ast = f.fn; env = ... // TCO
else: return apply(f, args)
"
In Forth `` eval '' is a colon definition , that is, a machine code
pointer and an array of tokens. The machine code takes care that
the tokens are interpreted via the SI register (x86)
Nesting is accomplished by storing SI in the return stack
pointed to by the EBP register.
These are the instructions.

DOCOL: LEA EBP,[EBP - (CW*(1))] ; *
MOV [EBP],ESI ; *
MOV ESI,[EAX+(CW*(D_HOFFSET - C_HOFFSET))] ; *
LODSD ; NEXT
JMP DWORD[EAX]

Nesting is marked with *.
The NEXT code takes care that the following token is fetched an
executed. This changes SI.

TCO (tail call optimisation) is accomplished by leaving out the
nesting.
DOCOLPRIME:
LODSD ; NEXT
JMP DWORD[EAX]

So we have
: eval .... ;
and we can define an alias and we fix the code pointer CFA .
'eval ALIAS eval-prime
DOCOLPRIME 'eval-prime >CFA !

So we can change each terminating eval with eval-prime without
bothering with other functions that may or may not be special.

How cool is that!

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 -

Re: tail call optimisation, lisp implemented in Forth

<de4f9e06-64bd-4447-8a57-c173faf76546n@googlegroups.com>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=24034&group=comp.lang.forth#24034

  copy link   Newsgroups: comp.lang.forth
X-Received: by 2002:a05:622a:1713:b0:3ff:3013:d2b0 with SMTP id h19-20020a05622a171300b003ff3013d2b0mr77508qtk.0.1689589036308; Mon, 17 Jul 2023 03:17:16 -0700 (PDT)
X-Received: by 2002:a05:6808:1b07:b0:39a:5a77:b1f1 with SMTP id bx7-20020a0568081b0700b0039a5a77b1f1mr14533524oib.4.1689589036104; Mon, 17 Jul 2023 03:17:16 -0700 (PDT)
Path: i2pn2.org!i2pn.org!usenet.blueworldhosting.com!diablo1.usenet.blueworldhosting.com!feeder.usenetexpress.com!tr3.iad1.usenetexpress.com!69.80.99.14.MISMATCH!border-1.nntp.ord.giganews.com!nntp.giganews.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.forth
Date: Mon, 17 Jul 2023 03:17:15 -0700 (PDT)
In-Reply-To: <nnd$7d844dab$52db8b4e@a0541ff0868dc0dd>
Injection-Info: google-groups.googlegroups.com; posting-host=2003:f7:1f3a:cbb0:4cc:8aea:1511:c468; posting-account=AqNUYgoAAADmkK2pN-RKms8sww57W0Iw
NNTP-Posting-Host: 2003:f7:1f3a:cbb0:4cc:8aea:1511:c468
References: <nnd$7d844dab$52db8b4e@a0541ff0868dc0dd>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <de4f9e06-64bd-4447-8a57-c173faf76546n@googlegroups.com>
Subject: Re: tail call optimisation, lisp implemented in Forth
From: minforth@arcor.de (minforth)
Injection-Date: Mon, 17 Jul 2023 10:17:16 +0000
Content-Type: text/plain; charset="UTF-8"
Lines: 5
 by: minforth - Mon, 17 Jul 2023 10:17 UTC

TCO through not adding a new stack frame is a well-known technique:
https://en.wikipedia.org/wiki/Tail_call

Patching execution tokens / function pointers on the fly is analogous to
self-modifying code. Can work well as long as the affected memory address
allows it. In some cases memory protection mechanisms may cut in.

Re: tail call optimisation, lisp implemented in Forth

<nnd$2f9f9937$360b68ef@79baa9a6e5621790>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=24036&group=comp.lang.forth#24036

  copy link   Newsgroups: comp.lang.forth
Newsgroups: comp.lang.forth
References: <nnd$7d844dab$52db8b4e@a0541ff0868dc0dd> <de4f9e06-64bd-4447-8a57-c173faf76546n@googlegroups.com>
Subject: Re: tail call optimisation, lisp implemented in Forth
X-Newsreader: trn 4.0-test77 (Sep 1, 2010)
From: albert@cherry (none)
Originator: albert@cherry.(none) (albert)
Message-ID: <nnd$2f9f9937$360b68ef@79baa9a6e5621790>
Organization: KPN B.V.
Date: Mon, 17 Jul 2023 13:09:28 +0200
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!feeder1.feed.usenet.farm!feed.usenet.farm!peer02.ams4!peer.am4.highwinds-media.com!news.highwinds-media.com!feed.abavia.com!abe004.abavia.com!abp001.abavia.com!news.kpn.nl!not-for-mail
Lines: 31
Injection-Date: Mon, 17 Jul 2023 13:09:28 +0200
Injection-Info: news.kpn.nl; mail-complaints-to="abuse@kpn.com"
X-Received-Bytes: 2144
 by: none - Mon, 17 Jul 2023 11:09 UTC

In article <de4f9e06-64bd-4447-8a57-c173faf76546n@googlegroups.com>,
minforth <minforth@arcor.de> wrote:
>TCO through not adding a new stack frame is a well-known technique:
>https://en.wikipedia.org/wiki/Tail_call
>
>Patching execution tokens / function pointers on the fly is analogous to
>self-modifying code. Can work well as long as the affected memory address
>allows it. In some cases memory protection mechanisms may cut in.

Although my mal implementation abounds with self modifying code
(as long as adding new definitions to a Forth is self modifying)
this is not patching.
You could define a :C analogous to : in a kernel and use :C
hencetoforth. In this case it doesn't require the Forth segment
to be executable and memory protection doesn't apply at all.

In the case I add a :C lateron I need the Forth segment to
be executable. That is not properly described as patching
execution tokens / function pointers.
The phrase "analogous to self-modifying code" is particularly
unenlightening. Usage of DEFER/IS in Forth or usage and modification
of pointers to functions in c is commonly not described as
"self modifying".

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 -

Re: tail call optimisation, lisp implemented in Forth

<nnd$7e86fc7e$471f840d@f35175c57801cac4>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=24037&group=comp.lang.forth#24037

  copy link   Newsgroups: comp.lang.forth comp.lang.lisp
Newsgroups: comp.lang.forth,comp.lang.lisp
Subject: Re: tail call optimisation, lisp implemented in Forth
References: <nnd$7d844dab$52db8b4e@a0541ff0868dc0dd>
X-Newsreader: trn 4.0-test77 (Sep 1, 2010)
From: albert@cherry (none)
Originator: albert@cherry.(none) (albert)
Message-ID: <nnd$7e86fc7e$471f840d@f35175c57801cac4>
Organization: KPN B.V.
Date: Mon, 17 Jul 2023 19:37:58 +0200
Path: i2pn2.org!i2pn.org!usenet.blueworldhosting.com!diablo1.usenet.blueworldhosting.com!peer03.iad!feed-me.highwinds-media.com!peer01.ams4!peer.am4.highwinds-media.com!news.highwinds-media.com!feed.abavia.com!abe006.abavia.com!abp001.abavia.com!news.kpn.nl!not-for-mail
Lines: 43
Injection-Date: Mon, 17 Jul 2023 19:37:58 +0200
Injection-Info: news.kpn.nl; mail-complaints-to="abuse@kpn.com"
X-Received-Bytes: 2307
 by: none - Mon, 17 Jul 2023 17:37 UTC

In article <nnd$7d844dab$52db8b4e@a0541ff0868dc0dd>,
none) (albert <albert@cherry.> wrote:
>I'm following the instructions of mal (clojure)
> https://github.com/kanaka/mal
>
>The instruction in mal step 5 :
>Several of the special forms that you have defined in EVAL end up
>calling back into EVAL. For those forms that call EVAL as the last
>thing that they do before returning (tail call) you will just loop
>back to the beginning of eval rather than calling it again.
>
<SNIP>
>Nesting is accomplished by storing SI in the return stack
>pointed to by the EBP register.
>These are the instructions.
>
>DOCOL: LEA EBP,[EBP - (CW*(1))] ; *
> MOV [EBP],ESI ; *
> MOV ESI,[EAX+(CW*(D_HOFFSET - C_HOFFSET))] ; *
> LODSD ; NEXT
> JMP DWORD[EAX]
>
>Nesting is marked with *.

This must be, of course:
DOCOL: LEA EBP,[EBP - (CW*(1))] ; *
MOV [EBP],ESI ; *
MOV ESI,[EAX+(CW*(D_HOFFSET - C_HOFFSET))]
LODSD ; NEXT
JMP DWORD[EAX]

(EAX points to the header and ESI must be loaded anew.)

>
>How cool is that!
>
>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 -

1
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor