Ok this has been bugging me for a while but because @CatsAreFluffy recently brought it up, I thought it might be a good time to bring this up.
Mismatched brackets do not necessarily cause Brain-Flak to error. Here are three examples of mismatched brackets that do not cause an error, each for a different reason:
(()()) #I'm a mismatched bracket :)
(<><>){I'm a mismatched bracket :)}
(()){()}I'm a mismatched bracket :)
1, 2, 3
The first one is obviously not a problem; its just a comment doing its job, however the next two are iffy. They are in portions of non-executed code, the first because it is skipped by a loop and the second because a infinite loop prevents the code from being run.
The reason this behavior exists is that balance checking is done during run time rather than compile time. Currently a bracket can only be mismatched if it is run. The solution to this "problem" would be to check for mismatched brackets before we begin running the program.
Is this a Problem?
In short, I'm not sure there is a pretty good case both ways. I'll start with the case that these are bad, and I'll start this case with a quote from DJMcMayhem:
The whole point of the language is the matching bracket restriction.
Brain-flak is the language of balanced brackets, thats what its about. We should stick to our values and enforce this restriction no matter what.
The next reason why it might be a good is error messages. Currently our mismatched bracket error messages are rather useless. Take this for example:
Where's the Mismatched bracket? ( <--- Is it that one?
>){}(<>[()]{})({({}()<(())>)})(({({}[])({}{})}<({})<(()({}))<>>(())>)<[]>
^ No its that one
When run this will output the rather unhelpful:
Error at character 33: Unmatched '(' character.
Make no mistake the 33rd character is a perfectly closed (
, however Brain-Flak really just means that the 33rd bracket is mismatched (I don't know why I wrote the error messages to say Unmatched
that's not a word). If Bracket matching was checked at compile time, this would be incredibly easy to check. It is possible to check with the current system, but it would be rather difficult and inconvenient, and likely would cause some slow down in the system. These messages really have to be fixed, and if the new system makes this easier thats a pro right?
Ok, tell me has this ever happened to you?
You just finished writing a massive Brain-Flak program, maybe your latest Mini-flak quine that takes hours to run, so you start it running so you can test it. You get up, get a drink, come back and the program is running, so you open the review queue, you review a couple of low quality posts and the program is still running, so you get another drink, you come back and its still running, so you figure it would be a good time for a nap. When you wake up from your nap the program has finally finished running. Like a kid on christmas morning you rush over to see if it worked.
Error at character 1516: Unmatched '<' character.
If enforced that all programs must be fully matched we could avoid this situation altogether. A compile time check would tell you in an instant whether or not you are going to encounter a bracket mismatch. Currently checking if a program is syntactically valid is equivalent to solving the halting problem and cannot be done at compile time. The only way to have a check at compile time is to make our check into something that can be computed. Whether or not brackets are matched is computable.
Ok, here's why we might want to keep it the way it is.
It will take longer to run every program with a compile time check. Our interpreter is already pretty bloated and slow, we should avoid any more overhead on programs. Our current system is pretty smart for checking the bracket matches as it runs the program. The current system might cause issues in a couple of places, but we would need to have this overhead every time we run a Brain-Flak program.
You can check yourself. If you have a giant program or want to make sure that your program wont error before you start it off, you can just check if its balanced using a pretty simple script. If you want you could even alias
it to do so every time you run a Brain-Flak using a little bit of bash
magic. This way people running small programs don't have to bother with the overhead each time.
It would not be backwards compatible. The behavior has been like this since the beginning of Brain-Flak, changing it would break at least one program I've written. I'm usually against legacy decisions like this one, but I've put this in here because I know that it might make a difference to some people, and they are entitled to that opinion.
We are writing an esolang, its just a quirk of the language. "practical" and "good practice" are not in our vocabulary. It just adds a little bit of spice to Brain-Flak that can be used to interesting effect, particularly in polyglot challenges.
What we should not do
Ok, I've been pretty flimsy on everything about this so far, but here I am going to take a stand. We should not add a new flag. I feel like every time we discuss a new change this is brought up by someone (sometimes me). We have a lot of flags right now, and we don't need another flag for something that might not even be noticeable. We should make a hard decision and stick with it.
We should also not do nothing. The two major problems mentioned in the first section should at least be attempted to be fixed. Our error messages are really bad right now. If we are not going to check balance before we run a program we should at least give people the option to do something when their program crashes several hours in. This may be allowing users to see the data, or even modify their code after the error to fix the problem and then resume execution.