It is not a runtime warning. It is a compiler warning while assembler output is being generated.caseih wrote:EDIT: wait a second. Your little screen shot seems to indicate you want a runtime warning. That's simply not possible in FB (nor in C).
Should an error be thrown here? (A Function calls itself)
Re: Should an error be thrown here? (A Function calls itself)
Re: Should an error be thrown here? (A Function calls itself)
Oh gotcha. That wasn't clear at all.
Note that the warning is actually false, though. In your example code there is no possibility of recursion, since the recursive call is in unreachable code. The correct compiler warning would probably want to be something about the fact there is unreachable code.
Anyway it's a unique feature I've not seen anywhere else. I'm sure it's useful to you and people who use SharpBASIC. I don't expect to see in FB, however.
Note that the warning is actually false, though. In your example code there is no possibility of recursion, since the recursive call is in unreachable code. The correct compiler warning would probably want to be something about the fact there is unreachable code.
Anyway it's a unique feature I've not seen anywhere else. I'm sure it's useful to you and people who use SharpBASIC. I don't expect to see in FB, however.
Last edited by caseih on Apr 15, 2020 22:11, edited 1 time in total.
Re: Should an error be thrown here? (A Function calls itself)
No, the code is not unreachable. Unlike FreeBasic, SharpBASIC uses the semicolon as statement terminator. As the comment says, testing an empty return statement without semicolon will include the next line.caseih wrote:Note that the warning is actually false, though. In your example code there is no possibility of recursion, since the recursive call is in unreachable code. The correct compiler warning would probably want to be something about the fact there is unreachable code.
Re: Should an error be thrown here? (A Function calls itself)
Oh okay. I see. That is definitely a gotcha. I see where you're coming from and why you would need that warning. Such a bug wouldn't happen in FB, hence I don't see a need for the warning.
Re: Should an error be thrown here? (A Function calls itself)
The reason why I checked FBC's behavior in this is because SharpBASIC is currently being written in FreeBasic, though eventually it's supposed to become a self-hosting compiler.
Re: Should an error be thrown here? (A Function calls itself)
Hi. Is it me or anyone else think it's not BASIC but a mix between Python + Go + Pascal?Munair wrote:I'm not here to say that FreeBasic should implement a hint / warning for potential infinite loops, but it would help if a switch could enable it to trace down potential pit falls. And yes, it can be done, as I'm currently developing just that for the SharpBASIC compiler.
I think you should give your language another name.
Re: Should an error be thrown here? (A Function calls itself)
Emphasis is on 'sharp'. And yes, it breaks with BASIC's tradition of verbosity and ambiguity. But it is still BASIC in that it has educational value and that it is easy to understand, even for someone not yet familiar with the language.systemctl wrote:Hi. Is it me or anyone else think it's not BASIC but a mix between Python + Go + Pascal?
I think you should give your language another name.
Re: Should an error be thrown here? (A Function calls itself)
@Munair: B#? XD
I kind of like it. Sometime ago, I tried to spark my 11 yo daughter's curiosity (since she's been watching me doing it ever since she was born), and leverage her interest on the subject when we were 'working' together for the last compo organized by Lachie.
So, I quickly threw together a compiler for a Logo + Forth crossbreed, complete with turtle graphics for her to play with. She picked it up rather quickly, despite my concerns. I thought that the stack concept, along with working with it, were going to give her troubles; it turned out that it prompted some very interesting conversations about why the world at large has adopted infix notation instead of RPN (among other things) since we were studying the basic mathematical notions of term, factor, and parens at the time. Seems like teachers here in Argentina can't be bothered anymore with this kind of stuff...
Unfortunately, like most kids of her generation, her attention span is quite limited so she wrote 2 or 3 programs and decided that coding wasn't for her XD
I kind of like it. Sometime ago, I tried to spark my 11 yo daughter's curiosity (since she's been watching me doing it ever since she was born), and leverage her interest on the subject when we were 'working' together for the last compo organized by Lachie.
So, I quickly threw together a compiler for a Logo + Forth crossbreed, complete with turtle graphics for her to play with. She picked it up rather quickly, despite my concerns. I thought that the stack concept, along with working with it, were going to give her troubles; it turned out that it prompted some very interesting conversations about why the world at large has adopted infix notation instead of RPN (among other things) since we were studying the basic mathematical notions of term, factor, and parens at the time. Seems like teachers here in Argentina can't be bothered anymore with this kind of stuff...
Unfortunately, like most kids of her generation, her attention span is quite limited so she wrote 2 or 3 programs and decided that coding wasn't for her XD
Re: Should an error be thrown here? (A Function calls itself)
Apparently, I overlooked that statement. The code will definitely cause the program to crash because it will run out of stack space, also in FB. Try the following FB code:caseih wrote:The example you gave would not crash with a segmentation fault. Why do you think it would?
.
This example, a procedure calling itself is the most obvious. But even if recursion is multiple levels deep and indirect with different procedures in-between, a 'stack' mechanism might be able to keep track of the depth and the procedures involved. By 'stack' I mean that a procedure called by another, is pushed on a list. The called procedure will do the same and so forth and so on. When a procedure ends, it pops off the previous one, which will be current again. Example:
Code: Select all
sub one()
' push previous proc (if any)
pitr.push()
pitr.proc = current_proc
call two()
' previous proc becomes current again
pitr.pop()
end sub
sub two()
'push proc 'one' (if it called 'two')
pitr.push()
' 'two' becomes current
pitr.proc = current_proc
call one() ' recursion (if 'two' is called by 'one')
' proc 'one' becomes current (if it called 'two')
pitr.pop()
end sub
In the case of procedures, the compiler can go through the list with each call and check if the same one has been called before and also how many times. A hint/warning could be raised immediately or after a specific amount of nesting, whatever. Currently SharpBASIC supports a compiler directive 'option norec' to indicate that recursion is not meant to occur or to deliberately raise the warning messages to see where in the program recursion occurs. Unintended recursion can then be tracked more easily.
Re: Should an error be thrown here? (A Function calls itself)
Sure you can tack as much runtime checking as you want onto a language. FB has some runtime checking you can enable with -exx, particularly in relation to bounds checking. But if you tack enough on, you'll end up with essentially an interpreter.
I repeat what I've said. I've never seen an actual segmentation fault in the wild from "accidental" recursion, at least the kind a compiler warning would flag. I've seen plenty of crashes from out of bounds referencing, though!
I can also see, however, how syntax choices you made in your SharpBASIC language can lead to such accidental recursion and crash (forgetting a semicolon). But as I mentioned, that kind of bug cannot be made in FB, or C. Personally if I were you I'd warn about the missing semicolon before I'd warn about the recursive call, or better yet make it impossible to make that kind of error. But I can understand and accept your recursion warning in this context.
Can you name any language other than SharpBASIC that can, with the right flag or "strict" option warn about recursion? I can't think of any.
Furthermore, how would you propose to detect and warn about recursive calls where more than one function is involved? Without doing some code path analysis, it's not a simple thing for a compiler. And like I said, the warning would be wrong nearly all the time.
I repeat what I've said. I've never seen an actual segmentation fault in the wild from "accidental" recursion, at least the kind a compiler warning would flag. I've seen plenty of crashes from out of bounds referencing, though!
I can also see, however, how syntax choices you made in your SharpBASIC language can lead to such accidental recursion and crash (forgetting a semicolon). But as I mentioned, that kind of bug cannot be made in FB, or C. Personally if I were you I'd warn about the missing semicolon before I'd warn about the recursive call, or better yet make it impossible to make that kind of error. But I can understand and accept your recursion warning in this context.
Can you name any language other than SharpBASIC that can, with the right flag or "strict" option warn about recursion? I can't think of any.
Furthermore, how would you propose to detect and warn about recursive calls where more than one function is involved? Without doing some code path analysis, it's not a simple thing for a compiler. And like I said, the warning would be wrong nearly all the time.
Re: Should an error be thrown here? (A Function calls itself)
The example is overly simplified. Actually SharpBASIC is not doing any runtime-checking (yet). The procedure stack happens at compile time when the procedure bodies are parsed. Same goes for nested expressions.caseih wrote:Sure you can tack as much runtime checking as you want onto a language. FB has some runtime checking you can enable with -exx, particularly in relation to bounds checking. But if you tack enough on, you'll end up with essentially an interpreter.
Beginners definitely make that kind of mistake, and it is easy to make, thinking you return a function's result, but calling it again in the process. Most professional compilers like C, C++ are hardly beginner friendly in this respect.I repeat what I've said. I've never seen an actual segmentation fault in the wild from "accidental" recursion, at least the kind a compiler warning would flag. I've seen plenty of crashes from out of bounds referencing, though!
It is impossible to warn about missing semicolons if the code over several lines is syntactically correct. I made the recursion mistake myself while testing (luckily), which inspired me to support recursion warning.Personally if I were you I'd warn about the missing semicolon before I'd warn about the recursive call, or better yet make it impossible to make that kind of error. But I can understand and accept your recursion warning in this context.
Not that I know of, but that is not an indication. My programming experience is limited to several BASIC and Pascal family languages and a bit of Go. And except for FPC, I have not tested all of them.Can you name any language other than SharpBASIC that can, with the right flag or "strict" option warn about recursion? I can't think of any.
I will have to do further testing to see what does and what doesn't work. But at least a comparison can be made against the procedure that started the chain.Furthermore, how would you propose to detect and warn about recursive calls where more than one function is involved? Without doing some code path analysis, it's not a simple thing for a compiler. And like I said, the warning would be wrong nearly all the time.
Re: Should an error be thrown here? (A Function calls itself)
Not impossible at all. To the parser the syntax tree looks the same whether its over several lines or one line.Munair wrote:It is impossible to warn about missing semicolons if the code over several lines is syntactically correct.
Yes I can see how your chosen syntax would lend itself to making that mistake. But you wouldn't have made that mistake in FB code, since multi-line statements require an explicit continuation character. Hence no warnings are necessary in the FreeBASIC compiler. That's my point really, and the topic of this extended thread.I made the recursion mistake myself while testing (luckily), which inspired me to support recursion warning.
I can see that you might want a warning in your language. But perhaps you might want to revisit this aspect of your syntax. For example, eliminate the redundant "functionname=result" syntax and just do simply, "return result." You've got the luxury of being able to make this change early on before there's any pre-existing code that depends on it. Doing this would completely prevent this type of problem.
Hopefully you'll get SharpBASIC to the point where you can use it to make itself! That's when the fun begins.
Re: Should an error be thrown here? (A Function calls itself)
That syntax is not redundant at all. There are times when you want to set the function result before leaving the function, even in FreeBasic:caseih wrote:For example, eliminate the redundant "functionname=result" syntax and just do simply, "return result."
Code: Select all
function tparse.label_new() as tlabel
label_new = "_L" + str(lcnt)
lcnt = lcnt + 1
end function
Re: Should an error be thrown here? (A Function calls itself)
One side of the problem is the double use of "=" for assignment and equality. You might also want to reconsider that.
I also think that I would never choose functioname= syntax for a new language, but rather the result:= syntax, even though it wouldn't matter for this example I think. Simply because when refactoring you have to also rename all instances of it.
Note that depending on FPC mode, an extra () is required for recursion.
I also think that I would never choose functioname= syntax for a new language, but rather the result:= syntax, even though it wouldn't matter for this example I think. Simply because when refactoring you have to also rename all instances of it.
Note that depending on FPC mode, an extra () is required for recursion.
Re: Should an error be thrown here? (A Function calls itself)
Right, I see what you're saying. Everything involves tradeoffs. Some end up being more costly than others. Your combination of FB-style function return syntax (a return statement as well as a function=expression syntax), the optional end of statement semicolon, the calling of functions without (), and allowing "=" as an assignment operator inside expressions, leads to the problem of accidentally recursively calling your function. Changing even one of those things would eliminate the problem. Given the probability of this being a source of bugs for the programmer, it's worth considering the options to change one or more of those four factors. There's nothing wrong with learning from the mistakes of other languages! Having an improved language is better than a compiler warning any day.
I like Marcov's suggestion of having a standard name for the function result that's not the same as the name of the function. I think other languages do that. FreeBASIC allows you to use "Function=someval" which is a more sensible thing than using the name of the function.
I like Marcov's suggestion of having a standard name for the function result that's not the same as the name of the function. I think other languages do that. FreeBASIC allows you to use "Function=someval" which is a more sensible thing than using the name of the function.