• Subject: Re: goto in expressions
• From: Sean Conner <sean@...>
• Date: Tue, 16 Dec 2014 19:52:47 -0500

```It was thus said that the Great Andrew Starks once stated:
>
> Yes. I understand this part and accepted it as a change. I'm wondering
> if there is an implication apart from pointing out that this would be
> a change?
>
> >
> >> Also, this logically begs the question, if this were legal,
> >> could/would this also be legal:
> >>
> >> ```
> >> x = x or return nil
> >> ```
> >>
> >> Maybe this is just a fundamentally bad idea? That is: "good code
> >> doesn't do this."
> >
> >   I'll reserve judgement on that question, but will respond with this one:
> > What should be printed in the following hypothetical code?
> >
> >         x = 1   -- create global X
> >         y = 2   -- create global Y
> >
> >         function foo()
> >           x = 3 + return 4
> >         end
> >
> >         function bar()
> >           y = return 4 + 3
> >         end
> >
> >         a = foo()
> >         b = bar()
> >
> >         print("a",a)
> >         print("b",b)
> >         print("x",x)
> >         print("y",y)
> >
>
> I believe that I demonstrated this answer. Is this example
> fundamentally different:
>
> ```
> local x = false
> local y = true
> local function fun()
>    x, y =  x or error('x must not be set!'), 'foo', 'bar'
> end
> local success, ret = pcall(fun)
> print(success, x, y)
> --> false, false, true
> ```
>
> That is, I did this because `error` is legal. The same sort of
> behavior could be imagined for goto, WITH the added limitation that
> (perhaps) the "local" would not be allowed here? That is, you couldn't
> create new locals on the left and have a goto happen on the right?
>
> I don't mean to keep this up, except that I may not be getting the
> significance behind the particular rule that you're pointing out, at
> least as something that "cannot ever be broken under any
> circumstance".
>
> Perhaps this is really off base, but `and`, `or` and `not` are all
> "naked" and allowed.

It'll require a change in the language.  Right now, you have (not all
productions listed):

exp ::=  nil | false | true | Number | String | ‘...’ | functiondef
| prefixexp | tableconstructor | exp binop exp | unop exp

binop ::= ‘+’ | ‘-’ | ‘*’ | ‘/’ | ‘^’ | ‘%’ | ‘..’ |
‘<’ | ‘<=’ | ‘>’ | ‘>=’ | ‘==’ | ‘~=’ |
and | or

The changes you are proposing are along these lines:

retstat ::= return [explist] [';']

explist ::= exp { ',' exp }

exp ::= nil | false | true | Number | String | '...' | functiondef
| prefixexp | tableconstructor | exp binop exp |
| exp logop exp | exp logop goto NAME | exp logop retstat
| unop exp

binop ::= ‘+’ | ‘-’ | ‘*’ | ‘/’ | ‘^’ | ‘%’ | ‘..’ |
‘<’ | ‘<=’ | ‘>’ | ‘>=’ | ‘==’ | ‘~=’ |

logop ::= and | or

which does allow for some crazy constructs:

function foo(x,y)
local x,y = x or return y or return z or goto HERE,5
end

which immediately shows a problem (or at least I see a problem):

function foo(x,y)
local x,y = x or return nil,"error",y  --- ... um ...
end

Question:  if you call foo(nil,3) does this return nil or nil and "error"?
If you call foo(2,2) is x 2 and y "error", or 2?  Well, parenthesis can
clear that up:

local x,y = x or (return nil,"error") , y

So that's okay.  But the BNF I presented still allows silly constructions
like:

local x = x or return "error" and goto WTF_WHO_WROTE_THIS

or

local x = x or return "error" and return "WTF????"
-- what do we end up returning in this case?

I'm not entirely sure there aren't other gotchas with this and it does
introduce a lot of odd corner cases ...

-spc (Granted, people shouldn't write code like that, but ... [1])

[1]	http://thedailywtf.com/

```