You meant to say "more PERL-type languages," right?
In case anyone is wondering KC_Rob did mean "REPL".
REPL stabds for "Read, Execute (or Evaluate). Print Loop". As provided by many interpreted languages, Forth, JavaScript, Python, Scheme, BASIC etc etc.
The REPL in JavaScript is a bit odd though as you can be typing new JS code into it whilst other JS code is still running on the machine. You can change the code as it runs! The strict ordering of Read-Execute does not apply.
Do any other REPLs do that? As far as I know they all run to completion and then stop with a command prompt.
The PERL language does indeed have a REPL, hence the joke.
The day I see people pushing Perl as a language to use on micro-controllers I'm going to take up knitting for a hobby instead
The REPL in JavaScript is a bit odd though as you can be typing new JS code into it whilst other JS code is still running on the machine. You can change the code as it runs! The strict ordering of Read-Execute does not apply.
I think this is likely to be true of any language that offers a way to attach a piece of code to an event. Do you know how Espruino does this? I assume the code is triggered by an interrupt?
I think this is likely to be true of any language that offers a way to attach a piece of code to an event.
Perhaps true. As far as I know outside of JS no REPL implementations do that.
Thing is JavaScript has always been built around an event loop. The classic case is handlers in the browser that are triggered by mouse clicks or image load events etc.
Events are and asynchronous code are "baked in" to JS. There are ways to create event driven code in Python, and others, but then you have to be sure never to call any "normal" library functions that block execution of your even handlers and hence the entire system.
Even then I'm not sure that when using event loops in Python, say, the PEPL does not stop the whole thing when it get's back to the prompt.
Do you know how Espruino does this? I assume the code is triggered by an interrupt?
I have not looked into the code deeply but yes.
Like any other JS implementation the Espruino is all event based. Input from the command line REPL is just more events to handle. Ultimately events come from interrupts and are queued up for the event loop to handle.
This has the nice property that when there are no events coming in Espruino can put the chip to sleep for really low power consumption. The programmer does not have to think about that at all.
I think I got it right - REPL: Read-Eval-Print-Loop. But to put it more simply, good ol' interactive programming.
Quite correct. That's what it has always been called in the Lisp world anyway. In fact, those are the exact functions that are invoked:
(define (repl)
(print (eval (read)))
(repl))
While it is true that this type of interactive programming can be done in many languages, I think Forth still has the advantage of being able to do it with a minimum of machine resources, particuarly memory. I doubt very much that JavaScript, Python, or Lisp/Scheme could be made to run on a Propeller with no external memory attached. Maybe a stripped down Lisp would work but it wouldn't perform as well as Forth. I have never been a Forth programmer but I do admire the simplicity of the Forth engine.
I am beginning to suspect you are a tout in deep cover as a Propeller user from OpenAVR.
That is slanderous. I had never even heard of OpenAVR until you said that. Sounds interesting, I'm all for running Linux on anything that can sensibly do so (and a few things where it is not so sensible ).
The MicroPython does offer to port it to another microcontroller for 1000 pounds, and they will develop any library feasible for 300 pounds.
Sure. Pay people money and they do work for you. We could pay pay someone to make a Propeller target of the open source GCC compiler. Wait, Parallax already did that.
Sounds like there are several cavaets to being entirely open-source...
That does not take away from the open source nature of the thing. You can take the code and modify it yourself or you can pay someone to do it for you. What's the issue here?
...and complete.
Of course it's not complete. Not if you mean they should supply versions for every possible micro-controller ever invented out of the box.
I still hold to the opinion that the limited size and resources of a micro-controller are an educational asset.
I agree.
Why would anyone run a BasicStamp2 emulation on an Intel PC with a TByte harddisk?
I run code destined for micro-controllers on such machines everyday, You can do a lot of development and debugging on a host PC prior to sending it down to the
target. That saves a lot of time. In fact I'm sure that a huge amount of embedded systems code is developed that way, I have seen it done in many projects at various places.
You miss (or ignore) the whole point of small software on small systems being the heartbeat of microcontollers.
Not at all. See my, admittedly few and humble, projects on the forum.
While it is true that this type of interactive programming can be done in many languages, I think Forth still has the advantage of being able to do it with a minimum of machine resources, particuarly memory. I doubt very much that JavaScript, Python, or Lisp/Scheme could be made to run on a Propeller with no external memory attached. Maybe a stripped down Lisp would work but it wouldn't perform as well as Forth. I have never been a Forth programmer but I do admire the simplicity of the Forth engine.
Yes, I believe that is true, David. Forth, as a result of its simplicity, has advantages in terms of both performance and resource usage. That's not likely to change, either.
That code, at any one time, is either reading, evaluating or printing. There is no scope for doing all three at the same time. Or at least interleaved with events that make it look like it's all happening at the same time.
Forth still has the advantage of being able to do it with a minimum of machine resources, particuarly memory
That is for sure true.
By virtue of the fact that JS, Python, etc do actually have a useful syntax and semantics they are much bigger to implement.
That code, at any one time, is either reading, evaluating or printing. There is no scope for doing all three at the same time. Or at least interleaved with events that make it look like it's all happening at the same time.
No, you need to add this sort of function for that kind of behavior:
I run code destined for micro-controllers on such machines everyday, You can do a lot of development and debugging on a host PC prior to sending it down to the target. That saves a lot of time. In fact I'm sure that a huge amount of embedded systems code is developed that way, I have seen it done in many projects at various places.
This is how I do many of my Propeller and Arduino projects. My C++ inverse kinematics code was written and tested on a PC before being ported to the Arduino and my libPropelleruino. If you look at my Forth inverse kinematics thread, I intentionally wrote my code to be platform neutral between gforth and Propforth by defining compatibility words.
I am aware of what stack comments are for. Also that languages like C require you write a lot of other stuff before you get down to your "a = b + c", the actual work.
All that extra stuff is there for a reason. Defining types for example so that the compiler can handle them differently as required and/or remind you of type mismatch errors.
Dynamic languages have a lot less of that extra "stuff" you have to write before getting down to your work. And consequently the least compile time checking.
Some prefer one style some prefer the other.
FORTH like some other interpreted languages (LISP, Prolog, Smalltalk, Java-Bean-Shell to name a few ...) provides mechanisms for introspection
This is new to me. Actually given that Forth does not have a type system I wonder how it can have any kind of introspection. do you have a simple example?
Heater: Have you looked at how Espruino implements the background processing that you keep mentioning? I'm playing with an old interpreter I wrote ages ago and I'd like to add a feature like that to it.
This is new to me. Actually given that Forth does not have a type system I wonder how it can have any kind of introspection. do you have a simple example?
Heater: Have you looked at how Espruino implements the background processing that you keep mentioning? I'm playing with an old interpreter I wrote ages ago and I'd like to add a feature like that to it.
I downloaded the Espruino code and as you might expect they use interrupts for things like timers and monitoring pin edges. I think they have the ISR set a flag that gets polled by the REPL loop to see if a function needs to be called to handle an event but I'm not absolutely sure about that. It seems more like though than that they are calling JavaScript code from the ISR directly.
Thanks KC_Rob, haven't seen this.
I wanted to point to Peters disassembler module as an example.
And I know the other languages that I mentioned better than Forth.
It seems more like though than that they are calling JavaScript code from the
ISR directly.
I have yet to take a look but this seems very unlikely.
My mental model of Javascript execution as seen in the browser or node or Espruino goes like this:
1) From start up (Reset in the Espruino case) load some code from the web server or a file or in this case FLASH memory.
2) Make an initial pass through that JS instantiating any global variables, arrays, objects or functions (Which are objects anyway). If there are any expressions at global scope execute those in top down order. During this first pass events might be set up that will trigger later. By setInterval or file read for example.
3) Having dealt with the JS code in the first pass drop into the event loop. Here we check for any incoming events, I imagine they are lined up in a queue somewhere. If there are no events put the machine into low power mode. (In a browser or node you suspend waiting on an event from the OS).
4) When an event occurs, a signal from the OS or interrupt in the Espruino case, the signal/interrupt handler places an event into the event queue and wakes up the sleeping event loop.
5) Event loop pulls the event off the event queue and executes the JS function attached to it.
6) Having dealt with the JS function attached to the event drop back to the event loop and eventually wake up at step 4 again.
Somewhere in all this the console keyboard is an event being handled by the event loop like all the others. Except this time it's editing code which gets added to the existing code, or changing existing code at the same time as it is handling any other events.
We have to remember that JS itself is single threaded at all times. Therefore an interrupt cannot just trigger the execution of JS code. That would be disastrous. But an interrupt can queue up events that will cause the event loop to run JS functions when it is ready to.
I have yet to take a look but this seems very unlikely.
My mental model of Javascript execution as seen in the browser or node or Espruino goes like this:
1) From start up (Reset in the Espruino case) load some code from the web server or a file or in this case FLASH memory.
2) Make an initial pass through that JS instantiating any global variables, arrays, objects or functions (Which are objects anyway). If there are any expressions at global scope execute those in top down order. During this first pass events might be set up that will trigger later. By setInterval or file read for example.
3) Having dealt with the JS code in the first pass drop into the event loop. Here we check for any incoming events, I imagine they are lined up in a queue somewhere. If there are no events put the machine into low power mode. (In a browser or node you suspend waiting on an event from the OS).
4) When an event occurs, a signal from the OS or interrupt in the Espruino case, the signal/interrupt handler places an event into the event queue and wakes up the sleeping event loop.
5) Event loop pulls the event off the event queue and executes the JS function attached to it.
6) Having dealt with the JS function attached to the event drop back to the event loop and eventually wake up at step 4 again.
Somewhere in all this the console keyboard is an event being handled by the event loop like all the others. Except this time it's editing code which gets added to the existing code, or changing existing code at the same time as it is handling any other events.
We have to remember that JS itself is single threaded at all times. Therefore an interrupt cannot just trigger the execution of JS code. That would be disastrous. But an interrupt can queue up events that will cause the event loop to run JS functions when it is ready to.
I looked some more and this is exactly what is happening in Espruino. The ISR puts an event in a FIFO and the idle loop removes the event and calls the appropriate handler. In some cases, this is a key handler that gets handled by the editor which is why you can enter code at the same time as pin and timer events are firing. I'll try doing the same thing with my little interpreter although I guess I'll use another COG to watch for the pin events and fill the event FIFO in hub memory.
That looks cool. I'm trying to figure out if it's the kind of introspection I had in mind.
Obviously a running Forth function cannot determine the nature of the parameters it is given as Forth has no type system.
A Forth function has no idea how many parameters it has been given.
Can a Forth function rewrite other functions or even it self?
It would be possible to add type bits to a dictionary entry so that that parameters could be checked when entering a compiled word. This would require passing XT's to a word instead of just numbers and data pointers. Some Forth interpreters use a type bit to distinguish between a CONSTANT and a VALUE so you can't use TO on a constant. However, many Forths will allow changing the value of a constant.
A Forth word does know how many parameters it will use, and it could check the stack level to ensure that it has at least that many values.
Forth words can add to the dictionary. A Forth word can be defined to just be a pointer to a list of XT's, so you can dynamically change the function of a word by pointing to a different list. Of course, you could also modify the list in place, but self-modifying code is a risky thing.
It would be possible to add type bits to a dictionary entry so that that parameters could be checked when entering a compiled word. This would require passing XT's to a word instead of just numbers and data pointers. Some Forth interpreters use a type bit to distinguish between a CONSTANT and a VALUE so you can't use TO on a constant. However, many Forths will allow changing the value of a constant.
A Forth word does know how many parameters it will use, and it could check the stack level to ensure that it has at least that many values.
Forth words can add to the dictionary. A Forth word can be defined to just be a pointer to a list of XT's, so you can dynamically change the function of a word by pointing to a different list. Of course, you could also modify the list in place, but self-modifying code is a risky thing.
Dave, thanks for the detailed answer to Heater's question. Simply based on my admittedly novice observations, there really isn't much (if anything) Forth can't do - assuming one has the stomach for it.
Dave, thanks for the detailed answer to Heater's question. Simply based on my admittedly novice observations, there really isn't much (if anything) Forth can't do - assuming one has the stomach for it.
Same can be said for any programming language, once off the metal from firmware it's all up to the engineer to not shoot his/her foot off, unless your not an engineer yet and still need advanced training wheels thinking because it compiles it must be "all good". I really like the portability non-sense I hear as if you could take a C/C++ program designed specifically for the Prop and "run it" on your PC since after all it's in C/C++ and that language is portable. Also all the linker damage I see over on the C++ SD card thread is really amusing as well. Need a PHD in GCC just to understand the tools let alone have any brain space left for the actual problem. Can you say accidental complexity. Now back to the topic of this thread as you see Peter has release a very basic webserver which you can extend dynamically teaching it new "words" while never shutting down the server and watch users come in and hit the new words. Is that silence I hear or are you all busy trying to figure out how to dynamically inject new binary into sealed libraries because "whatever FORTH can do C/++ must do better" Stay on topic please or go to the sandbox with your off topic side discussions.
Let me help "Interactive Forth as a development language and tool vs "sealed" compiled code" <> C++ is better than FORTH <> C++ is portable <> I just hate FORTH <> I'm just prejudice and will not take the time and effort to learn anything new and would rather waste time complaining.
You really should have bracketed this with <rant>...</rant>. LOL
I don't know if this was directed at me or at comments in the thread more generally; I'll only say that most of my comments here (and elsewhere) about Forth have been on the positive side.
Yes, one can say the same for any programming language. But there are very complex things you can do in Forth that would be even more difficult (nigh impossible) to do in, say, C. That said, one is in many ways out alone on an island with Forth and has to build many things that come ready-made with other languages/tools. Thus, there is validity to much of what Dave said, for example. (Yet this could, I suppose, also been seen by some as an advantage.)
I've said before that there is no doubt in my mind that an experienced Forth programmer can be as productive as an experienced programmer in any other language, perhaps even more so. On the other hand, you really have to commit to it to get there.
It is never a surprise when a thread goes OT but who can help that, where do you draw the line initially? When it becomes clearer then forum etiquette should kick in and we can keep the thread OT (context sensitive OT IYKWIM). As for misunderstandings that has always been the way it is with forums but we are all big boys and girls here, as long as we don't get personal the forum is indeed a forum for exchanging thoughts and ideas. Sometimes I think certain comments might be directed at me but I've got a thick skin even if they are, which I don't dwell on too much. How many times have I deliberated and revised and edited a posting before I pressed the post button. "Why did I say that", "I hope it's not taken the wrong way", "but I hope they get the point", "it's easier face to face" etc.:)
However, I think all those comments were directed at you KC
I think even the big debaters have been positive, even if they did so inadvertently! If we never participated in forums, online or otherwise then we wouldn't have any of these misunderstandings and debates.Neither would we have such an opportunity to think differently and learn more either
However, I think all those comments were directed at you KC
Probably so. But it's all good. I'm pretty sure that in my reply, at least, I made my thinking on this topic reasonably clear. Mind you, I'm not saying my thinking is clear, however.
Probably so. But it's all good. I'm pretty sure that in my reply, at least, I made my thinking on this topic reasonably clear. Mind you, I'm not saying my thinking is clear, however.
Nothing personal, apologies if anyone took my comments poorly. I'm gonna refrain from these discussions that don't involve syntax or support for people looking for help with things I know how to do.
Nothing personal, apologies if anyone took my comments poorly. I'm gonna refrain from these discussions that don't involve syntax or support for people looking for help with things I know how to do.
No problem, D.P. I was, I admit, a little confused regarding context, but I didn't take any of it personally. We're good. I've enjoyed reading and participating in this thread.
Comments
REPL stabds for "Read, Execute (or Evaluate). Print Loop". As provided by many interpreted languages, Forth, JavaScript, Python, Scheme, BASIC etc etc.
The REPL in JavaScript is a bit odd though as you can be typing new JS code into it whilst other JS code is still running on the machine. You can change the code as it runs! The strict ordering of Read-Execute does not apply.
Do any other REPLs do that? As far as I know they all run to completion and then stop with a command prompt.
The PERL language does indeed have a REPL, hence the joke.
The day I see people pushing Perl as a language to use on micro-controllers I'm going to take up knitting for a hobby instead
Thing is JavaScript has always been built around an event loop. The classic case is handlers in the browser that are triggered by mouse clicks or image load events etc.
Events are and asynchronous code are "baked in" to JS. There are ways to create event driven code in Python, and others, but then you have to be sure never to call any "normal" library functions that block execution of your even handlers and hence the entire system.
Even then I'm not sure that when using event loops in Python, say, the PEPL does not stop the whole thing when it get's back to the prompt.
I have not looked into the code deeply but yes.
Like any other JS implementation the Espruino is all event based. Input from the command line REPL is just more events to handle. Ultimately events come from interrupts and are queued up for the event loop to handle.
This has the nice property that when there are no events coming in Espruino can put the chip to sleep for really low power consumption. The programmer does not have to think about that at all.
target. That saves a lot of time. In fact I'm sure that a huge amount of embedded systems code is developed that way, I have seen it done in many projects at various places. Not at all. See my, admittedly few and humble, projects on the forum.
That code, at any one time, is either reading, evaluating or printing. There is no scope for doing all three at the same time. Or at least interleaved with events that make it look like it's all happening at the same time. That is for sure true.
By virtue of the fact that JS, Python, etc do actually have a useful syntax and semantics they are much bigger to implement.
This is how I do many of my Propeller and Arduino projects. My C++ inverse kinematics code was written and tested on a PC before being ported to the Arduino and my libPropelleruino. If you look at my Forth inverse kinematics thread, I intentionally wrote my code to be platform neutral between gforth and Propforth by defining compatibility words.
I am aware of what stack comments are for. Also that languages like C require you write a lot of other stuff before you get down to your "a = b + c", the actual work.
All that extra stuff is there for a reason. Defining types for example so that the compiler can handle them differently as required and/or remind you of type mismatch errors.
Dynamic languages have a lot less of that extra "stuff" you have to write before getting down to your work. And consequently the least compile time checking.
Some prefer one style some prefer the other. This is new to me. Actually given that Forth does not have a type system I wonder how it can have any kind of introspection. do you have a simple example?
-Phil
I wanted to point to Peters disassembler module as an example.
And I know the other languages that I mentioned better than Forth.
My mental model of Javascript execution as seen in the browser or node or Espruino goes like this:
1) From start up (Reset in the Espruino case) load some code from the web server or a file or in this case FLASH memory.
2) Make an initial pass through that JS instantiating any global variables, arrays, objects or functions (Which are objects anyway). If there are any expressions at global scope execute those in top down order. During this first pass events might be set up that will trigger later. By setInterval or file read for example.
3) Having dealt with the JS code in the first pass drop into the event loop. Here we check for any incoming events, I imagine they are lined up in a queue somewhere. If there are no events put the machine into low power mode. (In a browser or node you suspend waiting on an event from the OS).
4) When an event occurs, a signal from the OS or interrupt in the Espruino case, the signal/interrupt handler places an event into the event queue and wakes up the sleeping event loop.
5) Event loop pulls the event off the event queue and executes the JS function attached to it.
6) Having dealt with the JS function attached to the event drop back to the event loop and eventually wake up at step 4 again.
Somewhere in all this the console keyboard is an event being handled by the event loop like all the others. Except this time it's editing code which gets added to the existing code, or changing existing code at the same time as it is handling any other events.
We have to remember that JS itself is single threaded at all times. Therefore an interrupt cannot just trigger the execution of JS code. That would be disastrous. But an interrupt can queue up events that will cause the event loop to run JS functions when it is ready to.
Obviously a running Forth function cannot determine the nature of the parameters it is given as Forth has no type system.
A Forth function has no idea how many parameters it has been given.
Can a Forth function rewrite other functions or even it self?
A Forth word does know how many parameters it will use, and it could check the stack level to ensure that it has at least that many values.
Forth words can add to the dictionary. A Forth word can be defined to just be a pointer to a list of XT's, so you can dynamically change the function of a word by pointing to a different list. Of course, you could also modify the list in place, but self-modifying code is a risky thing.
Same can be said for any programming language, once off the metal from firmware it's all up to the engineer to not shoot his/her foot off, unless your not an engineer yet and still need advanced training wheels thinking because it compiles it must be "all good". I really like the portability non-sense I hear as if you could take a C/C++ program designed specifically for the Prop and "run it" on your PC since after all it's in C/C++ and that language is portable. Also all the linker damage I see over on the C++ SD card thread is really amusing as well. Need a PHD in GCC just to understand the tools let alone have any brain space left for the actual problem. Can you say accidental complexity. Now back to the topic of this thread as you see Peter has release a very basic webserver which you can extend dynamically teaching it new "words" while never shutting down the server and watch users come in and hit the new words. Is that silence I hear or are you all busy trying to figure out how to dynamically inject new binary into sealed libraries because "whatever FORTH can do C/++ must do better" Stay on topic please or go to the sandbox with your off topic side discussions.
Let me help "Interactive Forth as a development language and tool vs "sealed" compiled code" <> C++ is better than FORTH <> C++ is portable <> I just hate FORTH <> I'm just prejudice and will not take the time and effort to learn anything new and would rather waste time complaining.
Thanks
I don't know if this was directed at me or at comments in the thread more generally; I'll only say that most of my comments here (and elsewhere) about Forth have been on the positive side.
Yes, one can say the same for any programming language. But there are very complex things you can do in Forth that would be even more difficult (nigh impossible) to do in, say, C. That said, one is in many ways out alone on an island with Forth and has to build many things that come ready-made with other languages/tools. Thus, there is validity to much of what Dave said, for example. (Yet this could, I suppose, also been seen by some as an advantage.)
I've said before that there is no doubt in my mind that an experienced Forth programmer can be as productive as an experienced programmer in any other language, perhaps even more so. On the other hand, you really have to commit to it to get there.
However, I think all those comments were directed at you KC
I think even the big debaters have been positive, even if they did so inadvertently! If we never participated in forums, online or otherwise then we wouldn't have any of these misunderstandings and debates.Neither would we have such an opportunity to think differently and learn more either
Nothing personal, apologies if anyone took my comments poorly. I'm gonna refrain from these discussions that don't involve syntax or support for people looking for help with things I know how to do.