Closed aanastasiou closed 2 years ago
Great feedback! This change would require a few changes to the standard library, but fortunately it's still small so that shouldn't be a problem. I have to admit that I didn't really think about the practicality of multiple ifs when I added them.
I'll add this to my list of things to work on today and I'll keep the issue open until this has been implemented.
@cerus Hi, thanks for such a quick response.
For this one, I think it's the other way around, for while
you can leave the condition expression on the stack but not for if
which results in the different flavours.
All the best :)
I was planning on implementing it like this:
eq / neq / gt / gte / lt / lte will peek the top two items of the stack, perform a comparison and push the result (0 or 1). Peeking instead of popping would reduce the amount of required commands if the user wants to use these values after the comparison.
if will pop the top item and only fire if the value is > 0.
while and until will remain the way they are - they will continue to peek.
What do you think about this?
Implemented in 3aa12f949425895bcd83f4efc94b36aad3b62059. Thanks again for the great feedback!
I was planning on implementing it like this:
eq / neq / gt / gte / lt / lte will peek the top two items of the stack, perform a comparison and push the result (0 or 1). Peeking instead of popping would reduce the amount of required commands if the user wants to use these values after the comparison. [...] What do you think about this?
Hi there. Very quick once again. Making these comparison functions peek rather than pop and push might be premature optimisation. After all, these functions can be very useful when evaluating other expressions anyway. So, I would say keep them "standard".
If you are interested in the concatenative paradigm, I would suggest that you maintain a core subset of "words" as close as possible to the original Forth and expand that with features that make your language (e.g. Edina) more special. This will give you a baseline language that programmers that are familiar with concatenative languages would not spend too much time bending their head around the basics.
You might find the following interesting, if you have not come across them already:
All the best
Hey,
thank you for providing me with these great resources. Edina currently has routines, which is kind of the same as words from Forth, but much more verbose. Your comment is making me think about implementing words as well. I think they could coexist together nicely because they both have matching tradeoffs:
Routines | Words |
---|---|
Global & Internal | Always global |
Very verbose | Very minimalistic |
Must be explicitly called (:import.routine ) |
Automatically imported into the script with the import command, can be used directly |
Routines trade off flexibility for simplicity whereas with words it's the other way around.
# Declaration would be the same for both:
rt pop2
pop pop
end
word pop2
pop pop
end
.pop2 # Routines need the '.' in front to signal a routine call
pop2 # Words can be used directly
# --------------------------------------------------------
import "my_pop2_script.edina"
:my_pop2_script.pop2 # We need to specify the import name if we want to call a foreign routine - very verbose
pop2 # Words are automatically imported into this scope, we can use them directly
# ---------------------------------------------------------
# Routines can be internal which prevents other scripts that import this one from accessing the routine:
rt _my_internal_routine
"Secret code"
end
# Words can not be internal, they can always be used by scripts that import it
Again, I can not thank you enough for providing me with feedback and resources. It's always nice to see when someone takes the time to engage with your project. :)
No worries.
Re: routines Vs "words", it would probably be better to unify the two. Provide one interface that makes the distinction between valid data type that can go on the stack and a symbol. When you encounter a symbol you call it with the current stack state. How it gets resolved or referenced is a different matter (e.g, the built-ins could be imported at the same scope as the entry point and then preserved throughout).
All the best
Hi, just a note really: I found having different flavours for
if
test conditions a bit of an odd choice, instead of offeringeq, lt, lte, gt, gte
binary functions that respond withtrue
,false
and then having a singleif
, which would lead to leaner code. This is also a bit of a contradictory decision to the waywhile
works.while
checks by default for a nonzero condition. Which means that "while a number is positive" has to involve anif
. With agt, lt, gte, ...
all you have to do is workout an expression and then letif, while
"branch" depending on the result of that expression.