Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #51686 > unrolled thread
| Started by | tabcomputing@gmail.com |
|---|---|
| First post | 2016-10-07 17:56 -0700 |
| Last post | 2016-10-15 12:23 -0700 |
| Articles | 20 on this page of 87 — 25 participants |
Back to article view | Back to comp.lang.forth
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 →
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2016-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]
| From | trans <transfire@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2016-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]
| From | trans <transfire@gmail.com> |
|---|---|
| Date | 2016-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]
| From | trans <transfire@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Doug Hoffman <glidedog@gmail.com> |
|---|---|
| Date | 2016-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]
| From | trans <transfire@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Doug Hoffman <glidedog@gmail.com> |
|---|---|
| Date | 2016-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]
| From | trans <transfire@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2016-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]
| From | trans <transfire@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2016-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]
| From | Doug Hoffman <glidedog@gmail.com> |
|---|---|
| Date | 2016-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]
| From | trans <transfire@gmail.com> |
|---|---|
| Date | 2016-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]
| From | trans <transfire@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Doug Hoffman <glidedog@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Doug Hoffman <glidedog@gmail.com> |
|---|---|
| Date | 2016-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]
| From | trans <transfire@gmail.com> |
|---|---|
| Date | 2016-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]
| From | jim <anon@example.com> |
|---|---|
| Date | 2016-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]
| From | trans <transfire@gmail.com> |
|---|---|
| Date | 2016-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