5 ms·
Here's why it's interesting: https://termbin.com/blz3 https://termbin.com/blz3 There you go, now it has parens, just backwards. Can even use parens instead of
by veltas 2y ago
Here's why it's interesting: https://termbin.com/blz3 https://termbin.com/blz3
There you go, now it has parens, just backwards. Can even use parens instead of braces if you want, I just didn't want to overwrite comment syntax.
- Y_Y 2y agoI copy your code below, because it's so terse and marvellous and I don't want to deprive anyone who assumes otherwise and doesn't click on your link: : >BRACES 1 CELLS BRACES +! BRACES @ ! ; : BRACES> BRACES @ @ -1 CELLS BRACES +! ; : { DEPTH >BRACES ; : } DEPTH BRACES> 1+ <> ABORT"unbalanced" ; And the example "backwards lisp" expressions you give as test cases: { 1 2 + } . { 5 { 1 2 + } * }
- James_K 2y agoI don't find that particularly interesting. My entire point was that it has essentially the same semantics as lisp, and this just demonstrates that. Also, I don't know a lot about Forth, but it would seem to be limited to 30 levels of brace nesting, even between functions. Unless I am mistaken, it requires a pointless increment and decrement of a variable before and after every function call. I also don't know if it would work in a threaded context. Aren't those just functions? If so, it wouldn't work in compiled code.
- veltas 2y ago> it would seem to be limited to 30 levels of brace nesting Yes because I declared 30 cells, you can declare more if you want. > Unless I am mistaken, it requires a pointless increment and decrement of a variable before and after every function call. Yes it adds overhead, you can rebuild with : { ; IMMEDIATE : } IMMEDIATE ; and then there's zero overhead on any Forth, when you've demonstrated the braces match. This is meant as an aid for people that struggle without parens. > Aren't those just functions? If so, it wouldn't work in compiled code. It works in compiled and interpreted code, 'just functions' compile automatically without trouble in Forth, it's parsing words and immediate words that need care. No that code wouldn't work with multiple threads, but if you declare the space as USER space it would, similar to just whacking 'thread_local' on something. The example is failing in one regard, that it doesn't provide a way to reset the stack if something goes wrong. You can use something like : RESET{} BRACES BRACES ! ; to accomplish that. But it is just meant to show that Forth is quite succinct and powerful, which it does.
- James_K 2y ago> you can rebuild with : { ; IMMEDIATE : } IMMEDIATE ; Does the call to DEPTH still work in that case? > But it is just meant to show that Forth is quite succinct and powerful, which it does. How does it show that? You could write a similar function in almost any programming language, with the only difference being the call to DEPTH which I don't see as being generally that useful. As an example in common lisp: (defvar depth nil) (defun { () (push (depth) depth)) (defun } () (unless (and depth (= (depth) (pop depth))) (error "Unbalanced expression"))) And this example doesn't stop working after a certain number of open braces. It's simultaneously more readable and more terse than the Forth code. Saying that Forth is powerful just because you can use it to write a compiler for a more powerful language is silly. By the virtue of Turing-completeness, you can do this for any language.
- veltas 2y ago> Does the call to DEPTH still work in that case? Code using the braces can use those definitions when you want to remove the overhead, and it disables the feature. This lets you use it as a programming aid, and then remove the overhead completely when it's not necessary or for a 'release build'. > It's simultaneously more readable and more terse than the Forth code. Does it still look neater when you use the syntax you've defined? > And this example doesn't stop working after a certain number of open braces. If you really want to remove the limit you can, Forth is just explicit about memory management. This is like C vs JavaScript. I'm quite happy playing with memory management myself, but if you don't like that or think declaring a fixed size stack is hacky then I can see why Forth wouldn't be appealing. Here is one way to remove the limit, it has drawbacks (but so do all dynamic memory approaches, they're just hidden by managed languages). : POP HERE -1 CELLS + @ -1 CELLS ALLOT ; : { DEPTH , ; : } DEPTH POP 1+ <> ABORT" Unbalanced" ; > Saying that Forth is powerful just because you can use it to write a compiler for a more powerful language is silly. Yes but in a few lines of simple code, and the result is actually a syntax that looks nice to use.
- James_K 2y ago> This is like C vs JavaScript. And you'll notice that C isn't a very powerful language. > Does it still look neater when you use the syntax you've defined? No because in CL you would define a with- macro that syntactic enforces equal nesting. So the CL version is: (defmacro {} (&rest args) `(progn ,@args)) I thought that would be too trivial demonstrate though. If you really don't like how it looks, you can fix it with two more lines of reader macros. The result would be a nicer syntax as you wouldn't have to put spaces around the braces. > Yes but in a few lines of simple code, and the result is actually a syntax that looks nice to use. Those are a few lines of highly complicated code that does something very simple and just happens to use the short function names { and }. The actual implementation of those functions is easier to write in almost any other language, which is what I was demonstrating with the CL example. If you want to make the case that Forth is powerful, you need to do more to prove it than show you can hack together a half-solution for a problem Forth created. Forth simply isn't a powerful language when counting matching braces is a difficult problem.