When dealing with resources management and error handling goto is in my opinion the best option. At the start of the C function I declare a return variable and assign it the generic error return. Then I'm declaring the resources handles (mostly pointers) and setting them to NULL or whatever value represents the empty state. After the first resource allocation I write a comment that direct return is disallowed after this point. Instead the expression "goto cleanup_and_out;" shall be used to handle an error. And to signal success simply set the return variable to the success indicator. At the end of the function is the cleanup_and_out label. There will be all resources freed whose handle is not NULL or whatever value represents the empty state. After that I simply return the return variable from the beginning.
This pattern allows consistent graceful error handling while keeping resource safety. It also allows ownership transfer. Just assign a resource handle to the new owner of that resource and set the old resource handle to NULL.
The alternatives would be copy and paste the code of the deallocations in every error handling code or using tons of nested if statements.
It's bad because there's almost invariably a better way to write whatever you need a goto for.
I've actually run into a couple instances where goto resulted in an elegant solution, better than the alternatives. But 99.999% of the time there's a better alternative.
I'm thinking, could it be useful to introduce a command called TOGO which would basically be I want to export this context for later (label) but not have it now. So every local vars in that block would get moved to the label.
I was talking about C you Black person gorilla.
Plenty of languages have labelled breaks, doesn't make your troony lang special. >inb4 use Rust
Because I actually have to program instead of Larping on the internet, I don't get to choose what language I work with. It's decided by the project and use case.
Honestly, all this labeled break and continue is useless
All you need exactly one construct, a labeled return and a labeled scope around it and then it can implement continue and break as well.
As in something like 'label: { ... return 'label 4; ...}.
“break” is nothing more than returning to a scope one made directly outside of any loop, “continue” is nothing more than a scope directly inside of it. “return” itself is of course simply returning to a scope just inside of the function.
There is no performance equivalent for writing virtual machines with computed goto. Putting a switch in a loop can get the same functionality, but is not as fast.
It would need an array of pointers to functions, which is basically a computed goto with an extra indirection.
2 months ago
Anonymous
Calling a function is not a goto. Sometimes in assembly you need to push things to the stack (not on vms) and also on the language level you change scope. Also I think the goto option requires gnu c extensions so the advantage and reason to use function pointers is that they are more portable. I think they might end up not being as optimized in assembly tho if the compiler is not good enough. Maybe you could inline assembly to handle going to the next funciton and keep functions in an attempt to perserve portabilty and get maximum performance on this part.
Personally I'm not against goto. However because you can't jump across functions it forces your code to be less compartmentalised, for example when writting vms. The issue is more because you can't load labels that are in other functions for later use in the other function, bot for actually jumping to another function
2 months ago
Anonymous
Bypassing any context switching is a good reason to use goto in the first place, though.
With function pointers, it calls the function then returns to the dispatcher to advance to the next one. With computed goto, execution goes from one operation straight to the next with only a single jump. No need to jump back to the part that calls the next function. It's spaghetti-by-design, and can't be done in a language designed to avoid spaghetti code by omitting goto.
Breaking from nested loops by setting a flag which the outer loops check every iteration to decide to break is far less legible than a goto to the end of the loop.
Of course good languages have labeled breaks which can break from outer loops or continue them, which is nothing more than a restricted case of goto which stops it from being used in an asinine way, but when using goto like that of course no problem arises.
All statements such “while” as “return”,“break”, “continue” and hat-not are a restricted goto that are restricted in a way that they can't be used to generate unreadable code.
The thing is if Dijkstra was asked to comment on OOP he’d have an aneurysm. All the dynamic dispatch (polymorphism, interfaces) and implicit jumps (exceptions, raii) create spaghetti far worse than a simple goto. goto can at least be understood at compile-time and is essential to canonical implementations of computer science algorithms.
Because exceptions are considerably less flexible and unrestricted. They're again a restricted case of dynamic goto, which are essentially continuations.
In fact, the only real problem with exceptions is that in most languages they are untyped and a function's type signature doesn't indicate what exceptions it may throw. Checked, typed exceptions are as far as I can tell completely identical to returning and propagating a Result type except the latter is more convenient in that one can for instance store results into a data structure or loop over them and defer bubbling. Checked exceptions are nothing more than Results which are always and automatically bubbled.
2 months ago
Anonymous
>more convenient in that one can for instance store results into a data structure or loop over them and defer bubbling
You don't do that sort of thing very often, so it isn't worth making convenient. (You can do it with exceptions, but it takes more code. Given it's rarity, that doesn't really matter.)
2 months ago
Anonymous
Actually it's fairly common in rust.
People don't do it much in many languages because it doesn't really work there. Same with Haskell or Ocaml or other languages that mostly work with Result-like types for exceptional situations.
Real goto is unsupported in basically every language in use today besides assembly because it's incompatible with functions, that should tell you plenty.
Neutered C-style goto mainly makes up for missing features like cleanup. If you didn't have any loop constructs you'd obviously use goto for that as well, but we do have while loops, so you don't need it for that and nobody uses it for that.
There are a very small number of remaining use cases even in languages with a good feature set. It can make state machines more efficient.
>Real goto is unsupported in basically every language in use today besides assembly because it's incompatible with functions
That's not why because it can be used for control flow within a function. You don't allow goto to a location outside of the function, but labels/goto within it.
It's still almost always a bad idea, which is why it's not in very many languages.
Full goto in C is called longjmp() and it's regarded with horror for good reason. There are very very few legitimate use cases for it; I've never written code that needed it, but I've maintained code that included it in a few places. (Notably to smuggle a callback argument out of a non-terminating loop in the guts of a drawing library; horrible but worked).
2 months ago
Anonymous
It's useful if you want to compartmentalise your code in functions but these functions need to mamage jumps outside of other functions (like loading addresses of the jumps, which also makes sense to have a seperate function for, to load or select the next jump). Additionally I have used it to set up a specific environment in code I do not control in order to hack it but this is literally using code in ways not intented lol. So overall I'd say longjmp is more useful than simple goto
Reminds me of this gem: https://github.com/airbnb/javascript/issues/1103 >continue in a loop is worse than return in a forEach because…… IT JUST IS OKAY!!
My god, these people are clearly are just following rules they read somewhere without thinking: >Continue is not goto. That's like saying loops are goto. >@SelaO no, it's not like saying that. Loops that use break or continue are goto.
>It's just subjective
Look at pic related from the GitHub thread. >perfectly reasonable usage of some
.some is a js function to test if some element in an array matches the predicate. In his example, you could replace it with find or findIndex, and the functionality doesn't change.
First, he's mutating a variable from outside the function into a callback of something that's a search function, and shouldn't just mutate stuff.
Second, if the function you're using is interchangeable by multiple others, you're probably using it wrong. >perfectly reasonable usage of some when hidden by a presumably well-tested abstraction
It's good when you hide it LOL. >It also has the benefit of giving you array iteration method semantics largely for free, which you’d have to do manually when implementing with a loop.
He abstracted two arguments from some into ...args: the index of the current iteration, and the full array. For comparison, the classic for loop:
function take(arr, predicate, count = Infinity) {
const taken = [];
for (let i = 0; i < arr.length; i++)
if (predicate(item, i, arr)) {
taken.push(item);
}
if (taken.length >= count) break;
}
return taken;
}
" i, arr" is even the same amount of characters as "...args". Great abstraction: hides stuff while not even being shorter.
I don't know much about Javascript tho it seems like a cool language. The same thing can be expressed better using Haskell's take if available in js. I looked up some things so maybe
arr.filter(predicate).slice(0, count)
Unless push reverses it too so do .reverse() if it exists idk. Also the predicaye seems to also depend on the index so maybe use the equivalent of enumerate before filter. Both the loop and github version feel a bit like spaghetti
2 months ago
Anonymous
Filter and slice will work, but that is two iterations, and it filters the entire array, regardless of how many items you need. Probably not a problem on small arrays, but if the array is large and the predicate function is heavy, it might count.
There is an EcmaScript proposal for iteration helpers that might solve this problem in the future: https://github.com/tc39/proposal-iterator-helpers. But until that time, chaining array functions might not be optimal.
2 months ago
Anonymous
Yeah I thought this might be the case after posting it. It's kinda dumb that they don't do iterators or lazy evaluation because they are kinda useless like that
makes the code harder to read which is very bad and causes bugs.
also breaks compiler optimizations, because completely shadows logic behind your code structure.
of course the compiler (and the resulting assembly) does goto (jmp and j* friends) all the time.
>Code gets harder to read >GOTO label means go directly to the label and continue from there >Hard to read
GOTO is very easy to read and in certain circumstances very useful. In fact it is so useful that many try to implement it in roundabout ways because they want the functionality of a GOTO but are scared to use one.
The best tool for a problem is the one that: >works >doesn't waste resources >allows the programmer to tell what his code is doing when he looks at it again 6 months down the line
Sometimes that tool is goto. Simple as
if you work under a team don't @ me I don't give a shit about wagies or githubbers
Control flow and imperative paradigm is for midwits who can't envision their entire program state space in their brain. If you can't visualize a finite state machine in your brain, you don't deserve to be a programmer.
I like (forward-jump) goto :3 It often allows me to remove "x_is_valid" variable clutter. Also error handling but this is because C is C.
Another option would be to break a function such as this into even smaller functions which allows for similar control flow, but that creates unnecessary surface area and noise to the architecture. Also boilerplate. Issues gotos don't have.
I used goto to break out of a nested search loop eg
int main() {
Item* item = nullptr;
for (const auto& item : list) {
for (const auto& subItem : item.collection()) {
if (subItem.name() == key) {
goto search_done;
}
}
}
search_done:
if (!item) {
// error
}
return 0;
}
I could rewrite it to use a boolean and break twice but why when goto does the job with less verbosity? When people say don't use goto they mean don't use it for weird ass control flow. It is fine in this context.
In my irrelevant, 10 people company even if you change a comma in an error message to user, it must be reviewed by another person. I am surprised that shit like this can get into production at such important and big companies.
A shitty programmer will create even worse programs with goto than without. At intermediate/ advanced, it starts to be a worthwhile tool in his repertoire
So if jumps are literally key to assembly programs which all abstract languages compile down into then why would goto be bad? it’s literally just a jump in the end
I don't hate goto I just can rarely find any reason to use it.
When dealing with resources management and error handling goto is in my opinion the best option. At the start of the C function I declare a return variable and assign it the generic error return. Then I'm declaring the resources handles (mostly pointers) and setting them to NULL or whatever value represents the empty state. After the first resource allocation I write a comment that direct return is disallowed after this point. Instead the expression "goto cleanup_and_out;" shall be used to handle an error. And to signal success simply set the return variable to the success indicator. At the end of the function is the cleanup_and_out label. There will be all resources freed whose handle is not NULL or whatever value represents the empty state. After that I simply return the return variable from the beginning.
This pattern allows consistent graceful error handling while keeping resource safety. It also allows ownership transfer. Just assign a resource handle to the new owner of that resource and set the old resource handle to NULL.
The alternatives would be copy and paste the code of the deallocations in every error handling code or using tons of nested if statements.
>copy and paste the code
No macro for this? That would be a good time to use one.
I've actually run into a couple instances where goto resulted in an elegant solution, better than the alternatives. But 99.999% of the time there's a better alternative.
I'm thinking, could it be useful to introduce a command called TOGO which would basically be I want to export this context for later (label) but not have it now. So every local vars in that block would get moved to the label.
You may want to look into continuations.
It's bad because there's almost invariably a better way to write whatever you need a goto for.
Breaking/continuing an outer loop in
In Rust it's just
#![allow(unreachable_code, unused_labels)]
fn main() {
'outer: loop {
println!("Entered the outer loop");
'inner: loop {
println!("Entered the inner loop");
// This would break only the inner loop
//break;
// This breaks the outer loop
break 'outer;
}
println!("This point will never be reached");
}
println!("Exited the outer loop");
}
Break is a special case of goto
Break with a label is goto renamed
>hav goto
>literal fricking vanilla goto
>still change the name bc reasons
rustroons will never learn...
fricking vanilla goto
No, this is for breaking out of nested loops. You can only jump forward that way, so it's fundamentally less powerful
PowerShell has had this since 2004 btw.
nobody cares about powershell except IT jannies
>t. NEET4lyfe
t. real job haver
I was talking about C you Black person gorilla.
Plenty of languages have labelled breaks, doesn't make your troony lang special.
>inb4 use Rust
Because I actually have to program instead of Larping on the internet, I don't get to choose what language I work with. It's decided by the project and use case.
10 PRINT"OP IS A homosexual"
20 GOTO 10
cringe
> lua
> claims of money
lmao. indian currency really isn't worth much, anon.
Honestly, all this labeled break and continue is useless
All you need exactly one construct, a labeled return and a labeled scope around it and then it can implement continue and break as well.
As in something like 'label: { ... return 'label 4; ...}.
“break” is nothing more than returning to a scope one made directly outside of any loop, “continue” is nothing more than a scope directly inside of it. “return” itself is of course simply returning to a scope just inside of the function.
Just put the inner loop into a function and then return from it. Will also make the code more readable.
Maybe, but religiously avoiding goto leads to worse as its not always easy to find that better way.
There is no performance equivalent for writing virtual machines with computed goto. Putting a switch in a loop can get the same functionality, but is not as fast.
What about function pointers?
It would need an array of pointers to functions, which is basically a computed goto with an extra indirection.
Calling a function is not a goto. Sometimes in assembly you need to push things to the stack (not on vms) and also on the language level you change scope. Also I think the goto option requires gnu c extensions so the advantage and reason to use function pointers is that they are more portable. I think they might end up not being as optimized in assembly tho if the compiler is not good enough. Maybe you could inline assembly to handle going to the next funciton and keep functions in an attempt to perserve portabilty and get maximum performance on this part.
Personally I'm not against goto. However because you can't jump across functions it forces your code to be less compartmentalised, for example when writting vms. The issue is more because you can't load labels that are in other functions for later use in the other function, bot for actually jumping to another function
Bypassing any context switching is a good reason to use goto in the first place, though.
With function pointers, it calls the function then returns to the dispatcher to advance to the next one. With computed goto, execution goes from one operation straight to the next with only a single jump. No need to jump back to the part that calls the next function. It's spaghetti-by-design, and can't be done in a language designed to avoid spaghetti code by omitting goto.
Depends on the language.
Breaking from nested loops by setting a flag which the outer loops check every iteration to decide to break is far less legible than a goto to the end of the loop.
Of course good languages have labeled breaks which can break from outer loops or continue them, which is nothing more than a restricted case of goto which stops it from being used in an asinine way, but when using goto like that of course no problem arises.
All statements such “while” as “return”,“break”, “continue” and hat-not are a restricted goto that are restricted in a way that they can't be used to generate unreadable code.
Literally just jus add 'break N;' I can't believe this is not a standard language feature everywhere.
The thing is if Dijkstra was asked to comment on OOP he’d have an aneurysm. All the dynamic dispatch (polymorphism, interfaces) and implicit jumps (exceptions, raii) create spaghetti far worse than a simple goto. goto can at least be understood at compile-time and is essential to canonical implementations of computer science algorithms.
lmao
I have always found it incomprehensible how anyone can condemn goto whilst being perfectly happy with exceptions.
Because exceptions are considerably less flexible and unrestricted. They're again a restricted case of dynamic goto, which are essentially continuations.
In fact, the only real problem with exceptions is that in most languages they are untyped and a function's type signature doesn't indicate what exceptions it may throw. Checked, typed exceptions are as far as I can tell completely identical to returning and propagating a Result type except the latter is more convenient in that one can for instance store results into a data structure or loop over them and defer bubbling. Checked exceptions are nothing more than Results which are always and automatically bubbled.
>more convenient in that one can for instance store results into a data structure or loop over them and defer bubbling
You don't do that sort of thing very often, so it isn't worth making convenient. (You can do it with exceptions, but it takes more code. Given it's rarity, that doesn't really matter.)
Actually it's fairly common in rust.
People don't do it much in many languages because it doesn't really work there. Same with Haskell or Ocaml or other languages that mostly work with Result-like types for exceptional situations.
Real goto is unsupported in basically every language in use today besides assembly because it's incompatible with functions, that should tell you plenty.
Neutered C-style goto mainly makes up for missing features like cleanup. If you didn't have any loop constructs you'd obviously use goto for that as well, but we do have while loops, so you don't need it for that and nobody uses it for that.
There are a very small number of remaining use cases even in languages with a good feature set. It can make state machines more efficient.
>Real goto is unsupported in basically every language in use today besides assembly because it's incompatible with functions
That's not why because it can be used for control flow within a function. You don't allow goto to a location outside of the function, but labels/goto within it.
It's still almost always a bad idea, which is why it's not in very many languages.
I'm saying that not even C has real goto, only neutered goto.
Full goto in C is called longjmp() and it's regarded with horror for good reason. There are very very few legitimate use cases for it; I've never written code that needed it, but I've maintained code that included it in a few places. (Notably to smuggle a callback argument out of a non-terminating loop in the guts of a drawing library; horrible but worked).
It's useful if you want to compartmentalise your code in functions but these functions need to mamage jumps outside of other functions (like loading addresses of the jumps, which also makes sense to have a seperate function for, to load or select the next jump). Additionally I have used it to set up a specific environment in code I do not control in order to hack it but this is literally using code in ways not intented lol. So overall I'd say longjmp is more useful than simple goto
1 cls
10 ? ”Nigggggassss”
20 goto 10
Reminds me of this gem: https://github.com/airbnb/javascript/issues/1103
>continue in a loop is worse than return in a forEach because…… IT JUST IS OKAY!!
>When used incorrectly
Anything can be used incorrectly. How about when it's used correctly?
>discourages loops
wtf
My god, these people are clearly are just following rules they read somewhere without thinking:
>Continue is not goto. That's like saying loops are goto.
>@SelaO no, it's not like saying that. Loops that use break or continue are goto.
Pff
It's just subjective
for item in items:
if f(item):
continue
loop_body(item)
vs
for item in itmes:
if g(item):
loop_body(item)
vs
[if g(item): loop_body(item) else item for item in itmes]
unless it's equivalent to
[loop_body(item) for item in items if g(item)
The last two can also be expressed with map and filter
>It's just subjective
Look at pic related from the GitHub thread.
>perfectly reasonable usage of some
.some is a js function to test if some element in an array matches the predicate. In his example, you could replace it with find or findIndex, and the functionality doesn't change.
First, he's mutating a variable from outside the function into a callback of something that's a search function, and shouldn't just mutate stuff.
Second, if the function you're using is interchangeable by multiple others, you're probably using it wrong.
>perfectly reasonable usage of some when hidden by a presumably well-tested abstraction
It's good when you hide it LOL.
>It also has the benefit of giving you array iteration method semantics largely for free, which you’d have to do manually when implementing with a loop.
He abstracted two arguments from some into ...args: the index of the current iteration, and the full array. For comparison, the classic for loop:
function take(arr, predicate, count = Infinity) {
const taken = [];
for (let i = 0; i < arr.length; i++)
if (predicate(item, i, arr)) {
taken.push(item);
}
if (taken.length >= count) break;
}
return taken;
}
" i, arr" is even the same amount of characters as "...args". Great abstraction: hides stuff while not even being shorter.
I don't know much about Javascript tho it seems like a cool language. The same thing can be expressed better using Haskell's take if available in js. I looked up some things so maybe
arr.filter(predicate).slice(0, count)
Unless push reverses it too so do .reverse() if it exists idk. Also the predicaye seems to also depend on the index so maybe use the equivalent of enumerate before filter. Both the loop and github version feel a bit like spaghetti
Filter and slice will work, but that is two iterations, and it filters the entire array, regardless of how many items you need. Probably not a problem on small arrays, but if the array is large and the predicate function is heavy, it might count.
There is an EcmaScript proposal for iteration helpers that might solve this problem in the future: https://github.com/tc39/proposal-iterator-helpers. But until that time, chaining array functions might not be optimal.
Yeah I thought this might be the case after posting it. It's kinda dumb that they don't do iterators or lazy evaluation because they are kinda useless like that
I don't understand the "no loops" stuff
are they advocating for .map() or what am I missing?
>CONTINUE BAD
That github issue's dev comments gave me cancer, thanks
makes the code harder to read which is very bad and causes bugs.
also breaks compiler optimizations, because completely shadows logic behind your code structure.
of course the compiler (and the resulting assembly) does goto (jmp and j* friends) all the time.
>Code gets harder to read
>GOTO label means go directly to the label and continue from there
>Hard to read
GOTO is very easy to read and in certain circumstances very useful. In fact it is so useful that many try to implement it in roundabout ways because they want the functionality of a GOTO but are scared to use one.
Fired.
Hired.
goto filters those who know how to program from those who cant. like pointers
I make so much money I don't need to listen to the opinions of anyone, least of all anonymous hobbyists/employees on IQfy
This.
I will use goto.
I will use integer overflow.
And no basedboy on the internet can stop me.
GOTO is just a CALL without context saving. I often use it when I need unlimited jumping range. I dont see why its problematic.
The best tool for a problem is the one that:
>works
>doesn't waste resources
>allows the programmer to tell what his code is doing when he looks at it again 6 months down the line
Sometimes that tool is goto. Simple as
if you work under a team don't @ me I don't give a shit about wagies or githubbers
>if you work under a team don't @ me I don't give a shit about wagies or githubbers
based fellow entrepreneur
How comfy is that basement?
Houses don't have basements in Tokyo, stay mad githubber
Goto is for based chads, which makes it unsuitable for söydevs who need 10 frameworks to write a hello world.
Control flow and imperative paradigm is for midwits who can't envision their entire program state space in their brain. If you can't visualize a finite state machine in your brain, you don't deserve to be a programmer.
A finite state machine is not Turing complete
I like (forward-jump) goto :3 It often allows me to remove "x_is_valid" variable clutter. Also error handling but this is because C is C.
Another option would be to break a function such as this into even smaller functions which allows for similar control flow, but that creates unnecessary surface area and noise to the architecture. Also boilerplate. Issues gotos don't have.
I used goto to break out of a nested search loop eg
int main() {
Item* item = nullptr;
for (const auto& item : list) {
for (const auto& subItem : item.collection()) {
if (subItem.name() == key) {
goto search_done;
}
}
}
search_done:
if (!item) {
// error
}
return 0;
}
I could rewrite it to use a boolean and break twice but why when goto does the job with less verbosity? When people say don't use goto they mean don't use it for weird ass control flow. It is fine in this context.
I forgot to set item to subItem to item but w/e you get the point
>if statements without braces
>not using clang-tidy or cppcheck which would catch this shit
deserved
In my irrelevant, 10 people company even if you change a comma in an error message to user, it must be reviewed by another person. I am surprised that shit like this can get into production at such important and big companies.
A shitty programmer will create even worse programs with goto than without. At intermediate/ advanced, it starts to be a worthwhile tool in his repertoire
So if jumps are literally key to assembly programs which all abstract languages compile down into then why would goto be bad? it’s literally just a jump in the end
The ultimate filter.