[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: "formula" short anonymous func
- From: spir <denis.spir@...>
- Date: Fri, 25 Dec 2009 12:28:47 +0100
Hello,
This is an attempt at solving the here often debated issue of short anonymous funcs such as
x --> x * x
function(x) return x * x end
in a simplistic manner, in the case where a single variable is in play. This is rather intended to be used in higher-order funcs such as map or filter.
'formula' uses loadstring to construct a func from a string definition of the formula, in which a placeholder character (default: '¤') stands for the variable.
A higher-order func can easily call formula in case it is passed a string instead of a func.
See code below. Maybe some of you find this pattern useful.
Denis
PS: For any reason, I do not like cases like 'formulafunc' below where I'm forced to define an ambiguous parameter like 'formulafunc' in map below. Even if naming can somewhat help, some part of my brain feels it -stinks- smells. But I know of no clean way to handle such cases: hints welcome.
________________________________
la vita e estrany
http://spir.wikidot.com/
=======================================================================
formula = function (expression, placeholder)
--[[ func corresponding to given formula string --]]
-- 'placeholder' stands for variable, typically sequence item
if not placeholder then placeholder = '¤' end
expression = string.gsub(expression, placeholder, "x")
print(expression)
-- function definition
local funcbody = "local x = ... ; return " .. expression
local func,error = assert(loadstring(funcbody))
return func
end
map = function(seq, formulafunc, placeholder)
--[[ new sequence resulting of mapping formula/func on seq --]]
-- actual func
local func
if type(formulafunc) == "string" then
func = formula(formulafunc, placeholder)
elseif type(formulafunc) == "function" then
func = formulafunc
else
error("Map expects a function or (string) formula.")
end
-- new sequence
local newseq = {}
for _,item in ipairs(seq) do
newitem = func(item)
table.insert(newseq, newitem)
end
return newseq
end
test = function()
print "=== number squares"
numbers = {1,2,3}
print (table.view(numbers))
squares = map(numbers, "¤*¤")
print (table.view(squares))
print()
print "=== with slot access"
require "math"
points = {{x=1,y=2}, {x=3,y=4}, {x=5,y=6}}
print (table.view(points,true))
distances = map(points, "math.sqrt(¤.x*¤.x + ¤.y*¤.y)")
print (table.view(distances))
print()
print "=== case direct func"
numbers = {1,2,3}
print (table.view(numbers))
squares = map(numbers, function(x) return x*x end)
print ("function(x) return x*x end")
print (table.view(squares))
print()
print "=== error case"
numbers = {1,2,3}
squares = map(numbers, "¤ ¤")
print (table.view(squares))
end
test()
==>
=== number squares
{1 2 3}
x*x
{1 4 9}
=== with slot access
{{y:2 x:1} {y:4 x:3} {y:6 x:5}}
math.sqrt(x.x*x.x + x.y*x.y)
{2.2360679774998 5 7.8102496759067}
=== case direct func
{1 2 3}
function(x) return x*x end
{1 4 9}
=== error case
x x
lua: formulaMap.lua:31: [string "local x = ... ; return x x"]:1: '<eof>' expected near 'x'
stack traceback:
[C]: in function 'assert'
formulaMap.lua:31: in function 'formula'
formulaMap.lua:40: in function 'map'
formulaMap.lua:80: in function 'test'
formulaMap.lua:83: in main chunk
[C]: ?