goto but improved ================= * Use `section l` instead of `l:` * Disallow implicit fallthrough. Could have an explicit `fallthrough` keyword (also for `case` blocks) * Allow only goto to within the same or a containing block. * Sections have access to the variables of the "main" part of the block that it belongs to, but variables that aren't guaranteed to be initialized at all `goto` or `fallthrough` statements. * Allow goto within the nearest `switch` block. Perhaps with the syntax `goto case c` * Should `section`s be allowed in any block, or only at the outer `code` block? - won't work with `else` - won't work with `loopend`/`loopempty` - won't work with `switch (and somewhat redundant anyway) - also, it could be confusing. better break up the code in multiple functions? Syntax test: func example int x code if x >= 100 goto section fail end # or, maybe: require x <= 99 else goto section fail switch x case 1 do_stuff "A" fallthrough case 2 do_stuff "B" goto case 1 case 3 do_stuff "C" goto default case 4 do_stuff "D" fallthrough default do_stuff "other" end return true # Implicit fallthrough not allowed! section fail error "Oops" return false end Syntax test with assertion failure section: func example int x code assert x <= 99 ... return true section assert_fail error "Oops" return false end Alternative solution 1: Blocks for error/success/finally only ------------------------------------------------------------- Allow only "sections" as endings of functions. And only allow allow error/success/finally? Like this: func example int i code ... on error ... on success ... finally ... end Alternative solution 2: Blocks for error/return only ----------------------------------------------------- Or, perhaps skip the `on success` part? And rename `finally` to something that does not imply that it is executed in abnormal circumstances (e.g. thread termination)? func example int i code ... on error ... on return ... end Alternative solution 3: A before-return block only -------------------------------------------------- Skip the distinction between success and errors (and of course don't try to handle thread terminiation): func example int i code ... last ... end The `last` block can only access outermost-scoped variables that are initialized before the first return. In the example below, it should definitely be able to access `a`, but perhaps not `b` since it hasn't been "merged" to the outermost scope at the point of the return. func example int i code int a int b if i == 0 a = 1 else a = 2 end if i == 1 b = 1 else b = 2 if i == 3 return end end ... last ... end Alternative solution 4: Flow statement with custom block statements ------------------------------------------------------------------- A plain flow statement: flow if x goto s1 if y goto s2 section s1 ... section s2 ... end A flow statement could have an optional "flow function", which would decide where to jump after (and perhaps even before?) the initial block has been executed. flow FLOWFUNC INITIAL BLOCK section s1 ... section s2 ... end