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


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

Forth's list : the multo.

Started byalbert@cherry.spenarnc.xs4all.nl (Albert van der Horst)
First post2017-05-30 11:22 +0200
Last post2017-06-02 20:46 -0700
Articles 19 — 10 participants

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


Contents

  Forth's list : the multo. albert@cherry.spenarnc.xs4all.nl (Albert van der Horst) - 2017-05-30 11:22 +0200
    Re: Forth's list : the multo. minforth@arcor.de - 2017-05-30 07:34 -0700
    Re: Forth's list : the multo. Julian Fondren <julian.fondren@gmail.com> - 2017-05-30 10:57 -0700
    Re: Forth's list : the multo. lehs <skydda.barnen@gmail.com> - 2017-05-30 11:13 -0700
      Re: Forth's list : the multo. Paul Rubin <no.email@nospam.invalid> - 2017-05-30 21:30 -0700
        Re: Forth's list : the multo. lehs <skydda.barnen@gmail.com> - 2017-05-30 22:09 -0700
          Re: Forth's list : the multo. Julian Fondren <julian.fondren@gmail.com> - 2017-05-30 23:25 -0700
            Re: Forth's list : the multo. lehs <skydda.barnen@gmail.com> - 2017-05-31 01:36 -0700
              Re: Forth's list : the multo. albert@cherry.spenarnc.xs4all.nl (Albert van der Horst) - 2017-05-31 10:49 +0200
                Re: Forth's list : the multo. lehs <skydda.barnen@gmail.com> - 2017-05-31 02:16 -0700
                  Re: Forth's list : the multo. Paul Rubin <no.email@nospam.invalid> - 2017-06-01 01:11 -0700
                    Re: Forth's list : the multo. NN <november.nihal@gmail.com> - 2017-06-01 03:55 -0700
                      Re: Forth's list : the multo. foxaudioresearch@gmail.com - 2017-06-02 07:33 -0700
                      Re: Forth's list : the multo. obi65537@gmail.com - 2017-06-02 11:15 -0700
            Re: Forth's list : the multo. lehs <skydda.barnen@gmail.com> - 2017-05-31 01:38 -0700
              Re: Forth's list : the multo. NN <november.nihal@gmail.com> - 2017-05-31 03:29 -0700
                Re: Forth's list : the multo. Andrew Haley <andrew29@littlepinkcloud.invalid> - 2017-05-31 11:18 -0500
                Re: Forth's list : the multo. "Robert L." <No_spamming@noWhere_7073.org> - 2017-06-03 01:49 +0000
                  Re: Forth's list : the multo. Julian Fondren <julian.fondren@gmail.com> - 2017-06-02 20:46 -0700

#60053 — Forth's list : the multo.

Fromalbert@cherry.spenarnc.xs4all.nl (Albert van der Horst)
Date2017-05-30 11:22 +0200
SubjectForth's list : the multo.
Message-ID<ogjdkj$c91$1@cherry.spenarnc.xs4all.nl>
With all this HOF talk lately.

I had this epiphany why Lisp is superior to Forth. (Forth is still useful)
Elizabeth Rather tells us "just define an array structure the
way you need it". That is the Forth Way. The problem is
it blocks the usage of HOF's. HOF's presumes that the language
has standard ways of building data structures from more elementary
data structures. And without HOF's programming doesn't reach the next
level, I must give Aguilar that.

Even with a very simple structure one can do a lot. This is a
basic exploration.

\ I have a "bag" data structure in ciforth which is basically an array
\ where the first cell contains a pointer to the end.
\
\ I discovered that I can put those on a stack because my stack
\ grows down:

DSP@ >R 1 2 3 R>
 OK
DO-DEBUG

S[ 1 2 3 6242304 ] OK

\ Time for a name, I call them multo .

\ I can print a multo with the tool foreseen for bags:
WANT .BAG

S[ 1 2 3 6242304 ] OK DSP@ .BAG
3 2 1

S[ 1 2 3 6242304 ] OK

\ This is the definitions of .BAG
: .BAG  DO-BAG I ? LOOP-BAG ;

\ Let's make it easier to define multo's.
S[ ] OK : multo: DSP@ >R ^J PARSE EVALUATE R> ;

S[ ] OK multo: 1 2 3


S[ 1 2 3 6242304 ] OK
\ or print them
: .m DSP@ .BAG ;
S[ 1 2 3 6242304 ] OK .m
3 2 1

\ Or drop them
OK : mDROP DSP! ;

S[ 1 2 3 6242304 ] OK mDROP
S[ ] OK

\ Let's have some extra on the stack to see the difference.
4 5 6 multo: 1 2 3

S[ 4 5 6 1 2 3 6242280 ] OK .m
3 2 1
S[ 4 5 6 1 2 3 6242280 ] OK mDROP

S[ 4 5 6 ] OK

\ We can now have a HOF like lisp's MAPCAR

: mapcar DSP@ CELL+ DO-BAG I @ OVER EXECUTE I ! LOOP-BAG DROP ;

S[ 4 5 6 ] OK multo: 1 2 3

S[ 4 5 6 1 2 3 6242280 ] OK WANT SQ

 107( SQRT SQ SQ? ** )                               \ AvdH B4dec01 --
 107( SQRT SQ SQ? ** )                               \ AvdH B4dec01

S[ 4 5 6 1 2 3 6242280 ] OK 7 SQ .
49
\ Let's apply squaring to all elements of the multo
S[ 4 5 6 1 2 3 6242280 ] OK 'SQ mapcar

S[ 4 5 6 1 4 9 6242280 ] OK

S[ 4 5 6 1 4 9 6242280 ] OK

S[ 4 5 6 1 4 9 6242280 ] OK WANT SQRT

S[ 4 5 6 1 4 9 6242280 ] OK 49 SQRT .
7
\ Then draw the square roots again.
S[ 4 5 6 1 4 9 6242280 ] OK 'SQRT mapcar

S[ 4 5 6 1 2 3 6242280 ] OK .m mDROP
3 2 1

S[ 4 5 6 ] OK CLS    \ Clean up stack before you leave.
S[ ] OK
BYE

Note:
With this in mind we need stack manipulations.
This is a possible convention:
Preceede SWAP NIP OVER by the stack content
sdSWAP is in fact ROT
dsSWAP is -ROT
Normal NIP is ssNIP
ddOVER is 2OVER

We can now introduce the likes of
smSWAP mdSWAP mmOVER mmNIP mDUP
and use it for e.g. large numbers.

P.S
The examples have been edited to get rid of typo's.
This mean they have not been tested as such.
-- 
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

[toc] | [next] | [standalone]


#60062

Fromminforth@arcor.de
Date2017-05-30 07:34 -0700
Message-ID<7b609b5f-6c76-4707-81b7-cc267bf67591@googlegroups.com>
In reply to#60053
Am Dienstag, 30. Mai 2017 11:21:43 UTC+2 schrieb Albert van der Horst:
> With all this HOF talk lately.
> 
> I had this epiphany why Lisp is superior to Forth. (Forth is still useful)
> Elizabeth Rather tells us "just define an array structure the
> way you need it". That is the Forth Way. The problem is
> it blocks the usage of HOF's. HOF's presumes that the language
> has standard ways of building data structures from more elementary
> data structures. And without HOF's programming doesn't reach the next
> level, I must give Aguilar that.
> 
> Even with a very simple structure one can do a lot. This is a
> basic exploration.
> 
> \ I have a "bag" data structure in ciforth which is basically an array
> \ where the first cell contains a pointer to the end.
> \
> \ I discovered that I can put those on a stack because my stack
> \ grows down:
> 
> DSP@ >R 1 2 3 R>
>  OK
> DO-DEBUG
> 
> S[ 1 2 3 6242304 ] OK
> 
> \ Time for a name, I call them multo .
> 
> \ I can print a multo with the tool foreseen for bags:
> WANT .BAG
> 
> S[ 1 2 3 6242304 ] OK DSP@ .BAG
> 3 2 1
> 
> S[ 1 2 3 6242304 ] OK
> 
> \ This is the definitions of .BAG
> : .BAG  DO-BAG I ? LOOP-BAG ;
> 
> \ Let's make it easier to define multo's.
> S[ ] OK : multo: DSP@ >R ^J PARSE EVALUATE R> ;
> 
> S[ ] OK multo: 1 2 3
> 
> 
> S[ 1 2 3 6242304 ] OK
> \ or print them
> : .m DSP@ .BAG ;
> S[ 1 2 3 6242304 ] OK .m
> 3 2 1
> 
> \ Or drop them
> OK : mDROP DSP! ;
> 
> S[ 1 2 3 6242304 ] OK mDROP
> S[ ] OK
> 
> \ Let's have some extra on the stack to see the difference.
> 4 5 6 multo: 1 2 3
> 
> S[ 4 5 6 1 2 3 6242280 ] OK .m
> 3 2 1
> S[ 4 5 6 1 2 3 6242280 ] OK mDROP
> 
> S[ 4 5 6 ] OK
> 
> \ We can now have a HOF like lisp's MAPCAR
> 
> : mapcar DSP@ CELL+ DO-BAG I @ OVER EXECUTE I ! LOOP-BAG DROP ;
> 
> S[ 4 5 6 ] OK multo: 1 2 3
> 
> S[ 4 5 6 1 2 3 6242280 ] OK WANT SQ
> 
>  107( SQRT SQ SQ? ** )                               \ AvdH B4dec01 --
>  107( SQRT SQ SQ? ** )                               \ AvdH B4dec01
> 
> S[ 4 5 6 1 2 3 6242280 ] OK 7 SQ .
> 49
> \ Let's apply squaring to all elements of the multo
> S[ 4 5 6 1 2 3 6242280 ] OK 'SQ mapcar
> 
> S[ 4 5 6 1 4 9 6242280 ] OK
> 
> S[ 4 5 6 1 4 9 6242280 ] OK
> 
> S[ 4 5 6 1 4 9 6242280 ] OK WANT SQRT
> 
> S[ 4 5 6 1 4 9 6242280 ] OK 49 SQRT .
> 7
> \ Then draw the square roots again.
> S[ 4 5 6 1 4 9 6242280 ] OK 'SQRT mapcar
> 
> S[ 4 5 6 1 2 3 6242280 ] OK .m mDROP
> 3 2 1
> 
> S[ 4 5 6 ] OK CLS    \ Clean up stack before you leave.
> S[ ] OK
> BYE
> 
> Note:
> With this in mind we need stack manipulations.
> This is a possible convention:
> Preceede SWAP NIP OVER by the stack content
> sdSWAP is in fact ROT
> dsSWAP is -ROT
> Normal NIP is ssNIP
> ddOVER is 2OVER
> 
> We can now introduce the likes of
> smSWAP mdSWAP mmOVER mmNIP mDUP
> and use it for e.g. large numbers.
> 
> P.S
> The examples have been edited to get rid of typo's.
> This mean they have not been tested as such.
> -- 
> Albert van der Horst, UTRECHT,THE NETHERLANDS
> Economic growth -- being exponential -- ultimately falters.
> albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

I am using a somewhat different syntax for lists and 1d/2d-matrices.
Elements can be numerals or other lists and matrices.
But the point is that not everything is on the stack.
So everything relies on some gymnastics of data in heap memory
(FREE/ALLOCATE may be too slow)

With this you have mostly pointers on the stack and don't need
to add data-specific stack gymnastic words to the Forth zoo.

And it's a pity that all brackets and braces are already occupied
by the more popular Forths......  So agreement on a good syntax may become
difficult. You know, legacy stuff...   ;-)

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


#60071

FromJulian Fondren <julian.fondren@gmail.com>
Date2017-05-30 10:57 -0700
Message-ID<2efb5d8b-2d0c-44e5-80d3-9d2f8a8619cb@googlegroups.com>
In reply to#60053
On Tuesday, May 30, 2017 at 4:21:43 AM UTC-5, Albert van der Horst wrote:
>
> DSP@ >R 1 2 3 R>
>  OK
> DO-DEBUG
>
> S[ 1 2 3 6242304 ] OK
>
> \ Time for a name, I call them multo .
>

OK, so this isn't a bag itself, SP@ (with this on the stack) produces
the address of a bag.

  : do-bag ]] @+ swap do [[ ; immediate
  : loop-bag ]] cell +loop [[ ; immediate

  : .bag ( bag -- )  do-bag i ? loop-bag ;
  : mapcar ( multo xt -- )
    sp@ cell+ do-bag i @ over execute i ! loop-bag drop ;

  : b1 ( -- ...multo )  sp@ 1 swap 2 swap 3 swap ;
  cr b1 sp@ .bag
  cr ' 1+ mapcar sp@ .bag

Outputs:

  3 2 1
  4 3 2

And you can drop a multo with this of course:

  SP! ( ...multo -- )


But where have I seen these before? ...

  : multo-list ( ... u -- ...multo )  1+ cells sp@ + ;
  : counted-list ( ...multo --- ... u )  sp@ - cell / 1- ;

oh yeah.

  [4]FORTH> .s
    Data: 2 3 4 140734755979752 ---
  System: ---
   Float: --- ok
  [4]FORTH> counted-list .s
    Data: 2 3 4 3 ---
  System: ---
   Float: --- ok
  [4]FORTH> multo-list .s
    Data: 2 3 4 140734755979752 ---
  System: ---
   Float: --- ok
  [4]FORTH> sp@ .bag 4 3 2  ok

So you can use N>R and NR> as well, or you can pass GET-ORDER and such
through a bag HOF.

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


#60074

Fromlehs <skydda.barnen@gmail.com>
Date2017-05-30 11:13 -0700
Message-ID<6aab14e2-c89d-4be1-8ed3-f8461297b7b7@googlegroups.com>
In reply to#60053
Den tisdag 30 maj 2017 kl. 11:21:43 UTC+2 skrev Albert van der Horst:
> With all this HOF talk lately.
> 
> I had this epiphany why Lisp is superior to Forth. (Forth is still useful)
> Elizabeth Rather tells us "just define an array structure the
> way you need it". That is the Forth Way. The problem is
> it blocks the usage of HOF's. HOF's presumes that the language
> has standard ways of building data structures from more elementary
> data structures. And without HOF's programming doesn't reach the next
> level, I must give Aguilar that.
> 
> Even with a very simple structure one can do a lot. This is a
> basic exploration.
> 
> \ I have a "bag" data structure in ciforth which is basically an array
> \ where the first cell contains a pointer to the end.
> \
> \ I discovered that I can put those on a stack because my stack
> \ grows down:
> 
> DSP@ >R 1 2 3 R>
>  OK
> DO-DEBUG
> 
> S[ 1 2 3 6242304 ] OK
> 
> \ Time for a name, I call them multo .
> 
> \ I can print a multo with the tool foreseen for bags:
> WANT .BAG
> 
> S[ 1 2 3 6242304 ] OK DSP@ .BAG
> 3 2 1
> 
> S[ 1 2 3 6242304 ] OK
> 
> \ This is the definitions of .BAG
> : .BAG  DO-BAG I ? LOOP-BAG ;
> 
> \ Let's make it easier to define multo's.
> S[ ] OK : multo: DSP@ >R ^J PARSE EVALUATE R> ;
> 
> S[ ] OK multo: 1 2 3
> 
> 
> S[ 1 2 3 6242304 ] OK
> \ or print them
> : .m DSP@ .BAG ;
> S[ 1 2 3 6242304 ] OK .m
> 3 2 1
> 
> \ Or drop them
> OK : mDROP DSP! ;
> 
> S[ 1 2 3 6242304 ] OK mDROP
> S[ ] OK
> 
> \ Let's have some extra on the stack to see the difference.
> 4 5 6 multo: 1 2 3
> 
> S[ 4 5 6 1 2 3 6242280 ] OK .m
> 3 2 1
> S[ 4 5 6 1 2 3 6242280 ] OK mDROP
> 
> S[ 4 5 6 ] OK
> 
> \ We can now have a HOF like lisp's MAPCAR
> 
> : mapcar DSP@ CELL+ DO-BAG I @ OVER EXECUTE I ! LOOP-BAG DROP ;
> 
> S[ 4 5 6 ] OK multo: 1 2 3
> 
> S[ 4 5 6 1 2 3 6242280 ] OK WANT SQ
> 
>  107( SQRT SQ SQ? ** )                               \ AvdH B4dec01 --
>  107( SQRT SQ SQ? ** )                               \ AvdH B4dec01
> 
> S[ 4 5 6 1 2 3 6242280 ] OK 7 SQ .
> 49
> \ Let's apply squaring to all elements of the multo
> S[ 4 5 6 1 2 3 6242280 ] OK 'SQ mapcar
> 
> S[ 4 5 6 1 4 9 6242280 ] OK
> 
> S[ 4 5 6 1 4 9 6242280 ] OK
> 
> S[ 4 5 6 1 4 9 6242280 ] OK WANT SQRT
> 
> S[ 4 5 6 1 4 9 6242280 ] OK 49 SQRT .
> 7
> \ Then draw the square roots again.
> S[ 4 5 6 1 4 9 6242280 ] OK 'SQRT mapcar
> 
> S[ 4 5 6 1 2 3 6242280 ] OK .m mDROP
> 3 2 1
> 
> S[ 4 5 6 ] OK CLS    \ Clean up stack before you leave.
> S[ ] OK
> BYE
> 
> Note:
> With this in mind we need stack manipulations.
> This is a possible convention:
> Preceede SWAP NIP OVER by the stack content
> sdSWAP is in fact ROT
> dsSWAP is -ROT
> Normal NIP is ssNIP
> ddOVER is 2OVER
> 
> We can now introduce the likes of
> smSWAP mdSWAP mmOVER mmNIP mDUP
> and use it for e.g. large numbers.
> 
> P.S
> The examples have been edited to get rid of typo's.
> This mean they have not been tested as such.
> -- 
> Albert van der Horst, UTRECHT,THE NETHERLANDS
> Economic growth -- being exponential -- ultimately falters.
> albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

It would be a nice challenge to get a concrete example of a higher level application that can't be managed in Forth. 

If HOF stands for Higher Level Function and those really are necessary to reach "the next level", what stops a Forth programmer from using such an approach?

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


#60088

FromPaul Rubin <no.email@nospam.invalid>
Date2017-05-30 21:30 -0700
Message-ID<87r2z5odge.fsf@nightsong.com>
In reply to#60074
lehs <skydda.barnen@gmail.com> writes:
> It would be a nice challenge to get a concrete example of a higher
> level application that can't be managed in Forth.

I'd expect it can all be done in Forth, but you have to carefully manage
all of the scaffolding, probably including some kind of OOP system to
hold compound values; some kind of iteration convention for lists,
arrays, or what have you; and ways to pass those things to HOF's, along
with XT's all over the place.  It's a lot of complexity to follow and
likely to be bug-prone.  It's not impossible.  It's just harder than it
would be if those features were built in.

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


#60089

Fromlehs <skydda.barnen@gmail.com>
Date2017-05-30 22:09 -0700
Message-ID<d1763bd2-6fb8-46aa-9bfb-23afa972d64b@googlegroups.com>
In reply to#60088
Den onsdag 31 maj 2017 kl. 06:30:27 UTC+2 skrev Paul Rubin:
> lehs <skydda.barnen@gmail.com> writes:
> > It would be a nice challenge to get a concrete example of a higher
> > level application that can't be managed in Forth.
> 
> I'd expect it can all be done in Forth, but you have to carefully manage
> all of the scaffolding, probably including some kind of OOP system to
> hold compound values; some kind of iteration convention for lists,
> arrays, or what have you; and ways to pass those things to HOF's, along
> with XT's all over the place.  It's a lot of complexity to follow and
> likely to be bug-prone.  It's not impossible.  It's just harder than it
> would be if those features were built in.

In what kind of program are HOF's useful? How would they be produced and what would they produce?

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


#60092

FromJulian Fondren <julian.fondren@gmail.com>
Date2017-05-30 23:25 -0700
Message-ID<d9fe7e35-1144-4837-90be-2c3a278c9308@googlegroups.com>
In reply to#60089
On Wednesday, May 31, 2017 at 12:10:00 AM UTC-5, lehs wrote:
> 
> In what kind of program are HOF's useful? How would they be produced and what would they produce?

Virtually any kind of program. It'd be better to present one and ask
what it would look like if it abused HOFs.

  \ boring: always does the same thing
  : hi ( -- ) ." Hello, world" ;

  \ normal: takes data as an input to logic that is always the same
  : .balance ( -- )  cr ." Your balance is: " balance ? ;

  \ HOF: takes logic as an input
  : transaction ( xt -- )  balance swap execute ;
  : deposit ( n -- )  ['] +! transaction ;
  : withdraw ( n -- )  negate deposit ;

  fvariable slushfund
  : interest ( -- )
    [: ( a-balance ) dup @ 2dup s>f 0.02e f* f>s swap +!
       ( a-balance orig-balance )
       s>f 1.02e f* swap @ s>f f- slushfund f+! ;] transaction ;
  \ XXX: obfuscate before merging --jrf 21feb16 

For an array:

  : boring ( -- )  cr ." Hello, world!" ;

  : normal ( c-addr u )  cr ." Hello, " type ." !" ;

  100 buffer: salut
  s" Hello, world!" salut place
  : HOF ( xt -- )
    salut count bounds do
      i over execute
    loop drop ;

  : greet ( -- )  cr [: c@ emit ;] HOF ;
  : encrypt ( -- )  [: dup c@ 1+ swap c! ;] HOF ;

  encrypt encrypt encrypt greet

Outputs:

  Khoor/#zruog$

It would be better to ask for "code what would be difficult to do as
well in Forth without similar shenanigans". Forth doesn't have
closures so anything with a closure right away needs to be forced to
handle its memory more responsibly. An example is an accumulator
generator:


  \ hypothetical closure Forth

  : accgen {: n | acc -- xt :}  \ xt: ( -- n )
    0 to acc  [: n +to acc  acc ;] ;

  5 accgen constant +5er
  3 accgen constant +3er

  : series ( -- )
    cr 10 0 do +5er execute . loop
    cr 10 0 do +3er execute . loop ;

  series

Output would be:

  5 10 15 20 25 30 35 40 45 50
  3 6 9 12 15 18 21 24 27 30

ACCGEN accepts a number and returns a function that, when executed,
adds that number to an accumulator (initially zero) and then returns
the new accumulator value.

  \ actual Forth
  : accgen ( n "name" -- )
    create , 0 , does> dup @+ swap +! cell+ @ ;

  5 accgen +5er
  3 accgen +3er

  : series ( -- )
    cr 10 0 do +5er . loop
    cr 10 0 do +3er . loop ;

  series

Or more similarly to the first:

  : accgen ( n -- xt )
    align here >r 0 , >r
    :noname r> ]] literal [[
        r> dup ]] literal +! [[
               ]] literal @ ; [[ ;

  5 accgen constant +5er
  3 accgen constant +3er

  : series ( -- )
    cr 10 0 do +5er execute . loop
    cr 10 0 do +3er execute . loop ;

  series

With output:

  5 10 15 20 25 30 35 40 45 50
  3 6 9 12 15 18 21 24 27 30

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


#60094

Fromlehs <skydda.barnen@gmail.com>
Date2017-05-31 01:36 -0700
Message-ID<388b0d41-8d6c-4098-b5a1-c2023902ff96@googlegroups.com>
In reply to#60092
Den onsdag 31 maj 2017 kl. 08:25:08 UTC+2 skrev Julian Fondren:
> On Wednesday, May 31, 2017 at 12:10:00 AM UTC-5, lehs wrote:
> > 
> > In what kind of program are HOF's useful? How would they be produced and what would they produce?
> 
> Virtually any kind of program. It'd be better to present one and ask
> what it would look like if it abused HOFs.
> 
>   \ boring: always does the same thing
>   : hi ( -- ) ." Hello, world" ;
> 
>   \ normal: takes data as an input to logic that is always the same
>   : .balance ( -- )  cr ." Your balance is: " balance ? ;
> 
>   \ HOF: takes logic as an input
>   : transaction ( xt -- )  balance swap execute ;
>   : deposit ( n -- )  ['] +! transaction ;
>   : withdraw ( n -- )  negate deposit ;
> 
>   fvariable slushfund
>   : interest ( -- )
>     [: ( a-balance ) dup @ 2dup s>f 0.02e f* f>s swap +!
>        ( a-balance orig-balance )
>        s>f 1.02e f* swap @ s>f f- slushfund f+! ;] transaction ;
>   \ XXX: obfuscate before merging --jrf 21feb16 
> 
> For an array:
> 
>   : boring ( -- )  cr ." Hello, world!" ;
> 
>   : normal ( c-addr u )  cr ." Hello, " type ." !" ;
> 
>   100 buffer: salut
>   s" Hello, world!" salut place
>   : HOF ( xt -- )
>     salut count bounds do
>       i over execute
>     loop drop ;
> 
>   : greet ( -- )  cr [: c@ emit ;] HOF ;
>   : encrypt ( -- )  [: dup c@ 1+ swap c! ;] HOF ;
> 
>   encrypt encrypt encrypt greet
> 
> Outputs:
> 
>   Khoor/#zruog$
> 
> It would be better to ask for "code what would be difficult to do as
> well in Forth without similar shenanigans". Forth doesn't have
> closures so anything with a closure right away needs to be forced to
> handle its memory more responsibly. An example is an accumulator
> generator:
> 
> 
>   \ hypothetical closure Forth
> 
>   : accgen {: n | acc -- xt :}  \ xt: ( -- n )
>     0 to acc  [: n +to acc  acc ;] ;
> 
>   5 accgen constant +5er
>   3 accgen constant +3er
> 
>   : series ( -- )
>     cr 10 0 do +5er execute . loop
>     cr 10 0 do +3er execute . loop ;
> 
>   series
> 
> Output would be:
> 
>   5 10 15 20 25 30 35 40 45 50
>   3 6 9 12 15 18 21 24 27 30
> 
> ACCGEN accepts a number and returns a function that, when executed,
> adds that number to an accumulator (initially zero) and then returns
> the new accumulator value.
> 
>   \ actual Forth
>   : accgen ( n "name" -- )
>     create , 0 , does> dup @+ swap +! cell+ @ ;
> 
>   5 accgen +5er
>   3 accgen +3er
> 
>   : series ( -- )
>     cr 10 0 do +5er . loop
>     cr 10 0 do +3er . loop ;
> 
>   series
> 
> Or more similarly to the first:
> 
>   : accgen ( n -- xt )
>     align here >r 0 , >r
>     :noname r> ]] literal [[
>         r> dup ]] literal +! [[
>                ]] literal @ ; [[ ;
> 
>   5 accgen constant +5er
>   3 accgen constant +3er
> 
>   : series ( -- )
>     cr 10 0 do +5er execute . loop
>     cr 10 0 do +3er execute . loop ;
> 
>   series
> 
> With output:
> 
>   5 10 15 20 25 30 35 40 45 50
>   3 6 9 12 15 18 21 24 27 30

What can be done with higher order functions and closures that can't be done with xt's on stacks? Is it really necessary to point out that the closure is local? If the programmer know what he's doing the right xt's will be applied to the right xt's.

But what kind of programs need higher order functions so bad that you are willing to write all the brackets in Forth? (If you don't believe in xt's on stacks).

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


#60096

Fromalbert@cherry.spenarnc.xs4all.nl (Albert van der Horst)
Date2017-05-31 10:49 +0200
Message-ID<ogm01t$rdp$1@cherry.spenarnc.xs4all.nl>
In reply to#60094
In article <388b0d41-8d6c-4098-b5a1-c2023902ff96@googlegroups.com>,
lehs  <skydda.barnen@gmail.com> wrote:
<SNIP>
 >What can be done with higher order functions and closures that can't
 be done with xt's on stacks? Is it really necessary to point out that
 the closure is local? If the programmer know what he's doing the
 right xt's will be applied to the right xt's.

Please restrict your line length.

The right question is "what ... that *will* be done ..."
It is the thinking of the programmer that needs a higher level.
"A FORTRAN programmer can write FORTRAN in any language".

Once you know Forth you'll use short routine in C.
Once I know Lisp I'll (probably) write better Forth.

>
>But what kind of programs need higher order functions so bad that you
are willing to write all the brackets in Forth? (If you don't believe
in xt's on stacks).

You mean parentheses? That is not too bad.

Groetjes
-- 
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

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


#60097

Fromlehs <skydda.barnen@gmail.com>
Date2017-05-31 02:16 -0700
Message-ID<38757b5e-9259-4f41-a87a-3bc0db6be3bf@googlegroups.com>
In reply to#60096
Den onsdag 31 maj 2017 kl. 10:48:58 UTC+2 skrev Albert van der Horst:
> In article <388b0d41-8d6c-4098-b5a1-c2023902ff96@googlegroups.com>,
> lehs  <skydda.barnen@gmail.com> wrote:
> <SNIP>
>  >What can be done with higher order functions and closures that can't
>  be done with xt's on stacks? Is it really necessary to point out that
>  the closure is local? If the programmer know what he's doing the
>  right xt's will be applied to the right xt's.
> 
> Please restrict your line length.
> 
> The right question is "what ... that *will* be done ..."
> It is the thinking of the programmer that needs a higher level.
> "A FORTRAN programmer can write FORTRAN in any language".
> 
> Once you know Forth you'll use short routine in C.
> Once I know Lisp I'll (probably) write better Forth.
> 
> >
> >But what kind of programs need higher order functions so bad that you
> are willing to write all the brackets in Forth? (If you don't believe
> in xt's on stacks).
> 
> You mean parentheses? That is not too bad.
> 
> Groetjes
> -- 
> Albert van der Horst, UTRECHT,THE NETHERLANDS
> Economic growth -- being exponential -- ultimately falters.
> albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

I can agree with that. It's all about the way of thinking. All xt's on stacks are maybe just too general? It's an interesting but mind blowing thought with a "program" where xt's on stacks execute other xt's on stacks without crashing and giving some intelligent results.

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


#60131

FromPaul Rubin <no.email@nospam.invalid>
Date2017-06-01 01:11 -0700
Message-ID<87mv9snn4w.fsf@nightsong.com>
In reply to#60097
lehs <skydda.barnen@gmail.com> writes:
> I can agree with that. It's all about the way of thinking. All xt's on
> stacks are maybe just too general? It's an interesting but mind
> blowing thought with a "program" where xt's on stacks execute other
> xt's on stacks without crashing and giving some intelligent results.

Right, that's the whole thing.  You can do it in Forth but you'll
probably have to debug a lot of crashes before you get your thing
working.  Some other languages make it convenient and natural.

Here's a well-known old paper you might like.  The examples in it
are written in Miranda which was a forerunner of Haskell.

http://www.cs.utexas.edu/~shmat/courses/cs345/whyfp.pdf

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


#60136

FromNN <november.nihal@gmail.com>
Date2017-06-01 03:55 -0700
Message-ID<7bb5c5dc-6e0c-4d76-b9b4-7ba64577dd05@googlegroups.com>
In reply to#60131
On Thursday, 1 June 2017 09:11:14 UTC+1, Paul Rubin  wrote:
> are written in Miranda which was a forerunner of Haskell.
> 
> http://www.cs.utexas.edu/~shmat/courses/cs345/whyfp.pdf

or as an alternative,

http://evincarofautumn.blogspot.co.uk/2012/02/why-concatenative-programming-matters.html

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


#60198

Fromfoxaudioresearch@gmail.com
Date2017-06-02 07:33 -0700
Message-ID<7328df65-fa3f-4e78-924d-bdad2b1f3418@googlegroups.com>
In reply to#60136
On Thursday, June 1, 2017 at 6:55:39 AM UTC-4, NN wrote:
> On Thursday, 1 June 2017 09:11:14 UTC+1, Paul Rubin  wrote:
> > are written in Miranda which was a forerunner of Haskell.
> > 
> > http://www.cs.utexas.edu/~shmat/courses/cs345/whyfp.pdf
> 
> or as an alternative,
> 
> http://evincarofautumn.blogspot.co.uk/2012/02/why-concatenative-programming-matters.html

Hey. This is a nice paper. I have never read this kind of theoretical analysis 
of what we do here.  I am also fascinated by the prospect of compiling a 
program in parallel.  Seems like that would be possible now with appropriate
source code discipline. 

Thanks NN

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


#60204

Fromobi65537@gmail.com
Date2017-06-02 11:15 -0700
Message-ID<4d67690f-1824-4efa-9375-be54b33ce15c@googlegroups.com>
In reply to#60136
On Thursday, June 1, 2017 at 1:55:39 PM UTC+3, NN wrote:
> On Thursday, 1 June 2017 09:11:14 UTC+1, Paul Rubin  wrote:
> > are written in Miranda which was a forerunner of Haskell.
> > 
> > http://www.cs.utexas.edu/~shmat/courses/cs345/whyfp.pdf
> 
> or as an alternative,
> 
> http://evincarofautumn.blogspot.co.uk/2012/02/why-concatenative-programming-matters.html

Interesting, also little funny too.
For this forth code ( x y z -- x^2+y^2-|y| ) he writes:
 
"So our final function can be written:

f = drop dup dup × swap abs rot3 dup × swap − +

Well…that sucked."

I agree! :) Even without factoring could be written:

f = drop abs dup 1- * swap dup * +


Have a nice day,
hum9

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


#60095

Fromlehs <skydda.barnen@gmail.com>
Date2017-05-31 01:38 -0700
Message-ID<1e9243f9-d63c-4c8c-aa42-e7ff394f99b0@googlegroups.com>
In reply to#60092
Den onsdag 31 maj 2017 kl. 08:25:08 UTC+2 skrev Julian Fondren:
> On Wednesday, May 31, 2017 at 12:10:00 AM UTC-5, lehs wrote:
> > 
> > In what kind of program are HOF's useful? How would they be produced and what would they produce?
> 
> Virtually any kind of program. It'd be better to present one and ask
> what it would look like if it abused HOFs.
> 
>   \ boring: always does the same thing
>   : hi ( -- ) ." Hello, world" ;
> 
>   \ normal: takes data as an input to logic that is always the same
>   : .balance ( -- )  cr ." Your balance is: " balance ? ;
> 
>   \ HOF: takes logic as an input
>   : transaction ( xt -- )  balance swap execute ;
>   : deposit ( n -- )  ['] +! transaction ;
>   : withdraw ( n -- )  negate deposit ;
> 
>   fvariable slushfund
>   : interest ( -- )
>     [: ( a-balance ) dup @ 2dup s>f 0.02e f* f>s swap +!
>        ( a-balance orig-balance )
>        s>f 1.02e f* swap @ s>f f- slushfund f+! ;] transaction ;
>   \ XXX: obfuscate before merging --jrf 21feb16 
> 
> For an array:
> 
>   : boring ( -- )  cr ." Hello, world!" ;
> 
>   : normal ( c-addr u )  cr ." Hello, " type ." !" ;
> 
>   100 buffer: salut
>   s" Hello, world!" salut place
>   : HOF ( xt -- )
>     salut count bounds do
>       i over execute
>     loop drop ;
> 
>   : greet ( -- )  cr [: c@ emit ;] HOF ;
>   : encrypt ( -- )  [: dup c@ 1+ swap c! ;] HOF ;
> 
>   encrypt encrypt encrypt greet
> 
> Outputs:
> 
>   Khoor/#zruog$
> 
> It would be better to ask for "code what would be difficult to do as
> well in Forth without similar shenanigans". Forth doesn't have
> closures so anything with a closure right away needs to be forced to
> handle its memory more responsibly. An example is an accumulator
> generator:
> 
> 
>   \ hypothetical closure Forth
> 
>   : accgen {: n | acc -- xt :}  \ xt: ( -- n )
>     0 to acc  [: n +to acc  acc ;] ;
> 
>   5 accgen constant +5er
>   3 accgen constant +3er
> 
>   : series ( -- )
>     cr 10 0 do +5er execute . loop
>     cr 10 0 do +3er execute . loop ;
> 
>   series
> 
> Output would be:
> 
>   5 10 15 20 25 30 35 40 45 50
>   3 6 9 12 15 18 21 24 27 30
> 
> ACCGEN accepts a number and returns a function that, when executed,
> adds that number to an accumulator (initially zero) and then returns
> the new accumulator value.
> 
>   \ actual Forth
>   : accgen ( n "name" -- )
>     create , 0 , does> dup @+ swap +! cell+ @ ;
> 
>   5 accgen +5er
>   3 accgen +3er
> 
>   : series ( -- )
>     cr 10 0 do +5er . loop
>     cr 10 0 do +3er . loop ;
> 
>   series
> 
> Or more similarly to the first:
> 
>   : accgen ( n -- xt )
>     align here >r 0 , >r
>     :noname r> ]] literal [[
>         r> dup ]] literal +! [[
>                ]] literal @ ; [[ ;
> 
>   5 accgen constant +5er
>   3 accgen constant +3er
> 
>   : series ( -- )
>     cr 10 0 do +5er execute . loop
>     cr 10 0 do +3er execute . loop ;
> 
>   series
> 
> With output:
> 
>   5 10 15 20 25 30 35 40 45 50
>   3 6 9 12 15 18 21 24 27 30

What can be done with higher order functions and closures that can't be done with xt's on stacks? Is it really necessary to point out that the closure is local? If the programmer know what he's doing the right xt's will be applied to the right xt's. 

But what kind of programs need higher order functions so bad that you are willing to write all the brackets in Lisp? (If you don't believe in xt's on stacks). 

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


#60098

FromNN <november.nihal@gmail.com>
Date2017-05-31 03:29 -0700
Message-ID<bbe432b5-c68a-4c54-b475-a9af7ffa1fed@googlegroups.com>
In reply to#60095
On Wednesday, 31 May 2017 09:38:17 UTC+1, lehs  wrote:
> 
> What can be done with higher order functions and closures that can't be done with xt's on stacks? Is it really necessary to point out that the closure is local? If the programmer know what he's doing the right xt's will be applied to the right xt's. 
> 
> But what kind of programs need higher order functions so bad that you are willing to write all the brackets in Lisp? (If you don't believe in xt's on stacks).
 

I would say that 

- HOF's are a step towards functional abstraction. 

- Examples such as map, filter and fold allow you to
  replace loops and control structures with functions.

- if you want to "curry" fns, you would need to use a HOF
 
If language is about expressing your thoughts, communicating with another programmer and/or the machine in a clear and concise manner than I would argue that lisp is better tool than forth. 

NN

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


#60108

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2017-05-31 11:18 -0500
Message-ID<NaedndRIm9NCcbPEnZ2dnUU7-fGdnZ2d@supernews.com>
In reply to#60098
NN <november.nihal@gmail.com> wrote:
> 
> If language is about expressing your thoughts, communicating with
> another programmer and/or the machine in a clear and concise manner
> than I would argue that lisp is better tool than forth.

It depends on what youy're thinking about.  If you're thinking about
algorithms and machines in a concrete way, because you need to
interact with something outside the computer in real time, especially
in hard real time, I'd argue that Forth is a far better way to express
your thoughts.  The same is true if you need to control the way that
memory is used.

Andrew.

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


#60212

From"Robert L." <No_spamming@noWhere_7073.org>
Date2017-06-03 01:49 +0000
Message-ID<ogt4ir$bq8$1@gioia.aioe.org>
In reply to#60098
On 5/31/2017, NN wrote:

> Examples such as map, filter and fold allow you to
>   replace loops and control structures with functions.

Let's split that on non-word characters.

(define words
  (string-split
    "Examples such as map, filter and fold allow you to
    replace loops and control structures with functions."
    #/\W+/))

words
 ===>
("Examples" "such" "as" "map" "filter" "and" "fold" "allow" "you"
 "to" "replace" "loops" "and" "control" "structures" "with" "functions" "")

Remove any empty strings:

(define words (filter #/./ words))

words
 ===>
("Examples" "such" "as" "map" "filter" "and" "fold" "allow" "you"
 "to" "replace" "loops" "and" "control" "structures" "with" "functions")

The lengths of the words:

(map string-length words)
 ===>
(8 4 2 3 6 3 4 5 3 2 7 5 3 7 10 4 9)


Average word length:

(/ (fold + 0 (map string-length words)) (length words))
 ===>
5


-- 
Professor Goldman ... claimed that he and "most historians" regarded history
as a "weapon" to be used for "determining people's ideas and attitudes."
 --- Revilo P. Oliver, "The Price of the Head"

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


#60213

FromJulian Fondren <julian.fondren@gmail.com>
Date2017-06-02 20:46 -0700
Message-ID<b8423729-acbc-4b77-9dd0-7f14544bedad@googlegroups.com>
In reply to#60212
On Friday, June 2, 2017 at 8:49:21 PM UTC-5, Robert L. wrote:
> On 5/31/2017, NN wrote:
> 
> > Examples such as map, filter and fold allow you to
> >   replace loops and control structures with functions.
> 
> Let's split that on non-word characters.
> 
> (define words
>   (string-split
>     "Examples such as map, filter and fold allow you to
>     replace loops and control structures with functions."
>     #/\W+/))
> 
> words
>  ===>
> ("Examples" "such" "as" "map" "filter" "and" "fold" "allow" "you"
>  "to" "replace" "loops" "and" "control" "structures" "with" "functions" "")
> 
> Remove any empty strings:
> 
> (define words (filter #/./ words))
> 
> words
>  ===>
> ("Examples" "such" "as" "map" "filter" "and" "fold" "allow" "you"
>  "to" "replace" "loops" "and" "control" "structures" "with" "functions")
> 
> The lengths of the words:
> 
> (map string-length words)
>  ===>
> (8 4 2 3 6 3 4 5 3 2 7 5 3 7 10 4 9)
> 
> 
> Average word length:
> 
> (/ (fold + 0 (map string-length words)) (length words))
>  ===>
> 5

  : letter? ( c -- f )  bl or 'a' 'z' 1+ within ;

I realize this isn't \w. \w is gross anyway: it sees a_b as one word
and a-b as two.

  : skip-nonletter ( '  !@#foo' -- 'foo' )
    begin dup while
      over c@ letter? 0= while
      1 /string
    repeated ;
  
  : split-at-nonletter ( 'foo bar' -- ' bar' 'foo' )
    2dup begin dup while
      over c@ letter? while
      1 /string
    repeated tuck 2swap - -rot ;

an adaption of Niel Bawd's words. REPEATED is like REPEAT with as many
THENs as needed by a multi-WHILEd loop.

  : each-word ( c-addr1 u1 xt -- ) \ xt: ( c-addr2 u2 -- )
    {: xt :} begin skip-nonletter split-at-nonletter 2>r dup while
      xt execute 2r>
    repeat 2drop 2r> 2drop ;
  
  : nonsense ( c-addr u -- r )
    0 0 2swap [: nip + 1 under+ ;] each-word s>f s>f f/ ;

Here's a version with Hugh's essential feature, that uses it to leave
the stack messy in EACH-WORD:

  : each-word ( c-addr1 u1 xt -- ) \ xt: ( c-addr2 u2 -- )
    >r begin skip-nonletter split-at-nonletter 2swap dup while
      r@ execute
    repeat r> drop 2drop 2drop ;
  
  : nonsense ( c-addr u -- r )
    0 0 {: sum count :}
    [: +to sum drop 1 +to count ;] each-word
    sum s>f count s>f f/ ;

None of this is remotely hard. This isn't even trying to be efficient.
And yet there are serious benefits just from doing it the Forth way --
if your source string is a 1G in length you don't need to blow another
1G just to hold all those temporary copies of substrings (a resource
win) and you don't need to perform all of those copies and allocations
(a speed win).

If you're getting the average lengths of words for any actual
*reason*, you'll appreciate tools that aren't bloated and useless
right out the gate.

[toc] | [prev] | [standalone]


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


csiph-web