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


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

A New Forth

Started bytabcomputing@gmail.com
First post2016-10-07 17:56 -0700
Last post2016-10-15 12:23 -0700
Articles 20 on this page of 87 — 25 participants

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


Contents

  A New Forth tabcomputing@gmail.com - 2016-10-07 17:56 -0700
    Re: A New Forth Rod Pemberton <NeedNotReplyHere@xrsevnneqk.cem> - 2016-10-07 23:05 -0400
      Re: A New Forth Walter Banks <walter@bytecraft.com> - 2016-10-08 10:07 -0400
    Re: A New Forth anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-10-08 13:08 +0000
      Re: A New Forth trans <transfire@gmail.com> - 2016-10-08 10:54 -0700
        Re: A New Forth anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2016-10-08 18:03 +0000
          Re: A New Forth trans <transfire@gmail.com> - 2016-10-08 11:13 -0700
      Re: A New Forth Paul Rubin <no.email@nospam.invalid> - 2016-10-08 11:17 -0700
      Re: A New Forth hughaguilar96@gmail.com - 2016-10-13 14:44 -0700
        Re: A New Forth hughaguilar96@gmail.com - 2016-10-13 14:53 -0700
          Re: A New Forth hughaguilar96@gmail.com - 2016-10-13 15:04 -0700
          Re: A New Forth rickman <gnuarm@gmail.com> - 2016-10-13 22:55 -0400
    Re: A New Forth trans <transfire@gmail.com> - 2016-10-08 12:11 -0700
      Re: A New Forth albert@cherry.spenarnc.xs4all.nl (Albert van der Horst) - 2016-10-08 21:31 +0200
        Re: A New Forth trans <transfire@gmail.com> - 2016-10-08 17:07 -0700
      Re: A New Forth Paul Rubin <no.email@nospam.invalid> - 2016-10-08 12:33 -0700
        Re: A New Forth missycurl@gmail.com - 2016-10-08 12:54 -0700
          Re: A New Forth Paul Rubin <no.email@nospam.invalid> - 2016-10-08 13:29 -0700
        Re: A New Forth trans <transfire@gmail.com> - 2016-10-08 17:28 -0700
          Re: A New Forth Paul Rubin <no.email@nospam.invalid> - 2016-10-08 18:00 -0700
            Re: A New Forth trans <transfire@gmail.com> - 2016-10-09 09:00 -0700
              Re: A New Forth luser droog <mijoryx@yahoo.com> - 2016-10-09 11:19 -0700
              Re: A New Forth Paul Rubin <no.email@nospam.invalid> - 2016-10-10 01:09 -0700
                Re: A New Forth trans <transfire@gmail.com> - 2016-10-10 08:24 -0700
                  Re: A New Forth Paul Rubin <no.email@nospam.invalid> - 2016-10-10 13:28 -0700
                    Re: A New Forth "Elizabeth D. Rather" <erather@forth.com> - 2016-10-10 11:14 -1000
                      Re: A New Forth Paul Rubin <no.email@nospam.invalid> - 2016-10-10 15:11 -0700
                        Re: A New Forth Doug Hoffman <glidedog@gmail.com> - 2016-10-11 21:46 -0400
                    Re: A New Forth trans <transfire@gmail.com> - 2016-10-10 16:26 -0700
                      Re: A New Forth Paul Rubin <no.email@nospam.invalid> - 2016-10-10 18:58 -0700
                        Re: A New Forth trans <transfire@gmail.com> - 2016-10-10 20:15 -0700
                Re: A New Forth Ron Aaron <rambamist@gmail.com> - 2016-10-11 07:26 +0300
                  Re: A New Forth trans <transfire@gmail.com> - 2016-10-11 03:09 -0700
                    Re: A New Forth Ron Aaron <rambamist@gmail.com> - 2016-10-11 13:27 +0300
                  Re: A New Forth lawrencedo99@gmail.com - 2016-10-13 18:41 -0700
                    Re: A New Forth trans <transfire@gmail.com> - 2016-10-13 19:08 -0700
                    Re: A New Forth Ron Aaron <rambamist@gmail.com> - 2016-10-14 07:58 +0300
            Re: A New Forth franck.bensusan@gmail.com - 2016-10-09 11:09 -0700
            Re: A New Forth lawrencedo99@gmail.com - 2016-10-13 18:45 -0700
          Re: A New Forth albert@cherry.spenarnc.xs4all.nl (Albert van der Horst) - 2016-10-09 10:54 +0200
            Re: A New Forth missycurl@gmail.com - 2016-10-09 07:35 -0700
            Re: A New Forth Melzzzzz <mel@zzzzz.com> - 2016-10-11 06:23 +0200
            Re: A New Forth Paul Rubin <no.email@nospam.invalid> - 2016-10-10 21:31 -0700
            Re: A New Forth franck.bensusan@gmail.com - 2016-10-15 00:26 -0700
          Re: A New Forth Melzzzzz <mel@zzzzz.com> - 2016-10-13 19:16 +0200
            Re: A New Forth trans <transfire@gmail.com> - 2016-10-13 11:46 -0700
              Re: A New Forth Melzzzzz <Melzzzzz@zzzzz.com> - 2016-10-13 19:04 +0000
          Re: A New Forth "WJ" <w_a_x_man@yahoo.com> - 2016-10-15 20:07 +0000
      Re: A New Forth luser droog <mijoryx@yahoo.com> - 2016-10-08 13:56 -0700
    Re: A New Forth polymorph self <jackvanc3@gmail.com> - 2016-10-08 19:58 -0700
    Re: A New Forth Chris Curl <ccurl609@gmail.com> - 2016-10-10 19:22 -0700
      Re: A New Forth trans <transfire@gmail.com> - 2016-10-10 20:18 -0700
        Re: A New Forth Chris Curl <ccurl609@gmail.com> - 2016-10-11 11:14 -0700
          Re: A New Forth trans <transfire@gmail.com> - 2016-10-11 14:22 -0700
            Re: A New Forth jim.brakefield@ieee.org - 2016-10-11 15:11 -0700
              Re: A New Forth trans <transfire@gmail.com> - 2016-10-11 18:03 -0700
            Re: A New Forth Paul Rubin <no.email@nospam.invalid> - 2016-10-11 15:13 -0700
              Re: A New Forth Chris Curl <ccurl609@gmail.com> - 2016-10-11 17:52 -0700
                Re: A New Forth trans <transfire@gmail.com> - 2016-10-11 19:55 -0700
                Re: A New Forth hughaguilar96@gmail.com - 2016-10-13 14:21 -0700
                  Re: A New Forth hughaguilar96@gmail.com - 2016-10-13 14:36 -0700
              Re: A New Forth trans <transfire@gmail.com> - 2016-10-11 18:08 -0700
                Re: A New Forth Paul Rubin <no.email@nospam.invalid> - 2016-10-11 18:21 -0700
                  Re: A New Forth trans <transfire@gmail.com> - 2016-10-11 20:01 -0700
          Re: A New Forth trans <transfire@gmail.com> - 2016-10-11 20:33 -0700
            Re: A New Forth Doug Hoffman <glidedog@gmail.com> - 2016-10-12 01:15 -0400
              Re: A New Forth trans <transfire@gmail.com> - 2016-10-12 05:44 -0700
                Re: A New Forth Doug Hoffman <glidedog@gmail.com> - 2016-10-12 11:51 -0400
                  Re: A New Forth trans <transfire@gmail.com> - 2016-10-12 09:47 -0700
                    Re: A New Forth Paul Rubin <no.email@nospam.invalid> - 2016-10-12 10:08 -0700
                      Re: A New Forth trans <transfire@gmail.com> - 2016-10-12 11:48 -0700
                        Re: A New Forth Paul Rubin <no.email@nospam.invalid> - 2016-10-12 11:56 -0700
                    Re: A New Forth Doug Hoffman <glidedog@gmail.com> - 2016-10-12 13:41 -0400
                      Re: A New Forth trans <transfire@gmail.com> - 2016-10-12 11:57 -0700
                        Re: A New Forth trans <transfire@gmail.com> - 2016-10-12 12:02 -0700
                        Re: A New Forth Doug Hoffman <glidedog@gmail.com> - 2016-10-13 09:24 -0400
                          Re: A New Forth Doug Hoffman <glidedog@gmail.com> - 2016-10-13 10:33 -0400
                            Re: A New Forth trans <transfire@gmail.com> - 2016-10-13 10:05 -0700
                    Re: A New Forth jim <anon@example.com> - 2016-10-12 19:01 +0100
                      Re: A New Forth trans <transfire@gmail.com> - 2016-10-13 09:53 -0700
                        Re: A New Forth fred <anon@example.com> - 2016-10-14 12:37 +0100
                          Re: A New Forth jim <anon@example.com> - 2016-10-14 14:49 +0100
                          Re: A New Forth trans <transfire@gmail.com> - 2016-10-14 07:20 -0700
                            Re: A New Forth jim <anon@example.com> - 2016-10-15 11:58 +0100
                              Re: A New Forth tabcomputing@gmail.com - 2016-10-15 10:21 -0700
            Re: A New Forth Chris Curl <ccurl609@gmail.com> - 2016-10-12 04:33 -0700
    Re: A New Forth Whammo <sidciavic@gmail.com> - 2016-10-15 12:23 -0700

Page 4 of 5 — ← Prev page 1 2 3 [4] 5  Next page →


#51843

Fromhughaguilar96@gmail.com
Date2016-10-13 14:36 -0700
Message-ID<fa685f5b-1803-4140-af9c-176498781143@googlegroups.com>
In reply to#51842
On Thursday, October 13, 2016 at 2:21:12 PM UTC-7, hughag...@gmail.com wrote:
> On Tuesday, October 11, 2016 at 5:52:59 PM UTC-7, Chris Curl wrote:
> > On Tuesday, October 11, 2016 at 6:13:16 PM UTC-4, Paul Rubin wrote:
> > > trans <transfire@gmail.com> writes:
> > > > Say there are just 20 types in the system, every 3 arity word would
> > > > have a table of 8000 cells and most would be null. Just not
> > > > practical. So it would either have to be a search tree or a hash
> > > > table, and the later doesn't make sense since most words will have a
> > > > relatively small set of definitions.
> > > 
> > > Using a hash table is common enough in systems like CLOS.  Or you could
> > > use a tracing JIT to specialize the most common execution paths into
> > > monomorphism.
> > 
> > The elephant in the room is that the system doesn't know at runtime how 
> > many of the values/types on the stack(s) are there for the word/function 
> > group to use when trying to decide which vector to resolve to. The whole
> > paradigm in Forth is much more loosely coupled. You could have 2 flavors
> > of a word, one of which takes one int and one that takes two ints. If the
> > stack has 7 items on it for whatever reason, if the top 2 are ints, then
> > it would almost have to choose the 2nd version, even if that was not your
> > intention.
> > 
> > I suppose you could put a marker in somewhere, or always put the count of
> > args to use on the top, and then build a hash that you use as an index into 
> > the table. That probably wouldn't kill the performance too bad.
> > 
> > But I'm still not understanding the need for such a mechanism.
> 
> I don't see any need for such a mechanism --- I don't have tagged data in Straight Forth --- it is a traditional Forth in that you have to use the appropriate function for the data (if you use + on strings you are not going to get concatenation, you are going to get nonsense, and this is your fault not the language designer's fault).
> 
> I agree with Chris that too many people over-complicate problems that are inherently simple --- figuring this stuff out at run-time is not needed --- you almost always know how to write your code correctly at compile-time (if you don't, then maybe it is because you are confused).

Let me amend this. The purpose for this mechanism, is that you can write a function and have it work with any kind of data that is passed to it. In Straight Forth such a function would be a HOF --- you would give it a quotation that was specific to some kind of data --- this way the HOF can work with any kind of data.

HOFs and quotations are more robust than tagged-data. This is because you get support for any number of kinds of data, including anything you may invent in the future --- all you have to do is write a quotation specific to that kind of data --- by comparison, tagged-data typically has a 2-bit tag meaning that it only supports 4 kinds of data (Factor has a 3-bit tag meaning that it supports 8 kinds of data). 

Of course, one of those tags indicates a struct, so you aren't really limited to only 4 kinds of data, but you can have any number of structs. To support these structs however, you need (surprise!) HOFs and quotations. I think Oforth has a 1-bit tag, so it supports integers and structs --- this is not a bad design --- in Straight Forth however, I don't have tags at all, so all of my HOFs work only with structs (they have to be given a quotation specific to whatever type of object they are given).

In Straight Forth, it is idiomatic that all iteration is done inside of HOFs --- I do provide BEGIN WHILE REPEAT but I encourage programmers to only use this inside of HOFs and not put it in application code as is commonly done in ANS-Forth.

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


#51781

Fromtrans <transfire@gmail.com>
Date2016-10-11 18:08 -0700
Message-ID<5f9c146b-077b-4567-8acb-ce2a0b902c8f@googlegroups.com>
In reply to#51777
On Tuesday, October 11, 2016 at 6:13:16 PM UTC-4, Paul Rubin wrote:
> trans <transfire@gmail.com> writes:

> Or you could use a tracing JIT to specialize the most common execution paths into monomorphism.

I don't know anything about that. Are you saying a JIT that caches execution paths? So after the first time around (if the code is repeated) then it can use the cache to avoid the runtime lookup. Is that the basic idea?

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


#51782

FromPaul Rubin <no.email@nospam.invalid>
Date2016-10-11 18:21 -0700
Message-ID<878ttus6ot.fsf@nightsong.com>
In reply to#51781
trans <transfire@gmail.com> writes:
> I don't know anything about that. Are you saying a JIT that caches
> execution paths? So after the first time around (if the code is
> repeated) then it can use the cache to avoid the runtime lookup. Is
> that the basic idea?

LRU cache is a pretty simple idea.  JIT goes further, it analyzes the
hot spots in the program, and (among other things) generates machine
code specialized to the concrete datatypes that it sees going through
those spots.

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


#51785

Fromtrans <transfire@gmail.com>
Date2016-10-11 20:01 -0700
Message-ID<ae0c07cc-c4d3-4a7a-945a-532bd3b0fabe@googlegroups.com>
In reply to#51782
On Tuesday, October 11, 2016 at 9:21:39 PM UTC-4, Paul Rubin wrote:

> LRU cache is a pretty simple idea.  JIT goes further, it analyzes the
> hot spots in the program, and (among other things) generates machine
> code specialized to the concrete datatypes that it sees going through
> those spots.

I see. Thanks. At this point, I think that's outside of my scope (not to mention my knowledge). I am hoping to avoid a JIT anyway. And if I can, then I think something like SwifthForth's optimizer would suffice if higher performance is needed.

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


#51786

Fromtrans <transfire@gmail.com>
Date2016-10-11 20:33 -0700
Message-ID<08afa02e-9b87-44ac-a8ff-3da024091974@googlegroups.com>
In reply to#51773
On Tuesday, October 11, 2016 at 2:14:23 PM UTC-4, Chris Curl wrote:

> But there is no free lunch. To figure this stuff out at run-time will
> always add overhead.

I think I figured out a way to minimize the overhead. And it was a lot simpler than I thought. (So kudos to your first statement, "Geez. Do you people always have to make things more complex then they need to be?", because you were right.)

Quite simply, when a word is defined with a *union* type, i.e. with an argument that can be more than one possible type, then any word within the definition that is dependent on that type is simply replaced with if conditions to select which "flavor" to use. So:

    : foo ( int | float )
      0>

basically becomes (pseudo-code):

    : foo ( int | float )
      type int   = if 0>/int   else
      type float = if 0>/float else
        no-method-error throw
      then then ;

I could probably go a little further and extract the condition out into a hidden definition using quotations and reuse it where ever the same type condition is needed. It would be a tad slower but take up less memory.

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


#51788

FromDoug Hoffman <glidedog@gmail.com>
Date2016-10-12 01:15 -0400
Message-ID<57fdc6ff$0$335$14726298@news.sunsite.dk>
In reply to#51786
On 10/11/16 11:33 PM, trans wrote:
> On Tuesday, October 11, 2016 at 2:14:23 PM UTC-4, Chris Curl wrote:
>
>> But there is no free lunch. To figure this stuff out at run-time will
>> always add overhead.
>
> I think I figured out a way to minimize the overhead. And it was a
> lotsimpler than I thought.

>
> Quite simply, when a word is defined with a *union* type, i.e. with
> anargument that can be more than one possible type, then any word within
> the definition that is dependent on that type is simply replaced with if
> conditions to select which "flavor" to use. So:
>
>     : foo ( int | float )
>       0>
>
> basically becomes (pseudo-code):
>
>     : foo ( int | float )
>       type int   = if 0>/int   else
>       type float = if 0>/float else
>         no-method-error throw
>       then then ;

If you want to use part of oop why not just do that?

Using VFX:
: 0>/int ;
: 0>/float ;
: 0>/big ;
: type ;
: no-method-error ;
0 constant int
1 constant float
2 constant big


: foo ( int | float | big )
       type int   = if 0>/int   else
       type float = if 0>/float else
       type big   = if 0>/big   else
         no-method-error throw
       then then then ;

see foo
FOO
( 00086C60    83FB00 )                CMP       EBX, 00
( 00086C63    8B5D00 )                MOV       EBX, [EBP]
( 00086C66    8D6D04 )                LEA       EBP, [EBP+04]
( 00086C69    0F8505000000 )          JNZ/NE    00086C74
( 00086C6F    E92D000000 )            JMP       00086CA1
( 00086C74    83FB01 )                CMP       EBX, 01
( 00086C77    8B5D00 )                MOV       EBX, [EBP]
( 00086C7A    8D6D04 )                LEA       EBP, [EBP+04]
( 00086C7D    0F8505000000 )          JNZ/NE    00086C88
( 00086C83    E919000000 )            JMP       00086CA1
( 00086C88    83FB02 )                CMP       EBX, 02
( 00086C8B    8B5D00 )                MOV       EBX, [EBP]
( 00086C8E    8D6D04 )                LEA       EBP, [EBP+04]
( 00086C91    0F8505000000 )          JNZ/NE    00086C9C
( 00086C97    E905000000 )            JMP       00086CA1
( 00086C9C    E8B78AF9FF )            CALL      0001F758        THROW
( 00086CA1    C3 )                    NEXT,
( 66 bytes, 17 instructions )

Using VFX with Anton Ertl's 2-instruction message technique:
: foo ( obj -- flag ) \ obj could be an int or a float or a bignumber
   0>: ;

see foo
FOO
( 00087E10    8B13 )                  MOV       EDX, 0 [EBX]
( 00087E12    FF5208 )                CALL      [EDX+08]
( 00087E15    C3 )                    NEXT,
( 6 bytes, 3 instructions )

This comparison is of course limited because it is built on pseudocode.
For both techniques the number of instructions would be somewhat larger.
But it seems clear that the oop approach would be more efficient.

-Doug

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


#51793

Fromtrans <transfire@gmail.com>
Date2016-10-12 05:44 -0700
Message-ID<1259c8ca-8be8-4958-96c9-5bf7f8348d84@googlegroups.com>
In reply to#51788
On Wednesday, October 12, 2016 at 1:15:45 AM UTC-4, Doug Hoffman wrote:

> If you want to use part of oop why not just do that?

This is a little different from oop. In oop methods are tied to the receiver, so only the first argument dictates the specific method used. In my case the words can be dependent on all the parameters, i.e. multiple dispatch. My example doesn't make that clear b/c I am only using one parameter.

> Using VFX:
> : 0>/int ;
> : 0>/float ;
> : 0>/big ;
> : type ;
> : no-method-error ;
> 0 constant int
> 1 constant float
> 2 constant big
> 
> 
> : foo ( int | float | big )
>        type int   = if 0>/int   else
>        type float = if 0>/float else
>        type big   = if 0>/big   else
>          no-method-error throw
>        then then then ;
> 
> see foo
> FOO
> ( 00086C60    83FB00 )                CMP       EBX, 00
> ( 00086C63    8B5D00 )                MOV       EBX, [EBP]
> ( 00086C66    8D6D04 )                LEA       EBP, [EBP+04]
> ( 00086C69    0F8505000000 )          JNZ/NE    00086C74
> ( 00086C6F    E92D000000 )            JMP       00086CA1
> ( 00086C74    83FB01 )                CMP       EBX, 01
> ( 00086C77    8B5D00 )                MOV       EBX, [EBP]
> ( 00086C7A    8D6D04 )                LEA       EBP, [EBP+04]
> ( 00086C7D    0F8505000000 )          JNZ/NE    00086C88
> ( 00086C83    E919000000 )            JMP       00086CA1
> ( 00086C88    83FB02 )                CMP       EBX, 02
> ( 00086C8B    8B5D00 )                MOV       EBX, [EBP]
> ( 00086C8E    8D6D04 )                LEA       EBP, [EBP+04]
> ( 00086C91    0F8505000000 )          JNZ/NE    00086C9C
> ( 00086C97    E905000000 )            JMP       00086CA1
> ( 00086C9C    E8B78AF9FF )            CALL      0001F758        THROW
> ( 00086CA1    C3 )                    NEXT,
> ( 66 bytes, 17 instructions )

Heh, cool.

> Using VFX with Anton Ertl's 2-instruction message technique:
> : foo ( obj -- flag ) \ obj could be an int or a float or a bignumber
>    0>: ;
> 
> see foo
> FOO
> ( 00087E10    8B13 )                  MOV       EDX, 0 [EBX]
> ( 00087E12    FF5208 )                CALL      [EDX+08]
> ( 00087E15    C3 )                    NEXT,
> ( 6 bytes, 3 instructions )
> 
> This comparison is of course limited because it is built on pseudocode.
> For both techniques the number of instructions would be somewhat larger.
> But it seems clear that the oop approach would be more efficient.

Memory wise, yes, a little. But how is it determining the actual word definition to use in the end? No doubt it has to figure it out at runtime, i.e. the interpretor does it rather than the compiler. We are just not seeing that part of the code in the obj example, b/c it is elsewhere in the system. Having said that I don't know exactly how it works, so maybe there is something I can re-purpose from it.

Note I did some research and found a couple interesting links, first http://www.complang.tuwien.ac.at/forth/objects/opinion.html which I think is part of Anton's systems to which you refer (see http://www.complang.tuwien.ac.at/forth/objects/), and then this https://en.wikipedia.org/wiki/Virtual_method_table, especially the "Comparison with alternatives section".


 

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


#51796

FromDoug Hoffman <glidedog@gmail.com>
Date2016-10-12 11:51 -0400
Message-ID<57fe5bf0$0$337$14726298@news.sunsite.dk>
In reply to#51793
On 10/12/16 8:44 AM, trans wrote:
> On Wednesday, October 12, 2016 at 1:15:45 AM UTC-4, Doug Hoffman wrote:
>
>> If you want to use part of oop why not just do that?
>
> This is a little different from oop. In oop methods are tied to the
> receiver, so only the first argument dictates the specific method used.
> In my case the words can be dependent on all the parameters, i.e.
> multiple dispatch. My example doesn't make that clear b/c I am only
> using one parameter.

The IS-A function can be used to determine the type of the second 
parameter.  But I'd need to see a pseudocode example of how you planned 
to handle that with the 'type int = if' technique to judge if oop might 
offer an advantage.

>> Using VFX with Anton Ertl's 2-instruction message technique:
>> : foo ( obj -- flag ) \ obj could be an int or a float or a bignumber
>>    0>: ;
>>
>> see foo
>> FOO
>> ( 00087E10    8B13 )                  MOV       EDX, 0 [EBX]
>> ( 00087E12    FF5208 )                CALL      [EDX+08]
>> ( 00087E15    C3 )                    NEXT,
>> ( 6 bytes, 3 instructions )

> But how is it determining the actual word definition to use in the
> end?

That is all done by the code you see there. It selects an XT based on a 
tag field in the first cel of the object and executes that. So in the 
case of an int it executes 0>, in the case of a float F0>.


> No doubt it has to figure it out at runtime

Yes.  Which is what your 'type int = if' technique is doing IIUC.


> We are just not seeing that part of the code in the obj example, b/c
> it is elsewhere in the system.

It would be something as follows:

:class int
   1 cells bytes data
:m 0>: ( int -- flag ) data @ 0> ;m
;class

:class float
   1 floats bytes data
:m 0>: ( float -- flag ) data f@ f0> ;m
;class

etc.

An object on the stack would occupy 1 cell, a pointer to a structure
where the type (a pointer to a vtable) is in the first cell and the data
following ( in the case of an int 1 more cell).

The scaffolding to support this is 2-3k of code. YMMV
But in the case shown above just 2 instructions as shown (not counting 
next,) would call the correct XT and execute either 'data @ 0>' or 'data 
f@ f0>'. Not sure how that would compare to working code
that does it the 'type int = if' way

-Doug


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


#51799

Fromtrans <transfire@gmail.com>
Date2016-10-12 09:47 -0700
Message-ID<25a1bea0-942c-4a64-9a93-9a3cffda7675@googlegroups.com>
In reply to#51796
On Wednesday, October 12, 2016 at 11:51:14 AM UTC-4, Doug Hoffman wrote:
> The IS-A function can be used to determine the type of the second 
> parameter.  But I'd need to see a pseudocode example of how you planned 
> to handle that with the 'type int = if' technique to judge if oop might 
> offer an advantage.

Just additional ifs. Something like,

    : foo ( int | float  int | float ) 
      type int   = swap type int   = and if =/int/int     else
      type float = swap type float = and if =/float/float else
      type int   = swap type float = and if =/int/float   else
      type float = swap type int   = and if =/float/int   else
        no-method-error throw
      then then ; 

The swapping is wrong, but you get the idea. Of course, that can done much more efficiently, and I would abstract much of this out to supporting methods too, rather than actually inline all that code. But that the general idea.

> > But how is it determining the actual word definition to use in the
> > end?
> 
> That is all done by the code you see there. It selects an XT based on a 
> tag field in the first cel of the object and executes that. So in the 
> case of an int it executes 0>, in the case of a float F0>.
> 
> 
> > No doubt it has to figure it out at runtime
> 
> Yes.  Which is what your 'type int = if' technique is doing IIUC.
> 

Oh, Duh. Yeah, I still had my mind partly in the JIT cloud. But that's not a bad thing, because I now see a bit clearer the difference between this and a JIT solution, and an important question to consider: Is this Dynamic Dispatch approach better or is a JIT better? And the corollary question, can a JIT and Forth really be married?

In any case, my ifs and VFX are essentially the doing the same thing, one way or another.

> > We are just not seeing that part of the code in the obj example, b/c
> > it is elsewhere in the system.
> 
> It would be something as follows:
> 
> :class int
>    1 cells bytes data
> :m 0>: ( int -- flag ) data @ 0> ;m
> ;class
> 
> :class float
>    1 floats bytes data
> :m 0>: ( float -- flag ) data f@ f0> ;m
> ;class
> 
> etc.
> 
> An object on the stack would occupy 1 cell, a pointer to a structure
> where the type (a pointer to a vtable) is in the first cell and the data
> following ( in the case of an int 1 more cell).
> 
> The scaffolding to support this is 2-3k of code. YMMV
> But in the case shown above just 2 instructions as shown (not counting 
> next,) would call the correct XT and execute either 'data @ 0>' or 'data 
> f@ f0>'. Not sure how that would compare to working code
> that does it the 'type int = if' way

I couldn't rely on just one type (class) in my case, but something similar could be done. Perhaps tables organized by type signatures. And some supporting word to say effectively, lookup "=" in "int*float" signature table. 

Oh, and now I really see the tricky part Chris mentioned, how does it know what arity to use?

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


#51800

FromPaul Rubin <no.email@nospam.invalid>
Date2016-10-12 10:08 -0700
Message-ID<871szlsded.fsf@nightsong.com>
In reply to#51799
trans <transfire@gmail.com> writes:
> Is this Dynamic Dispatch approach better or is a JIT better?
> And the corollary question, can a JIT and Forth really be married?

Dynamic dispatch is much easier to implement than a serious JIT, though
it can't be as fast.  And even for pure monomorphic code, if you're
trying to get anywhere near modern compilers, you'll need an advanced
compiler yourself.

Can I ask what application areas and hardware platforms you plan to
target?  People use dynamic languages all day long without worrying much
about execution speed, since the bottlenecks are usually communications,
i/o, or trying to control something that's much slower than the CPU.
Most of my stuff is written in Python, which is probably 50x slower than
C or C++.  Gforth is maybe 5x faster than Python.  Stuff I work on where
any of that matters is the exception rather than the rule.

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


#51807

Fromtrans <transfire@gmail.com>
Date2016-10-12 11:48 -0700
Message-ID<77f7818b-5a8f-4972-9152-abd8aac1a304@googlegroups.com>
In reply to#51800
On Wednesday, October 12, 2016 at 1:09:00 PM UTC-4, Paul Rubin wrote:
> trans <transfire@gmail.com> writes:
> > Is this Dynamic Dispatch approach better or is a JIT better?
> > And the corollary question, can a JIT and Forth really be married?
> 
> Dynamic dispatch is much easier to implement than a serious JIT, though
> it can't be as fast.  And even for pure monomorphic code, if you're
> trying to get anywhere near modern compilers, you'll need an advanced
> compiler yourself.
> 
> Can I ask what application areas and hardware platforms you plan to
> target?  People use dynamic languages all day long without worrying much
> about execution speed, since the bottlenecks are usually communications,
> i/o, or trying to control something that's much slower than the CPU.
> Most of my stuff is written in Python, which is probably 50x slower than
> C or C++.  Gforth is maybe 5x faster than Python.  Stuff I work on where
> any of that matters is the exception rather than the rule.

I'd like it to be a general purpose language that you can write just about anything with, including video games. Which means ideally I'd like to at least get close to 4x of C. I got a sneaking suspicion though you are going to tell me that's not realistic :(

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


#51808

FromPaul Rubin <no.email@nospam.invalid>
Date2016-10-12 11:56 -0700
Message-ID<87wphdqtug.fsf@nightsong.com>
In reply to#51807
trans <transfire@gmail.com> writes:
> like to at least get close to 4x of C. I got a sneaking suspicion
> though you are going to tell me that's not realistic :(

I think it's doable especially if you stay with C-like monomorphic types
instead of the int|float stuff.  Use OOP or tags in the cases where you
need dispatch, and keep that out of inner loops.

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


#51803

FromDoug Hoffman <glidedog@gmail.com>
Date2016-10-12 13:41 -0400
Message-ID<57fe75d3$0$348$14726298@news.sunsite.dk>
In reply to#51799
On 10/12/16 12:47 PM, trans wrote:
> On Wednesday, October 12, 2016 at 11:51:14 AM UTC-4, Doug Hoffman wrote:
>> The IS-A function can be used to determine the type of the second
>> parameter.  But I'd need to see a pseudocode example of how you planned
>> to handle that with the 'type int = if' technique to judge if oop might
>> offer an advantage.
>
> Just additional ifs. Something like,
>
>     : foo ( int | float  int | float )
>       type int   = swap type int   = and if =/int/int     else
>       type float = swap type float = and if =/float/float else
>       type int   = swap type float = and if =/int/float   else
>       type float = swap type int   = and if =/float/int   else
>         no-method-error throw
>       then then ;
>
> The swapping is wrong, but you get the idea. Of course, that can
> donemuch more efficiently, and I would abstract much of this out to
> supporting methods too, rather than actually inline all that code. But
> that the general idea.

You are asking me for precise detail and I'm showing it. Without seeing 
precise detail for the above I don't know how to make a comparison.


> I couldn't rely on just one type (class) in my case,

Not sure I understand. You can have as many types (classes) as you want.

Anyway here is the precise code for the '=' foo you show above, the
swapping and so forth is correct:

: foo ( int int | float int | int float | float float -- flag )
   =: ;

:class int
   1 cells bytes data
:m 0>: ( -- flag ) data @ 0> ;m
:m @: ( -- int ) data @ ;m
:m =:  ( obj -- flag )
    dup is-a int   if   data @ swap @: =
    (it's a float) else @: data @ s>f  f=
                   then ;m
;class

:class float
   1 floats bytes data
:m 0>: ( -- flag ) data f@ f0> ;m
:m @: ( -- int ) data f@ ;m
:m =: ( obj -- flag )
    dup is-a int   if   @: s>f data f@ f=
    (it's a float) else @: data f@ f=
                   then ;m
;class

> Oh, and now I really see the tricky part Chris mentioned, how does
> it  know what arity to use?

The same way any Forth word would know the arity, and probably similar
to what you would have to do with the 'type int = if' technique.

But I gather you have specific ideas that might preclude the use of
objects, I can't tell. Regardless, do it whatever way you are
comfortable with.

-Doug

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


#51809

Fromtrans <transfire@gmail.com>
Date2016-10-12 11:57 -0700
Message-ID<ea35b8fa-520e-4fe4-83cb-4e6b9d0a0104@googlegroups.com>
In reply to#51803
On Wednesday, October 12, 2016 at 1:41:42 PM UTC-4, Doug Hoffman wrote:

> But I gather you have specific ideas that might preclude the use of
> objects, I can't tell. Regardless, do it whatever way you are
> comfortable with.

Have you looked at Julia at all? Basically the same thing it does, i.e. multiple dispatch. There are no objects, functions are just dispatched by their type signature.

So for instance I could define,

  : foo ( int float -- ) ... ;
  : foo ( string string -- ) ... ; 
  : foo ( array int int -- ) ... ;

etc. They  all different definitions, but all callable based on matching the types of values on the stack. Does that clear it up?

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


#51810

Fromtrans <transfire@gmail.com>
Date2016-10-12 12:02 -0700
Message-ID<1cf9ab9e-8b6d-45df-b5cd-3bc117407121@googlegroups.com>
In reply to#51809
On Wednesday, October 12, 2016 at 2:57:34 PM UTC-4, trans wrote:
> 
> There are no objects

In the OOP sense of the word that is.

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


#51830

FromDoug Hoffman <glidedog@gmail.com>
Date2016-10-13 09:24 -0400
Message-ID<57ff8af8$0$335$14726298@news.sunsite.dk>
In reply to#51809
On 10/12/16 2:57 PM, trans wrote:
> On Wednesday, October 12, 2016 at 1:41:42 PM UTC-4, Doug Hoffman wrote:
>
>> But I gather you have specific ideas that might preclude the use of
>> objects, I can't tell. Regardless, do it whatever way you are
>> comfortable with.
>
> Have you looked at Julia at all? Basically the same thing it does,
> i.e. multiple dispatch. There are no objects, functions are just
> dispatched by their type signature.
>
> So for instance I could define,
>
>   : foo ( int float -- ) ... ;
>   : foo ( string string -- ) ... ;
>   : foo ( array int int -- ) ... ;
>
> etc. They all different definitions, but all callable based on
> matching the types of values on the stack.

Determining the arity.  Two ways that come to mind:

1) Pass the number of input parameters as the top item on the stack.
Might be cumbersome.

2) Parse the comment and count the number of input parameters. While
parsing you could also determine the type of each input as well. Would
require accurate stack comments because the comments are now part of the
code.

-Doug

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


#51832

FromDoug Hoffman <glidedog@gmail.com>
Date2016-10-13 10:33 -0400
Message-ID<57ff9b2d$0$337$14726298@news.sunsite.dk>
In reply to#51830
On 10/13/16 9:24 AM, Doug Hoffman wrote:

> 1) Pass the number of input parameters as the top item on the stack.
> Might be cumbersome.

1) might be the more reasonable way.

: bar ( ... -- ... )
   ...
   ... 1 show ...
   3 show
   ...  bazz bizz  2 show
;

Similar to providing an index to an array.  This assumes the programmer 
knows which 'version' of show is to be called.  Might be a bad assumption.

-Doug

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


#51836

Fromtrans <transfire@gmail.com>
Date2016-10-13 10:05 -0700
Message-ID<565510a6-7c89-4a75-afae-6cd109aa967a@googlegroups.com>
In reply to#51832
On Thursday, October 13, 2016 at 10:33:20 AM UTC-4, Doug Hoffman wrote:
> On 10/13/16 9:24 AM, Doug Hoffman wrote:
> 
> > 1) Pass the number of input parameters as the top item on the stack.
> > Might be cumbersome.
> 
> 1) might be the more reasonable way.
> 
> : bar ( ... -- ... )
>    ...
>    ... 1 show ...
>    3 show
>    ...  bazz bizz  2 show
> ;
> 
> Similar to providing an index to an array.  This assumes the programmer 
> knows which 'version' of show is to be called.  Might be a bad assumption.

That is one possibility. I was thinking along the lines of Erlang's syntax so you could do `show/1` and `show/3`, but you could still just do `show` which would default to the first definition found in the dictionary search.

On the other hand, I'm thinking maybe I'd make it so the arity can't change once it is set the first time. If `: foo ( int int )` is defined, then trying to add `: foo ( int int int )` would throw an error, but adding a `: foo ( float float )` would be okay b/c it has the same arity. It's sort of the opposite of Erlang which allows you to reuse the same function name just so long as they have *different* arity.

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


#51805

Fromjim <anon@example.com>
Date2016-10-12 19:01 +0100
Message-ID<MPG.32688ab8be585f07989693@news.virginmedia.com>
In reply to#51799
> In article <25a1bea0-942c-4a64-9a93-9a3cffda7675@googlegroups.com>, transfire@gmail.com says...
> 

Sorry if I've missunderstood something (my newsreader doesnt work well with threads) 
but have you considered using private dictionaries ?

take the  NFA from your words and place them in your  virtual  object as a key
at compile time - unlink your words from the forth dictionary and place a word at the
end of the search with a zero link field to stop the search.
At runtime your instance object places the NFA of the operation word in the LFA  of
your unlock word - does the dirty then relocks the "private" dictionary effectively
hiding it.
I think that's right - I havnt done this for some time.

I can dig out more info if you think it worthwhile.




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


#51835

Fromtrans <transfire@gmail.com>
Date2016-10-13 09:53 -0700
Message-ID<f91e68a8-a943-4c40-b382-40856287f6ca@googlegroups.com>
In reply to#51805
On Wednesday, October 12, 2016 at 2:02:30 PM UTC-4, jim wrote:
> > In article <25a1bea0-942c-4a64-9a93-9a3cffda7675@googlegroups.com>, transfire@gmail.com says...
> > 
> 
> Sorry if I've missunderstood something (my newsreader doesnt work well with threads) 
> but have you considered using private dictionaries ?
> 
> take the  NFA from your words and place them in your  virtual  object as a key
> at compile time - unlink your words from the forth dictionary and place a word at the
> end of the search with a zero link field to stop the search.
> At runtime your instance object places the NFA of the operation word in the LFA  of
> your unlock word - does the dirty then relocks the "private" dictionary effectively
> hiding it.
> I think that's right - I havnt done this for some time.
> 
> I can dig out more info if you think it worthwhile.

Jim could you explain this more. What is this intended to accomplish? Also, you seem to be thinking in OOP terms, so maybe it doesn't apply b/c I shooting for multiple dispatch. But maybe there still something to your idea that would apply if I understood it better.

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


Page 4 of 5 — ← Prev page 1 2 3 [4] 5  Next page →

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


csiph-web