[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- 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/