• Subject: Re: special forms, take two (was Re: A lua version of "amb")
• From: Fabien <fleutot+lua@...>
• Date: Tue, 28 Feb 2012 14:11:40 +0100

On Tue, Feb 28, 2012 at 12:45 PM, steve donovan wrote:
-- apply a method of an object to an array of values

map(|x| (obj:f(x)), values)

This is the archetype of the functional idiom which will come back to haunt you in a side-effect-friendly language :)

In a functional language, when you write "a = b :map (|x| frobnicate(x) + bar)", "a" and "b" can't be altered at all; so of course you won't accidentally alter "b" as a side effect of altering/computing "a". But if you remove this guarantee, reasoning in terms of composing functions together becomes very treacherous.

If I have a "map" method on Lua tables, it's all too natural to write something like:

local function list_min(t, y)
table.sort(t)
return t[1]
end

local list_of_lists = whatever()
local mins = list_of_lists :map (list_min)

"list_mins" has a nasty side-effect, and the last line, which looks purely functional, actually messes up "list_of_lists". Here it's obvious because it's a toy example, and the poor design of "list_min" is glaring; but you'll get plenty of such bugs in a full-size application, and good luck finding / fixing these.

Note that altering tables is not necessary a bug: it can be a feature, because duplicating tables is expensive in Lua. That's why purely functional containers (maybe cons cells), which refuses to contain mutable values such as tables, would be needed in a serious functional dialect of Lua. Such immutable structures would have to be cheap to copy, should auto-cast easily into mutable equivalents, but not the other way around.

There is a use-case for thunks, but I bet they're better thought of as continuations than as lambdas. Moreover, they must not break Lua's beginner-friendliness. It might be possible, but it's certainly not easy, and syntactical details are only the emerged part of the iceberg.

• References: