Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #42803 > unrolled thread
| Started by | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| First post | 2015-10-25 15:47 -0700 |
| Last post | 2015-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.
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
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2015-10-25 15:47 -0700 |
| Subject | Re: 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]
| From | Doug Hoffman <glidedog@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Doug Hoffman <glidedog@gmail.com> |
|---|---|
| Date | 2015-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]
| From | franck.bensusan@gmail.com |
|---|---|
| Date | 2015-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]
| From | Doug Hoffman <glidedog@gmail.com> |
|---|---|
| Date | 2015-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