Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #60556 > unrolled thread
| Started by | christopherdumas@gmail.com |
|---|---|
| First post | 2017-06-10 07:15 -0700 |
| Last post | 2017-06-10 15:50 -0700 |
| Articles | 20 on this page of 42 — 16 participants |
Back to article view | Back to comp.lang.forth
Starting Forth christopherdumas@gmail.com - 2017-06-10 07:15 -0700
Re: Starting Forth christopherdumas@gmail.com - 2017-06-10 07:19 -0700
Re: Starting Forth Melzzzzz <Melzzzzz@zzzzz.com> - 2017-06-10 14:35 +0000
Re: Starting Forth christopherdumas@gmail.com - 2017-06-10 07:43 -0700
Re: Starting Forth rickman <gnuarm@gmail.com> - 2017-06-11 12:44 -0400
Re: Starting Forth christopherdumas@gmail.com - 2017-06-11 20:44 -0700
Re: Starting Forth gavino himself <jackvanc3@gmail.com> - 2017-06-12 12:52 -0700
Re: Starting Forth new@to.forth - 2017-06-10 15:19 +0000
Re: Starting Forth christopherdumas@gmail.com - 2017-06-10 08:27 -0700
Re: Starting Forth christopherdumas@gmail.com - 2017-06-10 08:29 -0700
Re: Starting Forth hughaguilar96@gmail.com - 2017-06-10 15:34 -0700
Re: Starting Forth christopherdumas@gmail.com - 2017-06-10 15:56 -0700
Re: Starting Forth christopherdumas@gmail.com - 2017-06-10 15:57 -0700
Re: Starting Forth rickman <gnuarm@gmail.com> - 2017-06-15 11:52 -0400
Re: Starting Forth new@to.forth - 2017-06-10 21:38 +0000
Re: Starting Forth christopherdumas@gmail.com - 2017-06-10 15:53 -0700
Re: Starting Forth NN <november.nihal@gmail.com> - 2017-06-12 05:36 -0700
Re: Starting Forth christopherdumas@gmail.com - 2017-06-12 07:02 -0700
Re: Starting Forth Julian Fondren <julian.fondren@gmail.com> - 2017-06-12 08:29 -0700
Factor (was: Starting Forth) anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2017-06-12 16:16 +0000
Re: Factor (was: Starting Forth) hughaguilar96@gmail.com - 2017-06-12 10:26 -0700
Re: Factor (was: Starting Forth) NN <november.nihal@gmail.com> - 2017-06-12 11:25 -0700
Re: Factor (was: Starting Forth) hughaguilar96@gmail.com - 2017-06-12 17:16 -0700
Re: Factor (was: Starting Forth) gavino himself <jackvanc3@gmail.com> - 2017-06-12 13:05 -0700
Re: Factor (was: Starting Forth) mhx@iae.nl - 2017-06-12 11:08 -0700
Re: Factor (was: Starting Forth) anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2017-06-13 16:31 +0000
Re: Starting Forth christopherdumas@gmail.com - 2017-06-14 07:49 -0700
Re: Starting Forth Andrew Haley <andrew29@littlepinkcloud.invalid> - 2017-06-14 11:50 -0500
Re: Starting Forth hughaguilar96@gmail.com - 2017-06-14 21:18 -0700
Re: Starting Forth Cecil Bayona <cbayona@cbayona.com> - 2017-06-14 10:02 -0500
Re: Starting Forth Julian Fondren <julian.fondren@gmail.com> - 2017-06-14 08:49 -0700
Re: Starting Forth stephen@mpeforth.com (Stephen Pelc) - 2017-06-14 16:45 +0000
Re: Starting Forth Mark Wills <markwills1970@gmail.com> - 2017-06-14 09:05 -0700
Re: Starting Forth Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2017-06-14 19:05 +0100
Re: Starting Forth hughaguilar96@gmail.com - 2017-06-14 21:43 -0700
Re: Starting Forth Julian Fondren <julian.fondren@gmail.com> - 2017-06-14 22:03 -0700
Re: Starting Forth Gerry Jackson <gerry@jackson9000.fsnet.co.uk> - 2017-06-15 21:50 +0100
Re: Starting Forth foxaudioresearch@gmail.com - 2017-06-10 09:22 -0700
Re: Starting Forth foxaudioresearch@gmail.com - 2017-06-10 09:40 -0700
Re: Starting Forth Cecil Bayona <cbayona@cbayona.com> - 2017-06-10 12:21 -0500
Re: Starting Forth Julian Fondren <julian.fondren@gmail.com> - 2017-06-10 14:30 -0700
Re: Starting Forth christopherdumas@gmail.com - 2017-06-10 15:50 -0700
Page 1 of 3 [1] 2 3 Next page →
| From | christopherdumas@gmail.com |
|---|---|
| Date | 2017-06-10 07:15 -0700 |
| Subject | Starting Forth |
| Message-ID | <190cd076-acbb-495e-8cac-4f7ba47680be@googlegroups.com> |
Hi forthers. So I want to check out Forth for the first time, and I'm not exactly sure what implementation would be the best to use, and where I should start. I've found the GForth Manual, Starting Forth and Thinking Forth. So at least that's a start. I've also installed GForth on my Macbook through Homebrew. My question is, should I try colorForth instead? It looks awesome but I can't seem to find an ISO (or something) to run in QEMU or Bochs. Or maybe I should stick with GForth? I've heard its massively bloated compared to other Forths, though, and since I'm a Scheme fan I'd prefer a tiny language. Or should I start with Factor? I've heard its similar, but with a dev environment/IDE all its own. Do you guys have any advice? Thank you!
[toc] | [next] | [standalone]
| From | christopherdumas@gmail.com |
|---|---|
| Date | 2017-06-10 07:19 -0700 |
| Message-ID | <07259c1b-2b1c-4b67-a767-b05782f2151c@googlegroups.com> |
| In reply to | #60556 |
On Saturday, June 10, 2017 at 7:15:29 AM UTC-7, christop...@gmail.com wrote: > Hi forthers. So I want to check out Forth for the first time, and I'm not exactly sure what implementation would be the best to use, and where I should start. I've found the GForth Manual, Starting Forth and Thinking Forth. So at least that's a start. I've also installed GForth on my Macbook through Homebrew. My question is, should I try colorForth instead? It looks awesome but I can't seem to find an ISO (or something) to run in QEMU or Bochs. Or maybe I should stick with GForth? I've heard its massively bloated compared to other Forths, though, and since I'm a Scheme fan I'd prefer a tiny language. Or should I start with Factor? I've heard its similar, but with a dev environment/IDE all its own. Do you guys have any advice? Thank you! If knowing my programming background would help, I'm most comfortable programming in Scheme and Javascript, with C and C++ coming after that, and Ruby and Python after that. I prefer to program functionally in most programming languages if allowed, but if another paradigm is more idiomatic (like OO in Ruby) I always make sure learn to use that paradigm.
[toc] | [prev] | [next] | [standalone]
| From | Melzzzzz <Melzzzzz@zzzzz.com> |
|---|---|
| Date | 2017-06-10 14:35 +0000 |
| Message-ID | <ohh02o$oeh$4@news.albasani.net> |
| In reply to | #60556 |
On 2017-06-10, christopherdumas@gmail.com <christopherdumas@gmail.com> wrote: > Hi forthers. So I want to check out Forth for the first time, and I'm > not exactly sure what implementation would be the best to use, and > where I should start. I've found the GForth Manual, Starting Forth and > Thinking Forth. So at least that's a start. I've also installed GForth > on my Macbook through Homebrew. My question is, should I try > colorForth instead? It looks awesome but I can't seem to find an ISO > (or something) to run in QEMU or Bochs. Or maybe I should stick with > GForth? I've heard its massively bloated compared to other Forths, > though, and since I'm a Scheme fan I'd prefer a tiny language. Or > should I start with Factor? I've heard its similar, but with a dev > environment/IDE all its own. Do you guys have any advice? Thank you! Scheme is huge bloatware in comparison to any Forth. So don' t let that criteria leads you in choice. -- press any key to continue or any other to quit...
[toc] | [prev] | [next] | [standalone]
| From | christopherdumas@gmail.com |
|---|---|
| Date | 2017-06-10 07:43 -0700 |
| Message-ID | <5f966aba-d3c1-4602-94ab-57b2c148a2ce@googlegroups.com> |
| In reply to | #60558 |
Based on size, yes, but not based on numbers of built-in operations for R5RS Scheme. All I'm really looking for is something that won't overwhelm me with stuff I have to memorize or look in the manual for. It doesn't really matter that much, though. I'm just not sure which of the 2.127 million versions of Forth I should use. (:
[toc] | [prev] | [next] | [standalone]
| From | rickman <gnuarm@gmail.com> |
|---|---|
| Date | 2017-06-11 12:44 -0400 |
| Message-ID | <ohjrqp$f4b$1@dont-email.me> |
| In reply to | #60559 |
christopherdumas@gmail.com wrote on 6/10/2017 10:43 AM: > Based on size, yes, but not based on numbers of built-in operations for R5RS Scheme. All I'm really looking for is something that won't overwhelm me with stuff I have to memorize or look in the manual for. It doesn't really matter that much, though. I'm just not sure which of the 2.127 million versions of Forth I should use. (: If you don't want to have to memorize or read the manual, I think you are out of luck with Forth. Most of the learning consists of finding and using appropriate words for your project. Once you come up to speed on the words you need (as least the N most common ones) you can do most of your work with less frequent dictionary searching. But Forth is *all about* learning the not so common words and ways that make it so unique. For example, input and output use about a dozen words, but they are not at all like the functions of other languages. Math has some dozen or two, but again, not much in common with other languages (consider how extended precision intermediates and modulo arithmetic is handled). Lather, rinse, repeat with other areas of Forth. In fact, the book Starting Forth presents much of this with an organization based around the functional groupings of the dictionary. If you learn everything presented in that book, you get a very good start. But you will still need to refer to the standard document to find new words that help you do your jobs more effectively. -- Rick C
[toc] | [prev] | [next] | [standalone]
| From | christopherdumas@gmail.com |
|---|---|
| Date | 2017-06-11 20:44 -0700 |
| Message-ID | <17b77041-4c11-44ae-8c40-e6b095628ea3@googlegroups.com> |
| In reply to | #60615 |
I'm apologise if this seems contradictory to what I said earlier, or if my earlier statements were unclear (I'm not a good spur-of-the-moment writer), but I don't mind memorizing words/commands AT ALL. What I'm trying to avoid is a weird, bloated language like C++ or CLISP that has tons of exceptions and sub-languages, etc. Anyway, I've adopted GForth and absolutely LOVING it.
[toc] | [prev] | [next] | [standalone]
| From | gavino himself <jackvanc3@gmail.com> |
|---|---|
| Date | 2017-06-12 12:52 -0700 |
| Message-ID | <a118047a-2923-44b9-b50b-f901622855c2@googlegroups.com> |
| In reply to | #60558 |
On Saturday, June 10, 2017 at 10:35:06 AM UTC-4, Melzzzzz wrote: > On 2017-06-10, christopherdumas@gmail.com <christopherdumas@gmail.com> wrote: > > Hi forthers. So I want to check out Forth for the first time, and I'm > > not exactly sure what implementation would be the best to use, and > > where I should start. I've found the GForth Manual, Starting Forth and > > Thinking Forth. So at least that's a start. I've also installed GForth > > on my Macbook through Homebrew. My question is, should I try > > colorForth instead? It looks awesome but I can't seem to find an ISO > > (or something) to run in QEMU or Bochs. Or maybe I should stick with > > GForth? I've heard its massively bloated compared to other Forths, > > though, and since I'm a Scheme fan I'd prefer a tiny language. Or > > should I start with Factor? I've heard its similar, but with a dev > > environment/IDE all its own. Do you guys have any advice? Thank you! > Scheme is huge bloatware in comparison to any Forth. So don' t let that > criteria leads you in choice. > > -- > press any key to continue or any other to quit... awesome!!!
[toc] | [prev] | [next] | [standalone]
| From | new@to.forth |
|---|---|
| Date | 2017-06-10 15:19 +0000 |
| Message-ID | <ohh2mm$jeu$1@gioia.aioe.org> |
| In reply to | #60556 |
> Hi forthers. So I want to check out Forth for the first time, and > I'm not e xactly sure what implementation would be the best to > use, and where I shoul d start. I've found the GForth Manual, > Starting Forth and Thinking Forth. S o at least that's a start. > I've also installed GForth on my Macbook through Homebrew. My > question is, should I try colorForth instead? It looks awesom e > but I can't seem to find an ISO (or something) to run in QEMU or > Bochs. O r maybe I should stick with GForth? I've heard its > massively bloated compar ed to other Forths, though, and since > I'm a Scheme fan I'd prefer a tiny la nguage. Or should I start > with Factor? I've heard its similar, but with a d ev environment/IDE > all its own. Do you guys have any advice? Thank you! I'm at a similar place WRT learning Forth. I'm mostly using Starting Forth as a text but, as has been pointed out by others here, the book contains some dated materials. Pretty much you can skip the block-files section; would only be useful now on systems without an operation system. Also the information on the return stack is missleading, at least in the earlier versions of the book. Other than that Starting Forth is pretty good in my opinion. As for Forths, I'm mostly using gforth as it's available for most systems without a bunch of dependencies and it's a modern Forth. It even runs on Android so you can do Forth instead of listening in those manditory office meetings. ;) Other Forths I'm using are pforth and ff, but both of those are more tempermental and missing some common Forth words, ie. ff doesn't have LEAVE even though it's a core word. Some other free resources I've found helpful: http://forth-standard.org/ http://field-theory.org/articles/starting-forth/index.html http://galileo.phys.virginia.edu/classes/551.jvn.fall01/primer.htm http://www.mpeforth.com/arena/ProgramForth.pdf
[toc] | [prev] | [next] | [standalone]
| From | christopherdumas@gmail.com |
|---|---|
| Date | 2017-06-10 08:27 -0700 |
| Message-ID | <6dd217bf-ba96-4359-8d89-5eb584a9b1ea@googlegroups.com> |
| In reply to | #60561 |
On Saturday, June 10, 2017 at 8:19:54 AM UTC-7, n...@to.forth wrote: > > Hi forthers. So I want to check out Forth for the first time, and > > I'm not e xactly sure what implementation would be the best to > > use, and where I shoul d start. I've found the GForth Manual, > > Starting Forth and Thinking Forth. S o at least that's a start. > > I've also installed GForth on my Macbook through Homebrew. My > > question is, should I try colorForth instead? It looks awesom e > > but I can't seem to find an ISO (or something) to run in QEMU or > > Bochs. O r maybe I should stick with GForth? I've heard its > > massively bloated compar ed to other Forths, though, and since > > I'm a Scheme fan I'd prefer a tiny la nguage. Or should I start > > with Factor? I've heard its similar, but with a d ev environment/IDE > > all its own. Do you guys have any advice? Thank you! > > I'm at a similar place WRT learning Forth. I'm mostly using Starting > Forth as a text but, as has been pointed out by others here, the book > contains some dated materials. Pretty much you can skip the block-files > section; would only be useful now on systems without an operation system. > Also the information on the return stack is missleading, at least in the > earlier versions of the book. Other than that Starting Forth is pretty > good in my opinion. > > As for Forths, I'm mostly using gforth as it's available for most systems > without a bunch of dependencies and it's a modern Forth. It even runs on > Android so you can do Forth instead of listening in those manditory office > meetings. ;) Other Forths I'm using are pforth and ff, but both of those > are more tempermental and missing some common Forth words, ie. ff doesn't > have LEAVE even though it's a core word. > > Some other free resources I've found helpful: > > http://forth-standard.org/ > http://field-theory.org/articles/starting-forth/index.html > http://galileo.phys.virginia.edu/classes/551.jvn.fall01/primer.htm > http://www.mpeforth.com/arena/ProgramForth.pdf What are your opinions on Factor (factorcode.org)?
[toc] | [prev] | [next] | [standalone]
| From | christopherdumas@gmail.com |
|---|---|
| Date | 2017-06-10 08:29 -0700 |
| Message-ID | <cd446d89-db37-4a4c-8dce-f89f8e0739df@googlegroups.com> |
| In reply to | #60562 |
On Saturday, June 10, 2017 at 8:27:59 AM UTC-7, christop...@gmail.com wrote: > On Saturday, June 10, 2017 at 8:19:54 AM UTC-7, n...@to.forth wrote: > > > Hi forthers. So I want to check out Forth for the first time, and > > > I'm not e xactly sure what implementation would be the best to > > > use, and where I shoul d start. I've found the GForth Manual, > > > Starting Forth and Thinking Forth. S o at least that's a start. > > > I've also installed GForth on my Macbook through Homebrew. My > > > question is, should I try colorForth instead? It looks awesom e > > > but I can't seem to find an ISO (or something) to run in QEMU or > > > Bochs. O r maybe I should stick with GForth? I've heard its > > > massively bloated compar ed to other Forths, though, and since > > > I'm a Scheme fan I'd prefer a tiny la nguage. Or should I start > > > with Factor? I've heard its similar, but with a d ev environment/IDE > > > all its own. Do you guys have any advice? Thank you! > > > > I'm at a similar place WRT learning Forth. I'm mostly using Starting > > Forth as a text but, as has been pointed out by others here, the book > > contains some dated materials. Pretty much you can skip the block-files > > section; would only be useful now on systems without an operation system. > > Also the information on the return stack is missleading, at least in the > > earlier versions of the book. Other than that Starting Forth is pretty > > good in my opinion. > > > > As for Forths, I'm mostly using gforth as it's available for most systems > > without a bunch of dependencies and it's a modern Forth. It even runs on > > Android so you can do Forth instead of listening in those manditory office > > meetings. ;) Other Forths I'm using are pforth and ff, but both of those > > are more tempermental and missing some common Forth words, ie. ff doesn't > > have LEAVE even though it's a core word. > > > > Some other free resources I've found helpful: > > > > http://forth-standard.org/ > > http://field-theory.org/articles/starting-forth/index.html > > http://galileo.phys.virginia.edu/classes/551.jvn.fall01/primer.htm > > http://www.mpeforth.com/arena/ProgramForth.pdf > > What are your opinions on Factor (factorcode.org)? Also, on a side note, I'm looking for some kind of graphics library for GForth. Can anyone help me there? I've heard that Forth was/is good for game programming. In addition, my favorite way to learn a programming language is writing a game in it.
[toc] | [prev] | [next] | [standalone]
| From | hughaguilar96@gmail.com |
|---|---|
| Date | 2017-06-10 15:34 -0700 |
| Message-ID | <5ad8ddc0-52b1-4cc4-b85e-0457685b691e@googlegroups.com> |
| In reply to | #60563 |
On Saturday, June 10, 2017 at 8:29:37 AM UTC-7, christop...@gmail.com wrote:
> On Saturday, June 10, 2017 at 8:27:59 AM UTC-7, christop...@gmail.com wrote:
> > What are your opinions on Factor (factorcode.org)?
I programmed in Factor a little bit, but then went back to Forth.
Factor is a dynamic-OOP language derived from Lisp, so it has tagged data. OForth also has tagged data. Both languages are good for desktop-computer programming.
I'm more into Forth because my interest is in micro-controllers.
> Also, on a side note, I'm looking for some kind of graphics library for GForth. Can anyone help me there? I've heard that Forth was/is good for game programming. In addition, my favorite way to learn a programming language is writing a game in it.
Another novice recently said the same thing, that he wanted to program a game in Forth to learn.
https://groups.google.com/forum/#!topic/comp.lang.forth/N5B1AbXqPfQ%5B1-25%5D
ANS-Forth doesn't work for games because TICKS was banned by the ANS-Forth committee. This was done presumably for the purpose of preventing common Forthers from writing games in competition with the ANS-Forth committee members.
VFX does have TICKS though, which is non-standard. Unfortunately, VFX has a bug in AT-XY that is a standard word.
I wrote a small demo game. This requires VFX because it needs TICKS available. It is playable, but because of the bug in AT-XY it scrolls off the top of the screen and you see two images of your game on the screen, which is pretty weird.
My game requires the novice-package, and it will be included in the next release of the novice-package along with my other example programs.
This is the game:
---------------------------------------------------------------------------
\ ARENA.4TH --- derived from tiny-arena01.fs by Darin Murphy --- needs NOVICE.4TH and LIST.4TH included.
\ This file is a framework that can be used in any char-based game.
\ Put your game in another file.
\ We need to have TICKS defined, which is not ANS-Forth and can't be written in ANS-Forth.
marker arena.4th
VFX? 0= [if]
!!! TICKS is needed!
: ticks ( -- ms ) \ current time in milliseconds
...
;
[then]
\ ******
\ ****** This contains SCREEN which is the array representing the screen.
\ ******
0 \ kinds of elements in the game
enum empty
enum wall \ II
enum ball \ {} \ this could be a ball, such as in BreakOut
enum eyes \ oo \ this could represent the player
enum wide-eyes \ OO \ this could represent the player under duress
enum mouth \ <> \ this could represent a monster
enum horz-bar \ == \ this could represent a bar in a BreakOut game
enum brick \ ## \ this could represent a brick in a BreakOut game
enum treasure \ $$ \ this could represent a bag of money
enum vert-bar \ [] \ this could represent a bar in a Pong game
enum down-spike \ \/ \ this could fall from the top of the screen
enum up-spike \ /\ \ this could shoot up from the bottom of the screen
constant kind-limit
\ We need to have EMPTY and WALL --- the others can be changed --- more can be added if needed.
\ Make sure that LEFT-SYMBOLS and RITE-SYMBOLS are updated too.
\ The suggestions above for what the elements represent will vary from game to game.
\ For example, DOWN-SPIKE and UP-SPIKE could be food that the player needs to consume.
\ The elements are two characters wide (they have a left and a right part).
\ The typical screen width is somewhat over twice the height, so we want wide elements.
\ Otherwise the screen would appear to be stretched out horizontally.
create left-symbols \ must correspond to elements
bl c, \ empty
char I c, \ wall
char { c, \ ball
char o c, \ eyes
char O c, \ wide-eyes
char < c, \ mouth
char [ c, \ horz-bar
char # c, \ brick
char $ c, \ treasure
char = c, \ vert-bar
char \ c, \ down-spike
char / c, \ up-spike
create rite-symbols \ must correspond to elements
bl c, \ empty
char I c, \ wall
char } c, \ ball
char o c, \ eyes
char O c, \ wide-eyes
char > c, \ mouth
char ] c, \ horz-bar
char # c, \ brick
char $ c, \ treasure
char = c, \ vert-bar
char / c, \ down-spike
char \ c, \ up-spike
: check-element ( element -- element )
dup 0< abort" *** SYMBOL given negative element ***"
dup kind-limit >= abort" *** SYMBOL given too large element ***"
;
: symbol ( element -- rite-char left-char )
check-element
dup rite-symbols + c@
swap left-symbols + c@ ;
35 constant horz \ horizontal size of screen \ half of display screen
25 constant vert \ vertical size of screen
\ HORZ is half of the display screen because the elements are two chars wide.
\ HORZ should not be the full screen because the CR in <DISPLAY-SCREEN> would be redundant.
\ HORZ is less than the full screen so there is a margin on the right edge for data (score, clock, etc.).
horz 2 / constant cx
vert 2 / constant cy \ CX and CY are the center of the screen
c 0 horz vert ary screen \ 0 0 is the upper-left corner
-1 constant up
1 constant down
-1 constant left
1 constant rite
\ It is traditional in games that 0 0 is the upper-left corner, not the lower-left corner like in Cartesian coordinates.
\ UP and DOWN would seem to be backwards for somebody who is assuming the first quadrant in Cartesian coordinates.
: traverse-screen { 'element -- } \ 'ELEMENT ( col col-adr -- )
vert 0 do
<screen I -> \ -- row-adr
horz 0 do
I \ -- row-adr col
over I screen> \ -- row-adr col col-adr
'element execute \ -- row-adr
loop
drop \ --
loop ;
: <clear-screen> ( col col-adr -- )
empty swap c!
drop ;
: clear-screen ( -- ) \ fills SCREEN with EMPTY SYMBOL
['] <clear-screen> traverse-screen ;
: <display-screen> ( col col-adr -- )
c@ symbol emit emit \ -- col
horz 1- = if cr then
;
: display-screen ( -- ) \ displays SCREEN on the display screen
0 0 at-xy \ AT-XY doesn't work in VFX --- but PAGE results in too much blinking
['] <display-screen> traverse-screen ;
\ ******
\ ****** This contains ERASE-BOX and DRAW-BOX for drawing obstacles.
\ ******
: <draw-box> { width height lx uy kind | rx dy -- } \ KIND is typically WALL or EMPTY
lx width + 1 - to rx \ RX is right-X, LX is left-X
uy height + 1- to dy \ UY is upper-Y, DY is lower-Y
rx lx ?do
kind I uy screen c! \ up edge
kind I dy screen c! \ down edge
loop
dy uy ?do
kind lx I screen c! \ left edge
kind rx I screen c! \ right edge
loop
kind rx dy screen c! ; \ left-down corner was not done in the loops above
: erase-box ( width height lx uy -- ) \ LX UY is the upper-left corner
empty <draw-box> ;
: draw-box ( width height lx uy -- ) \ LX UY is the upper-left corner
wall <draw-box> ;
\ DRAW-BOX is typically done during initialization, so it doesn't have to be efficient.
\ The assumption is that boxes don't move around during the game.
\ If they do move, use ERASE-BOX to get rid of the old box, then DRAW-BOX to install the new box.
\ ******
\ ****** This contains PLAY-GAME that executes the user's code peiodically and exits on ESC.
\ ******
300 value cycle \ how many milliseconds per cycle
variable cycles \ how many full cycles have passed \ this needs to be initialized to 0
27 constant <esc> \ the ascii for the ESC key
: elapsed ( start-time -- time )
ticks swap - ;
: cycled? ( start-time -- flag )
elapsed cycle > ;
: cursor-beyond ( -- )
horz vert at-xy cr ;
: play-game ( 'cycle -- ) \ 'CYCLE ( char|false -- str|false )
ticks false \ -- 'cycle start-time char|false
begin dup <esc> <> while
rover execute \ -- 'cycle start-time str|false
display-screen \ -- 'cycle start-time str|false
?dup if
cursor-beyond count type
2drop exit then
dup cycled? abort" *** the 'CYCLE code took too long ***"
begin dup cycled? until
1 cycles +!
cycle + \ -- 'cycle new-start-time
key? if key else false then \ -- 'cycle new-start-time char|false
repeat
cursor-beyond ." ESCAPE"
3drop ;
\ PLAY-GAME calls 'CYCLE every CYCLE milliseconds giving it the most recent keypress.
\ PLAY-GAME exits if the ESC key is pressed, so ESC can't be part of the game user-interface.
\ If the key is held down, there is a delay, then it begins to repeat --- this is very clumsy.
\ It is best for the player to just tap the key rather than hold it down.
\ The direction indicated by the key will continue to be in effect until another key is tapped.
\ ******
\ ****** This contains OBJECT and some support code.
\ ******
list \ these are objects in the game, other than WALL or EMPTY
w field .kind \ kind of element displayed
w field .x
w field .y \ coordinates of location
w field .dx
w field .dy \ offset to move
constant object
\ An offset is one of: -1 0 1
: init-object ( x y kind node -- node )
init-list >r
r@ .kind !
r@ .y !
r@ .x !
0 r@ .dy !
0 r@ .dx !
r> ;
: new-object ( x y kind -- node )
object alloc
init-object ;
: kill-object ( node -- )
dealloc ;
: draw-object { node -- }
node .kind @
node .x @ node .y @ screen c! ;
: erase-object { node -- }
empty
node .x @ node .y @ screen c! ;
: collision? { nodeA nodeB -- flag }
nodeA .x @ nodeB .x @ <> if false exit then
nodeA .y @ nodeB .y @ <> if false exit then
true ;
\ ******
\ ****** This contains SEEK and MOVE-OBJECT and some support code.
\ ******
300 value severe \ how many full cycles pass before the monsters totally zero in on the player
\ if CYCLE is 100 then a SEVERE of 1000 would be 10 seconds
: tweak-offset ( offset -- new-offset ) \ randomly tweaks the offset
cycles @ severe bias < if
?dup if negate
else 1 rnd 2 * 1 - then
then ;
: seek { monster goal -- } \ sets the .DX .DY offsets for the monster
goal .x @ monster .x @ - sgn tweak-offset monster .dx !
goal .y @ monster .y @ - sgn tweak-offset monster .dy ! ;
\ When CYCLES is low (early in the game) the chance of it being < the RND value is high, so the monster changes direction.
\ As the game progresses, the chance decreases, so the monster is increasingly likely to stay aimed at the player.
\ When CYCLES reaches SEVERE the chance is zero, so the monster is totally focused on the player.
\ When changing direction, if the direction is -1 or 1 then the direction becomes opposite.
\ If the direction is zero then we randomly choose -1 or 1 as the new direction.
\ We need INIT-SEED called in the initialization, because TWEAK-OFFSET uses RND above.
: move-object { node -- } \ needs .DX .DY set, adjusts .X .Y \ doesn't move into WALL
node .x @ node .dx @ + \ -- x
node .y @ node .dy @ + \ -- x y
2dup screen c@ wall = if
2drop \ leave object unmoved if there is a WALL in front of it
else
node .y ! node .x ! \ move object, possibly running into another object
then ;
\ ******
\ ****** This is a small example game --- it is kept simple for educational purposes.
\ ****** The player has to run over all the treasures before the monsters run over him.
\ ****** The player is displayed eyes oo early in the game, then becomes wide-eyes OO as the monsters' aggression increases
\ ****** The monsters are mouths <> and the treasures are money-bags: $$
\ ****** Initially the monsters are biased to moving away from the player, but increasingly
\ ****** become biased to moving toward the player. At SEVERE full cycles they totally go after the player.
\ ****** Anybody writing a game should put it in another file, unless it is a direct upgrade of this game.
\ ******
variable treasures \ list of treasures
variable monsters \ list of monsters
variable player \ the player
: <guide-player> ( dx dy -- ) \ sets the .DX .DY offsets for the player
player @ .dy !
player @ .dx ! ;
<switch \ PLAY-GAME also uses the <ESC> key to escape
:noname drop 1 0 <guide-player> ; char l swof \ right
:noname drop -1 0 <guide-player> ; char k swof \ left
:noname drop 0 -1 <guide-player> ; char q swof \ up
:noname drop 0 1 <guide-player> ; char a swof \ down
:noname drop ; fast-switch> guide-player ( char|false -- )
: init-obstacles ( -- ) \ assumes CLEAR-SCREEN already done
horz vert 0 0 draw-box \ border
1 7 cx 2 - cy 3 - draw-box \ left rail
1 7 cx 2 + cy 3 - draw-box \ right rail
4 7 cx 11 - cy 7 - draw-box \ left box
4 7 cx 8 + cy 1 + draw-box \ right box
;
: init-treasures ( -- node )
0
cx cy treasure new-object link \ center treasure
cx 5 - cy 3 - treasure new-object link \ left treasure
cx 5 + cy 3 + treasure new-object link \ right treasure
;
: init-monsters ( -- node )
0
cx 5 - cy 7 - mouth new-object link \ upper-left monster
cx 5 - cy 7 + mouth new-object link \ upper-right monster
cx 5 - cy 3 + mouth new-object link \ middle-left monster
cx 5 + cy 3 - mouth new-object link \ middle-right monster
cx 5 + cy 7 - mouth new-object link \ lower-left monster
cx 5 + cy 7 + mouth new-object link \ lower-right monster
;
: init-player ( -- node )
1 1 eyes new-object ;
: init-game ( -- )
page
1 seed ! \ init-seed
0 cycles !
clear-screen
init-obstacles
init-treasures dup treasures ! ['] draw-object each
init-monsters dup monsters ! ['] draw-object each
init-player dup player ! draw-object
display-screen ;
: maybe-remove-treasure { node -- } \ NODE must be in the TREASURES list
node player @ collision? if
treasures @ node remove \ -- new-head node
dup erase-object kill-object \ -- new-head node
treasures ! then ;
: taken-all-treasure? ( -- flag )
treasures @ ['] maybe-remove-treasure each
treasures @ 0= ;
: <eaten-by-monster?> ( flag node -- new-flag ) \ NODE must be in the MONSTERS list
player @ collision? or ;
: eaten-by-monster? ( -- flag )
false
monsters @ ['] <eaten-by-monster?> each ;
: guide-monster ( node -- ) \ sets the .DX .DY offsets for the monster
player @ seek ;
: erase-movers ( -- ) \ the monsters and the player can move
monsters @ ['] erase-object each
player @ erase-object
;
: move-monsters ( -- )
monsters @ ['] guide-monster each
monsters @ ['] move-object each \ monsters can run into each other and occupy the same space
;
: move-player ( char|false -- )
guide-player
player @ move-object
;
: draw-all ( -- ) \ treasures, monsters and the player
treasures @ ['] draw-object each \ treasures first so a monster can overwrite it
monsters @ ['] draw-object each
player @ draw-object
;
\ DRAW-ALL redraws the treasures in case a monster over-wrote it previously.
\ The treasures are drawn first, so if a monster is there the monster will over-write it in the display.
: <main> ( char|false -- str|false )
cycles @ severe 4 / >= if \ the monsters are becoming increasingly aggressive
wide-eyes player @ .kind ! then
erase-movers \ -- char|false
move-monsters \ -- char|false
move-player \ --
draw-all \ --
taken-all-treasure? if c" WIN! :-D " exit then
eaten-by-monster? if c" LOSE :-( " exit then
false ;
\ Monsters can run into other monsters or the treasure and occupy the same space.
\ If a monster is on top of a treasure, the monster is displayed (because monsters are drawn after treasures).
\ Neither monsters nor the player can occupy the same space as a wall.
: main ( -- )
init-game
begin key? until \ don't begin game until player presses a key
['] <main> play-game
treasures @ ['] kill-object each
monsters @ ['] kill-object each
player @ kill-object ;
[toc] | [prev] | [next] | [standalone]
| From | christopherdumas@gmail.com |
|---|---|
| Date | 2017-06-10 15:56 -0700 |
| Message-ID | <2ccde611-7eb6-4b6b-a3cf-6b845f9e500a@googlegroups.com> |
| In reply to | #60584 |
On Saturday, June 10, 2017 at 3:34:38 PM UTC-7, hughag...@gmail.com wrote:
> On Saturday, June 10, 2017 at 8:29:37 AM UTC-7, christop...@gmail.com wrote:
> > On Saturday, June 10, 2017 at 8:27:59 AM UTC-7, christop...@gmail.com wrote:
> > > What are your opinions on Factor (factorcode.org)?
>
> I programmed in Factor a little bit, but then went back to Forth.
>
> Factor is a dynamic-OOP language derived from Lisp, so it has tagged data. OForth also has tagged data. Both languages are good for desktop-computer programming.
>
> I'm more into Forth because my interest is in micro-controllers.
>
> > Also, on a side note, I'm looking for some kind of graphics library for GForth. Can anyone help me there? I've heard that Forth was/is good for game programming. In addition, my favorite way to learn a programming language is writing a game in it.
>
> Another novice recently said the same thing, that he wanted to program a game in Forth to learn.
> https://groups.google.com/forum/#!topic/comp.lang.forth/N5B1AbXqPfQ%5B1-25%5D
>
> ANS-Forth doesn't work for games because TICKS was banned by the ANS-Forth committee. This was done presumably for the purpose of preventing common Forthers from writing games in competition with the ANS-Forth committee members.
>
> VFX does have TICKS though, which is non-standard. Unfortunately, VFX has a bug in AT-XY that is a standard word.
>
> I wrote a small demo game. This requires VFX because it needs TICKS available. It is playable, but because of the bug in AT-XY it scrolls off the top of the screen and you see two images of your game on the screen, which is pretty weird.
>
> My game requires the novice-package, and it will be included in the next release of the novice-package along with my other example programs.
> This is the game:
> ---------------------------------------------------------------------------
>
> \ ARENA.4TH --- derived from tiny-arena01.fs by Darin Murphy --- needs NOVICE.4TH and LIST.4TH included.
>
> \ This file is a framework that can be used in any char-based game.
> \ Put your game in another file.
>
> \ We need to have TICKS defined, which is not ANS-Forth and can't be written in ANS-Forth.
>
> marker arena.4th
>
> VFX? 0= [if]
>
> !!! TICKS is needed!
>
> : ticks ( -- ms ) \ current time in milliseconds
> ...
> ;
>
> [then]
>
>
> \ ******
> \ ****** This contains SCREEN which is the array representing the screen.
> \ ******
>
> 0 \ kinds of elements in the game
> enum empty
> enum wall \ II
> enum ball \ {} \ this could be a ball, such as in BreakOut
> enum eyes \ oo \ this could represent the player
> enum wide-eyes \ OO \ this could represent the player under duress
> enum mouth \ <> \ this could represent a monster
> enum horz-bar \ == \ this could represent a bar in a BreakOut game
> enum brick \ ## \ this could represent a brick in a BreakOut game
> enum treasure \ $$ \ this could represent a bag of money
> enum vert-bar \ [] \ this could represent a bar in a Pong game
> enum down-spike \ \/ \ this could fall from the top of the screen
> enum up-spike \ /\ \ this could shoot up from the bottom of the screen
> constant kind-limit
>
> \ We need to have EMPTY and WALL --- the others can be changed --- more can be added if needed.
> \ Make sure that LEFT-SYMBOLS and RITE-SYMBOLS are updated too.
>
> \ The suggestions above for what the elements represent will vary from game to game.
> \ For example, DOWN-SPIKE and UP-SPIKE could be food that the player needs to consume.
>
> \ The elements are two characters wide (they have a left and a right part).
> \ The typical screen width is somewhat over twice the height, so we want wide elements.
> \ Otherwise the screen would appear to be stretched out horizontally.
>
> create left-symbols \ must correspond to elements
> bl c, \ empty
> char I c, \ wall
> char { c, \ ball
> char o c, \ eyes
> char O c, \ wide-eyes
> char < c, \ mouth
> char [ c, \ horz-bar
> char # c, \ brick
> char $ c, \ treasure
> char = c, \ vert-bar
> char \ c, \ down-spike
> char / c, \ up-spike
>
> create rite-symbols \ must correspond to elements
> bl c, \ empty
> char I c, \ wall
> char } c, \ ball
> char o c, \ eyes
> char O c, \ wide-eyes
> char > c, \ mouth
> char ] c, \ horz-bar
> char # c, \ brick
> char $ c, \ treasure
> char = c, \ vert-bar
> char / c, \ down-spike
> char \ c, \ up-spike
>
> : check-element ( element -- element )
> dup 0< abort" *** SYMBOL given negative element ***"
> dup kind-limit >= abort" *** SYMBOL given too large element ***"
> ;
>
> : symbol ( element -- rite-char left-char )
> check-element
> dup rite-symbols + c@
> swap left-symbols + c@ ;
>
> 35 constant horz \ horizontal size of screen \ half of display screen
> 25 constant vert \ vertical size of screen
>
> \ HORZ is half of the display screen because the elements are two chars wide.
> \ HORZ should not be the full screen because the CR in <DISPLAY-SCREEN> would be redundant.
> \ HORZ is less than the full screen so there is a margin on the right edge for data (score, clock, etc.).
>
> horz 2 / constant cx
> vert 2 / constant cy \ CX and CY are the center of the screen
>
> c 0 horz vert ary screen \ 0 0 is the upper-left corner
>
> -1 constant up
> 1 constant down
>
> -1 constant left
> 1 constant rite
>
> \ It is traditional in games that 0 0 is the upper-left corner, not the lower-left corner like in Cartesian coordinates.
> \ UP and DOWN would seem to be backwards for somebody who is assuming the first quadrant in Cartesian coordinates.
>
> : traverse-screen { 'element -- } \ 'ELEMENT ( col col-adr -- )
> vert 0 do
> <screen I -> \ -- row-adr
> horz 0 do
> I \ -- row-adr col
> over I screen> \ -- row-adr col col-adr
> 'element execute \ -- row-adr
> loop
> drop \ --
> loop ;
>
> : <clear-screen> ( col col-adr -- )
> empty swap c!
> drop ;
>
> : clear-screen ( -- ) \ fills SCREEN with EMPTY SYMBOL
> ['] <clear-screen> traverse-screen ;
>
> : <display-screen> ( col col-adr -- )
> c@ symbol emit emit \ -- col
> horz 1- = if cr then
> ;
>
> : display-screen ( -- ) \ displays SCREEN on the display screen
> 0 0 at-xy \ AT-XY doesn't work in VFX --- but PAGE results in too much blinking
> ['] <display-screen> traverse-screen ;
>
>
> \ ******
> \ ****** This contains ERASE-BOX and DRAW-BOX for drawing obstacles.
> \ ******
>
> : <draw-box> { width height lx uy kind | rx dy -- } \ KIND is typically WALL or EMPTY
> lx width + 1 - to rx \ RX is right-X, LX is left-X
> uy height + 1- to dy \ UY is upper-Y, DY is lower-Y
> rx lx ?do
> kind I uy screen c! \ up edge
> kind I dy screen c! \ down edge
> loop
> dy uy ?do
> kind lx I screen c! \ left edge
> kind rx I screen c! \ right edge
> loop
> kind rx dy screen c! ; \ left-down corner was not done in the loops above
>
> : erase-box ( width height lx uy -- ) \ LX UY is the upper-left corner
> empty <draw-box> ;
>
> : draw-box ( width height lx uy -- ) \ LX UY is the upper-left corner
> wall <draw-box> ;
>
> \ DRAW-BOX is typically done during initialization, so it doesn't have to be efficient.
> \ The assumption is that boxes don't move around during the game.
> \ If they do move, use ERASE-BOX to get rid of the old box, then DRAW-BOX to install the new box.
>
>
> \ ******
> \ ****** This contains PLAY-GAME that executes the user's code peiodically and exits on ESC.
> \ ******
>
> 300 value cycle \ how many milliseconds per cycle
>
> variable cycles \ how many full cycles have passed \ this needs to be initialized to 0
>
> 27 constant <esc> \ the ascii for the ESC key
>
> : elapsed ( start-time -- time )
> ticks swap - ;
>
> : cycled? ( start-time -- flag )
> elapsed cycle > ;
>
> : cursor-beyond ( -- )
> horz vert at-xy cr ;
>
> : play-game ( 'cycle -- ) \ 'CYCLE ( char|false -- str|false )
> ticks false \ -- 'cycle start-time char|false
> begin dup <esc> <> while
> rover execute \ -- 'cycle start-time str|false
> display-screen \ -- 'cycle start-time str|false
> ?dup if
> cursor-beyond count type
> 2drop exit then
> dup cycled? abort" *** the 'CYCLE code took too long ***"
> begin dup cycled? until
> 1 cycles +!
> cycle + \ -- 'cycle new-start-time
> key? if key else false then \ -- 'cycle new-start-time char|false
> repeat
> cursor-beyond ." ESCAPE"
> 3drop ;
>
> \ PLAY-GAME calls 'CYCLE every CYCLE milliseconds giving it the most recent keypress.
> \ PLAY-GAME exits if the ESC key is pressed, so ESC can't be part of the game user-interface.
>
> \ If the key is held down, there is a delay, then it begins to repeat --- this is very clumsy.
> \ It is best for the player to just tap the key rather than hold it down.
> \ The direction indicated by the key will continue to be in effect until another key is tapped.
>
>
> \ ******
> \ ****** This contains OBJECT and some support code.
> \ ******
>
> list \ these are objects in the game, other than WALL or EMPTY
> w field .kind \ kind of element displayed
> w field .x
> w field .y \ coordinates of location
> w field .dx
> w field .dy \ offset to move
> constant object
>
> \ An offset is one of: -1 0 1
>
> : init-object ( x y kind node -- node )
> init-list >r
> r@ .kind !
> r@ .y !
> r@ .x !
> 0 r@ .dy !
> 0 r@ .dx !
> r> ;
>
> : new-object ( x y kind -- node )
> object alloc
> init-object ;
>
> : kill-object ( node -- )
> dealloc ;
>
> : draw-object { node -- }
> node .kind @
> node .x @ node .y @ screen c! ;
>
> : erase-object { node -- }
> empty
> node .x @ node .y @ screen c! ;
>
> : collision? { nodeA nodeB -- flag }
> nodeA .x @ nodeB .x @ <> if false exit then
> nodeA .y @ nodeB .y @ <> if false exit then
> true ;
>
>
> \ ******
> \ ****** This contains SEEK and MOVE-OBJECT and some support code.
> \ ******
>
> 300 value severe \ how many full cycles pass before the monsters totally zero in on the player
> \ if CYCLE is 100 then a SEVERE of 1000 would be 10 seconds
>
> : tweak-offset ( offset -- new-offset ) \ randomly tweaks the offset
> cycles @ severe bias < if
> ?dup if negate
> else 1 rnd 2 * 1 - then
> then ;
>
> : seek { monster goal -- } \ sets the .DX .DY offsets for the monster
> goal .x @ monster .x @ - sgn tweak-offset monster .dx !
> goal .y @ monster .y @ - sgn tweak-offset monster .dy ! ;
>
> \ When CYCLES is low (early in the game) the chance of it being < the RND value is high, so the monster changes direction.
> \ As the game progresses, the chance decreases, so the monster is increasingly likely to stay aimed at the player.
> \ When CYCLES reaches SEVERE the chance is zero, so the monster is totally focused on the player.
> \ When changing direction, if the direction is -1 or 1 then the direction becomes opposite.
> \ If the direction is zero then we randomly choose -1 or 1 as the new direction.
>
> \ We need INIT-SEED called in the initialization, because TWEAK-OFFSET uses RND above.
>
> : move-object { node -- } \ needs .DX .DY set, adjusts .X .Y \ doesn't move into WALL
> node .x @ node .dx @ + \ -- x
> node .y @ node .dy @ + \ -- x y
> 2dup screen c@ wall = if
> 2drop \ leave object unmoved if there is a WALL in front of it
> else
> node .y ! node .x ! \ move object, possibly running into another object
> then ;
>
>
> \ ******
> \ ****** This is a small example game --- it is kept simple for educational purposes.
> \ ****** The player has to run over all the treasures before the monsters run over him.
> \ ****** The player is displayed eyes oo early in the game, then becomes wide-eyes OO as the monsters' aggression increases
> \ ****** The monsters are mouths <> and the treasures are money-bags: $$
> \ ****** Initially the monsters are biased to moving away from the player, but increasingly
> \ ****** become biased to moving toward the player. At SEVERE full cycles they totally go after the player.
> \ ****** Anybody writing a game should put it in another file, unless it is a direct upgrade of this game.
> \ ******
>
> variable treasures \ list of treasures
> variable monsters \ list of monsters
> variable player \ the player
>
> : <guide-player> ( dx dy -- ) \ sets the .DX .DY offsets for the player
> player @ .dy !
> player @ .dx ! ;
>
> <switch \ PLAY-GAME also uses the <ESC> key to escape
> :noname drop 1 0 <guide-player> ; char l swof \ right
> :noname drop -1 0 <guide-player> ; char k swof \ left
> :noname drop 0 -1 <guide-player> ; char q swof \ up
> :noname drop 0 1 <guide-player> ; char a swof \ down
> :noname drop ; fast-switch> guide-player ( char|false -- )
>
> : init-obstacles ( -- ) \ assumes CLEAR-SCREEN already done
> horz vert 0 0 draw-box \ border
> 1 7 cx 2 - cy 3 - draw-box \ left rail
> 1 7 cx 2 + cy 3 - draw-box \ right rail
> 4 7 cx 11 - cy 7 - draw-box \ left box
> 4 7 cx 8 + cy 1 + draw-box \ right box
> ;
>
> : init-treasures ( -- node )
> 0
> cx cy treasure new-object link \ center treasure
> cx 5 - cy 3 - treasure new-object link \ left treasure
> cx 5 + cy 3 + treasure new-object link \ right treasure
> ;
>
> : init-monsters ( -- node )
> 0
> cx 5 - cy 7 - mouth new-object link \ upper-left monster
> cx 5 - cy 7 + mouth new-object link \ upper-right monster
> cx 5 - cy 3 + mouth new-object link \ middle-left monster
> cx 5 + cy 3 - mouth new-object link \ middle-right monster
> cx 5 + cy 7 - mouth new-object link \ lower-left monster
> cx 5 + cy 7 + mouth new-object link \ lower-right monster
> ;
>
> : init-player ( -- node )
> 1 1 eyes new-object ;
>
> : init-game ( -- )
> page
> 1 seed ! \ init-seed
> 0 cycles !
> clear-screen
> init-obstacles
> init-treasures dup treasures ! ['] draw-object each
> init-monsters dup monsters ! ['] draw-object each
> init-player dup player ! draw-object
> display-screen ;
>
> : maybe-remove-treasure { node -- } \ NODE must be in the TREASURES list
> node player @ collision? if
> treasures @ node remove \ -- new-head node
> dup erase-object kill-object \ -- new-head node
> treasures ! then ;
>
> : taken-all-treasure? ( -- flag )
> treasures @ ['] maybe-remove-treasure each
> treasures @ 0= ;
>
> : <eaten-by-monster?> ( flag node -- new-flag ) \ NODE must be in the MONSTERS list
> player @ collision? or ;
>
> : eaten-by-monster? ( -- flag )
> false
> monsters @ ['] <eaten-by-monster?> each ;
>
> : guide-monster ( node -- ) \ sets the .DX .DY offsets for the monster
> player @ seek ;
>
> : erase-movers ( -- ) \ the monsters and the player can move
> monsters @ ['] erase-object each
> player @ erase-object
> ;
>
> : move-monsters ( -- )
> monsters @ ['] guide-monster each
> monsters @ ['] move-object each \ monsters can run into each other and occupy the same space
> ;
>
> : move-player ( char|false -- )
> guide-player
> player @ move-object
> ;
>
> : draw-all ( -- ) \ treasures, monsters and the player
> treasures @ ['] draw-object each \ treasures first so a monster can overwrite it
> monsters @ ['] draw-object each
> player @ draw-object
> ;
>
> \ DRAW-ALL redraws the treasures in case a monster over-wrote it previously.
> \ The treasures are drawn first, so if a monster is there the monster will over-write it in the display.
>
> : <main> ( char|false -- str|false )
> cycles @ severe 4 / >= if \ the monsters are becoming increasingly aggressive
> wide-eyes player @ .kind ! then
> erase-movers \ -- char|false
> move-monsters \ -- char|false
> move-player \ --
> draw-all \ --
> taken-all-treasure? if c" WIN! :-D " exit then
> eaten-by-monster? if c" LOSE :-( " exit then
> false ;
>
> \ Monsters can run into other monsters or the treasure and occupy the same space.
> \ If a monster is on top of a treasure, the monster is displayed (because monsters are drawn after treasures).
> \ Neither monsters nor the player can occupy the same space as a wall.
>
> : main ( -- )
> init-game
> begin key? until \ don't begin game until player presses a key
> ['] <main> play-game
> treasures @ ['] kill-object each
> monsters @ ['] kill-object each
> player @ kill-object ;
Nice. I'll look more thuroughly through your code later. In the meantime, I'll check out VFX Forth. Based on other recommendations here, I'm going to choose between GForth and VFX Forth.
[toc] | [prev] | [next] | [standalone]
| From | christopherdumas@gmail.com |
|---|---|
| Date | 2017-06-10 15:57 -0700 |
| Message-ID | <cb190d8e-d3e8-47c5-8d5d-451196aedb3d@googlegroups.com> |
| In reply to | #60587 |
On Saturday, June 10, 2017 at 3:56:23 PM UTC-7, christop...@gmail.com wrote:
> On Saturday, June 10, 2017 at 3:34:38 PM UTC-7, hughag...@gmail.com wrote:
> > On Saturday, June 10, 2017 at 8:29:37 AM UTC-7, christop...@gmail.com wrote:
> > > On Saturday, June 10, 2017 at 8:27:59 AM UTC-7, christop...@gmail.com wrote:
> > > > What are your opinions on Factor (factorcode.org)?
> >
> > I programmed in Factor a little bit, but then went back to Forth.
> >
> > Factor is a dynamic-OOP language derived from Lisp, so it has tagged data. OForth also has tagged data. Both languages are good for desktop-computer programming.
> >
> > I'm more into Forth because my interest is in micro-controllers.
> >
> > > Also, on a side note, I'm looking for some kind of graphics library for GForth. Can anyone help me there? I've heard that Forth was/is good for game programming. In addition, my favorite way to learn a programming language is writing a game in it.
> >
> > Another novice recently said the same thing, that he wanted to program a game in Forth to learn.
> > https://groups.google.com/forum/#!topic/comp.lang.forth/N5B1AbXqPfQ%5B1-25%5D
> >
> > ANS-Forth doesn't work for games because TICKS was banned by the ANS-Forth committee. This was done presumably for the purpose of preventing common Forthers from writing games in competition with the ANS-Forth committee members.
> >
> > VFX does have TICKS though, which is non-standard. Unfortunately, VFX has a bug in AT-XY that is a standard word.
> >
> > I wrote a small demo game. This requires VFX because it needs TICKS available. It is playable, but because of the bug in AT-XY it scrolls off the top of the screen and you see two images of your game on the screen, which is pretty weird.
> >
> > My game requires the novice-package, and it will be included in the next release of the novice-package along with my other example programs.
> > This is the game:
> > ---------------------------------------------------------------------------
> >
> > \ ARENA.4TH --- derived from tiny-arena01.fs by Darin Murphy --- needs NOVICE.4TH and LIST.4TH included.
> >
> > \ This file is a framework that can be used in any char-based game.
> > \ Put your game in another file.
> >
> > \ We need to have TICKS defined, which is not ANS-Forth and can't be written in ANS-Forth.
> >
> > marker arena.4th
> >
> > VFX? 0= [if]
> >
> > !!! TICKS is needed!
> >
> > : ticks ( -- ms ) \ current time in milliseconds
> > ...
> > ;
> >
> > [then]
> >
> >
> > \ ******
> > \ ****** This contains SCREEN which is the array representing the screen.
> > \ ******
> >
> > 0 \ kinds of elements in the game
> > enum empty
> > enum wall \ II
> > enum ball \ {} \ this could be a ball, such as in BreakOut
> > enum eyes \ oo \ this could represent the player
> > enum wide-eyes \ OO \ this could represent the player under duress
> > enum mouth \ <> \ this could represent a monster
> > enum horz-bar \ == \ this could represent a bar in a BreakOut game
> > enum brick \ ## \ this could represent a brick in a BreakOut game
> > enum treasure \ $$ \ this could represent a bag of money
> > enum vert-bar \ [] \ this could represent a bar in a Pong game
> > enum down-spike \ \/ \ this could fall from the top of the screen
> > enum up-spike \ /\ \ this could shoot up from the bottom of the screen
> > constant kind-limit
> >
> > \ We need to have EMPTY and WALL --- the others can be changed --- more can be added if needed.
> > \ Make sure that LEFT-SYMBOLS and RITE-SYMBOLS are updated too.
> >
> > \ The suggestions above for what the elements represent will vary from game to game.
> > \ For example, DOWN-SPIKE and UP-SPIKE could be food that the player needs to consume.
> >
> > \ The elements are two characters wide (they have a left and a right part).
> > \ The typical screen width is somewhat over twice the height, so we want wide elements.
> > \ Otherwise the screen would appear to be stretched out horizontally.
> >
> > create left-symbols \ must correspond to elements
> > bl c, \ empty
> > char I c, \ wall
> > char { c, \ ball
> > char o c, \ eyes
> > char O c, \ wide-eyes
> > char < c, \ mouth
> > char [ c, \ horz-bar
> > char # c, \ brick
> > char $ c, \ treasure
> > char = c, \ vert-bar
> > char \ c, \ down-spike
> > char / c, \ up-spike
> >
> > create rite-symbols \ must correspond to elements
> > bl c, \ empty
> > char I c, \ wall
> > char } c, \ ball
> > char o c, \ eyes
> > char O c, \ wide-eyes
> > char > c, \ mouth
> > char ] c, \ horz-bar
> > char # c, \ brick
> > char $ c, \ treasure
> > char = c, \ vert-bar
> > char / c, \ down-spike
> > char \ c, \ up-spike
> >
> > : check-element ( element -- element )
> > dup 0< abort" *** SYMBOL given negative element ***"
> > dup kind-limit >= abort" *** SYMBOL given too large element ***"
> > ;
> >
> > : symbol ( element -- rite-char left-char )
> > check-element
> > dup rite-symbols + c@
> > swap left-symbols + c@ ;
> >
> > 35 constant horz \ horizontal size of screen \ half of display screen
> > 25 constant vert \ vertical size of screen
> >
> > \ HORZ is half of the display screen because the elements are two chars wide.
> > \ HORZ should not be the full screen because the CR in <DISPLAY-SCREEN> would be redundant.
> > \ HORZ is less than the full screen so there is a margin on the right edge for data (score, clock, etc.).
> >
> > horz 2 / constant cx
> > vert 2 / constant cy \ CX and CY are the center of the screen
> >
> > c 0 horz vert ary screen \ 0 0 is the upper-left corner
> >
> > -1 constant up
> > 1 constant down
> >
> > -1 constant left
> > 1 constant rite
> >
> > \ It is traditional in games that 0 0 is the upper-left corner, not the lower-left corner like in Cartesian coordinates.
> > \ UP and DOWN would seem to be backwards for somebody who is assuming the first quadrant in Cartesian coordinates.
> >
> > : traverse-screen { 'element -- } \ 'ELEMENT ( col col-adr -- )
> > vert 0 do
> > <screen I -> \ -- row-adr
> > horz 0 do
> > I \ -- row-adr col
> > over I screen> \ -- row-adr col col-adr
> > 'element execute \ -- row-adr
> > loop
> > drop \ --
> > loop ;
> >
> > : <clear-screen> ( col col-adr -- )
> > empty swap c!
> > drop ;
> >
> > : clear-screen ( -- ) \ fills SCREEN with EMPTY SYMBOL
> > ['] <clear-screen> traverse-screen ;
> >
> > : <display-screen> ( col col-adr -- )
> > c@ symbol emit emit \ -- col
> > horz 1- = if cr then
> > ;
> >
> > : display-screen ( -- ) \ displays SCREEN on the display screen
> > 0 0 at-xy \ AT-XY doesn't work in VFX --- but PAGE results in too much blinking
> > ['] <display-screen> traverse-screen ;
> >
> >
> > \ ******
> > \ ****** This contains ERASE-BOX and DRAW-BOX for drawing obstacles.
> > \ ******
> >
> > : <draw-box> { width height lx uy kind | rx dy -- } \ KIND is typically WALL or EMPTY
> > lx width + 1 - to rx \ RX is right-X, LX is left-X
> > uy height + 1- to dy \ UY is upper-Y, DY is lower-Y
> > rx lx ?do
> > kind I uy screen c! \ up edge
> > kind I dy screen c! \ down edge
> > loop
> > dy uy ?do
> > kind lx I screen c! \ left edge
> > kind rx I screen c! \ right edge
> > loop
> > kind rx dy screen c! ; \ left-down corner was not done in the loops above
> >
> > : erase-box ( width height lx uy -- ) \ LX UY is the upper-left corner
> > empty <draw-box> ;
> >
> > : draw-box ( width height lx uy -- ) \ LX UY is the upper-left corner
> > wall <draw-box> ;
> >
> > \ DRAW-BOX is typically done during initialization, so it doesn't have to be efficient.
> > \ The assumption is that boxes don't move around during the game.
> > \ If they do move, use ERASE-BOX to get rid of the old box, then DRAW-BOX to install the new box.
> >
> >
> > \ ******
> > \ ****** This contains PLAY-GAME that executes the user's code peiodically and exits on ESC.
> > \ ******
> >
> > 300 value cycle \ how many milliseconds per cycle
> >
> > variable cycles \ how many full cycles have passed \ this needs to be initialized to 0
> >
> > 27 constant <esc> \ the ascii for the ESC key
> >
> > : elapsed ( start-time -- time )
> > ticks swap - ;
> >
> > : cycled? ( start-time -- flag )
> > elapsed cycle > ;
> >
> > : cursor-beyond ( -- )
> > horz vert at-xy cr ;
> >
> > : play-game ( 'cycle -- ) \ 'CYCLE ( char|false -- str|false )
> > ticks false \ -- 'cycle start-time char|false
> > begin dup <esc> <> while
> > rover execute \ -- 'cycle start-time str|false
> > display-screen \ -- 'cycle start-time str|false
> > ?dup if
> > cursor-beyond count type
> > 2drop exit then
> > dup cycled? abort" *** the 'CYCLE code took too long ***"
> > begin dup cycled? until
> > 1 cycles +!
> > cycle + \ -- 'cycle new-start-time
> > key? if key else false then \ -- 'cycle new-start-time char|false
> > repeat
> > cursor-beyond ." ESCAPE"
> > 3drop ;
> >
> > \ PLAY-GAME calls 'CYCLE every CYCLE milliseconds giving it the most recent keypress.
> > \ PLAY-GAME exits if the ESC key is pressed, so ESC can't be part of the game user-interface.
> >
> > \ If the key is held down, there is a delay, then it begins to repeat --- this is very clumsy.
> > \ It is best for the player to just tap the key rather than hold it down.
> > \ The direction indicated by the key will continue to be in effect until another key is tapped.
> >
> >
> > \ ******
> > \ ****** This contains OBJECT and some support code.
> > \ ******
> >
> > list \ these are objects in the game, other than WALL or EMPTY
> > w field .kind \ kind of element displayed
> > w field .x
> > w field .y \ coordinates of location
> > w field .dx
> > w field .dy \ offset to move
> > constant object
> >
> > \ An offset is one of: -1 0 1
> >
> > : init-object ( x y kind node -- node )
> > init-list >r
> > r@ .kind !
> > r@ .y !
> > r@ .x !
> > 0 r@ .dy !
> > 0 r@ .dx !
> > r> ;
> >
> > : new-object ( x y kind -- node )
> > object alloc
> > init-object ;
> >
> > : kill-object ( node -- )
> > dealloc ;
> >
> > : draw-object { node -- }
> > node .kind @
> > node .x @ node .y @ screen c! ;
> >
> > : erase-object { node -- }
> > empty
> > node .x @ node .y @ screen c! ;
> >
> > : collision? { nodeA nodeB -- flag }
> > nodeA .x @ nodeB .x @ <> if false exit then
> > nodeA .y @ nodeB .y @ <> if false exit then
> > true ;
> >
> >
> > \ ******
> > \ ****** This contains SEEK and MOVE-OBJECT and some support code.
> > \ ******
> >
> > 300 value severe \ how many full cycles pass before the monsters totally zero in on the player
> > \ if CYCLE is 100 then a SEVERE of 1000 would be 10 seconds
> >
> > : tweak-offset ( offset -- new-offset ) \ randomly tweaks the offset
> > cycles @ severe bias < if
> > ?dup if negate
> > else 1 rnd 2 * 1 - then
> > then ;
> >
> > : seek { monster goal -- } \ sets the .DX .DY offsets for the monster
> > goal .x @ monster .x @ - sgn tweak-offset monster .dx !
> > goal .y @ monster .y @ - sgn tweak-offset monster .dy ! ;
> >
> > \ When CYCLES is low (early in the game) the chance of it being < the RND value is high, so the monster changes direction.
> > \ As the game progresses, the chance decreases, so the monster is increasingly likely to stay aimed at the player.
> > \ When CYCLES reaches SEVERE the chance is zero, so the monster is totally focused on the player.
> > \ When changing direction, if the direction is -1 or 1 then the direction becomes opposite.
> > \ If the direction is zero then we randomly choose -1 or 1 as the new direction.
> >
> > \ We need INIT-SEED called in the initialization, because TWEAK-OFFSET uses RND above.
> >
> > : move-object { node -- } \ needs .DX .DY set, adjusts .X .Y \ doesn't move into WALL
> > node .x @ node .dx @ + \ -- x
> > node .y @ node .dy @ + \ -- x y
> > 2dup screen c@ wall = if
> > 2drop \ leave object unmoved if there is a WALL in front of it
> > else
> > node .y ! node .x ! \ move object, possibly running into another object
> > then ;
> >
> >
> > \ ******
> > \ ****** This is a small example game --- it is kept simple for educational purposes.
> > \ ****** The player has to run over all the treasures before the monsters run over him.
> > \ ****** The player is displayed eyes oo early in the game, then becomes wide-eyes OO as the monsters' aggression increases
> > \ ****** The monsters are mouths <> and the treasures are money-bags: $$
> > \ ****** Initially the monsters are biased to moving away from the player, but increasingly
> > \ ****** become biased to moving toward the player. At SEVERE full cycles they totally go after the player.
> > \ ****** Anybody writing a game should put it in another file, unless it is a direct upgrade of this game.
> > \ ******
> >
> > variable treasures \ list of treasures
> > variable monsters \ list of monsters
> > variable player \ the player
> >
> > : <guide-player> ( dx dy -- ) \ sets the .DX .DY offsets for the player
> > player @ .dy !
> > player @ .dx ! ;
> >
> > <switch \ PLAY-GAME also uses the <ESC> key to escape
> > :noname drop 1 0 <guide-player> ; char l swof \ right
> > :noname drop -1 0 <guide-player> ; char k swof \ left
> > :noname drop 0 -1 <guide-player> ; char q swof \ up
> > :noname drop 0 1 <guide-player> ; char a swof \ down
> > :noname drop ; fast-switch> guide-player ( char|false -- )
> >
> > : init-obstacles ( -- ) \ assumes CLEAR-SCREEN already done
> > horz vert 0 0 draw-box \ border
> > 1 7 cx 2 - cy 3 - draw-box \ left rail
> > 1 7 cx 2 + cy 3 - draw-box \ right rail
> > 4 7 cx 11 - cy 7 - draw-box \ left box
> > 4 7 cx 8 + cy 1 + draw-box \ right box
> > ;
> >
> > : init-treasures ( -- node )
> > 0
> > cx cy treasure new-object link \ center treasure
> > cx 5 - cy 3 - treasure new-object link \ left treasure
> > cx 5 + cy 3 + treasure new-object link \ right treasure
> > ;
> >
> > : init-monsters ( -- node )
> > 0
> > cx 5 - cy 7 - mouth new-object link \ upper-left monster
> > cx 5 - cy 7 + mouth new-object link \ upper-right monster
> > cx 5 - cy 3 + mouth new-object link \ middle-left monster
> > cx 5 + cy 3 - mouth new-object link \ middle-right monster
> > cx 5 + cy 7 - mouth new-object link \ lower-left monster
> > cx 5 + cy 7 + mouth new-object link \ lower-right monster
> > ;
> >
> > : init-player ( -- node )
> > 1 1 eyes new-object ;
> >
> > : init-game ( -- )
> > page
> > 1 seed ! \ init-seed
> > 0 cycles !
> > clear-screen
> > init-obstacles
> > init-treasures dup treasures ! ['] draw-object each
> > init-monsters dup monsters ! ['] draw-object each
> > init-player dup player ! draw-object
> > display-screen ;
> >
> > : maybe-remove-treasure { node -- } \ NODE must be in the TREASURES list
> > node player @ collision? if
> > treasures @ node remove \ -- new-head node
> > dup erase-object kill-object \ -- new-head node
> > treasures ! then ;
> >
> > : taken-all-treasure? ( -- flag )
> > treasures @ ['] maybe-remove-treasure each
> > treasures @ 0= ;
> >
> > : <eaten-by-monster?> ( flag node -- new-flag ) \ NODE must be in the MONSTERS list
> > player @ collision? or ;
> >
> > : eaten-by-monster? ( -- flag )
> > false
> > monsters @ ['] <eaten-by-monster?> each ;
> >
> > : guide-monster ( node -- ) \ sets the .DX .DY offsets for the monster
> > player @ seek ;
> >
> > : erase-movers ( -- ) \ the monsters and the player can move
> > monsters @ ['] erase-object each
> > player @ erase-object
> > ;
> >
> > : move-monsters ( -- )
> > monsters @ ['] guide-monster each
> > monsters @ ['] move-object each \ monsters can run into each other and occupy the same space
> > ;
> >
> > : move-player ( char|false -- )
> > guide-player
> > player @ move-object
> > ;
> >
> > : draw-all ( -- ) \ treasures, monsters and the player
> > treasures @ ['] draw-object each \ treasures first so a monster can overwrite it
> > monsters @ ['] draw-object each
> > player @ draw-object
> > ;
> >
> > \ DRAW-ALL redraws the treasures in case a monster over-wrote it previously.
> > \ The treasures are drawn first, so if a monster is there the monster will over-write it in the display.
> >
> > : <main> ( char|false -- str|false )
> > cycles @ severe 4 / >= if \ the monsters are becoming increasingly aggressive
> > wide-eyes player @ .kind ! then
> > erase-movers \ -- char|false
> > move-monsters \ -- char|false
> > move-player \ --
> > draw-all \ --
> > taken-all-treasure? if c" WIN! :-D " exit then
> > eaten-by-monster? if c" LOSE :-( " exit then
> > false ;
> >
> > \ Monsters can run into other monsters or the treasure and occupy the same space.
> > \ If a monster is on top of a treasure, the monster is displayed (because monsters are drawn after treasures).
> > \ Neither monsters nor the player can occupy the same space as a wall.
> >
> > : main ( -- )
> > init-game
> > begin key? until \ don't begin game until player presses a key
> > ['] <main> play-game
> > treasures @ ['] kill-object each
> > monsters @ ['] kill-object each
> > player @ kill-object ;
>
> Nice. I'll look more thuroughly through your code later. In the meantime, I'll check out VFX Forth. Based on other recommendations here, I'm going to choose between GForth and VFX Forth.
Oh no. Spellcheck, you've failed me!
[toc] | [prev] | [next] | [standalone]
| From | rickman <gnuarm@gmail.com> |
|---|---|
| Date | 2017-06-15 11:52 -0400 |
| Message-ID | <ohua9h$3no$2@dont-email.me> |
| In reply to | #60588 |
christopherdumas@gmail.com wrote on 6/10/2017 6:57 PM: >> >> Nice. I'll look more thuroughly through your code later. In the meantime, I'll check out VFX Forth. Based on other recommendations here, I'm going to choose between GForth and VFX Forth. > > Oh no. Spellcheck, you've failed me! Thorough is a tough word to learn to spell (along with tough and rough). I think I picked it up when the AMD Thoroughbred processor came out, lol. -- Rick C
[toc] | [prev] | [next] | [standalone]
| From | new@to.forth |
|---|---|
| Date | 2017-06-10 21:38 +0000 |
| Message-ID | <ohhos5$1lgv$1@gioia.aioe.org> |
| In reply to | #60562 |
>.. >What are your opinions on Factor (factorcode.org)? IDK, never used it. Obviously it's creators think Forth was lacking and decided to implement their own vision of how a stack-based language should work. Right now I'm just focused on learning FOrth. >graphics libraries? I see a vector graphics library here: http://theforth.net/packages Looks like gforth includes an interface (libffg2) to the G^2 2-D web graphics library: https://github.com/cd/g2
[toc] | [prev] | [next] | [standalone]
| From | christopherdumas@gmail.com |
|---|---|
| Date | 2017-06-10 15:53 -0700 |
| Message-ID | <f47e6092-176f-4135-9de3-f2404c2b818c@googlegroups.com> |
| In reply to | #60580 |
On Saturday, June 10, 2017 at 2:38:17 PM UTC-7, n...@to.forth wrote: > >.. > >What are your opinions on Factor (factorcode.org)? > > IDK, never used it. Obviously it's creators think Forth was lacking > and decided to implement their own vision of how a stack-based language > should work. Right now I'm just focused on learning FOrth. > > >graphics libraries? > > I see a vector graphics library here: > http://theforth.net/packages > > Looks like gforth includes an interface (libffg2) to the G^2 2-D web graphics library: > https://github.com/cd/g2 Ah, that's helpful. Also, it's encouraging to see there's a package manager.
[toc] | [prev] | [next] | [standalone]
| From | NN <november.nihal@gmail.com> |
|---|---|
| Date | 2017-06-12 05:36 -0700 |
| Message-ID | <2d86868a-15e0-46fd-9754-40de5654300b@googlegroups.com> |
| In reply to | #60580 |
On Saturday, 10 June 2017 22:38:17 UTC+1, n...@to.forth wrote: > >.. > >What are your opinions on Factor (factorcode.org)? > > IDK, never used it. Obviously it's creators think Forth was lacking > and decided to implement their own vision of how a stack-based language > should work. Right now I'm just focused on learning FOrth. > > >graphics libraries? > > I see a vector graphics library here: > http://theforth.net/packages > > Looks like gforth includes an interface (libffg2) to the G^2 2-D web graphics library: > https://github.com/cd/g2 My take is people compare factor and forth due to some similarities (eg short definitions, stacks) whilst forgetting the differences ( eg combinators, sequences ) If you want to know something about factor why not check out https://www.youtube.com/watch?v=f_0QlhYlS8g . Its long but well worth watching. Good luck with forth. NN
[toc] | [prev] | [next] | [standalone]
| From | christopherdumas@gmail.com |
|---|---|
| Date | 2017-06-12 07:02 -0700 |
| Message-ID | <c807d9be-91e0-4c29-b998-1584f8196dd1@googlegroups.com> |
| In reply to | #60652 |
Thanks, NN! I've been trying to decide between GForth and Factor now, and the one comparison that I know of, rosycrew.org/FactorVsForth.pdf, is no longer on the internet. I'm really split because I want to learn a pure stack-based language and I really like GForth so far, but Factor sounds really cool, being as it is a combination of Lisp (my favorite language) and Forth. The IDE isn't really a consideration for me, because I have EMACS, the Universal IDE. (:
[toc] | [prev] | [next] | [standalone]
| From | Julian Fondren <julian.fondren@gmail.com> |
|---|---|
| Date | 2017-06-12 08:29 -0700 |
| Message-ID | <91691e59-e568-4d60-bc4b-0350a0e4ba84@googlegroups.com> |
| In reply to | #60656 |
On Monday, June 12, 2017 at 9:02:39 AM UTC-5, christop...@gmail.com wrote: > Thanks, NN! I've been trying to decide between GForth and Factor now, and the one comparison that I know of, rosycrew.org/FactorVsForth.pdf, is no longer on the internet. *shrug*. I don't care enough about Factor even to have good arguments against it. I'd have to have used it for more than ten minutes to even be able to complain about it. But as someone who's seen it without finding it interesting, I can at least share that much perspective. When someone comes out with an incompatible Forth-like language, the first question to answer is "Why didn't you just extend Forth?" You have the most extensible language in existence (although not tamely extensible to all things), and instead of building on it you build some new thing that in Factor's case A) runs on only three x86 OSes, and B) has only a single implementation with a single set of tradeoffs. What, besides the ego of the creator, was the point? In Factor I see a lot of library work that could've gone into Forth instead, and a quotation-heavy style that I don't care for, but that at least is a little bit annoying to replicate in Forth. Today gforth (development version), lina, and iForth all have [: ... ;] and return stack manipulation can get you that as well. So it's weird in a way I don't care for and it has libraries. I'd rather have libraries in Forth, a language with a standard and many good implementations for enormously more architectures, without any worries like: tomorrow Slava Pestov will decide that what Factor really needs is *lazy semantics* - breaking all existing code. And I don't have rosy glasses about libraries or things appearing to be easy. There are limits to software that you only meet after a lot of investment in that software. Something that works like a dream for 300 users becomes a huge problem at 30,000 users. A library is easy easy easy until a tiny increment in desired behavior comes down the line... which the library makes impossible to do. So rather than the "oh a new thing, let's spend a lot of time on it!" attitude that I once had with programming languages, nowadays I spare some concern on "what are my options if this new thing is inadequate?" I've had very good experiences with Forth libraries that were inadequate. I used the part of the library I wanted, then dug up its buried tools to extend it in the direction I wanted. If a Forth system is ever part of the problem I know that there are other systems to consider. I glanced at the Factor mailing list and found this: http://www.mail-archive.com/factor-talk@lists.sourceforge.net/msg08109.html Sounds like a problem I don't want to run into 98% into a project. Or 120% into it, doing support work. One answer to "what are my options if this new thing is inadequate?", depending on your circumstances, is "use some of your budget to pay other people to fix the problem". If you have a problem with influxdb, a time-series database (in Go unfortunately--anyone doing time-series in Forth?), then you can pay InfluxData. I glanced at factorcode.org just now and the first thing my browser told me is that the SSL cert has been expired since March, so that option's probably out.
[toc] | [prev] | [next] | [standalone]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2017-06-12 16:16 +0000 |
| Subject | Factor (was: Starting Forth) |
| Message-ID | <2017Jun12.181647@mips.complang.tuwien.ac.at> |
| In reply to | #60660 |
Julian Fondren <julian.fondren@gmail.com> writes:
>When someone comes out with an incompatible Forth-like language, the
>first question to answer is "Why didn't you just extend Forth?" You
>have the most extensible language in existence (although not
>tamely extensible to all things), and instead of building on it you
>build some new thing that in Factor's case A) runs on only three x86
>OSes, and B) has only a single implementation with a single set of
>tradeoffs. What, besides the ego of the creator, was the point?
In the case of Factor, the point is that it is a managed language: The
Factor system has type information on the data that it uses for dyamic
and partially static type checking, and for supporting garbage
collection. And that can have quite a lot of advantages when
designing library functions.
If you want to go there, extending a normal Forth does not appear to
be a very viable approach to me. And the result will be so different
that I don't see a benefit to extending a normal Forth. Mixing normal
Forth with the managed part would destroy various invariants that the
run-time system relies on, unless the Forth code obeys the
restrictions that are necessary to keep them up; but then you are in
the foreign managed world instead of in the familiar low-level Forth
world.
So, his point was that he wanted to go there, and actually went there.
That being said, my experience with Factor has been rather miserable:
At the Forth-Tagung 2012 there was a Factor workshop, and we were
given the task to do something, and the first steps went well, and
then there was some step that rubbed the static type checker the wrong
way, and I could not get it to work, no matter what I tried; some
others achieved that step, but their advice did not help me.
My impression is that the static type checker has a rather fractal
surface: sometimes it decides that this is something it can check
statically, and then it may complain about something that the dynamic
checker would not complain about, and other times, it leaves the field
to the dynamic checker, which is much more reasonable.
But that impression is based on playing around with it for half an
afternoon. I am sure if you get more familiar with it, you learn to
deal with this issue and it soon becomes a non-issue.
- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2017: http://www.euroforth.org/ef17/
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | comp.lang.forth
csiph-web