label: {
break label;
}This is just Java, right? I don't think I've seen this in the C/C++ specs or compiler extensions.
https://docs.swift.org/swift-book/ReferenceManual/Statements...
(And I always forget about it)
'label: loop {
break 'label;
}
And if you want to go one further on that, you can break with value because Rust is expression-oriented: fn main() {
println!("Hello, {}!", 'label: loop {
break 'label "world";
});
}You can get loops and goto etc from there.
(You might still want extra first class support for eg exceptions.)
We are still paying this mistake as of today: most devs don't scope their async tasks lifecyle leading to a huge spaghetti code.
GOTOs are too easy to misuse.
We used to have only GOTOs, no loop, no if... But specialized keyword are better: they enforce a cleaner code, leverage conventions, play batter with tooling and make the whole experience easier to read and debug.
Python is 30 years old, is there any popular language created in the last 30 years that has goto?
(And also I emphatically agree on the end user executable thing)
Julia (9 years old) https://sodocumentation.net/julia-lang/topic/5564/-goto-and-...
Golang (11 years old) https://golang.org/ref/spec#Goto_statements
Lua (28 years old) http://lua-users.org/wiki/GotoStatement
If you had asked me a few minutes ago if Go had goto I would have said "definitely not and they would never add it because it goes against the Go ethos".
For example there's no ternary operator. Instead you'll have to write out a few lines of if/else. There's no function overloading or operator overloading, no built in min/max, and currently no generics (though they're being added).
They definitely try to keep the number of keywords down to a minimum compared to languages like Swift where you could write the same business logic in fewer lines using stuff like try, guard, !, and ?.
PHP perhaps gets honorable mention for not originally having a goto statement, but adding one something like 10 years later.
Zig moved in the opposite direction. It had one at first, and then removed it: https://github.com/ziglang/zig/issues/630
To jump backwards, there's labeled continue. To jump forwards, there's labeled break. The use case that computed goto tries to solve is addressed with labeled continue on a switch [1]
These features already have reasons to exist, because they solve control flow scenarios. So there they are. And then we are brought the question of introducing goto, and there's just nothing that it adds. It would make the language more complicated for no reason.
With goto you can't know at a glance if the code is following those patterns or doing some kind of spaghetti nonsense. It hurts readability.
Restricted versions each covering a major use case are easier to reason about, and to optimize.
Anyhow, pretty much every version of “goto” using the name implemented or proposed for Python or other structured languages is castrated: typically, it take only a static label and has restrictions on where it can jump based on structure (out of blocks but not into blocks, within the same function, is pretty typical.)
Proper goto can jump anywhere in the program, even dynamically computed at runtime, and if state isn't set up the way the code jumped to expects, too bad. Everything more restricted is just dickering about how much it should be castrated.
For example lines 15 through 20 ended up like this:
D15 = 40000
D16 = min(D1, D15)
D17 = min(D14, D16)
D18 = max(D1-D10, 0)
D19 = min(d1, 163300)
D20 = min(D15, D19)
The variable numbers match the form's line numbers, and the code is a straightforward implementation of the instructions for the line.The instructions include things like "If line X is greater than line Y, go to line Z".
I think the code would have been clearer if I could have used goto to match the instructions instead of having to convert to if blocks. For the forms I was interested in at least the if blocks were all fairly simple and the lines in the code were all in the same order as the lines on the form, but I'm not sure that would be true for all of the IRS forms.
The code’s logic would be able to better match the logic flow of the tax statement logic flow which often say things like “if no whatever, skip to #farther.down.the.page.”
Sometimes it’s best to let art^h^h^hcode imitate life.
And for the tax stuff, you wouldn't even need to worry too much about having properly optimized tail calls, as the business logic here is unlikely to blow up your stack.
And bonus, you can put them in several files, and import them when your program grows. Which means you can then call them in the shell to play with them.
It will make the whole experience much easier.
Perhaps files could have declared at the top whether they were Python 2 or 3, and the pyc could have been kept as compatible as possible?
When I evaluated the landscape a few years ago, I settled on PEX [1] as the solution that happened to fit my use-case the best— it uses a system-provided Python + stdlib, but otherwise brings everything (including compiled modules) with it in a self-extracting executable. Other popular options include pyinstaller and cx_freeze, which have different tradeoffs as far as size, speed, convenience, etc.
But that can also be seductive in its own way, like when you get used to just deploying a single binary but then suddenly have an application that also includes data files— do you do the go:embed thing to maintain the glorious single binary, or do the pieces go in an archive together? If it's that one, do you find the data at runtime with a flag, or an envvar, or a relative path, or something else?
Undoubtedly, Go is easier than Python or Ruby, especially for the trivial case. But deployment is overall a non-trivial problem.