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


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

Readable code and refactoring for optimization

Started byWendell <wendellxe@yahoo.com>
First post2011-12-05 18:14 -0800
Last post2011-12-14 15:49 +0200
Articles 20 on this page of 73 — 21 participants

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


Contents

  Readable code and refactoring for optimization Wendell <wendellxe@yahoo.com> - 2011-12-05 18:14 -0800
    Re: Readable code and refactoring for optimization "Elizabeth D. Rather" <erather@forth.com> - 2011-12-05 17:54 -1000
      Re: Readable code and refactoring for optimization "Elizabeth D. Rather" <erather@forth.com> - 2011-12-05 17:58 -1000
        Re: Readable code and refactoring for optimization Hans Bezemer <thebeez@xs4all.nl> - 2011-12-06 08:49 +0100
      Re: Readable code and refactoring for optimization mhx@iae.nl (Marcel Hendrix) - 2011-12-06 07:26 +0200
        Re: Readable code and refactoring for optimization "Elizabeth D. Rather" <erather@forth.com> - 2011-12-05 22:02 -1000
        Re: Readable code and refactoring for optimization Bernd Paysan <bernd.paysan@gmx.de> - 2011-12-07 00:49 +0100
      Re: Readable code and refactoring for optimization Paul Rubin <no.email@nospam.invalid> - 2011-12-08 00:08 -0800
        Re: Readable code and refactoring for optimization anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2011-12-08 11:25 +0000
          Re: Readable code and refactoring for optimization Paul Rubin <no.email@nospam.invalid> - 2011-12-08 23:51 -0800
        Re: Readable code and refactoring for optimization Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2011-12-08 14:47 +0000
          Re: Readable code and refactoring for optimization Doug Hoffman <glidedog@gmail.com> - 2011-12-08 14:05 -0500
            Re: Readable code and refactoring for optimization Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2011-12-09 17:21 +0000
              Re: Readable code and refactoring for optimization Doug Hoffman <glidedog@gmail.com> - 2011-12-10 09:08 -0500
              Re: Readable code and refactoring for optimization "Elizabeth D. Rather" <erather@forth.com> - 2011-12-10 07:37 -1000
                Re: Readable code and refactoring for optimization Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2011-12-12 10:27 +0000
                  Re: Readable code and refactoring for optimization Andrew Haley <andrew29@littlepinkcloud.invalid> - 2011-12-12 05:02 -0600
                    Re: Readable code and refactoring for optimization Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2011-12-12 11:18 +0000
                      Re: Readable code and refactoring for optimization Andrew Haley <andrew29@littlepinkcloud.invalid> - 2011-12-12 05:25 -0600
                        Re: Readable code and refactoring for optimization Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2011-12-12 12:41 +0000
                          Re: Readable code and refactoring for optimization Andrew Haley <andrew29@littlepinkcloud.invalid> - 2011-12-12 07:23 -0600
                            Re: Readable code and refactoring for optimization Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2011-12-12 20:28 +0000
                              Re: Readable code and refactoring for optimization Andrew Haley <andrew29@littlepinkcloud.invalid> - 2011-12-13 04:07 -0600
                                Re: Readable code and refactoring for optimization Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2011-12-13 21:04 +0000
                  Re: Readable code and refactoring for optimization Arnold Doray <thinksquared@gmail.com> - 2011-12-12 16:01 +0000
                    Re: Readable code and refactoring for optimization Doug Hoffman <glidedog@gmail.com> - 2011-12-26 09:30 -0500
                      Re: Readable code and refactoring for optimization Arnold Doray <invalid@invalid.com> - 2012-01-08 16:28 +0000
                        Re: Readable code and refactoring for optimization Doug Hoffman <glidedog@gmail.com> - 2012-01-08 20:17 -0500
                          Re: Readable code and refactoring for optimization Arnold Doray <invalid@invalid.com> - 2012-01-09 10:41 +0000
                            Re: Readable code and refactoring for optimization Doug Hoffman <glidedog@gmail.com> - 2012-01-09 08:55 -0500
                              Re: Readable code and refactoring for optimization Doug Hoffman <glidedog@gmail.com> - 2012-01-09 11:50 -0500
                                Re: Readable code and refactoring for optimization Arnold Doray <invalid@invalid.com> - 2012-01-10 06:56 +0000
                                  Re: Readable code and refactoring for optimization Doug Hoffman <glidedog@gmail.com> - 2012-01-10 16:34 -0500
                                    Re: Readable code and refactoring for optimization Arnold Doray <invalid@invalid.com> - 2012-01-11 06:57 +0000
                                      Re: Readable code and refactoring for optimization Doug Hoffman <glidedog@gmail.com> - 2012-01-11 09:50 -0500
                                        Re: Readable code and refactoring for optimization Arnold Doray <invalid@invalid.com> - 2012-01-11 16:28 +0000
                  Re: Readable code and refactoring for optimization Fritz Wuehler <fritz@spamexpire-201112.rodent.frell.theremailer.net> - 2011-12-12 22:57 +0100
                    Re: Readable code and refactoring for optimization Doug Hoffman <glidedog@gmail.com> - 2011-12-26 09:30 -0500
          Re: Readable code and refactoring for optimization Paul Rubin <no.email@nospam.invalid> - 2011-12-08 23:53 -0800
          Re: Readable code and refactoring for optimization "Elizabeth D. Rather" <erather@forth.com> - 2011-12-09 17:46 -1000
            Re: Readable code and refactoring for optimization Josh Grams <josh@qualdan.com> - 2011-12-10 11:39 +0000
              Re: Readable code and refactoring for optimization Ian Osgood <iano@quirkster.com> - 2011-12-21 13:09 -0800
            Re: Readable code and refactoring for optimization Doug Hoffman <glidedog@gmail.com> - 2011-12-10 08:52 -0500
            Re: Readable code and refactoring for optimization Paul Rubin <no.email@nospam.invalid> - 2011-12-12 09:11 -0800
              Re: Readable code and refactoring for optimization "Elizabeth D. Rather" <erather@forth.com> - 2011-12-12 07:48 -1000
                Re: Readable code and refactoring for optimization Doug Hoffman <glidedog@gmail.com> - 2011-12-12 13:47 -0500
                  Re: Readable code and refactoring for optimization Paul Rubin <no.email@nospam.invalid> - 2011-12-12 11:46 -0800
                    Re: Readable code and refactoring for optimization Doug Hoffman <glidedog@gmail.com> - 2011-12-12 16:20 -0500
                    Re: Readable code and refactoring for optimization BruceMcF <agila61@netscape.net> - 2011-12-12 13:48 -0800
                      Re: Readable code and refactoring for optimization anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2011-12-13 10:31 +0000
                Re: Readable code and refactoring for optimization Paul Rubin <no.email@nospam.invalid> - 2011-12-12 11:42 -0800
                  Re: Readable code and refactoring for optimization Mark Wills <markrobertwills@yahoo.co.uk> - 2011-12-12 13:35 -0800
                    Re: Readable code and refactoring for optimization "Elizabeth D. Rather" <erather@forth.com> - 2011-12-12 11:49 -1000
                      Re: Readable code and refactoring for optimization Paul Rubin <no.email@nospam.invalid> - 2011-12-12 23:50 -0800
                        Re: Readable code and refactoring for optimization JennyB <jennybrien@googlemail.com> - 2011-12-13 03:04 -0800
    Re: Readable code and refactoring for optimization stephenXXX@mpeforth.com (Stephen Pelc) - 2011-12-06 11:04 +0000
      Re: Readable code and refactoring for optimization John Passaniti <john.passaniti@gmail.com> - 2011-12-06 05:52 -0800
    Re: Readable code and refactoring for optimization Arnold Doray <thinksquared@gmail.com> - 2011-12-06 13:52 +0000
      Re: Readable code and refactoring for optimization "Elizabeth D. Rather" <erather@forth.com> - 2011-12-06 08:22 -1000
        Re: Readable code and refactoring for optimization Arnold Doray <thinksquared@gmail.com> - 2011-12-07 08:55 +0000
    Re: Readable code and refactoring for optimization Doug Hoffman <glidedog@gmail.com> - 2011-12-11 07:29 -0500
      Re: Readable code and refactoring for optimization "Elizabeth D. Rather" <erather@forth.com> - 2011-12-11 08:59 -1000
        Re: Readable code and refactoring for optimization Mark Wills <forthfreak@gmail.com> - 2011-12-13 05:33 -0800
          Re: Readable code and refactoring for optimization Andrew Haley <andrew29@littlepinkcloud.invalid> - 2011-12-13 09:05 -0600
            Re: Readable code and refactoring for optimization "Elizabeth D. Rather" <erather@forth.com> - 2011-12-13 08:10 -1000
              Re: Readable code and refactoring for optimization anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2011-12-15 16:44 +0000
                Re: Readable code and refactoring for optimization "Elizabeth D. Rather" <erather@forth.com> - 2011-12-15 09:15 -1000
                  Re: Readable code and refactoring for optimization anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2011-12-16 17:13 +0000
                    Re: Readable code and refactoring for optimization "Elizabeth D. Rather" <erather@forth.com> - 2011-12-16 08:11 -1000
                      Re: Readable code and refactoring for optimization anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2011-12-21 13:57 +0000
          Re: Readable code and refactoring for optimization anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2011-12-13 15:06 +0000
          Re: Readable code and refactoring for optimization Bernd Paysan <bernd.paysan@gmx.de> - 2011-12-13 16:18 +0100
            Re: Readable code and refactoring for optimization mhx@iae.nl (Marcel Hendrix) - 2011-12-14 15:49 +0200

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


#7981

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2011-12-12 07:23 -0600
Message-ID<2Z-dneZ1yournXvTnZ2dnUVZ_vqdnZ2d@supernews.com>
In reply to#7978
Gerry Jackson <gerry@jackson9000.fsnet.co.uk> wrote:
> On 12/12/2011 11:25, Andrew Haley wrote:
>> Gerry Jackson<gerry@jackson9000.fsnet.co.uk>  wrote:
>>> On 12/12/2011 11:02, Andrew Haley wrote:
>>>> Gerry Jackson<gerry@jackson9000.fsnet.co.uk>   wrote:
>>>>> On 10/12/2011 17:37, Elizabeth D. Rather wrote:
> [...]
> 
>>>>>>> That looks good and ought to be clear even to non-forthers. Perhaps a
>>>>>>> version should be submitted to the Rosetta code site as an alternative
>>>>>>> Forth example demonstrating what can be achieved with a good OO package.
>>>>>>
>>>>>> It's a horrible example! It adds massive complexity for no purpose, and
>>>>>> I find it very hard to read. Is it faster, smaller, or in any other
>>>>>> technical way superior? Surely the "Forth way" is to solve problems the
>>>>>> simplest way possible.
>>>>>
>>>>> What you say is true from the perspective of embedded systems where
>>>>> every byte and processing cycle is important. However it ignores the
>>>>> fact that to most programmers Forth, even if they have heard of it,
>>>>> is a write-only language - it is so different to other languages
>>>>> that, if unfamiliar to someone, requires far more effort to
>>>>> understand than an unfamiliar conventional language. I think that
>>>>> such a person would stand more chance of understanding Doug's code
>>>>> than yours as given in another post - despite the fact that your
>>>>> version is good and clear to an experienced Forth programmer. Who
>>>>> knows, someone who understood it might then go on to try using
>>>>> Forth.
>>>>
>>>> I think you're being very unfair.  This has nothing to do with
>>>> embedded programming.  Elizabeth's code is simple and clean.
>>>
>>> I don't think you read my post. I didn't Elizabeth's code wasn't
>>> simple and clean. I wrote "despite the fact that your version is
>>> good and clear to an experienced Forth programmer". The key bit
>>> being to someone experienced with Forth.
>>
>> Yes, and I'm disagreeing with that.  I think you are wrong.
> 
> That's OK, but I'd prefer you said so directly instead of 
> misrepresenting what was written.

I said, in full:

>>> I think you're being very unfair.  This has nothing to do with
>>> embedded programming.  Elizabeth's code is simple and clean.
>>> Forth is all about simple and clean.  There's no point writing
>>> non-idiomatic code in Rosetta.

I can't see anything in this that misrepresents anything in your
posting, and in any case I quoted the paragraph to which I responded.

IMO: Clean idiomatic code is exactly what Rosetta needs.  What Rosetta
does not need is code written in a nonstandard extension to Forth, no
matter how excellent that extension is.

Andrew.

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


#8012

FromGerry Jackson <gerry@jackson9000.fsnet.co.uk>
Date2011-12-12 20:28 +0000
Message-ID<jc5o4f$sjq$2@dont-email.me>
In reply to#7981
On 12/12/2011 13:23, Andrew Haley wrote:
> Gerry Jackson<gerry@jackson9000.fsnet.co.uk>  wrote:
>> On 12/12/2011 11:25, Andrew Haley wrote:
>>> Gerry Jackson<gerry@jackson9000.fsnet.co.uk>   wrote:
>>>> On 12/12/2011 11:02, Andrew Haley wrote:
>>>>> Gerry Jackson<gerry@jackson9000.fsnet.co.uk>    wrote:
>>>>>> On 10/12/2011 17:37, Elizabeth D. Rather wrote:
>> [...]
>>
>>>>>>>> That looks good and ought to be clear even to non-forthers. Perhaps a
>>>>>>>> version should be submitted to the Rosetta code site as an alternative
>>>>>>>> Forth example demonstrating what can be achieved with a good OO package.
>>>>>>>
>>>>>>> It's a horrible example! It adds massive complexity for no purpose, and
>>>>>>> I find it very hard to read. Is it faster, smaller, or in any other
>>>>>>> technical way superior? Surely the "Forth way" is to solve problems the
>>>>>>> simplest way possible.
>>>>>>
>>>>>> What you say is true from the perspective of embedded systems where
>>>>>> every byte and processing cycle is important. However it ignores the
>>>>>> fact that to most programmers Forth, even if they have heard of it,
>>>>>> is a write-only language - it is so different to other languages
>>>>>> that, if unfamiliar to someone, requires far more effort to
>>>>>> understand than an unfamiliar conventional language. I think that
>>>>>> such a person would stand more chance of understanding Doug's code
>>>>>> than yours as given in another post - despite the fact that your
>>>>>> version is good and clear to an experienced Forth programmer. Who
>>>>>> knows, someone who understood it might then go on to try using
>>>>>> Forth.
>>>>>
>>>>> I think you're being very unfair.  This has nothing to do with
>>>>> embedded programming.  Elizabeth's code is simple and clean.
>>>>
>>>> I don't think you read my post. I didn't Elizabeth's code wasn't
>>>> simple and clean. I wrote "despite the fact that your version is
>>>> good and clear to an experienced Forth programmer". The key bit
>>>> being to someone experienced with Forth.
>>>
>>> Yes, and I'm disagreeing with that.  I think you are wrong.
>>
>> That's OK, but I'd prefer you said so directly instead of
>> misrepresenting what was written.
>
> I said, in full:
>
>>>> I think you're being very unfair.  This has nothing to do with
>>>> embedded programming.  Elizabeth's code is simple and clean.
>>>> Forth is all about simple and clean.  There's no point writing
>>>> non-idiomatic code in Rosetta.
>
> I can't see anything in this that misrepresents anything in your
> posting, and in any case I quoted the paragraph to which I responded.
>

ISTM that your statement implied that I thought Elizabeth's code wasn't 
"simple and clean". I have no wish to enter into an infinite loop 
argument of the type you seem to favour so I shall just leave it at that 
whatever your reply.

-- 
Gerry

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


#8022

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2011-12-13 04:07 -0600
Message-ID<dLadnQ8mbP1qvnrTnZ2dnUVZ_r6dnZ2d@supernews.com>
In reply to#8012
Gerry Jackson <gerry@jackson9000.fsnet.co.uk> wrote:
> On 12/12/2011 13:23, Andrew Haley wrote:
>>
>> I said, in full:
>>
>>>>> I think you're being very unfair.  This has nothing to do with
>>>>> embedded programming.  Elizabeth's code is simple and clean.
>>>>> Forth is all about simple and clean.  There's no point writing
>>>>> non-idiomatic code in Rosetta.
>>
>> I can't see anything in this that misrepresents anything in your
>> posting, and in any case I quoted the paragraph to which I responded.
> 
> ISTM that your statement implied that I thought Elizabeth's code
> wasn't "simple and clean". I have no wish to enter into an infinite
> loop argument of the type you seem to favour so I shall just leave
> it at that whatever your reply.

OK, I see.  I had to ask because I was genuinely baffled.  I'm sorry
that you inferred that, but I had no intention of implying it.  I'm
glad to have the opportunity to make that clear.

Andrew.

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


#8047

FromGerry Jackson <gerry@jackson9000.fsnet.co.uk>
Date2011-12-13 21:04 +0000
Message-ID<jc8ej8$n4a$1@dont-email.me>
In reply to#8022
On 13/12/2011 10:07, Andrew Haley wrote:
> Gerry Jackson<gerry@jackson9000.fsnet.co.uk>  wrote:
>> On 12/12/2011 13:23, Andrew Haley wrote:
>>>
>>> I said, in full:
>>>
>>>>>> I think you're being very unfair.  This has nothing to do with
>>>>>> embedded programming.  Elizabeth's code is simple and clean.
>>>>>> Forth is all about simple and clean.  There's no point writing
>>>>>> non-idiomatic code in Rosetta.
>>>
>>> I can't see anything in this that misrepresents anything in your
>>> posting, and in any case I quoted the paragraph to which I responded.
>>
>> ISTM that your statement implied that I thought Elizabeth's code
>> wasn't "simple and clean". I have no wish to enter into an infinite
>> loop argument of the type you seem to favour so I shall just leave
>> it at that whatever your reply.
>
> OK, I see.  I had to ask because I was genuinely baffled.  I'm sorry
> that you inferred that, but I had no intention of implying it.  I'm
> glad to have the opportunity to make that clear.

OK, apology accepted, let's close it there with no hard feelings. I'm 
sorry I got annoyed.

-- 
Gerry

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


#7990

FromArnold Doray <thinksquared@gmail.com>
Date2011-12-12 16:01 +0000
Message-ID<jc58gb$q3l$1@dont-email.me>
In reply to#7966
On Mon, 12 Dec 2011 10:27:12 +0000, Gerry Jackson wrote:

> On 10/12/2011 17:37, Elizabeth D. Rather wrote:
>> On 12/9/11 7:21 AM, Gerry Jackson wrote:
>>> On 08/12/2011 19:05, Doug Hoffman wrote:
>> ....
>>>> This makes a good daily crossword puzzle. Here's a version that kicks
>>>> it up to a higher level for clarity, though it will surely horrify
>>>> some. But what the heck:
>>>>
>>>> 0 [if] A door is a physical object. So perhaps use objects. First
>>>> make a door object factory and test it with a single door to assure
>>>> that it will correctly open, shut, toggle, and can be queried for
>>>> state. Once that all works, only then proceed. [then]
>>>>
>>>> :class door <super object
>>>> bool shut? \ set = shut \ clear = open :m open: shut? clear: ;m
>>>> :m shut: shut? set: ;m
>>>> :m shut?: ( -- f ) shut? @: ;m
>>>> :m toggle:
>>>> self shut?: IF self open:
>>>> ELSE self shut:
>>>> THEN ;m
>>>> ;class
>>>>
>>>> 0 [if] \ test on a single door
>>>> door d
>>>> d open: d shut?: . => 0
>>>> d toggle: d shut?: . => -1
>>>> d toggle: d shut?: . => 0
>>>> [then]
>>>>
>>>> \ same
>>>> 100 constant ndoors
>>>>
>>>> \ an objArray() will check for valid indexes ndoors objArray() door
>>>> doors()
>>>>
>>>> 0 [if] openAll is a descriptive name and we are confident that open:
>>>> will work as it should on any number of doors. [then] : openAll
>>>> ndoors 0 DO i doors() open: LOOP ;
>>>>
>>>> 0 [if] displayShut is written and tested next before proceeding.
>>>> "shut?:" is used instead of "@ 1 and" [then] : displayShut \ display
>>>> as if a 1-based array ndoors 0 DO i doors() shut?: IF i 1+ . THEN
>>>> LOOP ;
>>>>
>>>> 0 [if] pass is very similar to your pass except we use a local to
>>>> avoid stack shuffling and "toggle:" instead of "1 ... +!" [then] :
>>>> pass { n -- } \ toggle every (n+1)th door in the array \ but door(0)
>>>> is toggled just once
>>>> ndoors n DO i doors() toggle: n 1+ +LOOP ;
>>>>
>>>> \ identical run definition
>>>> : run ndoors 0 DO i pass LOOP ;
>>>>
>>>> openAll run displayShut
>>>>
>>>>
>>>> -Doug
>>>
>>> That looks good and ought to be clear even to non-forthers. Perhaps a
>>> version should be submitted to the Rosetta code site as an alternative
>>> Forth example demonstrating what can be achieved with a good OO
>>> package.
>>
>> It's a horrible example! It adds massive complexity for no purpose, and
>> I find it very hard to read. Is it faster, smaller, or in any other
>> technical way superior? Surely the "Forth way" is to solve problems the
>> simplest way possible.
>>
>>
> What you say is true from the perspective of embedded systems where
> every byte and processing cycle is important. However it ignores the
> fact that to most programmers Forth, even if they have heard of it, is a
> write-only language - it is so different to other languages that, if
> unfamiliar to someone, requires far more effort to understand than an
> unfamiliar conventional language. I think that such a person would stand
> more chance of understanding Doug's code than yours as given in another
> post - despite the fact that your version is good and clear to an
> experienced Forth programmer. Who knows, someone who understood it might
> then go on to try using Forth.
> 
> It seems to be a sad fact that embedded system programmers don't seem to
> realise that getting the smallest, fastest program isn't that important
> to those who use run Forth on desktop systems. Of course some
> applications need the ultimate in speed and size but mostly those
> considerations are irrelevant.

I am a forth newbie, and I found the OOP'ized version to be an 
abomination. It's gratuitously complex. It feels contrived. 

Perhaps it could be used profitably as an example of how to solve a toy 
problem within the OOP paradigm in Forth. Or perhaps it may be useful as 
a comparison against other forth OOP frameworks. 

But to compare it favourably against Elizabeth's code in the context of 
this specific problem is just nonsense. Elizabeth's code is so much 
better there's just no comparison. 

Cheers,
Arnold










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


#8355

FromDoug Hoffman <glidedog@gmail.com>
Date2011-12-26 09:30 -0500
Message-ID<4ef884ed$0$292$14726298@news.sunsite.dk>
In reply to#7990
On 12/12/11 11:01 AM, Arnold Doray wrote:

> I am a forth newbie, and I found the OOP'ized version to be an
> abomination. It's gratuitously complex. It feels contrived.
>
> Perhaps it could be used profitably as an example of how to solve a toy
> problem within the OOP paradigm in Forth.

I suppose it could be used for that.  But the intended purpose was to 
provide the OP an example that illustrated an answer to his question:

"The common advice to developers in most languages is to write first for 
clarity and correctness, then optimize only if necessary. How well does 
that approach work for Forth?"

One could quibble about clarity, but I didn't see any other Forth code 
that first showed a "high level" solution and then a follow-up 
converting it to "low level" as an optimization.  My follow-up 
"optimized" code kept the overall flow and logic of the oop solution. 
Btw, the oop solution was the only correct code posted at the time, 
correct as in giving the right answer.

> But to compare it favourably against Elizabeth's code in the context of
> this specific problem is just nonsense. Elizabeth's code is so much
> better there's just no comparison.

Correctness was also a requirement.

The oop code was never intended to be a showcase example of Forth for 
Forth outsiders.

-Doug

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


#8727

FromArnold Doray <invalid@invalid.com>
Date2012-01-08 16:28 +0000
Message-ID<jecg86$c0k$1@dont-email.me>
In reply to#8355
On Mon, 26 Dec 2011 09:30:04 -0500, Doug Hoffman wrote:

> But the intended purpose was to
> provide the OP an example that illustrated an answer to his question:
> 
> "The common advice to developers in most languages is to write first for
> clarity and correctness, then optimize only if necessary. How well does
> that approach work for Forth?"
> 
> One could quibble about clarity, but I didn't see any other Forth code
> that first showed a "high level" solution and then a follow-up
> converting it to "low level" as an optimization.  My follow-up
> "optimized" code kept the overall flow and logic of the oop solution.
> Btw, the oop solution was the only correct code posted at the time,
> correct as in giving the right answer.
> 
>> But to compare it favourably against Elizabeth's code in the context of
>> this specific problem is just nonsense. Elizabeth's code is so much
>> better there's just no comparison.
> 
> Correctness was also a requirement.
> 

Certainly, correctness is a requirement. 

The question is whether an OOP solution is necessary to arrive at a 
correct and clear solution for a simple problem like the 100 doors. 

Those not familiar with OOP would likely say "no", while those familiar 
with OOP would have to interpolate your Forth OOP into their frame of 
reference. Either way, that's unnecessary additional mental overhead for 
a simple problem. 

> The oop code was never intended to be a showcase example of Forth for
> Forth outsiders.
> 

Yes, you didn't claim this, and I never said that you did. 

But the poster to whom I replied to *did* seem to think it was suitable 
for this purpose, and further, a suitable candidate for Rosetta. I think 
it would have put people off Forth, because in a way, it grossly 
misrepresents Forth. 

BTW, I think the 100 doors problem is a silly one that doesn't really 
showcase/prove anything for any language. Any door whose number is a 
square (eg 9 = 3x3 is square) will be open in the end , because they 
alone have an odd number of factors [1]. I think this is what the 
"optimized" Forth version on Rosetta does --it's just printing the square 
numbers leq N (N = the number of doors). In that spirit, why not just: 

: 100doors 10 1 do i * . loop ; 

And be done with it. Far more "Forth Way" in that it doesn't have 
unnecessary generalizations! :) Or if you have "floor" and 
"sqrt" (probably a fairer comparison with your OOP version), then you can 
do : 

: doors sqrt floor 1 do i * . loop ; 

LOL

Cheers,
Arnold

[1] For every number k that divides N, the pair (k, N/k) is a pair of 
unique divisors of N. The collection of all such pairs obviously yields 
an even number of unique divisors, *unless* K = N/K , thus N = K*K. Ie, N 
is a square number. In this case, the number of *unique* divisiors is odd 
since we don't double-count K. Thus, any number with an odd number of 
factors must be square. Conversely, for any square number, we can 
enumerate their divisors as pairs using the scheme above. Only one of 
these collection of divisor pairs must be (K,K). So, the number of unique 
divisors of square numbers is always odd. Thus you have the implication 
both ways. 

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


#8742

FromDoug Hoffman <glidedog@gmail.com>
Date2012-01-08 20:17 -0500
Message-ID<4f0a401e$0$290$14726298@news.sunsite.dk>
In reply to#8727
On 1/8/12 11:28 AM, Arnold Doray wrote:
> On Mon, 26 Dec 2011 09:30:04 -0500, Doug Hoffman wrote:
>
>> But the intended purpose was to
>> provide the OP an example that illustrated an answer to his question:
>>
>> "The common advice to developers in most languages is to write first for
>> clarity and correctness, then optimize only if necessary. How well does
>> that approach work for Forth?"
>>
>> One could quibble about clarity, but I didn't see any other Forth code
>> that first showed a "high level" solution and then a follow-up
>> converting it to "low level" as an optimization.  My follow-up
>> "optimized" code kept the overall flow and logic of the oop solution.
>> Btw, the oop solution was the only correct code posted at the time,
>> correct as in giving the right answer.
>>
>>> But to compare it favourably against Elizabeth's code in the context of
>>> this specific problem is just nonsense. Elizabeth's code is so much
>>> better there's just no comparison.
>>
>> Correctness was also a requirement.
>>
>
> Certainly, correctness is a requirement.

Then *how* can you say Elizabeth's code was better?  Correct answer is 
the price of admission.  Style points only come after that.

> The question is whether an OOP solution is necessary to arrive at a
> correct and clear solution for a simple problem like the 100 doors.

That's not the question as I see it because obviously it's not (it *is* 
one of many possible illustrations), but let's not get sidetracked on that.

> BTW, I think the 100 doors problem is a silly one that doesn't really
> showcase/prove anything for any language.

You have no interest in seeing how other languages step though arrays?

It only becomes useless, or silly, when the algorithm is changed going 
from the "clear and correct" code to the "optimized" code.  I'm not 
saying that one should never change an algorithm during optimization.  I 
*am* saying it doesn't make sense to do so for this exercise.

> Any door whose number is a
> square ...[snip]... In that spirit, why not just:
>
> : 100doors 10 1 do i * . loop ;

Then why waste the dictionary memory?
Just use: .( 1 4 9 16 25 36 49 64 81 100)

Because changing the algorithm as you and others have done then makes 
this a useless demonstration.  I wouldn't do that, and I didn't.


The take away for me from this whole exercise is three-fold:

1) During development it can help a *lot* to use arrays that self-check 
index validity.

2) A common pattern seen in Forth is the  "n 0 do i ... loop" construct. 
  To Forth newbies this can look a bit strange.  The thing to keep in 
mind is the loop will execute exactly n times (n-0) assuming no LEAVEs 
are invoked, even though the index i will never reach n: i will step 
from 0 to n-1, which is useful for a zero-based array.  So if you have n 
items in your array and write something like "n 1 do ... loop" then the 
first array item will be skipped.

3) It is frequently useful to first write a programming solution in 
pseudo-code or simple-and-clear code without worrying about efficiency. 
  Once the program works, then one can go back and make it smaller or 
faster or whatever only *if* that is needed.  This last take-away point 
directly addresses the OP's question: Yes, this approach works well in 
Forth.

Btw, the oo solution was plenty fast, even with 1000 doors, on my old 
and slow PC.  Press the run key and the answer appeared 'instantly'.

-Doug

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


#8751

FromArnold Doray <invalid@invalid.com>
Date2012-01-09 10:41 +0000
Message-ID<jeeg8f$gd$1@dont-email.me>
In reply to#8742
On Sun, 08 Jan 2012 20:17:16 -0500, Doug Hoffman wrote:

> On 1/8/12 11:28 AM, Arnold Doray wrote:
>> On Mon, 26 Dec 2011 09:30:04 -0500, Doug Hoffman wrote:
>>
>>> But the intended purpose was to provide the OP an example that
>>> illustrated an answer to his question:
>>>
>>> "The common advice to developers in most languages is to write first
>>> for clarity and correctness, then optimize only if necessary. How well
>>> does that approach work for Forth?"
>>>
>>> One could quibble about clarity, but I didn't see any other Forth code
>>> that first showed a "high level" solution and then a follow-up
>>> converting it to "low level" as an optimization.  My follow-up
>>> "optimized" code kept the overall flow and logic of the oop solution.
>>> Btw, the oop solution was the only correct code posted at the time,
>>> correct as in giving the right answer.
>>>
>>>> But to compare it favourably against Elizabeth's code in the context
>>>> of this specific problem is just nonsense. Elizabeth's code is so
>>>> much better there's just no comparison.
>>>
>>> Correctness was also a requirement.
>>>
>>>
>> Certainly, correctness is a requirement.
> 
> Then *how* can you say Elizabeth's code was better?  Correct answer is
> the price of admission.  Style points only come after that.
> 

I may be missing something but I tried out Elizabeth's original solution: 

: toggle ( caddr -- ) \ Toggle the byte at caddr
    dup c@ 1 xor swap c! ;  \ Many systems already have this.

100 constant ndoors
create doors ndoors allot

: init ( -- )   doors ndoors erase ;

: pass ( n -- )   \ toggle every nth door in the array.
    dup ndoors 1+ rot do
       doors i + toggle dup
    ( n ) +loop drop ;

: run ( -- )   ndoors 1+ 1 do  i pass  loop ;
: display ( -- )   ndoors 1+ 1 do  doors i + c@ if  i . then  loop cr ; 

init run display 1 4 9 16 25 36 49 64 81 100 
 ok

On my MacBook Air using the MacPorts Gforth v0.7.0. This seems to yield 
the right solution. 

Which error are you refering to?

Unlike her solution, which works out of the box, I can't even run yours: 

include 100-doors-oop.4th 
100-doors-oop.4th:6: Undefined word
>>>:class<<< door <super object
 
Could you post a link to the OOP bootstrap code that I need to load to 
test your solution? 

>> The question is whether an OOP solution is necessary to arrive at a
>> correct and clear solution for a simple problem like the 100 doors.
> 
> That's not the question as I see it because obviously it's not (it *is*
> one of many possible illustrations), but let's not get sidetracked on
> that.
> 
>> BTW, I think the 100 doors problem is a silly one that doesn't really
>> showcase/prove anything for any language.
> 
> You have no interest in seeing how other languages step though arrays?
> 

Of course I am. But IMHO, your OOP solution obscures this. This is just a 
my opinion of course. There are others on this thread who have disagreed. 

> It only becomes useless, or silly, when the algorithm is changed going
> from the "clear and correct" code to the "optimized" code.  I'm not
> saying that one should never change an algorithm during optimization.  I
> *am* saying it doesn't make sense to do so for this exercise.
> 

Exactly. IMO, the impression the Rosetta solutions (for any language) 
gives by putting up these "solutions" is that it is a fair comparison 
between languages. It isn't because there are at least two very different 
solutions : the direct simulation one and the one that prints out the 
square numbers. 

>> Any door whose number is a square ...[snip]... In that spirit, why not
>> just:
>>
>> : 100doors 10 1 do i * . loop ;
> 
> Then why waste the dictionary memory?
> Just use: .( 1 4 9 16 25 36 49 64 81 100)

My "solution" was just tongue-in-cheek. Don't take it too seriously. 

> 
> Because changing the algorithm as you and others have done then makes
> this a useless demonstration.  I wouldn't do that, and I didn't.
> 
> 
> The take away for me from this whole exercise is three-fold:
> 
> 1) During development it can help a *lot* to use arrays that self-check
> index validity.
> 
> 2) A common pattern seen in Forth is the  "n 0 do i ... loop" construct.
>   To Forth newbies this can look a bit strange.  The thing to keep in
> mind is the loop will execute exactly n times (n-0) assuming no LEAVEs
> are invoked, even though the index i will never reach n: i will step
> from 0 to n-1, which is useful for a zero-based array.  So if you have n
> items in your array and write something like "n 1 do ... loop" then the
> first array item will be skipped.
> 
> 3) It is frequently useful to first write a programming solution in
> pseudo-code or simple-and-clear code without worrying about efficiency.
>   Once the program works, then one can go back and make it smaller or
> faster or whatever only *if* that is needed.  This last take-away point
> directly addresses the OP's question: Yes, this approach works well in
> Forth.
> 

All very valid points and worthwile for an illustration. But do you 
really have to resort to OOP to illustrate these points?! Surely that's 
not also a takeaway message from your post? 

> Btw, the oo solution was plenty fast, even with 1000 doors, on my old
> and slow PC.  Press the run key and the answer appeared 'instantly'.
> 
> -Doug

Could you please quantify "fast"? 

On what system did you run it on? I tried Elizabeth's code on Gforth with 
my Macbook Air and N = 10^6 and it runs under a second. 

Cheers,
Arnold


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


#8754

FromDoug Hoffman <glidedog@gmail.com>
Date2012-01-09 08:55 -0500
Message-ID<4f0af1dc$0$289$14726298@news.sunsite.dk>
In reply to#8751
On 1/9/12 5:41 AM, Arnold Doray wrote:

> Which error are you refering to?

try:
100 constant ndoors
create doors ndoors allot
1 c,  \ <-- add this here
everything else the same

It is accessing memory not allotted for ndoors.  You were lucky it worked.

> Could you post a link to the OOP bootstrap code that I need to load to
> test your solution?

http://soton.mpeforth.com/flag/fms/index.html
Download the complete set and use version 31dDispatch with errorcheck 
set to false.

> All very valid points and worthwile for an illustration. But do you
> really have to resort to OOP to illustrate these points?!

Of course not.  As I have told you, "it is one of many possible 
illustrations".

> Could you please quantify "fast"?

As in press the key and with no human-perceptible delay all the numbers 
are on the screen.


> On what system did you run it on?

iMac G5 2 ghz  1000 doors 88.2 msec

> I tried Elizabeth's code on Gforth with
> my Macbook Air and N = 10^6 and it runs under a second.

0.70 seconds with n= 1000000.

-Doug

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


#8759

FromDoug Hoffman <glidedog@gmail.com>
Date2012-01-09 11:50 -0500
Message-ID<4f0b1af0$0$288$14726298@news.sunsite.dk>
In reply to#8754
On 1/9/12 8:55 AM, Doug Hoffman wrote:
> On 1/9/12 5:41 AM, Arnold Doray wrote:

>> Could you please quantify "fast"?
>
> As in press the key and with no human-perceptible delay all the numbers
> are on the screen.
>
>
>> On what system did you run it on?
>
> iMac G5 2 ghz 1000 doors 88.2 msec
>
>> I tried Elizabeth's code on Gforth with
>> my Macbook Air and N = 10^6 and it runs under a second.
>
> 0.70 seconds with n= 1000000.

That's a typo.  It should be 4.70 seconds with n= 1000000 (not 0.70). 
Carbon MacForth.  With iForth on a WindowsXP P4 3ghz the time is under 1 
second.

You have changed the problem from the original 100 doors.  In general, 
raw speed is not what objects are all about, although FMS didn't do too 
badly in that respect as it is designed to be a very fast object system.

The flaw in the original code wasn't really Elizabeth's.  She was just 
offering some improvements on someone else's code.  There was a lot of 
stack juggling going on to set up the limits for the do...loop and it 
was not at all obvious what they ultimately were.

-Doug

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


#8762

FromArnold Doray <invalid@invalid.com>
Date2012-01-10 06:56 +0000
Message-ID<jegne9$pi0$1@dont-email.me>
In reply to#8759
On Mon, 09 Jan 2012 11:50:54 -0500, Doug Hoffman wrote:

> On 1/9/12 8:55 AM, Doug Hoffman wrote:
>> On 1/9/12 5:41 AM, Arnold Doray wrote:
> 
>>> Could you please quantify "fast"?
>>
>> As in press the key and with no human-perceptible delay all the numbers
>> are on the screen.
>>
>>
>>> On what system did you run it on?
>>
>> iMac G5 2 ghz 1000 doors 88.2 msec
>>
>>> I tried Elizabeth's code on Gforth with my Macbook Air and N = 10^6
>>> and it runs under a second.
>>
>> 0.70 seconds with n= 1000000.
> 
> That's a typo.  It should be 4.70 seconds with n= 1000000 (not 0.70).
> Carbon MacForth.  With iForth on a WindowsXP P4 3ghz the time is under 1
> second.
> 
> You have changed the problem from the original 100 doors.  In general,
> raw speed is not what objects are all about, although FMS didn't do too
> badly in that respect as it is designed to be a very fast object system.
> 
> The flaw in the original code wasn't really Elizabeth's.  She was just
> offering some improvements on someone else's code.  There was a lot of
> stack juggling going on to set up the limits for the do...loop and it
> was not at all obvious what they ultimately were.
> 
> -Doug

It runs much faster on my Mac Airbook (1.5GHz ?), about a second. What 
could be the reason for the slowdown on your PC?

Thanks for the link on the FMS, I will certainly give your code a spin. 
It is a nice simple illustration of the use of OOP in Forth. 

Yes, minimizing stack juggling takes some experience to eliminate. It 
might have been better to use locals in this instance. 

Cheers,
Arnold



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


#8777

FromDoug Hoffman <glidedog@gmail.com>
Date2012-01-10 16:34 -0500
Message-ID<4f0caeea$0$292$14726298@news.sunsite.dk>
In reply to#8762
On 1/10/12 1:56 AM, Arnold Doray wrote:

> Thanks for the link on the FMS, I will certainly give your code a spin.
> It is a nice simple illustration of the use of OOP in Forth.

I once toyed with an extreme minimalist approach.  Never published the 
code.  But here it is for anyone interested:

-Doug

\ mini-fms                      06/05/10 dbh
0 value ^class
: dfa  ( class -- adr)   cell+ ;
: sfa  ( class -- adr) [ 2 cells ] literal + ;
3 cells constant classSize
: find-method  ( SelID class -- xt)
   begin @ dup while 2dup cell+ @ =
   if [ 2 cells ] literal + nip @  exit then repeat ;
create object classSize here over allot swap erase
: <super ( 'name' --) here to ^class classSize allot
   ' >body dup ^class classSize move ^class sfa ! ;
: (ivar) ( offset --) create , does> @  + ;
: ivar ( n 'name' --) ^class dup cell+ @ (ivar) cell+ +! ;
: :c ( 'name' -- adr) create here \ create message name
   does> over [ 1 cells ] literal - @  find-method execute ;
: :r ( 'name' -- adr) ' >body ; \ re-use message name
: :m ( adr -- adr xt)
   ^class here over @ , swap ! , here 0 , :noname ;
: ;m ( adr xt --) postpone ; swap ! ; immediate
: <class_as ( o class 'name' --)
   ' >body swap find-method compile, ; immediate
: new ( class -- o) dup dfa @ cell+ here swap allot
   dup cell+ rot rot ! ;
: :class ( 'name') create immediate does> ( class) ;
: ;class ;


This is a real OO extension for Forth, in 780 bytes of dictionary space 
(32-bit system), YMMV. Could be reduced further but clarity would suffer.
No constraints on message name re-use (hierarchy, order, etc).
Linked-lists are used for method lookup, hierarchy, and inheritance.
Further functionality could include things like (each are just 1 or 2 
lines of code):
- Objects cast in the Heap
- Encapsulated Ivars: i.e., not in global namespace
- Implicit Object Initialization
- SELF Pseudo Ivar (eliminate stack juggling of o)
- SUPER Pseudo Ivar
- etc. etc.

For an example of use, here is how the "doors" problem might be written 
in mini-fms:

:class door <super object
   1 ivar shut? \ 0 = shut  1 = open
   :c open: :m ( o -- ) 0 swap shut? c! ;m
   :c shut: :m ( o -- ) 1 swap shut? c! ;m
   :c shut?: :m ( o -- f ) shut? c@ ;m
   :c toggle: :m { o -- }
      o shut?: IF   o open:
               ELSE o shut:
               THEN ;m
;class

100 constant ndoors
create doors() ndoors cells allot
: doors(i)' ( i -- addr )
   dup 0 ndoors within 0= abort" invalid index"
   1 cells * doors() + ;
: doors(i) ( i -- ^obj ) doors(i)' @ ;
: make-doors() ndoors 0 DO postpone door new i doors(i)' ! LOOP ;
make-doors()
: openAll ndoors 0 DO i doors(i) open: LOOP ;
: displayShut ndoors 0 DO i doors(i) shut?: IF i 1+ . THEN LOOP ;
: pass { n -- }
    ndoors n DO i doors(i) toggle: n 1+ +LOOP ;
: run ndoors 0 DO i pass LOOP ;

timer-reset openAll run displayShut .elapsed
1 4 9 16 25 36 49 64 81 100 7.66 msec

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


#8787

FromArnold Doray <invalid@invalid.com>
Date2012-01-11 06:57 +0000
Message-ID<jejbsl$rkq$1@dont-email.me>
In reply to#8777
On Tue, 10 Jan 2012 16:34:33 -0500, Doug Hoffman wrote:

> On 1/10/12 1:56 AM, Arnold Doray wrote:
> 
>> Thanks for the link on the FMS, I will certainly give your code a spin.
>> It is a nice simple illustration of the use of OOP in Forth.
> 
> I once toyed with an extreme minimalist approach.  Never published the
> code.  But here it is for anyone interested:
> 
> -Doug
> 
> \ mini-fms                      06/05/10 dbh 0 value ^class : dfa  (
> class -- adr)   cell+ ;
> : sfa  ( class -- adr) [ 2 cells ] literal + ;
> 3 cells constant classSize : find-method  ( SelID class -- xt)
>    begin @ dup while 2dup cell+ @ =
>    if [ 2 cells ] literal + nip @  exit then repeat ;
> create object classSize here over allot swap erase : <super ( 'name' --)
> here to ^class classSize allot
>    ' >body dup ^class classSize move ^class sfa ! ;
> : (ivar) ( offset --) create , does> @  + ;
> : ivar ( n 'name' --) ^class dup cell+ @ (ivar) cell+ +! ;
> : :c ( 'name' -- adr) create here \ create message name
>    does> over [ 1 cells ] literal - @  find-method execute ;
> : :r ( 'name' -- adr) ' >body ; \ re-use message name : :m ( adr -- adr
> xt)
>    ^class here over @ , swap ! , here 0 , :noname ;
> : ;m ( adr xt --) postpone ; swap ! ; immediate : <class_as ( o class
> 'name' --)
>    ' >body swap find-method compile, ; immediate
> : new ( class -- o) dup dfa @ cell+ here swap allot
>    dup cell+ rot rot ! ;
> : :class ( 'name') create immediate does> ( class) ;
> : ;class ;
> 
> 
> This is a real OO extension for Forth, in 780 bytes of dictionary space
> (32-bit system), YMMV. Could be reduced further but clarity would
> suffer.
> No constraints on message name re-use (hierarchy, order, etc).
> Linked-lists are used for method lookup, hierarchy, and inheritance.
> Further functionality could include things like (each are just 1 or 2
> lines of code):
> - Objects cast in the Heap - Encapsulated Ivars: i.e., not in global
> namespace - Implicit Object Initialization - SELF Pseudo Ivar (eliminate
> stack juggling of o)
> - SUPER Pseudo Ivar - etc. etc.
> 
> For an example of use, here is how the "doors" problem might be written
> in mini-fms:
> 
> :class door <super object
>    1 ivar shut? \ 0 = shut  1 = open :c open: :m ( o -- ) 0 swap shut?
>    c! ;m :c shut: :m ( o -- ) 1 swap shut? c! ;m :c shut?: :m ( o -- f )
>    shut? c@ ;m :c toggle: :m { o -- }
>       o shut?: IF   o open:
>                ELSE o shut:
>                THEN ;m
> ;class
> 
> 100 constant ndoors create doors() ndoors cells allot : doors(i)' ( i --
> addr )
>    dup 0 ndoors within 0= abort" invalid index"
>    1 cells * doors() + ;
> : doors(i) ( i -- ^obj ) doors(i)' @ ;
> : make-doors() ndoors 0 DO postpone door new i doors(i)' ! LOOP ;
> make-doors()
> : openAll ndoors 0 DO i doors(i) open: LOOP ;
> : displayShut ndoors 0 DO i doors(i) shut?: IF i 1+ . THEN LOOP ;
> : pass { n -- }
>     ndoors n DO i doors(i) toggle: n 1+ +LOOP ;
> : run ndoors 0 DO i pass LOOP ;
> 
> timer-reset openAll run displayShut .elapsed 1 4 9 16 25 36 49 64 81 100
> 7.66 msec

Your minimalist OOP looks interesting. Thank you for posting it.

BTW, here's yet another solution for 100-doors that doesn't "cheat" with 
square numbers . But does not use arrays either:

\ Is door X open, given N doors?
: open? ( N+1 X -- N+1 f )
        >R                                      \ save X
        true                                    \ door is initially open 
        over 2 do  
                i j > if leave then             \ early termination?
                j i mod 0= if invert then       \ toggle door
                        
        loop                                    
        R> drop ;                               \ tidy R stack.          

\ Prints the open doors in the N door puzzle.
: doors ( N -- )
        1+ dup 1 do i open? if i . then loop drop ;

1000000000 doors \ Billion doors takes too long, but should work. 

What I can't understand is that even though N N OPEN? takes less than a 
second, when used in DOORS, it is much slower (I'm using the MacPorted 
GForth 0.7.0 on a 1.5GHz Macbook Air). The DOORS iteration slows down to 
a crawl as "X" increases. 

Any ideas? 

Cheers,
Arnold














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


#8804

FromDoug Hoffman <glidedog@gmail.com>
Date2012-01-11 09:50 -0500
Message-ID<4f0da1be$0$289$14726298@news.sunsite.dk>
In reply to#8787
On 1/11/12 1:57 AM, Arnold Doray wrote:

> \ Is door X open, given N doors?
> : open? ( N+1 X -- N+1 f )
>          >R                                      \ save X
>          true                                    \ door is initially open
>          over 2 do
>                  i j>  if leave then             \ early termination?
>                  j i mod 0= if invert then       \ toggle door
>
>          loop
>          R>  drop ;                               \ tidy R stack.
>
> \ Prints the open doors in the N door puzzle.
> : doors ( N -- )
>          1+ dup 1 do i open? if i . then loop drop ;
>
> 1000000000 doors \ Billion doors takes too long, but should work.
>
> What I can't understand is that even though N N OPEN? takes less than a
> second, when used in DOORS, it is much slower (I'm using the MacPorted
> GForth 0.7.0 on a 1.5GHz Macbook Air). The DOORS iteration slows down to
> a crawl as "X" increases.

Because executing " N N OPEN? " in isolation doesn't behave the same as 
when " N N OPEN? " is encountered when running this program.

consider:

2 doors
   : DOORS                     ( 1 ) \ 2
   1+                          ( 1 ) \ 3
   dup                         ( 2 ) \ 3 \ 3
   1                           ( 3 ) \ 3 \ 3 \ 1
   do                          ( 1 ) \ 3
      i                        ( 2 ) \ 3 \ 1
       : OPEN?                 ( 2 ) \ 3 \ 1
       >R                      ( 1 ) \ 3
        true                   ( 2 ) \ 3 \ -1
        over                   ( 3 ) \ 3 \ -1 \ 3
        2                      ( 4 ) \ 3 \ -1 \ 3 \ 2
        do                     ( 2 ) \ 3 \ -1
           i                   ( 3 ) \ 3 \ -1 \ 2
           j                   ( 4 ) \ 3 \ -1 \ 2 \ 1
           >                   ( 3 ) \ 3 \ -1 \ -1
           if                  ( 2 ) \ 3 \ -1
           leave               ( 2 ) \ 3 \ -1
        R>                     ( 3 ) \ 3 \ -1 \ 1
       drop                    ( 2 ) \ 3 \ -1
       ;                       ( 2 ) \ 3 \ -1
      if                       ( 1 ) \ 3
      i                        ( 2 ) \ 3 \ 1
      . 1                      ( 1 ) \ 3
      then                     ( 1 ) \ 3
      loop                     ( 1 ) \ 3
      i                        ( 2 ) \ 3 \ 2
       : OPEN?                 ( 2 ) \ 3 \ 2
       >R                      ( 1 ) \ 3
        true                   ( 2 ) \ 3 \ -1
        over                   ( 3 ) \ 3 \ -1 \ 3
        2                      ( 4 ) \ 3 \ -1 \ 3 \ 2
        do                     ( 2 ) \ 3 \ -1
           i                   ( 3 ) \ 3 \ -1 \ 2
           j                   ( 4 ) \ 3 \ -1 \ 2 \ 2
           >                   ( 3 ) \ 3 \ -1 \ 0
           if                  ( 2 ) \ 3 \ -1
           j                   ( 3 ) \ 3 \ -1 \ 2
           i                   ( 4 ) \ 3 \ -1 \ 2 \ 2
           mod                 ( 3 ) \ 3 \ -1 \ 0
           0=                  ( 3 ) \ 3 \ -1 \ -1
           if                  ( 2 ) \ 3 \ -1
           invert              ( 2 ) \ 3 \ 0
           then                ( 2 ) \ 3 \ 0
           loop                ( 2 ) \ 3 \ 0
        R>                     ( 3 ) \ 3 \ 0 \ 2
       drop                    ( 2 ) \ 3 \ 0
       ;                       ( 2 ) \ 3 \ 0
      if                       ( 1 ) \ 3
      loop                     ( 1 ) \ 3
   drop                        ( 0 )
   ;  ok


Look above at the stack items when " 3 2 OPEN? " occurs.  Compare that 
to the following:

3 2 open? \ execute in isolation
   : OPEN?                     ( 2 ) \ 3 \ 2
   >R                          ( 1 ) \ 3
    true                       ( 2 ) \ 3 \ -1
    over                       ( 3 ) \ 3 \ -1 \ 3
    2                          ( 4 ) \ 3 \ -1 \ 3 \ 2
    do                         ( 2 ) \ 3 \ -1
       i                       ( 3 ) \ 3 \ -1 \ 2
       j                       ( 4 ) \ 3 \ -1 \ 2 \ 1
       >                       ( 3 ) \ 3 \ -1 \ -1
       if                      ( 2 ) \ 3 \ -1
       leave                   ( 2 ) \ 3 \ -1
    R>                         ( 3 ) \ 3 \ -1 \ 2
   drop                        ( 2 ) \ 3 \ -1
   ;  ok    ( 2 ) \ 3 \ -1

It's different because the prior LEAVE left the value of j at the same 
number ( 2 ), but in isolation j is ( 1 ).

-Doug

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


#8807

FromArnold Doray <invalid@invalid.com>
Date2012-01-11 16:28 +0000
Message-ID<jekdbh$l2$1@dont-email.me>
In reply to#8804
On Wed, 11 Jan 2012 09:50:37 -0500, Doug Hoffman wrote:

> On 1/11/12 1:57 AM, Arnold Doray wrote:
> 
>> \ Is door X open, given N doors?
>> : open? ( N+1 X -- N+1 f )
>>          >R                                      \ save X
>>          true                                    \ door is initially
>>          open over 2 do
>>                  i j>  if leave then             \ early termination?
>>                  j i mod 0= if invert then       \ toggle door
>>
>>          loop R>  drop ;                               \ tidy R stack.
>>
>> \ Prints the open doors in the N door puzzle.
>> : doors ( N -- )
>>          1+ dup 1 do i open? if i . then loop drop ;
>>
>> 1000000000 doors \ Billion doors takes too long, but should work.
>>
>> What I can't understand is that even though N N OPEN? takes less than a
>> second, when used in DOORS, it is much slower (I'm using the MacPorted
>> GForth 0.7.0 on a 1.5GHz Macbook Air). The DOORS iteration slows down
>> to a crawl as "X" increases.
> 
> Because executing " N N OPEN? " in isolation doesn't behave the same as
> when " N N OPEN? " is encountered when running this program.
> 
> consider:
> 
> 2 doors
>    : DOORS                     ( 1 ) \ 2 1+                          ( 1
>    ) \ 3 dup                         ( 2 ) \ 3 \ 3 1                    
>          ( 3 ) \ 3 \ 3 \ 1 do                          ( 1 ) \ 3
>       i                        ( 2 ) \ 3 \ 1
>        : OPEN?                 ( 2 ) \ 3 \ 1
>        >R                      ( 1 ) \ 3
>         true                   ( 2 ) \ 3 \ -1 over                   ( 3
>         ) \ 3 \ -1 \ 3 2                      ( 4 ) \ 3 \ -1 \ 3 \ 2 do 
>                            ( 2 ) \ 3 \ -1
>            i                   ( 3 ) \ 3 \ -1 \ 2 j                   (
>            4 ) \ 3 \ -1 \ 2 \ 1
>            >                   ( 3 ) \ 3 \ -1 \ -1
>            if                  ( 2 ) \ 3 \ -1 leave               ( 2 )
>            \ 3 \ -1
>         R>                     ( 3 ) \ 3 \ -1 \ 1
>        drop                    ( 2 ) \ 3 \ -1 ;                       (
>        2 ) \ 3 \ -1
>       if                       ( 1 ) \ 3 i                        ( 2 )
>       \ 3 \ 1 . 1                      ( 1 ) \ 3 then                   
>        ( 1 ) \ 3 loop                     ( 1 ) \ 3 i                   
>           ( 2 ) \ 3 \ 2
>        : OPEN?                 ( 2 ) \ 3 \ 2
>        >R                      ( 1 ) \ 3
>         true                   ( 2 ) \ 3 \ -1 over                   ( 3
>         ) \ 3 \ -1 \ 3 2                      ( 4 ) \ 3 \ -1 \ 3 \ 2 do 
>                            ( 2 ) \ 3 \ -1
>            i                   ( 3 ) \ 3 \ -1 \ 2 j                   (
>            4 ) \ 3 \ -1 \ 2 \ 2
>            >                   ( 3 ) \ 3 \ -1 \ 0
>            if                  ( 2 ) \ 3 \ -1 j                   ( 3 )
>            \ 3 \ -1 \ 2 i                   ( 4 ) \ 3 \ -1 \ 2 \ 2 mod  
>                          ( 3 ) \ 3 \ -1 \ 0 0=                  ( 3 ) \
>            3 \ -1 \ -1 if                  ( 2 ) \ 3 \ -1 invert        
>                 ( 2 ) \ 3 \ 0 then                ( 2 ) \ 3 \ 0 loop    
>                       ( 2 ) \ 3 \ 0
>         R>                     ( 3 ) \ 3 \ 0 \ 2
>        drop                    ( 2 ) \ 3 \ 0 ;                       ( 2
>        ) \ 3 \ 0
>       if                       ( 1 ) \ 3 loop                     ( 1 )
>       \ 3
>    drop                        ( 0 )
>    ;  ok
> 
> 
> Look above at the stack items when " 3 2 OPEN? " occurs.  Compare that
> to the following:
> 
> 3 2 open? \ execute in isolation
>    : OPEN?                     ( 2 ) \ 3 \ 2
>    >R                          ( 1 ) \ 3
>     true                       ( 2 ) \ 3 \ -1 over                      
>     ( 3 ) \ 3 \ -1 \ 3 2                          ( 4 ) \ 3 \ -1 \ 3 \ 2
>     do                         ( 2 ) \ 3 \ -1
>        i                       ( 3 ) \ 3 \ -1 \ 2 j                     
>         ( 4 ) \ 3 \ -1 \ 2 \ 1
>        >                       ( 3 ) \ 3 \ -1 \ -1
>        if                      ( 2 ) \ 3 \ -1 leave                   (
>        2 ) \ 3 \ -1
>     R>                         ( 3 ) \ 3 \ -1 \ 2
>    drop                        ( 2 ) \ 3 \ -1 ;  ok    ( 2 ) \ 3 \ -1
> 
> It's different because the prior LEAVE left the value of j at the same
> number ( 2 ), but in isolation j is ( 1 ).
> 
> -Doug

I can't get the same trace as you using GForth. It's the same J in 
isolation or in the loop. J is picked up from the previously saved >R in 
both cases. The OPEN? functions correctly in both cases (it should not in 
your trace). 

I was under the impression that the return stack behaved this way:

a) The loop in DOORS puts its counter on the Return stack 
	(1) \ I0 
b) The call to OPEN? puts some junk onto the Return stack 
	(2) \ I0 \ Junk 
c) The >R in OPEN? puts the X onto the Return stack
	(3) \ I0 \ Junk \ X 
d) The loop in OPEN? puts its own counter on the Ret. Stack
	(4) \ I0 \ Junk \ X \ I1

So, I is = I1, while J = X, as expected.  

When OPEN? is called in isolation, then only (c) and (d) apply, so the 
result for J is the same. 

Am I mistaken? Or is this implementation dependent? Should I avoid using 
the return stack with loops? 

Interestingly, saving X to a variable instead of the return stack results 
in OPEN? which is twice as slow.  

Thanks,
Arnold



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


#8018

FromFritz Wuehler <fritz@spamexpire-201112.rodent.frell.theremailer.net>
Date2011-12-12 22:57 +0100
Message-ID<93df27c49aa7d5a25a07cfc64eb640eb@msgid.frell.theremailer.net>
In reply to#7966
> What you say is true from the perspective of embedded systems where 
> every byte and processing cycle is important. However it ignores the 
> fact that to most programmers Forth, even if they have heard of it, is a 
> write-only language - it is so different to other languages that, if 
> unfamiliar to someone, requires far more effort to understand than an 
> unfamiliar conventional language.

That shouldn't make any difference. Many languages are that way, and you're
still obligated by common decency to write idiomatic code, not write
everything like the language you used to use. According to you, how will
anyone learn anything unless it's just like what he first learnt?

> I think that such a person would stand more chance of understanding Doug's
> code than yours as given in another  post - despite the fact that your
> version is good and clear to an experienced Forth programmer. Who knows,
> someone who understood it might then go on to try using Forth.

Oh, so the idea is to water everything down in the name of advocacy? Then
who are you attracting? Visual Basic coders? OTOH if you write good code in
whatever language you write then experienced coders who don't know your
language may learn to do things the right way.

> It seems to be a sad fact that embedded system programmers don't seem to 
> realise that getting the smallest, fastest program isn't that important 
> to those who use run Forth on desktop systems.

I don't think it's embedded v. desktop, because I don't think anyone besides
Elizabeth or Steven can name 10 desktop Forth coders. I think it's people
who use things properly v. people who don't care about anything, and they
excuse their bad behaviour by calling it more readable.

> Of course some applications need the ultimate in speed and size but mostly
> those considerations are irrelevant.

I don't agree. What's more, good code is always needed whilst bad code never
is. 

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


#8356

FromDoug Hoffman <glidedog@gmail.com>
Date2011-12-26 09:30 -0500
Message-ID<4ef884f3$0$287$14726298@news.sunsite.dk>
In reply to#8018
On 12/12/11 4:57 PM, Fritz Wuehler wrote:

> I don't think it's embedded v. desktop, because I don't think anyone besides
> Elizabeth or Steven can name 10 desktop Forth coders.

Use of Forth on the "desktop" is probably a lot more common than you think.


> I think it's people
> who use things properly v. people who don't care about anything, and they
> excuse their bad behaviour by calling it more readable.

We have had bad behavior in this newsgroup.  I don't think anything in 
this thread qualifies as that.

-Doug

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


#7849

FromPaul Rubin <no.email@nospam.invalid>
Date2011-12-08 23:53 -0800
Message-ID<7xobvi6uzs.fsf@ruckus.brouhaha.com>
In reply to#7830
Gerry Jackson <gerry@jackson9000.fsnet.co.uk> writes:
> A lot better but there are still a number of improvements/problems ...

Thanks, the suggestions are informative.

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


#7870

From"Elizabeth D. Rather" <erather@forth.com>
Date2011-12-09 17:46 -1000
Message-ID<gOSdnaP6RepkSH_TnZ2dnUVZ_qadnZ2d@supernews.com>
In reply to#7830
On 12/8/11 4:47 AM, Gerry Jackson wrote:
...
> 100 constant ndoors \ number of doors
> : array ( n -- )
> create cells allot
> does> ( i -- ad ) swap cells + ;
> 100 array doors \ allocate the array
>
> : init ( -- ) 0 doors ndoors cells erase ;
> : pass ( n -- ) \ toggle every nth door in the array.
> dup 1+ ndoors rot do 1 i doors +! dup +loop drop ;
> : run ( -- ) ndoors 0 do i pass loop ;
> : display ( -- ) ndoors 0 do i doors @ 1 and if i 1+ . then loop cr ;
>
> init run display \ bye
>
> Better or clearer - I don't know - opinions will differ.

Pretty good, but it could be faster (since we're proving that you don't 
have to be unreadable to be fast).

How's this:

: toggle ( caddr -- ) \ Toggle the byte at caddr
    dup c@ 1 xor swap c! ;  \ Many systems already have this.

100 constant ndoors
create doors ndoors allot

: init ( -- )   doors ndoors erase ;

: pass ( n -- )   \ toggle every nth door in the array.
    dup ndoors 1+ rot do
       doors i + toggle dup
    ( n ) +loop drop ;

: run ( -- )   ndoors 1+ 1 do  i pass  loop ;
: display ( -- )   ndoors 1+ 1 do  doors i + c@ if  i . then  loop cr ;


Notes:
1. I used bytes, instead of cells, since we're only using one bit.
2. I moved the 1+ outside the loop.
3. I tried it with a CREATE ... DOES> automatically indexing array, but 
it was slower.

This does 1000 iterations in 80 ms on my Macbook Pro with SwiftForth, 
compared with 82 ms for the "Factored" version at the OP's link (which 
is faster than the "Unfactored" example), and I think it's a lot clearer.

Cheers,
Elizabeth

-- 
==================================================
Elizabeth D. Rather   (US & Canada)   800-55-FORTH
FORTH Inc.                         +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com

"Forth-based products and Services for real-time
applications since 1973."
==================================================

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


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

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


csiph-web