Shop OBEX P1 Docs P2 Docs Learn Events
How does Forth manage memory? — Parallax Forums

How does Forth manage memory?

David BetzDavid Betz Posts: 14,516
edited 2014-01-04 08:44 in General Discussion
There seem to be lots of Forth enthusiasts here. I'm wondering if anyone can tell me how Forth manages memory. Since it's an interactive language it's possible to define functions (words) on the fly. What happens if I redefine a word? Is the old definition removed and the memory that it occupied reclaimed or does the new definition just shadow the old definition?
«1

Comments

  • Martin_HMartin_H Posts: 4,051
    edited 2013-12-29 20:01
    Peter or David will likely have a definite answer, but as near as I can tell Forth has an allocation high-water mark which is the last thing allocated. So when you redefine a function the old space is wasted. In some dialects callers defined before the redefinition seem to retain the reference to the original version too.

    Forth includes a word called forget that removes all definitions to the word argument passed. So it's possible to pop off a definition and everything that depends upon it. This allows for a crude form of garbage collection to say the least. What I do instead is keep my source on the PC and reinitalize the system if I had too many changes to a word.
  • David BetzDavid Betz Posts: 14,516
    edited 2013-12-29 20:16
    Thanks Martin. That's sort of what I thought although my knowledge of Forth internals dates back a long time. I thought maybe things had changed in modern versions.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2013-12-29 22:11
    David Betz wrote: »
    There seem to be lots of Forth enthusiasts here. I'm wondering if anyone can tell me how Forth manages memory. Since it's an interactive language it's possible to define functions (words) on the fly. What happens if I redefine a word? Is the old definition removed and the memory that it occupied reclaimed or does the new definition just shadow the old definition?

    A redefinition is normally just a new definition with the same name as an earlier one, the previous word cannot be referenced anymore as the new version has precedence in the dictionary search. This means that the code for the old word is still valid for all those definitions which referenced it at the time they were compiled. The new word normally can have no impact on precompiled code.

    There is a mechanism in Tachyon for revectoring the old code to point to the new as Tachyon uses a vector table for all high level defintiions. It is also possible to reclaim that old code space as well as the name space as once again we just move all the code after it back down and readjust the vectors although that mechanism has not yet been implemented.

    Typical Forths however use indirect addresses so they would not be happy if the code is not where it's supposed to be.
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2013-12-30 04:12
    David Betz wrote: »
    There seem to be lots of Forth enthusiasts here. I'm wondering if anyone can tell me how Forth manages memory. Since it's an interactive language it's possible to define functions (words) on the fly. What happens if I redefine a word? Is the old definition removed and the memory that it occupied reclaimed or does the new definition just shadow the old definition?

    How does Forth manage memory?
    Well, you have a couple of stacks that if over-run, they crash. And then the dictionary space has a word Free to tell you how much free space is available in the dictionary for new additions.

    All the dictionary entries are chained and dependent on the previous dictionary entries. So the search of the dictionary space starts with the last entry and goes toward the first. If two definitions have the same name, you will only reach the last one (unless you do something fancy to get to the earlier one).

    Old definitions are not removed unless you expressly remove them. But I suppose that if you want a definition to be continually redefined as an important programing feature, there would be a way to get what you want.

    ~~~~~~~~~~
    The main points are that the dictionary is usually used in two fashions.

    A. As a learning tool, where the dictionary might be filled with all sorts of experimental nonsense that can be purged back to the original state.
    B. As a programing project, where the dictionary additons might all be written to a text file and then loaded enmasse to have the desired use start on a single command.

    Those are the usually uses.

    But one could have other modes of use where you are reprograming, learning, and using in alternation. I think that if you had a ROV with Forth, this might be the case. The ROV gets stuck in a situation that you haven't forseen, so you run diagnostics, try a few new routines to get it unstuck, and then load a revised program to avoid more of the same. That is all very possible. I find this possiblity delightful and less dreary than using C, Spin, or PASM for the same.
  • David BetzDavid Betz Posts: 14,516
    edited 2013-12-30 04:35
    But one could have other modes of use where you are reprograming, learning, and using in alternation. I think that if you had a ROV with Forth, this might be the case. The ROV gets stuck in a situation that you haven't forseen, so you run diagnostics, try a few new routines to get it unstuck, and then load a revised program to avoid more of the same. That is all very possible. I find this possiblity delightful and less dreary than using C, Spin, or PASM for the same.
    What is "ROV"?

    Thanks everyone for your explanations!
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2013-12-30 06:11
    ROV? A remotely operated vehicle. It could be an underwater robot, a lunar explorer, or cave explorer.
    Parallax has a long standing interest in robotics and I am a bit facinated by the abilities of device to roam in places that are hard for humans to get to and to be able to perform useful tasks.

    What exactly do you expect Forth to do?
  • David BetzDavid Betz Posts: 14,516
    edited 2013-12-30 06:50
    ROV? A remotely operated vehicle. It could be an underwater robot, a lunar explorer, or cave explorer.
    Parallax has a long standing interest in robotics and I am a bit facinated by the abilities of device to roam in places that are hard for humans to get to and to be able to perform useful tasks.

    What exactly do you expect Forth to do?
    Okay, now I'm going to run into trouble with the Forth enthusiasts. The reason I've been asking how Forth handles memory is that I'm investigating the idea of building a more traditional infix language that has some of the efficiency advantages of Forth but with a more familiar syntax. One big problem I have with other languages I've written is that they mostly use heap-based memory managers that tend to take up more memory and also involve complicated code to maintain. If I could use a simpler symbol table and object storage scheme then I could reduce significantly the code and data space requirements. I feel as though one of the biggest advantages of Forth is it's interactivity. I want that but with a more traditional syntax.
  • Martin_HMartin_H Posts: 4,051
    edited 2013-12-30 07:09
    David, it will be interesting to see what you come up with. Forth's RPN syntax never causes me grief, but the stack is another story. I don't like using global variables, so will often juggle a complicated stack to avoid them. This can result in write only code when done poorly.

    Forth's interactivity in such a space constrained environment is certainly a big advantage, and I don’t think I've ever called new in my Propgcc programs either. I tend to use either static or stack allocation, and avoid memory leaks.
  • David BetzDavid Betz Posts: 14,516
    edited 2013-12-30 07:27
    Martin_H wrote: »
    David, it will be interesting to see what you come up with. Forth's RPN syntax never causes me grief, but the stack is another story. I don't like using global variables, so will often juggle a complicated stack to avoid them. This can result in write only code when done poorly.

    Forth's interactivity in such a space constrained environment is certainly a big advantage, and I don’t think I've ever called new in my Propgcc programs either. I tend to use either static or stack allocation, and avoid memory leaks.
    I fully admit that the difficulties I have with Forth syntax are probably due to the fact that I haven't spent enough time with it to get used to it. I don't really have a problem with infix expressions but I tend to get lost in the control structures. I'm sure a little practice would help.
  • Heater.Heater. Posts: 21,230
    edited 2013-12-30 08:23
    David,
    I tend to get lost in the control structures. I'm sure a little practice would help.
    Patient: Every time I poke this stick in my eye it hurts like hell.
    Doctor: Well then stop doing that.
  • David BetzDavid Betz Posts: 14,516
    edited 2013-12-30 08:27
    Heater. wrote: »
    David,

    Patient: Every time I poke this stick in my eye it hurts like hell.
    Doctor: Well then stop doing that.
    The thing is, I'm attracted to the simpicity of the Forth environment. I keep *wanting* to like it. I haven't found anything else so far that can use the limited resources of something like a Propeller more efficiently. Forth is far better than an old-school line-numbered Basic for example. At least you get named functions (words) that can take arguments (on the stack). This is infinitely better than "gosub 1000".
  • Heater.Heater. Posts: 21,230
    edited 2013-12-30 10:24
    David,
    The thing is, I'm attracted to the simpicity of the Forth environment. I keep *wanting* to like it.
    I totally understand that, I feel the same way.
    I haven't found anything else so far that can use the limited resources of something like a Propeller more efficiently.
    Sure you have, It's called Spin and PASM. Not only small and efficient but it's easier to write complex code in PASM than Forth.
    Forth is far better than an old-school line-numbered Basic for example. At least you get named functions (words) that can take arguments (on the stack). This is
    infinitely better than "gosub 1000".
    That is not saying very much. I'm not convinced it's true anyway.


    Now, if the only computer you had was something of the power of a Z80 or Propeller and your only way to communicate with it was an ASR33 teletype or Morse Key, then yes, Forth is very impressive in that you can put a whole high level language (sort of) system into such a small machine and have a self hosting environment. Brilliant.


    But, that is not what we do. We talk to our embedded systems with PCs running terminal emulators. Perhaps even phones and tablets. Those machines have giga bytes of RAM and storage. Compiling Spin or C or whatever little program for an MCU is just a little hiccup in their operation. They do more work rendering the fonts in the terminals. Even if you hook your Prop to a modern VGA screen that screen probably has enough processing power on board to run the Spin compiler.

    It does not make sense.

    It has not made sense since 8 bit computers and compilers running under CP/M.

    Stop poking yourself in the eye with that stick!
  • David BetzDavid Betz Posts: 14,516
    edited 2013-12-30 11:05
    Heater. wrote: »
    David,

    I totally understand that, I feel the same way.

    Sure you have, It's called Spin and PASM. Not only small and efficient but it's easier to write complex code in PASM than Forth.

    That is not saying very much. I'm not convinced it's true anyway.


    Now, if the only computer you had was something of the power of a Z80 or Propeller and your only way to communicate with it was an ASR33 teletype or Morse Key, then yes, Forth is very impressive in that you can put a whole high level language (sort of) system into such a small machine and have a self hosting environment. Brilliant.


    But, that is not what we do. We talk to our embedded systems with PCs running terminal emulators. Perhaps even phones and tablets. Those machines have giga bytes of RAM and storage. Compiling Spin or C or whatever little program for an MCU is just a little hiccup in their operation. They do more work rendering the fonts in the terminals. Even if you hook your Prop to a modern VGA screen that screen probably has enough processing power on board to run the Spin compiler.

    It does not make sense.

    It has not made sense since 8 bit computers and compilers running under CP/M.

    Stop poking yourself in the eye with that stick!
    I'm talking about an interactive language that runs on the target processor. You're quite correct that there are better alternatives if you accept a PC-based development environment.
  • jazzedjazzed Posts: 11,803
    edited 2013-12-30 11:12
    Urge to wretch mercifully not quoted.

    At least old-school basic is readable after a few months. May as well program in another write-only language like Brain***k. We have several interpreters like that around here too that just as many people have used.
    As for David's idea of making an infix variation (htrof?), I look forward to seeing what he comes up with. Maybe it will be (a less terse) lisp relative?
  • David BetzDavid Betz Posts: 14,516
    edited 2013-12-30 11:16
    jazzed wrote: »
    Urge to wretch mercifully not quoted.

    At least old-school basic is readable after a few months. May as well program in another write-only language like Brain***k. We have several interpreters like that around here too that just as many people have used.
    As for David's idea of making an infix variation (htrof?), I look forward to seeing what he comes up with. Maybe it will be (a less terse) lisp relative?
    It won't be a Lisp relative because that would require automatic memory management and hence kill the space and runtime efficiency of a Forth-like system.
  • KC_RobKC_Rob Posts: 465
    edited 2013-12-30 11:22
    Heater. wrote: »
    Sure you have, It's called Spin and PASM. Not only small and efficient but it's easier to write complex code in PASM than Forth.
    Much as I like PASM, I wouldn't go that far.
    Now, if the only computer you had was something of the power of a Z80 or Propeller and your only way to communicate with it was an ASR33 teletype or Morse Key, then yes, Forth is very impressive in that you can put a whole high level language (sort of) system into such a small machine and have a self hosting environment. Brilliant.
    You actually get quite a bit, paid for with very little penalty.

    It does not make sense.
    Oh but it does - there's still something to be said for the immediacy and proximity of interactive programming; certainly on smaller, deeply embedded systems particularly.

    David isn't completely off his rocker.
  • David BetzDavid Betz Posts: 14,516
    edited 2013-12-30 11:31
    KC_Rob wrote: »
    David isn't completely off his rocker.
    I wouldn't go that far! :-)
  • KC_RobKC_Rob Posts: 465
    edited 2013-12-30 11:35
    David Betz wrote: »
    I wouldn't go that far! :-)
    LOL! Fair enough. I'll only say that you haven't put your eye out -- yet. :)
  • Heater.Heater. Posts: 21,230
    edited 2013-12-30 14:12
    David,
    I'm talking about an interactive language that runs on the target processor. You're quite correct that there are better alternatives if you accept a PC-based development environment.
    Yes I know. That was the whole point of my post. We are living in a ocean of silicon perpetually surrounded by compute power, all networked as a bonus. There is little point in suffering just for the sake of having the dev environment on the Prop.

    KC_Rob,
    ...there's still something to be said for the immediacy and proximity of interactive programming;
    I do agree. That is the attraction and the frustration of the "try to like it" part. Until such time that I can actually write any even marginally useful program in Forth with out having a nervous break down there is no advantage to that immediacy. I have had an easier time editing op codes in HEX using the monitor programs of 6800 and Z80 microprocessor systems.

    Besides, writing in Spin and hitting the compile/download button is as interactive as I ever need a system to be.
  • David BetzDavid Betz Posts: 14,516
    edited 2013-12-30 14:23
    Heater. wrote: »
    David,

    Yes I know. That was the whole point of my post. We are living in a ocean of silicon perpetually surrounded by compute power, all networked as a bonus. There is little point in suffering just for the sake of having the dev environment on the Prop.

    KC_Rob,

    I do agree. That is the attraction and the frustration of the "try to like it" part. Until such time that I can actually write any even marginally useful program in Forth with out having a nervous break down there is no advantage to that immediacy. I have had an easier time editing op codes in HEX using the monitor programs of 6800 and Z80 microprocessor systems.

    Besides, writing in Spin and hitting the compile/download button is as interactive as I ever need a system to be.
    But not every interactive language is Forth. As you've pointed out, there is at least one microcontroller version of JavaScript and I think one of Python as well.
  • Heater.Heater. Posts: 21,230
    edited 2013-12-30 14:30
    Thank goodness for that. At least those languages do not cause epilepsy :)
  • David BetzDavid Betz Posts: 14,516
    edited 2013-12-30 15:02
    Heater. wrote: »
    Thank goodness or that. At least those languages do not cause epilepsy :)
    Really, I don't know why there is so much hate of Forth. It may not be your choice as a good interactive language but people have used it effectively and it's currently the best that is available for the Propeller.
  • potatoheadpotatohead Posts: 10,261
    edited 2013-12-30 15:04
    The magic of Forth and the reason it has the expression structure it does boils down to being able to have a very small, simple kernel.

    A core set of words runs in that, to which everything else is built.

    I am curious about what that core looks like for more standard expressions.
  • David BetzDavid Betz Posts: 14,516
    edited 2013-12-30 15:08
    potatohead wrote: »
    The magic of Forth and the reason it has the expression structure it does boils down to being able to have a very small, simple kernel.

    A core set of words runs in that, to which everything else is built.

    I am curious about what that core looks like for more standard expressions.
    I'm sure that the kernel for an infix language will be larger than a Forth kernel but I'm hoping it won't be *much* larger. In particular, I'm hoping to fit it in a Propeller without having to use external memory. If I can't achieve that goal, my secondary goal is to be able to use only external flash (program memory) and have my interactive language live within the 32k of hub memory without any external SRAM.
  • KC_RobKC_Rob Posts: 465
    edited 2013-12-30 15:19
    David Betz wrote: »
    Really, I don't know why there is so much hate of Forth.
    I don't get that either. But I imagine that for the most part it's a matter of taste, which invariably is a factor in language debates.

    The problem with other languages that provide the same or similar functionality is the huge performance hit you take for using them.
  • David BetzDavid Betz Posts: 14,516
    edited 2013-12-30 15:25
    KC_Rob wrote: »
    I don't get that either. But I imagine that for the most part it's a matter of taste, which invariably is a factor in language debates.
    Yes but that's a reason not to use it yourself. It isn't a reason to claim that it is useless for everyone.
    The problem with other languages that provide the same or similar functionality is the huge performance hit you take for using them.
    I don't believe that it is impossible to create other languages with similar performance. It just hasn't been done yet on the Propeller.
  • potatoheadpotatohead Posts: 10,261
    edited 2013-12-30 15:27
    Should be interesting!
  • David BetzDavid Betz Posts: 14,516
    edited 2013-12-30 15:32
    potatohead wrote: »
    Should be interesting!
    The problem of course will be that any language simple enough to fit on the Propeller will probably not be a "standard language" so won't be interesting to most people. This is probably just an academic exercise with no practical value.
  • localrogerlocalroger Posts: 3,451
    edited 2013-12-30 16:03
    David Betz wrote: »
    I'm sure that the kernel for an infix language will be larger than a Forth kernel but I'm hoping it won't be *much* larger. In particular, I'm hoping to fit it in a Propeller without having to use external memory. If I can't achieve that goal, my secondary goal is to be able to use only external flash (program memory) and have my interactive language live within the 32k of hub memory without any external SRAM.

    David, having done a number of things like this over the years, I would suggest that instead of Forth you consider Tiny BASIC as a starting point. It's not very efficient but it's very, very small. The interpreter probably wouldn't fit in a Cog but the runtime kernal would, and the interpreter could be written in (somewhat extended) Tiny BASIC.

    Original TB stores line numbers in binary and the rest of the program in ASCII. There are 26 permanent variables named A-Z, and whatever memory is left over is devoted to a "vector" array addressible from !(0) to !(whatever). Strings are not supported. The math expression evaluator uses recursion to implement true precedence of operators and containing function calls with full expressions as arguments within expressions.

    Once you get it running, you have a number of mostly very easy optimization paths.

    * Add a tokenizer so you can use a tables instead of parsing keywords at runtime.
    * Tokenize numeric constants
    * Create a separate line number table and use binary search instead of linear scan to find jump targets
    * or better, create jump tokens with space for an address to be pre-compiled in pre-runtime
    * Add a string vector growing from the opposite end of space, with fixed length storage
    * Add DIM and fixed variable storage eating away at the vector
    * Add procedure names (still needing line numbers for the simple editor though)
    * Static local variables of the internal form procname_varname if DIM is in a PROC

    Most of this is trivially easy once you've understood and ported the original simple Tiny Basic interpreter, and can add up to a surprisingly capable development environment. Here is a version that adds strings very similar to the one I reverse engineered when I was a teenager:

    http://www.vintagecomputer.net/cisc367/DrDobbs%20Apr%2076%20Minol%20Listing%20w-corrections.pdf
  • Heater.Heater. Posts: 21,230
    edited 2013-12-30 16:06
    David,
    I don't believe that it is impossible to create other languages with similar performance.
    When you say "performance" do you mean execution speed of the finished program or the expressive power of the syntax/semantics and the much lauded interactivity.?
    Or perhaps all of that?

    Because...I have always assumed, perhaps wrongly, that the reason Forth manages to pack all that performance, in all the above ways, into such a small space is precisely because of it's stack based RPN syntax.

    That is to say there is no other language that can do that, unless it looks and behaves much as Forth does.

    It will be interesting to see what you come up with.
Sign In or Register to comment.