Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.forth > #37427 > unrolled thread

8 queens problem in Oforth

Started by"WJ" <w_a_x_man@yahoo.com>
First post2015-03-19 07:53 +0000
Last post2015-03-21 21:52 +0000
Articles 20 on this page of 65 — 12 participants

Back to article view | Back to comp.lang.forth


Contents

  8 queens problem in Oforth "WJ" <w_a_x_man@yahoo.com> - 2015-03-19 07:53 +0000
    Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-19 08:58 -0700
      Re: 8 queens problem in Oforth Doug Hoffman <glidedog@gmail.com> - 2015-03-20 08:16 -0400
        Re: 8 queens problem in Oforth anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2015-03-21 10:11 +0000
          Re: 8 queens problem in Oforth franck.bensusan@gmail.com - 2015-03-21 03:45 -0700
            Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-21 14:14 -0700
              Re: 8 queens problem in Oforth franck.bensusan@gmail.com - 2015-03-21 14:28 -0700
                Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-21 14:38 -0700
                  Re: 8 queens problem in Oforth franck.bensusan@gmail.com - 2015-03-21 15:15 -0700
                    Re: 8 queens problem in Oforth hughaguilar96@gmail.com - 2015-03-21 18:23 -0700
                      Re: 8 queens problem in Oforth franck.bensusan@gmail.com - 2015-03-22 03:03 -0700
                        Re: 8 queens problem in Oforth hughaguilar96@gmail.com - 2015-03-22 14:04 -0700
                          Re: 8 queens problem in Oforth franck.bensusan@gmail.com - 2015-03-22 16:34 -0700
                            Re: 8 queens problem in Oforth hughaguilar96@gmail.com - 2015-03-22 21:49 -0700
                              Re: 8 queens problem in Oforth Raimond Dragomir <raimond.dragomir@gmail.com> - 2015-03-23 00:05 -0700
                                Re: 8 queens problem in Oforth hughaguilar96@gmail.com - 2015-03-23 21:43 -0700
                                  Re: 8 queens problem in Oforth franck.bensusan@gmail.com - 2015-03-24 04:13 -0700
                              Re: 8 queens problem in Oforth franck.bensusan@gmail.com - 2015-03-23 00:17 -0700
                    Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-21 19:47 -0700
                      Re: 8 queens problem in Oforth franck.bensusan@gmail.com - 2015-03-22 08:41 -0700
                        Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-22 13:37 -0700
                      Re: 8 queens problem in Oforth Bernd Paysan <bernd.paysan@gmx.de> - 2015-03-22 18:13 +0100
                        Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-22 13:55 -0700
                          Re: 8 queens problem in Oforth "Alex McDonald" <blog@rivadpm.com> - 2015-03-22 21:08 +0000
                            Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-22 14:39 -0700
                              Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-22 14:50 -0700
                              Re: 8 queens problem in Oforth Bernd Paysan <bernd.paysan@gmx.de> - 2015-03-22 22:58 +0100
                                Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-22 15:13 -0700
                                  Re: 8 queens problem in Oforth Bernd Paysan <bernd.paysan@gmx.de> - 2015-03-23 01:03 +0100
                                    Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-22 17:33 -0700
                                      Re: 8 queens problem in Oforth Bernd Paysan <bernd.paysan@gmx.de> - 2015-03-23 02:37 +0100
                                        Re: 8 queens problem in Oforth hughaguilar96@gmail.com - 2015-03-22 20:53 -0700
                                        Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-22 21:11 -0700
                                          Re: 8 queens problem in Oforth anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2015-03-23 11:34 +0000
                                            Re: 8 queens problem in Oforth albert@spenarnc.xs4all.nl (Albert van der Horst) - 2015-03-23 19:31 +0000
                                            Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-23 15:56 -0700
                                              Re: 8 queens problem in Oforth Bernd Paysan <bernd.paysan@gmx.de> - 2015-03-24 00:38 +0100
                                                Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-23 19:08 -0700
                                                Re: 8 queens problem in Oforth hughaguilar96@gmail.com - 2015-03-30 05:02 -0700
                                                  Re: 8 queens problem in Oforth hughaguilar96@gmail.com - 2015-03-30 05:08 -0700
                                                    Re: 8 queens problem in Oforth "Alex McDonald" <blog@rivadpm.com> - 2015-03-30 15:36 +0100
                                          Re: 8 queens problem in Oforth Bernd Paysan <bernd.paysan@gmx.de> - 2015-03-23 16:46 +0100
                                            Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-23 15:32 -0700
                                              Re: 8 queens problem in Oforth Bernd Paysan <bernd.paysan@gmx.de> - 2015-03-23 23:48 +0100
                                                Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-23 16:14 -0700
                                    Re: 8 queens problem in Oforth hughaguilar96@gmail.com - 2015-03-22 17:54 -0700
                              Re: 8 queens problem in Oforth "Alex McDonald" <blog@rivadpm.com> - 2015-03-22 23:09 +0000
                          Re: 8 queens problem in Oforth Bernd Paysan <bernd.paysan@gmx.de> - 2015-03-22 22:11 +0100
                            Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-22 14:48 -0700
                              Re: 8 queens problem in Oforth hughaguilar96@gmail.com - 2015-03-22 15:11 -0700
                              Re: 8 queens problem in Oforth anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2015-03-23 11:29 +0000
                                Re: 8 queens problem in Oforth albert@spenarnc.xs4all.nl (Albert van der Horst) - 2015-03-23 12:20 +0000
                          Re: 8 queens problem in Oforth hughaguilar96@gmail.com - 2015-03-22 14:21 -0700
                          Re: 8 queens problem in Oforth Coos Haak <chforth@hccnet.nl> - 2015-03-22 22:30 +0100
              Re: 8 queens problem in Oforth anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2015-03-23 14:45 +0000
                Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-23 14:53 -0700
                  Re: 8 queens problem in Oforth "Elizabeth D. Rather" <erather@forth.com> - 2015-03-24 09:16 -1000
                    Re: 8 queens problem in Oforth Paul Rubin <no.email@nospam.invalid> - 2015-03-24 12:40 -0700
                    Re: 8 queens problem in Oforth anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2015-03-30 12:24 +0000
            Re: 8 queens problem in Oforth Coos Haak <chforth@hccnet.nl> - 2015-03-21 22:27 +0100
    Re: 8 queens problem in Oforth "WJ" <w_a_x_man@yahoo.com> - 2015-03-19 20:31 +0000
    Re: 8 queens problem in Oforth "WJ" <w_a_x_man@yahoo.com> - 2015-03-19 20:35 +0000
    Re: 8 queens problem in Oforth "WJ" <w_a_x_man@yahoo.com> - 2015-03-21 17:31 +0000
      Re: 8 queens problem in Oforth "WJ" <w_a_x_man@yahoo.com> - 2015-03-21 20:50 +0000
      Re: 8 queens problem in Oforth "WJ" <w_a_x_man@yahoo.com> - 2015-03-21 21:52 +0000

Page 1 of 4  [1] 2 3 4  Next page →


#37427 — 8 queens problem in Oforth

From"WJ" <w_a_x_man@yahoo.com>
Date2015-03-19 07:53 +0000
Subject8 queens problem in Oforth
Message-ID<medv8t$k7a$1@dont-email.me>
This is a fun language.  It really blows ANS Forth out of the water.

func: decode-position
  { #[ 8 divrem ] times(8) drop ListBuffer init(8, #[]) }

func: no-dups? {asSet size 8 ==}

func: skew-board(brd, op) {brd zipWith(op, seqFrom(0,7) )}

func: check-diagonals(brd)
  { [#+, #-] conform(#[ brd skew-board no-dups? ]) }

func: check(brd)
  { [#no-dups?, #check-diagonals] conform( #[ perform(brd) ] ) }

func: go {|i board|
  0 "77777777" asIntegerOfBase(8)
  for: i [ i decode-position -> board
    check(board)
    ifTrue: [ board println ]
  ] }

go

[0, 4, 7, 5, 2, 6, 1, 3]
[0, 5, 7, 2, 6, 3, 1, 4]
[0, 6, 3, 5, 7, 1, 4, 2]
[0, 6, 4, 7, 1, 3, 5, 2]
[1, 3, 5, 7, 2, 0, 6, 4]
[1, 4, 6, 0, 2, 7, 5, 3]
[1, 4, 6, 3, 0, 7, 5, 2]
[1, 5, 0, 6, 3, 7, 2, 4]
[1, 5, 7, 2, 0, 3, 6, 4]
[1, 6, 2, 5, 7, 4, 0, 3]
[1, 6, 4, 7, 0, 3, 5, 2]
[1, 7, 5, 0, 2, 4, 6, 3]
[2, 0, 6, 4, 7, 1, 3, 5]
[2, 4, 1, 7, 0, 6, 3, 5]
[2, 4, 1, 7, 5, 3, 6, 0]
[2, 4, 6, 0, 3, 1, 7, 5]
[2, 4, 7, 3, 0, 6, 1, 5]
[2, 5, 1, 4, 7, 0, 6, 3]
[2, 5, 1, 6, 0, 3, 7, 4]
[2, 5, 1, 6, 4, 0, 7, 3]
[2, 5, 3, 0, 7, 4, 6, 1]
[2, 5, 3, 1, 7, 4, 6, 0]
[2, 5, 7, 0, 3, 6, 4, 1]
[2, 5, 7, 0, 4, 6, 1, 3]
[2, 5, 7, 1, 3, 0, 6, 4]
[2, 6, 1, 7, 4, 0, 3, 5]
[2, 6, 1, 7, 5, 3, 0, 4]
[2, 7, 3, 6, 0, 5, 1, 4]
[3, 0, 4, 7, 1, 6, 2, 5]
[3, 0, 4, 7, 5, 2, 6, 1]
[3, 1, 4, 7, 5, 0, 2, 6]
[3, 1, 6, 2, 5, 7, 0, 4]
[3, 1, 6, 2, 5, 7, 4, 0]
[3, 1, 6, 4, 0, 7, 5, 2]
[3, 1, 7, 4, 6, 0, 2, 5]
[3, 1, 7, 5, 0, 2, 4, 6]
[3, 5, 0, 4, 1, 7, 2, 6]
[3, 5, 7, 1, 6, 0, 2, 4]
[3, 5, 7, 2, 0, 6, 4, 1]
[3, 6, 0, 7, 4, 1, 5, 2]
[3, 6, 2, 7, 1, 4, 0, 5]
[3, 6, 4, 1, 5, 0, 2, 7]
[3, 6, 4, 2, 0, 5, 7, 1]
[3, 7, 0, 2, 5, 1, 6, 4]
[3, 7, 0, 4, 6, 1, 5, 2]
[3, 7, 4, 2, 0, 6, 1, 5]
[4, 0, 3, 5, 7, 1, 6, 2]
[4, 0, 7, 3, 1, 6, 2, 5]
[4, 0, 7, 5, 2, 6, 1, 3]
[4, 1, 3, 5, 7, 2, 0, 6]
[4, 1, 3, 6, 2, 7, 5, 0]
[4, 1, 5, 0, 6, 3, 7, 2]
[4, 1, 7, 0, 3, 6, 2, 5]
[4, 2, 0, 5, 7, 1, 3, 6]
[4, 2, 0, 6, 1, 7, 5, 3]
[4, 2, 7, 3, 6, 0, 5, 1]
[4, 6, 0, 2, 7, 5, 3, 1]
[4, 6, 0, 3, 1, 7, 5, 2]
[4, 6, 1, 3, 7, 0, 2, 5]
[4, 6, 1, 5, 2, 0, 3, 7]
[4, 6, 1, 5, 2, 0, 7, 3]
[4, 6, 3, 0, 2, 7, 5, 1]
[4, 7, 3, 0, 2, 5, 1, 6]
[4, 7, 3, 0, 6, 1, 5, 2]
[5, 0, 4, 1, 7, 2, 6, 3]
[5, 1, 6, 0, 2, 4, 7, 3]
[5, 1, 6, 0, 3, 7, 4, 2]
[5, 2, 0, 6, 4, 7, 1, 3]
[5, 2, 0, 7, 3, 1, 6, 4]
[5, 2, 0, 7, 4, 1, 3, 6]
[5, 2, 4, 6, 0, 3, 1, 7]
[5, 2, 4, 7, 0, 3, 1, 6]
[5, 2, 6, 1, 3, 7, 0, 4]
[5, 2, 6, 1, 7, 4, 0, 3]
[5, 2, 6, 3, 0, 7, 1, 4]
[5, 3, 0, 4, 7, 1, 6, 2]
[5, 3, 1, 7, 4, 6, 0, 2]
[5, 3, 6, 0, 2, 4, 1, 7]
[5, 3, 6, 0, 7, 1, 4, 2]
[5, 7, 1, 3, 0, 6, 4, 2]
[6, 0, 2, 7, 5, 3, 1, 4]
[6, 1, 3, 0, 7, 4, 2, 5]
[6, 1, 5, 2, 0, 3, 7, 4]
[6, 2, 0, 5, 7, 4, 1, 3]
[6, 2, 7, 1, 4, 0, 5, 3]
[6, 3, 1, 4, 7, 0, 2, 5]
[6, 3, 1, 7, 5, 0, 2, 4]
[6, 4, 2, 0, 5, 7, 1, 3]
[7, 1, 3, 0, 6, 4, 2, 5]
[7, 1, 4, 2, 0, 6, 3, 5]
[7, 2, 0, 5, 1, 4, 6, 3]
[7, 3, 0, 2, 5, 1, 6, 4]

[toc] | [next] | [standalone]


#37434

FromPaul Rubin <no.email@nospam.invalid>
Date2015-03-19 08:58 -0700
Message-ID<871tklugfx.fsf@jester.gateway.sonic.net>
In reply to#37427
"WJ" <w_a_x_man@yahoo.com> writes:
> This is a fun language.  It really blows ANS Forth out of the water.

It seems to have almost nothing in common with Forth.  It's another
Lisp-like language with postfix syntax and some nice multitasking
features.  You could try Erlang/Elixir/LFE.  The 8 queens solution is
ugly too.  This works for me in Haskell:

    noattack (a,b) (c,d) = a/=c && b/=d && abs(a-c)/=abs(b-d)

    gen 8 qss = qss
    gen n qss = gen (n+1) [(n,q):qs | qs <- qss, q <- [0..7]
                                    , all (noattack (n,q)) qs ]

    main = mapM_ (print . map snd) $ gen 0 [[]]

*Main> main
[3,1,6,2,5,7,4,0]
[4,1,3,6,2,7,5,0]
[2,4,1,7,5,3,6,0]
[2,5,3,1,7,4,6,0]
[4,6,0,2,7,5,3,1]
...

[toc] | [prev] | [next] | [standalone]


#37468

FromDoug Hoffman <glidedog@gmail.com>
Date2015-03-20 08:16 -0400
Message-ID<550c0f87$0$284$14726298@news.sunsite.dk>
In reply to#37434
On 3/19/15 11:58 AM, Paul Rubin wrote:
> "WJ" <w_a_x_man@yahoo.com> writes:
>> This is a fun language.  ... [snip]
>
> It seems to have almost nothing in common with Forth.

It appears to be a Forth dialect, IMO, perhaps more along the
lines of 8th though.  The code snippets posted so far are using what a
long time Forther would consider to be (non ANS) library definitions.
Unfortunately the OP's usenet manners remain poor but at least
she's/he's now making Forth related posts.

See: http://www.oforth.com/tutorial1.html

-Doug


> It's another Lisp-like language with postfix syntax and some nice
> multitasking features.  You could try Erlang/Elixir/LFE.  The 8
> queens solution is ugly too.

[toc] | [prev] | [next] | [standalone]


#37508

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2015-03-21 10:11 +0000
Message-ID<2015Mar21.111159@mips.complang.tuwien.ac.at>
In reply to#37468
Doug Hoffman <glidedog@gmail.com> writes:
>On 3/19/15 11:58 AM, Paul Rubin wrote:
>> "WJ" <w_a_x_man@yahoo.com> writes:
>>> This is a fun language.  ... [snip]
>>
>> It seems to have almost nothing in common with Forth.
>
>It appears to be a Forth dialect, IMO, perhaps more along the
>lines of 8th though.

From the examples that WJ posted, Oforth looks less close to Forth
than Factor or Postscript, at least syntactically.  It has all this
stuff that it's doing with the parentheses that does not look like
Forth.  Semantically, it seems that the axamples work a lot with
higher-order functions, like in functional programming.

- 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: http://www.forth200x.org/forth200x.html
   EuroForth 2014: http://www.euroforth.org/ef14/

[toc] | [prev] | [next] | [standalone]


#37509

Fromfranck.bensusan@gmail.com
Date2015-03-21 03:45 -0700
Message-ID<484d2063-5877-4820-9989-9aa8358516d0@googlegroups.com>
In reply to#37508
> >>> This is a fun language.  ... [snip]
> >>
> >> It seems to have almost nothing in common with Forth.
> >
> >It appears to be a Forth dialect, IMO, perhaps more along the
> >lines of 8th though.
> 
> From the examples that WJ posted, Oforth looks less close to Forth
> than Factor or Postscript, at least syntactically.  It has all this
> stuff that it's doing with the parentheses that does not look like
> Forth.  Semantically, it seems that the axamples work a lot with
> higher-order functions, like in functional programming.
> 

Oforth interpreter allows use of sugar to handle parameters of functions called. 
This sugar is not mandatory. It is a programming style.

If f is a function and a b c are parameters that should be on the stack to call f : 

c b a f 
and
f(a, b, c)

are the same call. Indeed, interpreter will translate the last one into the first one before performing (or compiling) f call. There is no performance cost to use this sugar.

Example : 
func: f(a, b) { a b + }

2 3 f 5 f println
10

f(5, 2 3 f) println
10

f(5, f(3, 2)) println
10

Franck

[toc] | [prev] | [next] | [standalone]


#37520

FromPaul Rubin <no.email@nospam.invalid>
Date2015-03-21 14:14 -0700
Message-ID<87a8z6aw9b.fsf@jester.gateway.sonic.net>
In reply to#37509
franck.bensusan@gmail.com writes:
> Oforth interpreter allows use of sugar to handle parameters of
> functions called.  This sugar is not mandatory. It is a programming
> style.

It still seems much different from Forth, whose main characteristic
(IMHO) is the availability of the input stream to words in the text
interpreter, i.e. the possibility of user-defined defining words, and
the possibility of an implementation where almost all of the usual Forth
words are actually defined that way.

[toc] | [prev] | [next] | [standalone]


#37521

Fromfranck.bensusan@gmail.com
Date2015-03-21 14:28 -0700
Message-ID<bf5f7457-17dc-46be-8262-c64d40181af3@googlegroups.com>
In reply to#37520
> It still seems much different from Forth, whose main characteristic
> (IMHO) is the availability of the input stream to words in the text
> interpreter, i.e. the possibility of user-defined defining words, and
> the possibility of an implementation where almost all of the usual Forth
> words are actually defined that way.

Oforth uses the same mecanisms : 

When you write : 
func: foo(a) { a 2 + }

"func:" is a word that switch interpreter to compile mode.
"}" is an immediate word that switch interpreter back to interpret mode.

Between those two words, is the current definition where all immediate words are performed. 

When } is performed and the interpreter returns to interpret mode, the word foo (here a function) is created.

[toc] | [prev] | [next] | [standalone]


#37523

FromPaul Rubin <no.email@nospam.invalid>
Date2015-03-21 14:38 -0700
Message-ID<87619uav5r.fsf@jester.gateway.sonic.net>
In reply to#37521
franck.bensusan@gmail.com writes:
> "func:" is a word that switch interpreter to compile mode.
> "}" is an immediate word that switch interpreter back to interpret mode.

Hmm, interesting, yeah it's Forth-like in that regard.  The other part
is harder to specify but it's the sense of minimalism that has always
pervaded Forth.  The presence of type tags and GC make Oforth seem more
like a Lisp dialect, at least in the loose sense that Ruby ("MatzLisp")
is also a Lisp dialect.  I know that Anton wrote a Boehm-style GC for
traditional Forth, but that's less pervasive than Oforth's.

[toc] | [prev] | [next] | [standalone]


#37526

Fromfranck.bensusan@gmail.com
Date2015-03-21 15:15 -0700
Message-ID<9e9efbe7-b0c8-45a3-9d0a-3dea3651759e@googlegroups.com>
In reply to#37523
> Hmm, interesting, yeah it's Forth-like in that regard.  The other part
> is harder to specify but it's the sense of minimalism that has always
> pervaded Forth.  The presence of type tags and GC make Oforth seem more
> like a Lisp dialect, at least in the loose sense that Ruby ("MatzLisp")
> is also a Lisp dialect.  I know that Anton wrote a Boehm-style GC for
> traditional Forth, but that's less pervasive than Oforth's.

Yes, I understand, but GC is almost mandatory when you want some features.

For instance if you want closures, you have to save some 
environment and you don't know when to release it.

Oforth has blocks, which are anonymous functions.
They are defined between #[ and ] and executed using perform :

1 #[ 2 + sq ] perform println
9

Into a definition (#[ and ] are immediate words :) ), these blocks can 
use parameters or local variables. If so, they are closures :

func: foo(a) { #[ a + ] }
10 12 foo perform println
22

Doing this without GC is a pain... With GC, it is simple.

What do you mean by "type tags" ? 

[toc] | [prev] | [next] | [standalone]


#37530

Fromhughaguilar96@gmail.com
Date2015-03-21 18:23 -0700
Message-ID<c1023d9c-fef6-4c32-82a0-34123b9164f6@googlegroups.com>
In reply to#37526
On Saturday, March 21, 2015 at 3:15:36 PM UTC-7, franck....@gmail.com wrote:
> ...GC is almost mandatory when you want some features.
> 
> For instance if you want closures, you have to save some 
> environment and you don't know when to release it.

Anton Ertl believes this too, but it is not true. Your closure's activation-record (local-frame) can be held on the return-stack --- just make the rule that it is illegal for your closure to be executed after its parent function (the function it was defined inside of) has gone out of scope --- so you do know when to release it: at the EXIT from the parent function.

This seems super-obvious, but I have yet to meet anybody on C.L.F. that understands this.

This is also super-efficient --- I'm doing this in my language, and I expect my language to work well on the 8-bit AVR --- by comparison, your Oforth won't work on micro-controllers at all, not even the 32-bit ARM, and so Oforth is just one of a myriad of powerful languages available for the 64-bit x86.

> What do you mean by "type tags" ?

He means tags in every datum that indicate what type the datum is. For example, in Racket we have a 2-bit tag, so the fundamental data-types are: 30-bit integer, double-precision float, string and struct (to the best of my recollection). Every function, such as +, as to test the tag for its parameters so it knows what to do. For + there are 2 parameters, so there are 16 (4*4) things that it can do. In some cases, it has to cast one of the parameters (for example, if called upon to add a float to an integer, it casts the integer into a float, then adds two floats, then returns a float). In some cases, it has to abort (for example, it makes no sense to add a float to a struct pointer). 

Also, as I recall, Factor had a 3-bit tag, so it had 8 fundamental data-types --- this increases the complexity a lot, as a two-parameter function now has 64 (8*8) things that it can do.

BTW: Languages that have tagged-data are generally referred to as "dynamic-OOP" languages. By comparison, "static-OOP" refers to languages like C++.

Your Oforth doesn't have tagged-data, does it? I hope not, as I am not very interested in dynamic-OOP languages (this is one of the reasons why I quit Factor).

[toc] | [prev] | [next] | [standalone]


#37536

Fromfranck.bensusan@gmail.com
Date2015-03-22 03:03 -0700
Message-ID<6945d547-0788-414d-9d12-fe91fa095071@googlegroups.com>
In reply to#37530
> Anton Ertl believes this too, but it is not true. Your closure's activation-record (local-frame) can be held on the return-stack --- just make the rule that it is illegal for your closure to be executed after its parent function (the function it was defined inside of) has gone out of scope --- so you do know when to release it: at the EXIT from the parent function.
> 
> This seems super-obvious, but I have yet to meet anybody on C.L.F. that understands this.

Yes, if you add thoses contrainsts, you don't need GC and it is efficient. 
But, imho, it is no more a closure. 
At least, it is not what people have in mind when they talk about closures.
After that, you can say that what you have implemented is suffisant, 
and other features are not needed. That's fine.
But this is not the closure definition (imo).
I think this is where the misunderstanding comes from.

Let't take an example : 

func: show { perform println }

func: testClosure
{
| s cl1 cl2 |
   "aaa" ->s
   #[ s ] ->cl1
   "bbb" ->s
   #[ s ] ->cl2
   cl1 show
   cl2 show   
}

With closures, the values should be kept at the time the closure is created
and the result should be : 
aaa
bbb


> This is also super-efficient --- I'm doing this in my language, and I expect my language to work well on the 8-bit AVR --- by comparison, your Oforth won't work on micro-controllers at all, not even the 32-bit ARM, and so Oforth is just one of a myriad of powerful languages available for the 64-bit x86.
> 

Sure. Oforth target is desktop/server programming. Not micro-controller
programming or embedded. (but Oforth works on 32-bits platforms...).
Oforth objective is to have Forth mecanisms with features, imo, a 
desktop/server language should now have to be competitive on those platforms.

> > What do you mean by "type tags" ?
> 
> He means tags in every datum that indicate what type the datum is. For example, in Racket we have a 2-bit tag, so the fundamental data-types are: 30-bit integer, double-precision float, string and struct (to the best of my recollection). Every function, such as +, as to test the tag for its parameters so it knows what to do. For + there are 2 parameters, so there are 16 (4*4) things that it can do. In some cases, it has to cast one of the parameters (for example, if called upon to add a float to an integer, it casts the integer into a float, then adds two floats, then returns a float). In some cases, it has to abort (for example, it makes no sense to add a float to a struct pointer). 
> 
> Also, as I recall, Factor had a 3-bit tag, so it had 8 fundamental data-types --- this increases the complexity a lot, as a two-parameter function now has 64 (8*8) things that it can do.
> 
> BTW: Languages that have tagged-data are generally referred to as "dynamic-OOP" languages. By comparison, "static-OOP" refers to languages like C++.
> 
> Your Oforth doesn't have tagged-data, does it? I hope not, as I am not very interested in dynamic-OOP languages (this is one of the reasons why I quit Factor).

Well, this does not still sound clear for me.
I don't know these languages, but I think Oforth does not works like 
Racket or Factor. A least the way you present them.

But, of course, internally, Oforth objects have tagged data used to retrieve 
their type. This data is internal and used to handle polymorphism. 

btw, all C++ objects that can answer to at least one virtual method
have also internal tagged data (a pointer to a vtable).
Otherwise C++ would not be able not handle polymophism.
This is why this comparison between "dynamic-OOP" & "static-OOP" 
is not very clear for me...

[toc] | [prev] | [next] | [standalone]


#37546

Fromhughaguilar96@gmail.com
Date2015-03-22 14:04 -0700
Message-ID<aaac8c96-48e1-44b6-a752-5fc2ac508bdf@googlegroups.com>
In reply to#37536
On Sunday, March 22, 2015 at 3:03:27 AM UTC-7, franck....@gmail.com wrote:
> > Anton Ertl believes this too, but it is not true. Your closure's activation-record (local-frame) can be held on the return-stack --- just make the rule that it is illegal for your closure to be executed after its parent function (the function it was defined inside of) has gone out of scope --- so you do know when to release it: at the EXIT from the parent function.
> > 
> > This seems super-obvious, but I have yet to meet anybody on C.L.F. that understands this.
> 
> Yes, if you add thoses contrainsts, you don't need GC and it is efficient. 
> But, imho, it is no more a closure. 
> At least, it is not what people have in mind when they talk about closures.
> After that, you can say that what you have implemented is suffisant, 
> and other features are not needed. That's fine.
> But this is not the closure definition (imo).
> I think this is where the misunderstanding comes from.

I agree that the definition of "closure" includes the feature that the closure can be executed after the parent function has exited. The parent function's local-frame is a struct in the heap. The heap-object has to be GC'd after it can no longer be used, which means that the language has to keep a count of how many pointers to the closure are still floating around and could possibly be executed --- when this count goes to zero, the closure is dead and the local-frame can be deallocated from the heap. This is extremely difficult in Forth because there is no way to tell the difference between a pointer and an integer because the datum doesn't have a tag to indicate what it is, and there is no way to keep track of all this data anyway, because DUP etc. don't keep any kind of record.

The problem is not that I don't know what a closure is --- the problem is that I don't know what they are for --- I have yet to get an answer to the question: "Why would anybody want to execute a closure after the parent function has gone out of scope?"

If I release my language the way that I described, will everybody complain that it is too restrictive because it doesn't allow them to do what they want to do? What would that be?

> > > What do you mean by "type tags" ?
> > 
> > He means tags in every datum that indicate what type the datum is. For example, in Racket we have a 2-bit tag, so the fundamental data-types are: 30-bit integer, double-precision float, string and struct (to the best of my recollection). Every function, such as +, as to test the tag for its parameters so it knows what to do. For + there are 2 parameters, so there are 16 (4*4) things that it can do. In some cases, it has to cast one of the parameters (for example, if called upon to add a float to an integer, it casts the integer into a float, then adds two floats, then returns a float). In some cases, it has to abort (for example, it makes no sense to add a float to a struct pointer). 
> > 
> > Also, as I recall, Factor had a 3-bit tag, so it had 8 fundamental data-types --- this increases the complexity a lot, as a two-parameter function now has 64 (8*8) things that it can do.
> > 
> > BTW: Languages that have tagged-data are generally referred to as "dynamic-OOP" languages. By comparison, "static-OOP" refers to languages like C++.
> > 
> > Your Oforth doesn't have tagged-data, does it? I hope not, as I am not very interested in dynamic-OOP languages (this is one of the reasons why I quit Factor).
> 
> Well, this does not still sound clear for me.
> I don't know these languages, but I think Oforth does not works like 
> Racket or Factor. A least the way you present them.
> 
> But, of course, internally, Oforth objects have tagged data used to retrieve 
> their type. This data is internal and used to handle polymorphism. 
> 
> btw, all C++ objects that can answer to at least one virtual method
> have also internal tagged data (a pointer to a vtable).
> Otherwise C++ would not be able not handle polymophism.
> This is why this comparison between "dynamic-OOP" & "static-OOP" 
> is not very clear for me...

It is true that C++ has a pointer to the VMT (virtual-method-table) in the front of every object (struct), and that this is effectively a tag.

The difference between C++ (static-OOP) and Scheme/Lisp etc. (dynamic-OOP), is that in the dynamic-OOP languages EVERY datum has a tag --- this includes integers, floats, strings, etc., not just structs.

So, is your language dynamic-OOP or static-OOP?

Note that I'm not criticizing your language. I'm interested in learning it. I just need to start by learning the answers to these two questions:

1.) Why would anybody want their closure to execute after the parent function has exited? Why not just use :NONAME for this, and not have a parent function?

2.) Does Oforth have a tag on every datum, or just on structs?

[toc] | [prev] | [next] | [standalone]


#37562

Fromfranck.bensusan@gmail.com
Date2015-03-22 16:34 -0700
Message-ID<d070cf3d-ecbd-4fa6-8a7d-0827be6902d1@googlegroups.com>
In reply to#37546
> Note that I'm not criticizing your language. I'm interested in learning it. I just need to start by learning the answers to these two questions:
> 
> 1.) Why would anybody want their closure to execute after the parent function has exited? Why not just use :NONAME for this, and not have a parent function?
> 
> 2.) Does Oforth have a tag on every datum, or just on structs?


Some Oforth closure examples : 

With the first ones, GC is needed because nothing is created into the dictionary. When the closure is no more needed, it is garbaged. 

1) Function composition : 

func: compose(f, g) { #[ g perform f perform ] }
compose(#sin, #sqrt) Constant new: sin-sqrt

2 sin-sqrt perform println
0.987765945992736

Of course, compose can take a closure as parameter 
and returns a closure of closure.
2 compose(#sqrt, sin-sqrt) perform println
0.993864148660538


2) Y-Combinator ==> See : rosettacode.org/wiki/Y_combinator
func: Y(f) { #[ Y(f) f perform ] }


3) Dérivation examples : 
deriv is a function that will return the value 
of the derivative of a function at a point : 

func: deriv(f) { | x | #[ ->x x 0.0000001 + f perform x f perform - 0.0000001 / ] }

This function returns a closure that encapsulate f and returns it on the stack.
When performed, it uses f value it had when created to calculate (f(x+e) -f(x)) /e 

For, instance, to calculate the derivative of f(x) = x^2 + x at 2.0 point : 
#[ dup sq + ] deriv Constant new: der-f

2.0 der-f perform println
5.00000009395762

3.0 der-f perform println
7.00000008180268

To calculate the derivative of sin-sqrt at 1.0
1.0 sin-sqrt deriv perform println
0.270151135906005

I think that these examples could perhaps be done using NONAME. 
For the next, I don't know : the closure returned by deriv is sent again as input of deriv.

To calculate derivative of derivative of f(x) = x^3 + 1 : 

#[ dup sq * 1 + ] deriv deriv Constant new: d2f
2.0 d2f perform println
11.9015908239817 (normally it's 12, but error is propagating quickly here... but it is the idea).

Those one will surely need GC, even with NONAME : 

4) Accumulator factory : see http://rosettacode.org/wiki/Accumulator_factory

func: foo(n)
{
| ch |
   Channel new dup ->ch send(n) drop
   #[ ch receive swap + dup ch send drop ]
}

5) More complicated closures are used to run parallel tasks. I can post some if you want, but they are more complicated.


Otherwise, unless for small integers (-2^30, 2^30), Oforth has tag. I think it enter into what you call dynamic-OOP.

[toc] | [prev] | [next] | [standalone]


#37573

Fromhughaguilar96@gmail.com
Date2015-03-22 21:49 -0700
Message-ID<4bcafbd5-a643-4291-a0bd-881b12e3b17e@googlegroups.com>
In reply to#37562
On Sunday, March 22, 2015 at 4:34:29 PM UTC-7, franck....@gmail.com wrote:
> > Note that I'm not criticizing your language. I'm interested in learning it. I just need to start by learning the answers to these two questions:
> > 
> > 1.) Why would anybody want their closure to execute after the parent function has exited? Why not just use :NONAME for this, and not have a parent function?
> 
> Some Oforth closure examples : 
> 
> With the first ones, GC is needed because nothing is created into the dictionary. When the closure is no more needed, it is garbaged. 

I'm dubious of the idea of garbaging the closure when it is no longer needed, because the next time that the parent function executes it would have to generate that code again --- this means we are doing compilation at run-time, which is very inefficient --- it seems better to compile at compile-time, and just leave the closure in the dictionary throughout the execution of the program in case it is ever needed (same as with any function).

Am I misunderstanding this? Did you really mean that the closure is garbaged --- or did you mean that the local-frame is garbaged (this would make more sense to me).

I hope my questions don't seem dumb --- all of this desktop-computer programming stuff is new to me (I'm more familiar with real-time programming) --- a big part of why I quit Factor is that I just didn't understand the concepts, and all the documentation was a reference, but it assumed that the user knew the concepts already.

[toc] | [prev] | [next] | [standalone]


#37579

FromRaimond Dragomir <raimond.dragomir@gmail.com>
Date2015-03-23 00:05 -0700
Message-ID<7474b601-3514-4788-a107-96f72bbdcc59@googlegroups.com>
In reply to#37573
luni, 23 martie 2015, 06:49:13 UTC+2, hughag...@gmail.com a scris:
> On Sunday, March 22, 2015 at 4:34:29 PM UTC-7, franck....@gmail.com wrote:
> > > Note that I'm not criticizing your language. I'm interested in learning it. I just need to start by learning the answers to these two questions:
> > > 
> > > 1.) Why would anybody want their closure to execute after the parent function has exited? Why not just use :NONAME for this, and not have a parent function?
> > 
> > Some Oforth closure examples : 
> > 
> > With the first ones, GC is needed because nothing is created into the dictionary. When the closure is no more needed, it is garbaged. 
> 
> I'm dubious of the idea of garbaging the closure when it is no longer needed, because the next time that the parent function executes it would have to generate that code again --- this means we are doing compilation at run-time, which is very inefficient --- it seems better to compile at compile-time, and just leave the closure in the dictionary throughout the execution of the program in case it is ever needed (same as with any function).
> 
> Am I misunderstanding this? Did you really mean that the closure is garbaged --- or did you mean that the local-frame is garbaged (this would make more sense to me).
> 
> I hope my questions don't seem dumb --- all of this desktop-computer programming stuff is new to me (I'm more familiar with real-time programming) --- a big part of why I quit Factor is that I just didn't understand the concepts, and all the documentation was a reference, but it assumed that the user knew the concepts already.

"Why would anybody want their closure to execute after the parent function has exited?"

A simple example that Lua and Javascript always present is:
function create_counter {
  local var cnt = 0;
  return function {
    cnt = cnt + 1;
    return cnt;
  }
}
Take above like a sort of pseudo-code. create_counter is a "factory", it creates functions that when executed at runtime they will return an increment count, but every counting function created has it's own copy of the count, so they count independently. That means local var cnt is not a stack local, it's a heap local, create_counter allocate the local var cnt on the heap each time it's executed. Also, the quotation (the function that create_counter returns) sees the cnt var of the parent as a global variable.

This is just examples told by Lua and Javascript people. They are probably proud of this, but if you ask me, I don't know what a real usage of this could be.

On the other hand, there is no dynamic compilation here. The "factory" functions are just statically compiled, so are the quotations inside them. The only dynamic thing is the local var of the parent, but this is simple, just alloc it on the heap. More, if the application doesn't need to reuse those 'counters', it is what I call pseudo-dynamic, a dynamic allocation on the heap with no deallocation. This pseudo-dynamic can have lot of usage even in microcontroller applications. 

In Forth this can be done with a special type of locals, let's call them HEAP_LOCALS. The parent function just need to allocate them on the heap and make their address visible as global variables (but with local name visibility as in LOCALS) to the body of the definition.

[toc] | [prev] | [next] | [standalone]


#37616

Fromhughaguilar96@gmail.com
Date2015-03-23 21:43 -0700
Message-ID<fce52287-f213-4b38-bce0-87a9195cd9ba@googlegroups.com>
In reply to#37579
On Monday, March 23, 2015 at 12:05:08 AM UTC-7, Raimond Dragomir wrote:
> "Why would anybody want their closure to execute after the parent function has exited?"
> 
> A simple example that Lua and Javascript always present is:
> function create_counter {
>   local var cnt = 0;
>   return function {
>     cnt = cnt + 1;
>     return cnt;
>   }
> }
> Take above like a sort of pseudo-code. create_counter is a "factory", it creates functions that when executed at runtime they will return an increment count, but every counting function created has it's own copy of the count, so they count independently. That means local var cnt is not a stack local, it's a heap local, create_counter allocate the local var cnt on the heap each time it's executed. Also, the quotation (the function that create_counter returns) sees the cnt var of the parent as a global variable.
> 
> This is just examples told by Lua and Javascript people. They are probably proud of this, but if you ask me, I don't know what a real usage of this could be.

This is trivial to implement in Forth --- just write a function that takes a pointer to a struct as a parameter and does something with it; we will call this a "pseudo-closure." Write a meta-compiling word (your "factory") that allocates and initializes a struct, and it builds a function (using :NAME) that consists of a literal of the pointer to the struct, followed by the pseudo-closure, followed by semicolon. 

I could have up to 16 local variables in MFX. I had a word that incremented a local variable by 1 (like your counter). I didn't actually write 16 versions of this word --- I wrote one meta-compiling word and used it to generate 16 versions, one for each local variable. This is a real-world usage of a factory.

I relied on this technique heavily in MFX. I had a lot of meta-compiling words that generated a lot of primitive functions (primitives being functions written in machine-code, rather than Forth). I generated so many primitives (hundreds of them) that I began to run out of program-memory. This was when I came up with "ghost code." I would generate primitives, but I would save the source-code and not actually assemble them into machine-code . Only if the primitive was used, did it "materialize" and take up space in program-memory.

Getting back to the subject of lambda functions, my purpose in providing them in my language, is to allow for general-purpose data-structures. The idea is that the higher-order function traverses the data-structure, and it executes the lambda-function for every node, giving it the pointer to the node as a parameter. The lambda-function needs access to the parent function's local variables so it can communicate information back to the parent (for example, a count of how many nodes meet some criteria). This information could be stashed in a struct on the heap that the parent has access to (this is commonly done in C programs), but this is over-complicated because the parent has to allocate and deallocate the struct, and the struct has to be defined (with FIELD in Forth programs) --- this just bloats and uglifies the program, and we are no better off than if we were programming in C --- lambda functions are much simpler and more straight-forward.

> On the other hand, there is no dynamic compilation here. The "factory" functions are just statically compiled, so are the quotations inside them. The only dynamic thing is the local var of the parent, but this is simple, just alloc it on the heap. More, if the application doesn't need to reuse those 'counters', it is what I call pseudo-dynamic, a dynamic allocation on the heap with no deallocation. This pseudo-dynamic can have lot of usage even in microcontroller applications. 

Okay, you are saying the same thing that Franck is saying --- the quotation is not recompiled after it has been garbaged --- the only thing that got garbaged was the pointer to the quotations code in the dictionary, and the local-frame, both of which are in the heap.

> In Forth this can be done with a special type of locals, let's call them HEAP_LOCALS. The parent function just need to allocate them on the heap and make their address visible as global variables (but with local name visibility as in LOCALS) to the body of the definition.

Gerry Jackson already did this --- apparently his code is going to go into Forth-200x.

I don't think this is a good idea. As I described above, there is an easier way to make a "factory" such as you described. Also, using the heap for locals is inefficient --- we don't want to slow down the whole language just to solve a problem that is rare, and can already be solved easily with Forth as it currently exists.

I do think that having lambda functions that access the parent function's local-frame on the return-stack is a good idea --- this is useful for general-purpose data-structures --- this is also easy to implement and efficient (note: I have recently figured out a more efficient way to do this than what I showed you previously with that ARM cross-compiler).

[toc] | [prev] | [next] | [standalone]


#37619

Fromfranck.bensusan@gmail.com
Date2015-03-24 04:13 -0700
Message-ID<4e91bc1f-8f41-4bdc-b57e-e52c34e084be@googlegroups.com>
In reply to#37616
> Okay, you are saying the same thing that Franck is saying --- the quotation is not recompiled after it has been garbaged --- the only thing that got garbaged was the pointer to the quotations code in the dictionary, and the local-frame, both of which are in the heap.

Yes for the pointer, no for local frames on the heap (at least in Oforth).

Oforth never creates local frames on the heap.

- Of course, parent local frame is not on the heap.

- Into the closure, you only have values of variables used.
If you use 1 local variable among 10, only 1 object reference is into the closure.
( otherwise, GC could not free the others until the closure is garbaged, 
this would be very inefficient).

- And if you don't use local variables, nothing is created on the HEAP.

If interested, it is perhap's better to describe how Oforth 
compiles this kind of thing : 

func: compose(f, g) { #[ g perform f perform ] }

0) Local frame of parent (for f and g) is not on heap.
 
1) #[ is, of course, an immediate word :
- It creates a static block object into the dictionary.
- It compiles a jump 
- Then it set pointer code of the block object into the dictionary
to the current value.
==> Block code begins here as part of compose code but compose 
never reaches this code (because of the jump).

2) During the block compilation, each local variable used is tagged.

3) ] is an immediate word :

- It compiles a return (to return from the block) 

- It updates the block into the dictionary with informations
about used variables (if any).
 
- It resolves the jump initiated by #[
 
- Then it compiles a push of the static Block object (created into 
the dictionary) on the stack.
 
- And, ONLY if some local variables have been used, it compiles a call to an
internal function. Let's call it "makeClosure".

==> If no local variable is used, nothing is created on the heap, it is 
just a static Block object coming from the dictionary that is on 
the stack.

==> If at least one variable is used, a closure is needed and 
"makeClosure" will do the job to create it.
 
4) Now when you run compose, because the block uses local variables, 
a call to "makeClosure" has been compiled after the push. 

The static Block (the one that is coming from dictionary) on the stack 
is replaced with a dynamic Block created on the HEAP.
Then references stored into variables the block uses (into parent local frame) are stored into this object.
 
5) When you perform this object (and you don't know when this will happen) : 
- It creates its own local frame (not on the heap) with values needed.
- It runs its pointer code.

Franck

[toc] | [prev] | [next] | [standalone]


#37580

Fromfranck.bensusan@gmail.com
Date2015-03-23 00:17 -0700
Message-ID<50b4946f-6d6f-4811-a38e-4595a66ef7be@googlegroups.com>
In reply to#37573
> Am I misunderstanding this? Did you really mean that the closure is garbaged --- or did you mean that the local-frame is garbaged (this would make more sense to me).
> 

Yes I really mean that the closure is garbaged.

When you write : 

func: compose(f, g) { #[ g perform f perform ] }

The function and the block are only compiled once.

At runtime, when you perform compose, there is no compilation :

#[ ] has compiled into compose the code that will create an object on the stack.
This object hold f and g values and a pointer to code "g perform f perform"

When you perform this object it executes the code behind the pointer
and, when this object is no more used,  you can garbage it.

[toc] | [prev] | [next] | [standalone]


#37531

FromPaul Rubin <no.email@nospam.invalid>
Date2015-03-21 19:47 -0700
Message-ID<871tkhbvex.fsf@jester.gateway.sonic.net>
In reply to#37526
franck.bensusan@gmail.com writes:
> Yes, I understand, but GC is almost mandatory when you want some features.

Sure, those are features not traditionally found in Forth ;-).  Forth
has something like malloc/free but really, Forth's typical application
domain is hardware control, and the programs tend to use static
allocation.  A program might create a few variables and arrays at the
start of execution and then do no more allocation or deallocation.

> For instance if you want closures, you have to save some environment
> and you don't know when to release it.

Sure, now tell me how that was done in Fortran: do you see where this is
going?  Forth programs sometimes do stuff like that using OOP libraries,
but Forth doesn't have first-class functions like Scheme.

> Doing this without GC is a pain... With GC, it is simple.

GC makes all kinds of things simple, but increases the program
footprint, complicates the interpreter implementation, and (this is
often a significant issue in hardware control) makes the program timing
non-deterministic.

> What do you mean by "type tags" ? 

I just mean objects in memory have some kind of field (either in the
pointer or in the heap structure) that says what type of object it is,
that the interpreter can inspect and dispatch on at runtime.  That's
just like Lisp and its descendants which is why I compared Oforth to
Lisp.  It contrasts with (say) Ada, which figures out the types at
compile time and generates code specialized to those types; and with
assembly language, where types and code selection are done manually by
the programmer, with no automatic tracking by the language either at
compile time or run time and your program can simply get it wrong
without any detection.  Forth is like assembly code in that regard.
Automatic type checking is against the ideals of Forth, since it would
interfere with your freedom or something like that.

[toc] | [prev] | [next] | [standalone]


#37537

Fromfranck.bensusan@gmail.com
Date2015-03-22 08:41 -0700
Message-ID<54f48f02-c218-40c2-a61e-5c5d8f6097db@googlegroups.com>
In reply to#37531
> Sure, those are features not traditionally found in Forth ;-).  Forth
> has something like malloc/free but really, Forth's typical application
> domain is hardware control, and the programs tend to use static
> allocation.  A program might create a few variables and arrays at the
> start of execution and then do no more allocation or deallocation.
>
I think Forth mecanisms are really great and could also apply to desktop/server
programming. Those are not the same concerns, of course, but there is no 
reason why those mecanisms should be limited to hardware control programming.


> GC makes all kinds of things simple, but increases the program
> footprint, complicates the interpreter implementation, and (this is
> often a significant issue in hardware control) makes the program timing
> non-deterministic.
> 

Perhaps those features disqualify Oforth to target 
micro-controller programming but, well, that was a choice to make. 
I don't think a GC will be added to ANS Forth, because it would be 
disqualified too (see your arguments), and I don't think an extention 
could give a fast, optimized GC. 
There are not many choices left if you want a higher level Forth to be used 
on desktop/server targets...

[toc] | [prev] | [next] | [standalone]


Page 1 of 4  [1] 2 3 4  Next page →

Back to top | Article view | comp.lang.forth


csiph-web