# Statements In Expressions  wiki

In Lua, statements (including assignments and local variable declarations) cannot normally be placed in expressions but rather must be in separate statements. This contrasts to, for example, the C language, where one can have an expression that does an assignment as a side effect. This is often used for things like

```while((c = fgetc(fh)) != EOF) { fputc(c, fh2); }
```

or

```double x, y, z;
if (strcmp(v, "0,0,0") == 0) printf("zeros\n");
else if(sscanf(v, "%f,%f,%f", &x, &y, &z) == 3) {
printf("tuple (%d,%d,%d)\n", x, y, z);
}
else printf("unknown\n");
```

To take a Lua example consider this:

```local w = (x+y+z)^2 + (x+y+z) + 1
```

contains a single expression but is redundant and is normally simplified computationally only by moving code into an assignment in a separate statement:

```local xyz = x+y+z
local w = xyz^2 + xyz + 1
```

or even

```local w; do
local xyz = x+y+z
w = xyz^2 + xyz + 1
end
```

It's somewhat a matter of taste, but we lose the nicety of having the computation as a single expression (`w = ...`). The style becomes more [imperative].

There are various workarounds with closures and function/metatable side-effects (or even memoizing) to write it with a single expression, but they are not as efficient here and would typically be poor choices:

```local w = (function() local xyz = x+y+z; return xyz^2 + xyz + 1 end)()
```

Or one could do

```local w = (function(xyz) return xyz^2 + xyz + 1 end)(x + y + z)
```

which is the same transformation Scheme uses with [`let`] and avoids creating the outmost upvalues.

Though this is not valid Lua syntax, it could be preferable to write this as a single expression as follows:

```local w = let xyz = x+y+z in xyz^2 + xyz + 1
```

At least there are theoretical reasons why this would be useful, in writing programs in a functional style or for a program that modifies another Lua program, a la MetaLua. In fact Metalua incorporates a mechanism similar to this to allow more efficient code.

Notice the resemblance to Lisp:

```(let ((xyz (+ x y z)))
(+ (* xyz xyz) xyz 1)
)
```

and OCaml.

### Pattern: Stored Expressions

We can achieve a similar effect to locals in expressions by having the expression call a function that then does some assignment. It can have a syntax like this:

```local ex = StoredExpression()
for _,v in ipairs{"4,5,6", "7,8,9", "0,0,0"} do
if v == "0,0,0" then print("zeros")
elseif ex(string.match(v, "(%d),(%d),(%d)")) then
print("tuple", ex, ex, ex, "of size", ex.n)
else
print("unknown")
end
end
-- Outputs: tuple   4       5       6       of size 3
--          tuple   7       8       9       of size 3
--          zeros
```

Here is the implementation of `StoredExpression`:

```do
local function call(self, ...)
self.__index = {n = select('#', ...), ...}
return ...
end
function StoredExpression()
local self = {__call = call}
return setmetatable(self, self)
end
end
```

This also allows things like

```result = ex(math.random()) and (ex < 0.3 and "low" or
ex > 0.7 and "high" or
"med")
```

Some care may be needed since the order of execution of sub-expressions is not always defined.

--DavidManura, 2007-02. `StoredExpression` implementation was improved by RiciLake.

### Proposal to extend Lua with "let"

The proposal as discussed with RiciLake is to add a new "let" construct to the Lua language for embedding statements, including local variable declarations, in an expression.

The proposed syntax is

```let <chunk> in <expr>
```

where "let <chunk> in <expr>" acts as an expression (or expression list?) and where "let <chunk> in" acts like a low-precedence prefix operator (like `not` or `#` not with low precedence):

Locals in <chunk> are visible in <expr>.

```-- typical usage
y = let local t = complex_function(x) in t and g(t)

-- any statement (not just local variable declarations) can be used
y = let local x = 5; print("hello") in x*2

-- can be nested
y = let local x = 5 in let local y = x in y*2  -- sets y=10

-- useful when declaring closures this way
local func =
let
local x = 10
in function()
x = x + 1
return x
end

local y =
let local x = 0
for _,v in pairs(t) do x = x + v end
in  x+x^2+x^3

-- using let with tuple proposal
t[let x... = 1,2,3 in x] = true

-- if statments:
local y
if x == 1 then
print(x)
elseif let y = compute(x) in y > z then
print("more", y)
elseif y < -z then
print("less", y)
end
```

### Let...in with Metalua

The `let ... in ...` syntax has been implemented in Metalua. See , and particularly this one .

### Alternative Metalua proposal

In , another way to put statements where an expression is expected is presented. This Metalua extension defines a stat...end block, which can be put in an expression context. Its value as an expression is the parameter of the first return statement executed in the stat...end block.

Therefore, `stat <foo> bar` is semantically equivalent to `((function() foo end)())` in plain Lua. However, the Metalua implementation uses a much more efficient compilation, which doesn't involve the creation of a closure with upvalues.

For instance, `print(stat local x=21; return 2*x end)` will print 42, as would have the slower and less readable `print(((function()local x=21; return 2*x; end)()))`

### Hack: Expression Stack

Warning: the following is academic and isn't really recommended for most situations.

Let's define the following functions:

```local save, restore; do
local saved
save = function(value) saved = value; return true end
restore = function() return saved end
end
```

We can then do

```local z = save(x+y+z) and restore()^3 + restore() + math.sqrt(restore())
```

It's more terse, though at the expense of the function call overhead. That overhead might be removed if we made save/restore a built-in operation in Lua. It behaves somewhat like a stack as in [Forth] but with one element.

This concept might be extended to support more than one memory location:

```local save, restore do
local saved = {}
let = function(name, value) saved[name] = value; return true end
get = function(name) return saved[name] end
end
```

We can then do things like

```local z =
let('n', x+y+z) and
let('m', x^2+y^2+z^2) and
get('n')^3 + get('n') + math.sqrt(get('m'))
```

That seems like a complicated way of inefficiently reimplementing local variables, in which the variables aren't really local

Eventually we'd want to clear the saved table so it doesn't grow to infinity. There may be various approaches, such as using a circular queue or periodically clearing this table.

### Related stuff (older)

Here's another example:

```-- How I might like to write it
-- Assuming rotate_coordinates() returns a tuple of three numbers.
-- Note: Invalid Lua.
function transform_object(o)
return is_vector(o) and do
local x, y, z = rotate_coordinates(o[x], o[y], o[z])
return {x*2, y*2, z*2}
end or o*2
end
```

The values x, y, and z must be stored away in temporary variables before we can operate on them--that is, assuming we don't want to call rotate_coordinates three times:

```--Yuck
function transform_object(o)
return is_vector(o) and {
select(1, rotate_coordinates(o[x], o[y], o[z])) * 2,
select(2, rotate_coordinates(o[x], o[y], o[z])) * 2,
select(3, rotate_coordinates(o[x], o[y], o[z])) * 2
} or o*2
end
```

This may not seem very reccomended, but it's the best I could think of, sorry for your expressions not having syntax highlighting...

```function Let(statement)
local locals = {}
return function(In)
return function(expression)
if In == "In" or In == "in" then
table.insert(locals, statement)
local func = load(locals .. ' return ' .. expression)
return func()
else
error("'In' or 'in' expected near " .. In, 2)
end
end
end
end

val = Let 'local x = 10' 'In' 'x - x'
local val2 = Let 'local x = 9' 'In' 'x * x'
print(Let 'local x = 5' 'In' 'x + x')

print(val + 1 + val2)

```