Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #135571 > unrolled thread
| Started by | Hans Bezemer <the.beez.speaks@gmail.com> |
|---|---|
| First post | 2026-09-05 19:55 +0200 |
| Last post | 2026-09-08 17:18 +0200 |
| Articles | 16 on this page of 36 — 9 participants |
Back to article view | Back to comp.lang.forth
Postscript in 4tH Hans Bezemer <the.beez.speaks@gmail.com> - 2026-09-05 19:55 +0200
Re: Postscript in 4tH Paul Rubin <no.email@nospam.invalid> - 2026-09-05 15:54 -0700
Re: Postscript in 4tH albert@spenarnc.xs4all.nl - 2026-09-06 11:08 +0200
Re: Postscript in 4tH Paul Rubin <no.email@nospam.invalid> - 2026-09-07 09:24 -0700
Re: Postscript in 4tH albert@spenarnc.xs4all.nl - 2026-09-07 23:47 +0200
Re: Postscript in 4tH Kragen Javier Sitaker <kragen@canonical.org> - 2026-09-08 02:09 -0300
Re: Postscript in 4tH Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-09-08 20:34 +0000
Re: Postscript in 4tH Kragen Javier Sitaker <kragen@canonical.org> - 2026-09-08 22:38 -0300
Re: Postscript in 4tH Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-09-09 03:05 +0000
XML in Pythong (was: Re: Postscript in 4tH) Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-09-09 15:00 +0800
Re: Postscript in 4tH Kragen Javier Sitaker <kragen@canonical.org> - 2026-09-10 01:06 -0300
Re: Postscript in 4tH Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-09-10 07:38 +0000
Re: Postscript in 4tH Peter Flass <Peter@Iron-Spring.com> - 2026-09-10 07:39 -0700
Re: Postscript in 4tH antispam@fricas.org (Waldek Hebisch) - 2026-09-15 16:04 +0000
Re: Postscript in 4tH Paul Rubin <no.email@nospam.invalid> - 2026-09-15 09:24 -0700
Re: Postscript in 4tH Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-09-09 15:15 +0800
Re: Postscript in 4tH Kragen Javier Sitaker <kragen@canonical.org> - 2026-09-10 01:11 -0300
Re: Postscript in 4tH anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-09-09 07:35 +0000
Re: Postscript in 4tH Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-09-09 08:10 +0000
Re: Postscript in 4tH Hans Bezemer <the.beez.speaks@gmail.com> - 2026-09-10 17:58 +0200
Re: Postscript in 4tH Kragen Javier Sitaker <kragen@canonical.org> - 2026-09-10 01:44 -0300
Re: Postscript in 4tH Paul Rubin <no.email@nospam.invalid> - 2026-09-09 03:01 -0700
Re: Postscript in 4tH albert@spenarnc.xs4all.nl - 2026-09-09 14:05 +0200
Re: Postscript in 4tH anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-09-09 06:42 +0000
Re: Postscript in 4tH Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-09-09 08:28 +0000
Re: Postscript in 4tH anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2026-09-09 10:03 +0000
Re: Postscript in 4tH Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-09-09 22:17 +0000
Re: Postscript in 4tH albert@spenarnc.xs4all.nl - 2026-09-09 14:42 +0200
Re: Postscript in 4tH antispam@fricas.org (Waldek Hebisch) - 2026-09-09 19:17 +0000
Re: Postscript in 4tH albert@spenarnc.xs4all.nl - 2026-09-10 12:22 +0200
Re: Postscript in 4tH Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-09-09 21:54 +0000
Re: Postscript in 4tH Paul Rubin <no.email@nospam.invalid> - 2026-09-09 22:14 -0700
Re: Postscript in 4tH albert@spenarnc.xs4all.nl - 2026-09-10 12:30 +0200
Re: Postscript in 4tH albert@spenarnc.xs4all.nl - 2026-09-09 14:36 +0200
Re: Postscript in 4tH Hans Bezemer <the.beez.speaks@gmail.com> - 2026-09-06 14:27 +0200
Re: Postscript in 4tH Hans Bezemer <the.beez.speaks@gmail.com> - 2026-09-08 17:18 +0200
Page 2 of 2 — ← Prev page 1 [2]
| From | Kragen Javier Sitaker <kragen@canonical.org> |
|---|---|
| Date | 2026-09-10 01:44 -0300 |
| Message-ID | <8733vhaf5g.fsf@debian> |
| In reply to | #135620 |
anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
> Kragen Javier Sitaker <kragen@canonical.org> writes:
>>PostScript has several other key similarities to Lisp. Referencing Paul
>>Graham's "What Made Lisp Different" <https://paulgraham.com/diff.html>:
>
> Given your claim below that Forth has only #1, #3, #9, let's look at
> the others:
>
>>2. A function type. “In Lisp, functions are first class objects--
>>they’re a data type just like integers, strings, etc, and have a literal
>>representation, can be stored in variables, can be passed as arguments,
>>and so on.”
>
> Forth has execution tokens.
I thought about this when posting. Xts certainly can be stored in
variables or passed around as arguments or results. But orthodox Forth
doesn’t have Joy-like quotations, which I think is the language feature
that allows you to claim that functions “have a literal representation”,
although it does have `:noname`. Orthodox Forth is almost the same as C
in this sense, in that you must define all of your functions at the top
level. Function pointers such as Forth xts provide a very significant
gain in expressiveness, but function *literals* add so much
expressiveness that you can use them to define custom control
structures, as in Smalltalk (or PostScript).
Lisp programs also commonly create new functions at runtime, although in
modern Lisp this is largely limited to creating closures. Forth has
closures in the form of `create does>`, but because that appends to the
dictionary, you don’t normally do it willy-nilly, usually only when you
are loading a program.
>>4. A new concept of variables. “In Lisp, all variables are effectively
>>pointers. Values are what have types, not variables, and assigning or
>>binding variables means copying pointers, not what they point to.”
>
> In Forth, neither variables nor values have types that are known to
> the Forth system. The way to use that is that the programmer must
> know the type, and that typically means always storing the same type
> into a variable.
That is certainly true, but to my eye, Forth is much more similar to
assembly, Fortran, or C in this sense than to Lisp. You might `create`
an array and give it a name, for example, and you can think of that name
as referring to the beginning of the array (like a label in assembly
language) or to the entire array (as in Fortran or C), but it definitely
does not refer to a cell somewhere holding a *pointer to* the array, the
way it does in Lisp and PostScript (or Python, or JS, or Lua, or
Smalltalk, etc.)
Forth uses the term `variable` for single-cell variables, and those are
often used to store integers that are not pointers. Some Lisps (and,
for example, Lua and Squeak) avoid “boxing” their integers in a memory
allocation by packing type bits into a pointer, but this trick is
invisible to the language semantics, while it is very visible in Forth.
>>6. Programs composed of expressions. Not really, but closer than any of
>>the currently popular languages.
>
> Forth is like Postscript here: Programs composed of words (operators
> in Postscript), which work on values on the stack.
Yes. D’Oliveiro suggested that what PG intended here was that there’s
no distinction between statements and expresions, which is plausible;
but, as I see it, in neither PostScript nor Forth do we have clear-cut
expressions in the syntax, so even if PostScript (and Forth) fit what PG
intended to say, they do not fit what he actually said.
>>7. A symbol type. Yes, PostScript distinguishes /names from strings,
>
> Forth distinguishes name tokens from strings, but they do not play the
> role they play in Lisp or Postscript; in particular, you have to
> create new named words outside a colon definitions, and if you use a
> named word to get a unique value, you tend to use its body address,
> not its name token.
I had forgotten about name tokens; thank you for the reminder.
>>8. A notation for code using trees of symbols. Yes. The only
>>difference is that in conventional Lisp they’re binary trees, while in
>>PostScript they’re N-ary ordered trees.
>
> As mentioned in <2026Sep9.084205@mips.complang.tuwien.ac.at>, one
> might consider the indirect-threaded code representation and its
> modern equivalents for inlining to be such a notation, but in Forth
> many control structures become branches, whereas in Postscript the
> controlled stuff is a procedure (in Forth terminology, a quotation).
As you say, Forth flattens the tree into an array at compile time.
Also, though, it is entirely omitted from the standards, so that Forths
that do not use threaded code can still count as “compliant”.
The things in the array are generally not name tokens, but execution
tokens. PostScript supports either one, and people usually do `bind`
their subroutines, replacing the symbols with subroutine pointers, so
that they run faster:
GS>/square {dup mul} def
GS>4 square =
16
GS>/square load ===
{dup mul}
GS>/square load bind ===
{--dup-- --mul--}
>>Forth hits #1, #3, and #9.
>
> And also #2, and partially #6, #7, and #8.
Well, that’s certainly a defensible position, but I think it’s still
debatable.
Thank you very much for your thought-provoking post.
Kragen
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2026-09-09 03:01 -0700 |
| Message-ID | <87se3ikal8.fsf@nightsong.com> |
| In reply to | #135613 |
Kragen Javier Sitaker <kragen@canonical.org> writes: > At the time that PostScript was designed, most Lisps did not have > macros; they still had fexprs.... PostScript first shipped in 01982, 1982 was right in Lisp's heyday and I expect the major implementations all had macros (Maclisp, Lisp Machine Lisp and its descendants, Nil, Spicelisp). Scheme was around and didn't have macros but I don't think it had fexprs either. > Given that PostScript clearly hits 8 out of 9 of these criteria, and > arguably all 9, while no then-popular language other than Lisp came > anywhere close, I think it’s pretty clear that it mostly belongs to the > Lisp family. I think that list is pretty bogus. The main characteristic of Lisp imho is lambda calculus and lambda binding. In order to even have a local variable in a PostScript function, you have to literally push a dictionary on the evaluation stack and invoke BEGIN, then later END to pop the dictionary stack, like Forth wordlists.
[toc] | [prev] | [next] | [standalone]
| From | albert@spenarnc.xs4all.nl |
|---|---|
| Date | 2026-09-09 14:05 +0200 |
| Message-ID | <nnd$66ac8d37$0fe57054@d549c6987e9e0f52> |
| In reply to | #135613 |
In article <87o6e7cifh.fsf@debian>,
Kragen Javier Sitaker <kragen@canonical.org> wrote:
>(Please forgive in advance the LLM-like wording of what follows. I
>wrote it entirely by hand, including reading the documents I linked, but
>I’ve been coaxing
>
>Lawrence D’Oliveiro <ldo@nz.invalid> writes:
>> On Tue, 08 Sep 2026 02:09:43 -0300, Kragen Javier Sitaker wrote:
>>> I think of PostScript as being Lisp, more or less, but with
>>> quasi-Forth syntax ...
>>
>> PostScript is homoiconic, but the resemblance to Lisp ends there. Lisp
>> has macros, PostScript doesn’t. Lisp needs macros,
>
>At the time that PostScript was designed, most Lisps did not have
>macros; they still had fexprs. Some Lisps did have macros, most notably
>MACLISP, but they had not yet become central to language style the way
>they are today. Remember that PostScript first shipped in 01982, when
>the world was dominated by BASIC, FORTRAN, and COBOL.
>
>PostScript does in fact have something like readmacros; in particular,
>readhexstring was the recommended way to handle image data, so that the
>image data didn’t have to be loaded into a PostScript object by way of
>the PostScript parser. But, for the most part, like Smalltalk,
>PostScript uses a lightweight lambda syntax for most of the things you
>would use macros for in Lisp.
I was thinking about a simplified Forth where the { .. } is a behaviour,
say a lambda. (Actually it works more or less.)
: SQUARE DUP * ;
becomes
{ DUP * } : SQUARE ; Squaring (n -- n^2)
: CONSTANT CREATE , DOES> @ ;
becomes
{ , } { @ } META CONSTANT ; execute NETA, add CONSTANT to dictionary.
It does away with idosyncratic stuff like:
:NONAME ; CREATE DOES> [: ;]
; replaces \ .
<SNIP>
>Kragen
--
The Chinese government is satisfied with its military superiority over USA.
The next 5 year plan has as primary goal to advance life expectancy
over 80 years, like Western Europe.
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2026-09-09 06:42 +0000 |
| Message-ID | <2026Sep9.084205@mips.complang.tuwien.ac.at> |
| In reply to | #135611 |
Lawrence =?iso-8859-13?q?D=FFOliveiro?= <ldo@nz.invalid> writes:
>Lisp needs macros, because it also has
>"special forms" for syntactic constructs that implement things like
>control constructs, declarations etc. PostScript doesn’t have "special
>forms", since all these concepts are implemented as built-in
>functions. Which is also why it doesn’t need macros.
You cannot get around this kind of stuff. Postscript has a subparser
for executable arrays ({ ... }) that behaves completely differently
from the regular parser that is also used to build literal arrays ([
... ]). Forth has interpret state and compile state. The regular
Postscript parser can be considered to be similar to interpret state
(operators are executed), while the parser for executable arrays is
similar to compile state (operators become part of the array).
In Lisp, if you have a function like +, it's operands are evaluated
and then passed to the function (comparable to interpret state),
whereas a special form like defun (or whatever it's name is in your
dialect of Lisp), the components are not evaluated by the REPL, but
passed uninterpreted to the special form.
>Also, Forth never heard of homoiconicity ...
The traditional indirect-threaded-code implememtations can be
considered homoiconic, and I wrote a word in the 1980s that made use
of this property to show a call graph of Forth words. Also,
decompilers made use of this property.
When Forth implementations became more advanced and switched to native
code, some (commercial) implementations abandoned that feature (paying
custormers pay to have the Forth vendor work on the innards, or at
least that's what the vendor's think; presentations by Nick Nelson,
one of the paying customers, make me think differently), while others
still have similar stuff as an intermediate representation that is
used for inlining and sometimes decompilation; one commercial
implementation probably also has an intermediate representation for
inlining, but I have not seen it using it for decompilation.
These days, one could consider the sequence of translations (in the
sense of the recognizer proposal
<https://forth-standard.org/proposals/recognizer-committee-proposal-2025-09-11?hideDiff#reply-1686>)
of a Forth program to be the homoiconic representation, except for one
problem: translations may parse, and the translation returned from
REC-STRING often does parse.
However, after the translation, we do not have a central point for
collecting the data; one might consider the sequence of calls made by
the translations to EXECUTE COMPILE, LITERAL SLITERAL etc. (combined
with their arguments) to be a homoiconic representation, but the
question is where the "etc." above stops.
- 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 2026 CFP: http://www.euroforth.org/ef26/cfp.html
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-09-09 08:28 +0000 |
| Message-ID | <117r5b2$u52n$5@dont-email.me> |
| In reply to | #135619 |
On Wed, 09 Sep 2026 06:42:05 GMT, Anton Ertl wrote:
> On Tue, 8 Sep 2026 20:34:07 -0000 (UTC), Lawrence D’Oliveiro wrote:
>>
>> Lisp needs macros, because it also has “special forms” for
>> syntactic constructs that implement things like control constructs,
>> declarations etc. PostScript doesn’t have “special forms”, since
>> all these concepts are implemented as built-in functions. Which is
>> also why it doesn’t need macros.
>
> You cannot get around this kind of stuff. Postscript has a subparser
> for executable arrays ({ ... }) that behaves completely differently
> from the regular parser that is also used to build literal arrays ([
> ... ]).
I have implemented an actual PostScript-like language. The token
interpreter core looks basically like this:
def interpret(ctx, sym, symval : bytes) :
"callback from lexer to interpret next symbol."
...
a few dozen lines to do various symbol specific processing,
culminating in the construction of a token object in the_obj
...
if len(ctx.currentprocs) != 0 :
ctx.currentprocs[-1].append(the_obj)
else :
ctx.execute(the_obj, doproc = False)
#end if
#end interpret
So the only difference in the parser between being inside a procedure
definition (there is an entry in the ctx.currentprocs stack of
in-progress procedure definitions) and outside it comes down to that
last if-statement: if inside, append the just-parsed object (symbol,
literal, nested procedure, whatever) to the current procedure
definition; if outside, just execute it directly.
>> Also, Forth never heard of homoiconicity ...
>
> The traditional indirect-threaded-code implememtations can be
> considered homoiconic, and I wrote a word in the 1980s that made use
> of this property to show a call graph of Forth words. Also,
> decompilers made use of this property.
That’s a limited form of read-only introspection. You couldn’t do
transformations on the AST or such, could you? For a start, that would
require dynamic memory allocation, which Forth doesn’t have.
Even Java could probably manage what Forth does, and nobody would call
it “homoiconic”.
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2026-09-09 10:03 +0000 |
| Message-ID | <2026Sep9.120313@mips.complang.tuwien.ac.at> |
| In reply to | #135622 |
Lawrence =?iso-8859-13?q?D=FFOliveiro?= <ldo@nz.invalid> writes:
>On Wed, 09 Sep 2026 06:42:05 GMT, Anton Ertl wrote:
>> You cannot get around this kind of stuff. Postscript has a subparser
>> for executable arrays ({ ... }) that behaves completely differently
>> from the regular parser that is also used to build literal arrays ([
>> ... ]).
[...]
> if len(ctx.currentprocs) != 0 :
> ctx.currentprocs[-1].append(the_obj)
> else :
> ctx.execute(the_obj, doproc = False)
> #end if
> #end interpret
>
>So the only difference in the parser between being inside a procedure
>definition (there is an entry in the ctx.currentprocs stack of
>in-progress procedure definitions) and outside it comes down to that
>last if-statement: if inside, append the just-parsed object (symbol,
>literal, nested procedure, whatever) to the current procedure
>definition; if outside, just execute it directly.
Sounds very much like compile state and interpret state.
>> The traditional indirect-threaded-code implememtations can be
>> considered homoiconic, and I wrote a word in the 1980s that made use
>> of this property to show a call graph of Forth words. Also,
>> decompilers made use of this property.
>
>That’s a limited form of read-only introspection. You couldn’t do
>transformations on the AST or such, could you?
Changing the compiled code was not common, but used. Even development
Gforth has:
|'replace-word' ( xt1 xt2 - ) gforth-1.0
| make xt2 do xt1, both need to be colon definitions
However, the more common approach is to change the source code and
load it again (typically in a new session, or after a FORGET or a
marker). And in Postscript and Lisp that's also the case.
And consequently, this feature of indirect-threaded code has been
abandoned by more advanced Forth systems. E.g., in Gforth, which
still has a threaded-code substrate, writing to some threaded-code
locations has no effect in the engines gforth and gforth-fast. If you
want to do such things, use the engine gforth-itc (for
indirect-threaded code).
>For a start, that would
>require dynamic memory allocation, which Forth doesn’t have.
Forth has what is usually understood under "dynamic memory
allocation", but it's not clear why that should be required for
writing to code.
- 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 2026 CFP: http://www.euroforth.org/ef26/cfp.html
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-09-09 22:17 +0000 |
| Message-ID | <117sluj$1gjra$7@dont-email.me> |
| In reply to | #135624 |
On Wed, 09 Sep 2026 10:03:13 GMT, Anton Ertl wrote:
> On Wed, 9 Sep 2026 08:28:18 -0000 (UTC), Lawrence D’Oliveiro wrote:
>
>> On Wed, 09 Sep 2026 06:42:05 GMT, Anton Ertl wrote:
>>
>>> You cannot get around this kind of stuff. Postscript has a
>>> subparser for executable arrays ({ ... }) that behaves completely
>>> differently from the regular parser that is also used to build
>>> literal arrays ([ ... ]).
>>
>> if len(ctx.currentprocs) != 0 :
>> ctx.currentprocs[-1].append(the_obj)
>> else :
>> ctx.execute(the_obj, doproc = False)
>> #end if
>> #end interpret
>>
>> So the only difference in the parser between being inside a
>> procedure definition (there is an entry in the ctx.currentprocs
>> stack of in-progress procedure definitions) and outside it comes
>> down to that last if-statement: if inside, append the just-parsed
>> object (symbol, literal, nested procedure, whatever) to the current
>> procedure definition; if outside, just execute it directly.
>
> Sounds very much like compile state and interpret state.
You said the “subparser ... behaves completely differently from the
regular parser that is also used to build literal arrays”. I showed
that it doesn’t.
>>> The traditional indirect-threaded-code implememtations can be
>>> considered homoiconic, and I wrote a word in the 1980s that made use
>>> of this property to show a call graph of Forth words. Also,
>>> decompilers made use of this property.
>>
>> That’s a limited form of read-only introspection. You couldn’t do
>> transformations on the AST or such, could you?
>
> Changing the compiled code was not common, but used. ...
In Lisp code, it’s very common.
> However, the more common approach is to change the source code and
> load it again (typically in a new session, or after a FORGET or a
> marker). And in Postscript and Lisp that's also the case.
The difference being, PostScript and Lisp have a more efficient
approach to dealing with the memory occupied by the deleted objects.
>> For a start, that would require dynamic memory allocation, which
>> Forth doesn’t have.
>
> Forth has what is usually understood under "dynamic memory
> allocation", but it's not clear why that should be required for
> writing to code.
More efficient memory management. In a dynamic language, you are
creating and deleting objects all the time, and not in a
last-in-first-out order. So you need a heap mechanism of some sort to
manage storage efficiently.
[toc] | [prev] | [next] | [standalone]
| From | albert@spenarnc.xs4all.nl |
|---|---|
| Date | 2026-09-09 14:42 +0200 |
| Message-ID | <nnd$5bb303af$6d539df9@bf8ade32fca4bcd8> |
| In reply to | #135622 |
In article <117r5b2$u52n$5@dont-email.me>, Lawrence DÿOliveiro <ldo@nz.invalid> wrote: <SNIP> >That’s a limited form of read-only introspection. You couldn’t do >transformations on the AST or such, could you? For a start, that would >require dynamic memory allocation, which Forth doesn’t have. Infinite memory is as good as dynamic memory. I can expand my Forth to e.g. 128 Gbyte that is for all practical purposes infinite. Then it is a small change to use ALLOCATE that is not in the kernel of my Forth, but it is a loadable extension. > >Even Java could probably manage what Forth does, and nobody would call >it “homoiconicâ€. -- The Chinese government is satisfied with its military superiority over USA. The next 5 year plan has as primary goal to advance life expectancy over 80 years, like Western Europe.
[toc] | [prev] | [next] | [standalone]
| From | antispam@fricas.org (Waldek Hebisch) |
|---|---|
| Date | 2026-09-09 19:17 +0000 |
| Message-ID | <117sbbg$3qin1$2@paganini.bofh.team> |
| In reply to | #135630 |
In comp.lang.forth albert@spenarnc.xs4all.nl wrote:
> In article <117r5b2$u52n$5@dont-email.me>,
> Lawrence DÿOliveiro <ldo@nz.invalid> wrote:
> <SNIP>
>>Thatâ??s a limited form of read-only introspection. You couldnâ??t do
>>transformations on the AST or such, could you? For a start, that would
>>require dynamic memory allocation, which Forth doesnâ??t have.
>
> Infinite memory is as good as dynamic memory. I can expand my Forth
> to e.g. 128 Gbyte that is for all practical purposes infinite.
Maybe it is enough for use with Forth. I have a computation that
runs out of memory in IIRC 100 GB. I do not think giving it full
128 GB would make a big difference. OTOH I am pretty sure that
this computation is finite, I simply do not know how much it
needs, maybe 256 GB, maybe terabyte.
More important, if you do not reclaim memory you eventually will
run out of it. And modern processors are fast, so it can happen
faster than you suspect. Of course, this is matter of programming
style. In Lisp program when I monitor memory use I see gigabytes
allocated in seconds. Without GC after few minutes all 128 GB
that I have would be gone.
--
Waldek Hebisch
[toc] | [prev] | [next] | [standalone]
| From | albert@spenarnc.xs4all.nl |
|---|---|
| Date | 2026-09-10 12:22 +0200 |
| Message-ID | <nnd$432caf24$659f6ace@ad95b52e6e30fcd7> |
| In reply to | #135632 |
In article <117sbbg$3qin1$2@paganini.bofh.team>, Waldek Hebisch <antispam@fricas.org> wrote: >In comp.lang.forth albert@spenarnc.xs4all.nl wrote: >> In article <117r5b2$u52n$5@dont-email.me>, >> Lawrence DÿOliveiro <ldo@nz.invalid> wrote: >> <SNIP> >>>Thatâ??s a limited form of read-only introspection. You couldnâ??t do >>>transformations on the AST or such, could you? For a start, that would >>>require dynamic memory allocation, which Forth doesnâ??t have. >> >> Infinite memory is as good as dynamic memory. I can expand my Forth >> to e.g. 128 Gbyte that is for all practical purposes infinite. > >Maybe it is enough for use with Forth. I have a computation that >runs out of memory in IIRC 100 GB. I do not think giving it full >128 GB would make a big difference. OTOH I am pretty sure that >this computation is finite, I simply do not know how much it >needs, maybe 256 GB, maybe terabyte. > >More important, if you do not reclaim memory you eventually will >run out of it. And modern processors are fast, so it can happen >faster than you suspect. Of course, this is matter of programming >style. In Lisp program when I monitor memory use I see gigabytes >allocated in seconds. Without GC after few minutes all 128 GB >that I have would be gone. I plan to use dynamic memory, if and when it becomes a problem for me. It is Forth filosofy. If the optimiser doesn't get finished at all, this is a waste of time. > >-- > Waldek Hebisch -- The Chinese government is satisfied with its military superiority over USA. The next 5 year plan has as primary goal to advance life expectancy over 80 years, like Western Europe.
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-09-09 21:54 +0000 |
| Message-ID | <117ski9$1gjra$2@dont-email.me> |
| In reply to | #135630 |
On Wed, 09 Sep 2026 14:42:10 +0200, albert wrote: > On Wed, 9 Sep 2026 08:28:18 -0000 (UTC), Lawrence D’Oliveiro wrote: > >> That’s a limited form of read-only introspection. You couldn’t do >> transformations on the AST or such, could you? For a start, that >> would require dynamic memory allocation, which Forth doesn’t have. > > Infinite memory is as good as dynamic memory. I can expand my Forth > to e.g. 128 Gbyte that is for all practical purposes infinite. Then > it is a small change to use ALLOCATE that is not in the kernel of my > Forth, but it is a loadable extension. Interestingly enough, some Lisp machines behaved in a similar way. They lacked garbage collection. After memory became full, you took a snapshot of all the live objects in your machine state, and rebooted. Reloading the snapshot left all the garbage behind, so you were able to resume work from there, until memory filled up again. Apparently you could typically go for longer than a day before filling all of memory. Not sure if this was a sign of how large memories had become by then, or how slow Lisp machines were ... Still, you get the point that that’s a crude way of managing memory. It is not good for handling long-running tasks. Also on modern multitasking systems, you might need to be running other things simultaneously, besides your Forth or Lisp program. So having the one process hog all available resources is ... not very sociable.
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2026-09-09 22:14 -0700 |
| Message-ID | <87h5jxk7rh.fsf@nightsong.com> |
| In reply to | #135634 |
Lawrence D’Oliveiro <ldo@nz.invalid> writes: > Apparently you could typically go for longer than a day before filling > all of memory. Not sure if this was a sign of how large memories had > become by then, or how slow Lisp machines were ... Lisp code in those days was written to avoid unnecessary allocation. You'd use imperative-style RPLACA/RPLACD (aka setcar/setcdr) a lot, nreverse, nconc, that sort of thing. All not really in the Lisp spirit, I would say, but it reflected Lisp programming practices from even earlier and more limited machines.
[toc] | [prev] | [next] | [standalone]
| From | albert@spenarnc.xs4all.nl |
|---|---|
| Date | 2026-09-10 12:30 +0200 |
| Message-ID | <nnd$432caf24$659f6ace@1b0d889235360ae2> |
| In reply to | #135634 |
In article <117ski9$1gjra$2@dont-email.me>, Lawrence D˙Oliveiro <ldo@nz.invalid> wrote: >On Wed, 09 Sep 2026 14:42:10 +0200, albert wrote: > >> On Wed, 9 Sep 2026 08:28:18 -0000 (UTC), Lawrence D’Oliveiro wrote: >> >>> That’s a limited form of read-only introspection. You couldn’t do >>> transformations on the AST or such, could you? For a start, that >>> would require dynamic memory allocation, which Forth doesn’t have. >> >> Infinite memory is as good as dynamic memory. I can expand my Forth >> to e.g. 128 Gbyte that is for all practical purposes infinite. Then >> it is a small change to use ALLOCATE that is not in the kernel of my >> Forth, but it is a loadable extension. > >Interestingly enough, some Lisp machines behaved in a similar way. >They lacked garbage collection. After memory became full, you took a >snapshot of all the live objects in your machine state, and rebooted. >Reloading the snapshot left all the garbage behind, so you were able >to resume work from there, until memory filled up again. > >Apparently you could typically go for longer than a day before filling >all of memory. Not sure if this was a sign of how large memories had >become by then, or how slow Lisp machines were ... > >Still, you get the point that that’s a crude way of managing memory. >It is not good for handling long-running tasks. > >Also on modern multitasking systems, you might need to be running >other things simultaneously, besides your Forth or Lisp program. So >having the one process hog all available resources is ... not very >sociable. My context is an optimiser. At one point the result is an optimised program, that is run, and all resources used by the optimiser can be released. The optimiser is not run for an undefinite time. Although garbage collection is convenient, ALLOCATE plus explicit release will be feasible for an optimiser, as far as I can tell. Groetjes Albert -- The Chinese government is satisfied with its military superiority over USA. The next 5 year plan has as primary goal to advance life expectancy over 80 years, like Western Europe.
[toc] | [prev] | [next] | [standalone]
| From | albert@spenarnc.xs4all.nl |
|---|---|
| Date | 2026-09-09 14:36 +0200 |
| Message-ID | <nnd$7b797a94$596c9278@d549c6987e9e0f52> |
| In reply to | #135619 |
In article <2026Sep9.084205@mips.complang.tuwien.ac.at>, Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote: >Lawrence =?iso-8859-13?q?D=FFOliveiro?= <ldo@nz.invalid> writes: <SNIP> >>Also, Forth never heard of homoiconicity ... > >The traditional indirect-threaded-code implememtations can be >considered homoiconic, and I wrote a word in the 1980s that made use >of this property to show a call graph of Forth words. Also, >decompilers made use of this property. ciforth (computer intelligence Forth) was originally intended to be a substrate for an intelligence. One of the first design goals is to understand itself. I didn't known the term homo-iconic, but is is similar. For example the ci would write a function and then analyse and speed up the function. So replacing functions as in actual brain. (A ci thinks for herself and formulates goals to understand the world better. The idea is to live in the real world, so giving her internet access.) I'm working on an optimiser that leans on this, starting from assigning properties to individual words that make it possible All AI aspirations are abandoned, but a reasonable optimiser is within reach. See also https://home.hccnet.nl/a.w.m.van.der.horst/forthlecture6.html > >- anton -- The Chinese government is satisfied with its military superiority over USA. The next 5 year plan has as primary goal to advance life expectancy over 80 years, like Western Europe.
[toc] | [prev] | [next] | [standalone]
| From | Hans Bezemer <the.beez.speaks@gmail.com> |
|---|---|
| Date | 2026-09-06 14:27 +0200 |
| Message-ID | <117jm6t$2bc6l$1@dont-email.me> |
| In reply to | #135573 |
On 06-09-2026 00:54, Paul Rubin wrote:
> Hans Bezemer <the.beez.speaks@gmail.com> writes:
>> Note that existing SVG programs can easily be converted to Postscript
>> by simply including the correct libraries and replace "SVGopen" by
>> "PSopen" and "SVGclose" by "PSclose".
>
> That's interesting as Postscript itself is a rather broken version of
> Forth. Do you mean with SVG calls you can do all the usual Postscript
> stuff including text rendering?
>
> I just wrote some Postscript code recently and hit some ridiculous snags
> due to dumb stuff in the language. They were fixable but "traps for the
> unwary" as it were.
First you have to realize those libraries aren't supposed to be a full
Postscript implementation, but rather a useful subset of the language
that will allow you to perform most basic tasks -- like:
- Drawing pixels (yes!)
- Drawing lines, circles, half circles, ellipses, polylines, polygons,
rectangles, stuff like that;
- Adding basic texts to those drawings.
In addition, it can do 3D graphs and Turtle graphs -- both in SVG and PS
-- and yes, with only minor changes to the code. E.g. this is a basic PS
example by Anton Ertl, converted to those libraries:
---8<---
\ example of how to do graphics by outputting Postscript (to Ghostscript)
\ This program is in the public domain. No Warranty.
\ Author: Anton Ertl
\ 4tH conversion: Hans Bezemer
\ this example just draws an sine wave. You could also do this
\ directly in Postscript.
\ For learning Postscript, look at the appropriate books or websites;
\ this program only uses very little and the comments don't explain
\ that.
include lib/psgraph.4th
include lib/pspoly.4th
include lib/fp1.4th
include lib/zenfsin.4th
[UNDEFINED] y' [IF]
: y' negate pic_height @ + ; ( y -- y')
[THEN]
: init-ps
s" psine.ps" PSopen abort" Cannot open 'psine.ps'"
512 256 canvas white whiteout black color
polyline[ ;
: data2coord ( f: rx f: ry -- rx1 ry1 )
\ transform from our data to Postscript coordinates
fswap 20 s>f f* 250 s>f f+ fswap
100 s>f f* 125 s>f f+ ;
: next-point ( f: rx f: ry -- )
fround f>s >r fround f>s r> y' swap +point ;
: finish-line ( -- )
\ only stroke actually draws the line, so this is a good time to
\ flush the output: earlier there is little effect, later delays
\ displaying the line
]poly PSclose ;
: sin-lines ( -- )
100 -100 do
i s>f 10 s>f f/ fdup fsin data2coord next-point
loop ;
: sin-graph ( -- )
init-ps sin-lines finish-line ;
\ We could now do the following to get postscript output (e.g., for
\ redirecting it to a file or a printer):
sin-graph
---8<---
This is the PS code generated by this program:
---8<---
%!PS-Adobe-3.0
%%Creator: 4tH PostScript library
%%Pages: 1
%%BoundingBox: 0 0 512 256
%%EndComments
0.75 setlinewidth
/Courier findfont
11 scalefont
setfont
% Example Usage:
/ellipse { % usage: X Y Rx Ry ellipse
matrix currentmatrix % save current transformation matrix
5 1 roll % roll parameters out of the way
translate % move to center X Y
scale % scale by Rx Ry
0 0 1 0 360 arc % draw unit circle
setmatrix % restore original transformation matrix
} def
% Macro definition: paints a rectangle
% Stack X Y width height
/rectangle {
newpath
4 2 roll % w h x y
moveto % w h
1 index 0 rlineto % w h
0 exch rlineto % w
neg 0 rlineto % --
closepath
} def
1.0000 1.0000 1.0000 setrgbcolor
0 0 512 256 rectfill
0.0000 0.0000 0.0000 setrgbcolor
newpath
50 179 moveto
52 171 lineto
54 162 lineto
56 152 lineto
58 142 lineto
60 132 lineto
62 123 lineto
64 113 lineto
66 103 lineto
68 93 lineto
70 84 lineto
72 75 lineto
74 67 lineto
76 59 lineto
78 52 lineto
80 45 lineto
82 40 lineto
84 35 lineto
86 31 lineto
88 28 lineto
90 26 lineto
92 25 lineto
94 25 lineto
96 26 lineto
98 28 lineto
100 31 lineto
102 35 lineto
104 40 lineto
106 46 lineto
108 52 lineto
110 59 lineto
112 67 lineto
114 76 lineto
116 85 lineto
118 94 lineto
120 103 lineto
122 113 lineto
124 123 lineto
126 133 lineto
128 143 lineto
130 153 lineto
132 162 lineto
134 171 lineto
136 180 lineto
138 188 lineto
140 196 lineto
142 202 lineto
144 208 lineto
146 213 lineto
148 218 lineto
150 221 lineto
152 223 lineto
154 225 lineto
156 225 lineto
158 224 lineto
160 223 lineto
162 220 lineto
164 217 lineto
166 212 lineto
168 207 lineto
170 201 lineto
172 194 lineto
174 186 lineto
176 178 lineto
178 169 lineto
180 160 lineto
182 151 lineto
184 141 lineto
186 131 lineto
188 121 lineto
190 111 lineto
192 101 lineto
194 92 lineto
196 82 lineto
198 73 lineto
200 65 lineto
202 57 lineto
204 50 lineto
206 44 lineto
208 39 lineto
210 34 lineto
212 30 lineto
214 28 lineto
216 26 lineto
218 25 lineto
220 25 lineto
222 26 lineto
224 29 lineto
226 32 lineto
228 36 lineto
230 41 lineto
232 47 lineto
234 53 lineto
236 61 lineto
238 69 lineto
240 77 lineto
242 86 lineto
244 95 lineto
246 105 lineto
248 115 lineto
250 125 lineto
252 135 lineto
254 145 lineto
256 155 lineto
258 164 lineto
260 173 lineto
262 181 lineto
264 189 lineto
266 197 lineto
268 203 lineto
270 209 lineto
272 214 lineto
274 218 lineto
276 221 lineto
278 224 lineto
280 225 lineto
282 225 lineto
284 224 lineto
286 222 lineto
288 220 lineto
290 216 lineto
292 211 lineto
294 206 lineto
296 200 lineto
298 193 lineto
300 185 lineto
302 177 lineto
304 168 lineto
306 158 lineto
308 149 lineto
310 139 lineto
312 129 lineto
314 119 lineto
316 109 lineto
318 99 lineto
320 90 lineto
322 81 lineto
324 72 lineto
326 64 lineto
328 56 lineto
330 49 lineto
332 43 lineto
334 38 lineto
336 33 lineto
338 30 lineto
340 27 lineto
342 26 lineto
344 25 lineto
346 25 lineto
348 27 lineto
350 29 lineto
352 32 lineto
354 37 lineto
356 42 lineto
358 48 lineto
360 54 lineto
362 62 lineto
364 70 lineto
366 79 lineto
368 88 lineto
370 97 lineto
372 107 lineto
374 117 lineto
376 127 lineto
378 137 lineto
380 147 lineto
382 156 lineto
384 165 lineto
386 174 lineto
388 183 lineto
390 191 lineto
392 198 lineto
394 204 lineto
396 210 lineto
398 215 lineto
400 219 lineto
402 222 lineto
404 224 lineto
406 225 lineto
408 225 lineto
410 224 lineto
412 222 lineto
414 219 lineto
416 215 lineto
418 210 lineto
420 205 lineto
422 198 lineto
424 191 lineto
426 183 lineto
428 175 lineto
430 166 lineto
432 157 lineto
434 147 lineto
436 137 lineto
438 127 lineto
440 118 lineto
442 108 lineto
444 98 lineto
446 88 lineto
448 79 lineto
stroke
showpage
%%EOF
---8<---
And this is the SVG code:
---8<---
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="512" height="256" viewBox="0 0 512 256"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect width="100%" height="100%" fill="#FFFFFF" />
<polyline points="50,77 52,85 54,94 56,104 58,114 60,124 62,133 64,143
66,153 68,163 70,172 72,181 74,189 76,197 78,204 80,211
82,216 84,221 86,225 88,228 90,230 92,231 94,231 96,230
98,228 100,225 102,221 104,216 106,210 108,204 110,197 112,189
114,180 116,171 118,162 120,153 122,143 124,133 126,123 128,113
130,103 132,94 134,85 136,76 138,68 140,60 142,54 144,48
146,43 148,38 150,35 152,33 154,31 156,31 158,32 160,33
162,36 164,39 166,44 168,49 170,55 172,62 174,70 176,78
178,87 180,96 182,105 184,115 186,125 188,135 190,145 192,155
194,164 196,174 198,183 200,191 202,199 204,206 206,212 208,217
210,222 212,226 214,228 216,230 218,231 220,231 222,230 224,227
226,224 228,220 230,215 232,209 234,203 236,195 238,187 240,179
242,170 244,161 246,151 248,141 250,131 252,121 254,111 256,101
258,92 260,83 262,75 264,67 266,59 268,53 270,47 272,42
274,38 276,35 278,32 280,31 282,31 284,32 286,34 288,36
290,40 292,45 294,50 296,56 298,63 300,71 302,79 304,88
306,98 308,107 310,117 312,127 314,137 316,147 318,157 320,166
322,175 324,184 326,192 328,200 330,207 332,213 334,218 336,223
338,226 340,229 342,230 344,231 346,231 348,229 350,227 352,224
354,219 356,214 358,208 360,202 362,194 364,186 366,177 368,168
370,159 372,149 374,139 376,129 378,119 380,109 382,100 384,91
386,82 388,73 390,65 392,58 394,52 396,46 398,41 400,37
402,34 404,32 406,31 408,31 410,32 412,34 414,37 416,41
418,46 420,51 422,58 424,65 426,73 428,81 430,90 432,99
434,109 436,119 438,129 440,138 442,148 444,158 446,168 448,177"
fill="none" stroke="#000000" />
</svg>
---8<---
With some care, it is also possible to generate a raster representation
of the same graph.
Hans Bezemer
[toc] | [prev] | [next] | [standalone]
| From | Hans Bezemer <the.beez.speaks@gmail.com> |
|---|---|
| Date | 2026-09-08 17:18 +0200 |
| Message-ID | <117p8vs$9pm3$1@dont-email.me> |
| In reply to | #135583 |
BTW, this is the code for the raster version:
---8<---
\ This program is in the public domain. No Warranty.
\ Author: Anton Ertl
\ 4tH conversion: Hans Bezemer
\ this example just draws an sine wave.
include lib/graphics.4th
include lib/gpoly.4th
include lib/fp1.4th
include lib/zenfsin.4th
: y' negate pic_height @ + ; ( y -- y')
: init-ps
512 256 canvas 255 whiteout black color
polyline[ ;
: data2coord ( f: rx f: ry -- rx1 ry1 )
\ transform from our data to Postscript coordinates
fswap 20 s>f f* 250 s>f f+ fswap
100 s>f f* 125 s>f f+ ;
: next-point ( f: rx f: ry -- )
fround f>s >r fround f>s r> y' swap +point ;
: finish-line ( -- )
]poly s" gsine.ppm" save_image ;
: sin-lines ( -- )
100 -100 do
i s>f 10 s>f f/ fdup fsin data2coord next-point
loop ;
: sin-graph ( -- )
init-ps sin-lines finish-line ;
sin-graph
---8<---
Hans Bezemer
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.forth
csiph-web