If you can rely on the developer to use gotos in clear patterns like that, then great. But if there is a recognizable pattern, it's an opportunity for the language to provide an alternative like with{} or try{}finally{}.
I agree with with{}, less so with try/finally. First of all, I think exceptions are at least as easy to get wrong in your application (or worse system) design as goto. And if you get them wrong, it's probably even harder to debug. Second of all, the resulting code is IMO far less readable.
To illustrate - which would you prefer:
a = None
try:
a = get_ressource_a()
b = None
try:
b = get_ressource_b(a)
process(a,b)
except BException as e:
handle_errors(e)
finally:
cleanup_b(b)
except AException as e:
handle_errors(e)
finally:
cleanup_a(a)
or
a = get_ressource_a()
if not a:
handle_errors()
return
b = get_ressource_b(a)
if not b:
handle_errors()
goto cleanup_a
process(a,b)
cleanup_b:
#do the cleanup
cleanup_a:
#do the cleanup
My dream language would have more or less Python's syntax, with dynamic, inferred, but strong types, no exception handling, and instead Swift's "optional" baked into the language and a very smart logging that I can peak into with the error handler. The error handler could be the only sideeffect allowed when a function is declared pure. I don't need goto if with{} works well with such a system.
It provides nearly everything you mention and covers the "finally" case with `defer`. Worth looking at - I re-implemented suckless' slock in Nim[2][3] and it was very pleasant experience.
Interesting, I never looked at it really. As a statically typed language, how does it handle complex objects, something like a document coming from a document based DB sent over JSON?
There's a JSON parser in the standard library (http://nim-lang.org/docs/json.html). It works by declaring discriminated union (called enum in Nim) of possible JSON types, declared here: https://github.com/nim-lang/Nim/blob/master/lib/pure/json.ni... You get a tree of nodes out of the parser and switch (lightweight pattern matching) on each node type. Nim does exhaustiveness checking, so you will never fail to handle some kind of JSON node by accident. You're forced to deal with nulls explicitly, either via pattern matching or convenience functions like `getOrDefault`.
It's not as nice as F# Type Providers, but it's workable. You could write something similar to Type Providers with macros (given a schema or sample), but I don't know if someone tried this already. With all the standard operators (like property access/assignment and toString equivalent) overloaded to support JSON, it feels quite natural. I wrote a little script consuming a JSON service, it looks like this for example: https://gist.github.com/piotrklibert/b2ba0774244bb7368748a3b...
Nim has its peculiarities and rough edges (it's not even at 1.0 yet), but it's expressive (many of the construct typically built-in in languages are implemented as libraries) and fast. C-level fast, without a huge runtime, so for things like this script it's 4x-16x (IIRC, when reading cached data from disk) faster than compiled F# version (on Mono), for example. My impression of the language is that it's pragmatic and flexible. Also opinionated, which may be both a good and a bad thing, depending on what are your preferences.
That does look quite reasonable yes. You're right, for a statically typed language it does feels quite dynamic. I think a good blog article comparing Nim to Swift would be very interesting, I couldn't find such a thing.
Thanks for your input!
Edit: Looking at http://roadfiresoftware.com/2015/10/how-to-parse-json-with-s... I think I'd much rather have Nim. This is exactly the sort of thing where types get in the way and slow development down tremendously. If I get external data it should be enough to just be aware that all accesses return an "optional", which has to be dealt with accordingly as part of error handling. Letting types get in the way as well is basically doing the work twice.
To illustrate - which would you prefer:
or My dream language would have more or less Python's syntax, with dynamic, inferred, but strong types, no exception handling, and instead Swift's "optional" baked into the language and a very smart logging that I can peak into with the error handler. The error handler could be the only sideeffect allowed when a function is declared pure. I don't need goto if with{} works well with such a system.