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


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

Re: How to solve this problem in FORTH?

Started byPaul Rubin <no.email@nospam.invalid>
First post2015-10-25 15:47 -0700
Last post2015-10-28 05:42 -0400
Articles 5 — 3 participants

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

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: How to solve this problem in FORTH? Paul Rubin <no.email@nospam.invalid> - 2015-10-25 15:47 -0700
    Re: How to solve this problem in FORTH? Doug Hoffman <glidedog@gmail.com> - 2015-10-27 07:25 -0400
      Re: How to solve this problem in FORTH? Doug Hoffman <glidedog@gmail.com> - 2015-10-27 13:04 -0400
        Re: How to solve this problem in FORTH? franck.bensusan@gmail.com - 2015-10-27 12:04 -0700
          Re: How to solve this problem in FORTH? Doug Hoffman <glidedog@gmail.com> - 2015-10-28 05:42 -0400

#42803 — Re: How to solve this problem in FORTH?

FromPaul Rubin <no.email@nospam.invalid>
Date2015-10-25 15:47 -0700
SubjectRe: How to solve this problem in FORTH?
Message-ID<874mhey38n.fsf@jester.gateway.sonic.net>
Marek Brunda <marekb@phoenics.org> writes:
> void vadd(int *v1, int *v2, int *v3)
> {
>        v3[0] = v1[0] + v2[0];
>        v3[1] = v1[1] + v2[1];
>        v3[2] = v1[2] + v2[2];
> }

: vv ( i n -- addr ) cells here + @ swap cells + ;
: vx ( i -- ) \ v3[i] = v2[i] + v1[i]
    dup dup -1 vv @ >r -2 vv @ r> + swap -3 vv ! ;
: vadd ( v1 v2 v3 -- ) , , ,   0 vx 1 vx 2 vx  -3 cells allot ;

[toc] | [next] | [standalone]


#42873

FromDoug Hoffman <glidedog@gmail.com>
Date2015-10-27 07:25 -0400
Message-ID<562f5f33$0$293$14726298@news.sunsite.dk>
In reply to#42803
On 10/25/15 6:47 PM, Paul Rubin wrote:
> Marek Brunda <marekb@phoenics.org> writes:
>> void vadd(int *v1, int *v2, int *v3)
>> {
>>         v3[0] = v1[0] + v2[0];
>>         v3[1] = v1[1] + v2[1];
>>         v3[2] = v1[2] + v2[2];
>> }
>
> : vv ( i n -- addr ) cells here + @ swap cells + ;
> : vx ( i -- ) \ v3[i] = v2[i] + v1[i]
>      dup dup -1 vv @ >r -2 vv @ r> + swap -3 vv ! ;
> : vadd ( v1 v2 v3 -- ) , , ,   0 vx 1 vx 2 vx  -3 cells allot ;
>

Here is an Oforth solution. But instead of using a "library" word like
zipWith as has already been done I'll expose the low level guts of just
one possible solution. Apologies to Franck Bensusan if I have abused or
mis-used Oforth. It is still fairly new to me.


: makeList // n -- empty-list
ListBuffer newSize ;

: vadd(v2 v1) // v1 v2 -- v3
| i | v1 size dup makeList swap
loop: i [ i v1 at i v2 at + over add ] ;

[10, 20, 30] [100, 200, 300] vadd .
// [110, 220, 330] ok

[1.1, 2, 3.3] [100, 200, 300] vadd .
// [101.1, 202, 303.3] ok

["abc", "def"] ["xy", "tj"] vadd .
// [abcxy, deftj] ok

[922337203685477580795690987654322]
[99922337203685477580795690987658321] vadd .
// [100844674407370955161591381975312643] ok


Comments:

1) makeList sends the newSize message to the class ListBuffer with the
size on the stack. It returns an empty list with enough room for n objects.

2) vadd takes 2 lists from the stack and stores them in the local
variables v2 and v1. Note that the locals ordering is identical to
classic Forth's locals| ... |. Franck says it must be that way for
technical reasons. In this example it makes no difference.

3) n loop: i [ ... ] is Oforth's version of a do ... loop. The local
variable i starts at 1 and ends at n. The code inside [ ... ] is
executed n times and the local variable i is incremented appropriately.

For your amusement.

-Doug

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


#42882

FromDoug Hoffman <glidedog@gmail.com>
Date2015-10-27 13:04 -0400
Message-ID<562fae9f$0$296$14726298@news.sunsite.dk>
In reply to#42873
> Here is an Oforth solution.

> : makeList // n -- empty-list
> ListBuffer newSize ;
>
> : vadd(v2 v1) // v1 v2 -- v3
> | i | v1 size dup makeList swap
> loop: i [ i v1 at i v2 at + over add ] ;
>
> [10, 20, 30] [100, 200, 300] vadd .
> // [110, 220, 330] ok
>
> [1.1, 2, 3.3] [100, 200, 300] vadd .
> // [101.1, 202, 303.3] ok
>
> ["abc", "def"] ["xy", "tj"] vadd .
> // [abcxy, deftj] ok
>
> [922337203685477580795690987654322]
> [99922337203685477580795690987658321] vadd .
> // [100844674407370955161591381975312643] ok

It might make sense to simply define + as a method of the list class. 
We get the desired behavior without adding a new word to remember. 
Oforth allows adding methods to existing classes without recompiling:


Indexable method: + // list -- List2
  self zipWith(#+) ;

[10, 20, 30] [100, 200, 300] + .

[1.1, 2, 3.3] [100, 200, 300] + .

["abc", "def"] ["xy", "tj"] + .

[922337203685477580795690987654322] 
[99922337203685477580795690987658321] + .


The definition of zipWith, which comes already defined in Oforth, 
follows a basic flow similar to vadd above.

" #+ " is in concept like classic Forth's " ' + " yielding an executable 
token.  Self is like Smalltalk's/FMS's self.

-Doug

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


#42884

Fromfranck.bensusan@gmail.com
Date2015-10-27 12:04 -0700
Message-ID<91c5a2c2-a898-4132-b6fb-274bb6844a90@googlegroups.com>
In reply to#42882
Le mardi 27 octobre 2015 18:12:04 UTC+1, Doug Hoffman a écrit :
> > Here is an Oforth solution.
> 
> > : makeList // n -- empty-list
> > ListBuffer newSize ;
> >
> > : vadd(v2 v1) // v1 v2 -- v3
> > | i | v1 size dup makeList swap
> > loop: i [ i v1 at i v2 at + over add ] ;
> >
> > [10, 20, 30] [100, 200, 300] vadd .
> > // [110, 220, 330] ok
> >
> > [1.1, 2, 3.3] [100, 200, 300] vadd .
> > // [101.1, 202, 303.3] ok
> >
> > ["abc", "def"] ["xy", "tj"] vadd .
> > // [abcxy, deftj] ok
> >
> > [922337203685477580795690987654322]
> > [99922337203685477580795690987658321] vadd .
> > // [100844674407370955161591381975312643] ok
> 
> It might make sense to simply define + as a method of the list class. 
> We get the desired behavior without adding a new word to remember. 
> Oforth allows adding methods to existing classes without recompiling:
> 
> 
> Indexable method: + // list -- List2
>   self zipWith(#+) ;
> 
> [10, 20, 30] [100, 200, 300] + .
> 
> [1.1, 2, 3.3] [100, 200, 300] + .
> 
> ["abc", "def"] ["xy", "tj"] + .
> 
> [922337203685477580795690987654322] 
> [99922337203685477580795690987658321] + .
> 
> 
> The definition of zipWith, which comes already defined in Oforth, 
> follows a basic flow similar to vadd above.
> 
> " #+ " is in concept like classic Forth's " ' + " yielding an executable 
> token.  Self is like Smalltalk's/FMS's self.
> 
> -Doug

Hi Doug,

I would have write this #vadd word the same way you did.

This is not part of the problem to resolve, but it could be interesting 
to have the operation sent also as parameter, like : 

: makeList // n -- empty-list
   ListBuffer newSize ;

: v-op(op v2 v1) // v1 v2 op -- v3
| i | v1 size dup makeList swap
   loop: i [ i v1 at i v2 at op perform over add ] ; 

: vadd 		// v1 v2 -- v3
   #+ v-op ;

: vsub		// v1 v2 -- V3
   #- v-op ;

But then, this #v-op word is almost ... #zipWith word. 

For your second post, this is tempting but I wouldn't do this, 
because #+ already has a meaning for collections and this is not this 
one : it just returns the concatenation of the elements of the two 
collections on the stack.

For instance : 

[ [ 1, 2, 3 ], [ 4, 5, 6 ] ] [ [ 7, 8, 9 ], [ 10, 11, 12 ] ] vadd .
// [[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12]] ok

In order to define a #+ with the meaning of #vadd, it could be interesting 
to declare a new class (Vector for instance) and define the #+ operation 
on two vectors. 

For #+, concept is similar to "' +" but not exactly the same because #+ allows
to access to all informations about a word : it represents the word itself, 
not only its execution token.
But, yes, "#+ perform" is the same as "' + execute".

Regards,
Franck 

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


#42895

FromDoug Hoffman <glidedog@gmail.com>
Date2015-10-28 05:42 -0400
Message-ID<56309873$0$296$14726298@news.sunsite.dk>
In reply to#42884
On 10/27/15 3:04 PM, franck.bensusan@gmail.com wrote:
> Le mardi 27 octobre 2015 18:12:04 UTC+1, Doug Hoffman a écrit :
>>> Here is an Oforth solution.
>>
>>> : makeList // n -- empty-list
>>> ListBuffer newSize ;
>>>
>>> : vadd(v2 v1) // v1 v2 -- v3
>>> | i | v1 size dup makeList swap
>>> loop: i [ i v1 at i v2 at + over add ] ;
>>>
>>> [10, 20, 30] [100, 200, 300] vadd .

>> It might make sense to simply define + as a method of the list
>> class.

>> [10, 20, 30] [100, 200, 300] + .


> I would have write this #vadd word the same way you did.

Good to know I didn't mis-use.


> For your second post, this is tempting but I wouldn't do this,
> because #+ already has a meaning for collections

Agreed. I noticed that after I made the post.


> For #+, concept is similar to "' +" but not exactly the same because
> #+ allows to access to all informations about a word : it represents
> the word itself, not only its execution token.

Interesting.

> But, yes, "#+ perform" is the same as "' + execute".

Thanks for the feedback. Nice work with Oforth.

-Doug

[toc] | [prev] | [standalone]


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


csiph-web