[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Assignment in functional conditionals, any alternative?
- From: RLake@...
- Date: Tue, 6 May 2003 12:28:06 -0500
Hi, Rich, and welcome to Lua.
I thought a bit more about your example, and I think that the generalised
"for" statement suits your needs pretty well.
It certainly works for your first example, with a while statement (with
limited scope):
(*) while x := foo() do print(x) end (to use Mark's syntax)
is simply
for x in foo do print(x) end
(as I said yesterday). I think that covers a number of cases where you
might want to do this; others could easily be coded. For example, the
typical construction:
(*) while p := p.link do print(p.val) end
becomes
for p in function(p) return p.link end
do print(p.val)
end
which is slightly less concise, but that might encourage the use of
accessor methods.
> Why my interest in this? In part because I'm finding my code heavily
> populated with duplicated pattern matches, along the lines of:
> if string.find(s,"<lhs><rhs>") then
> _,_,rhs = string.find(s,"<lhs>(<rhs>)")
> which is pretty awful on several fronts, when what I need is just:
Yes, I understand that. It is rather ugly. You could use the string.gfind
library function with a break statement:
for rhs in string.gfind(s, "<lhs>(<rhs>)") do
-- do something with rhs
break
end
Of course, that doesn't give you "if then else". But there are some
interesting alternatives, with a little functional infrastructure.
For example:
-- fn, s, v can be any triple suitable for "for in"
function once(fn, s, v)
return function(s, flag)
if flag == nil return fn(s, v) or false
end, s
end
-- Now we have:
for rhs in once(string.gfind(s, "<lhs>(<rhs>)") do
if rhs then
print (rhs)
else
print "No match!"
end
end
-- But it also works with pairs:
for k in once(pairs(t)) do
if k then
print "t has at least one key"
else
print "t is empty"
end
end
Warning: None of this code is tested.
R.
PD:
> but the valid alternative of:
> _,_,rhs = string.find(s,"<lhs>(<rhs>)")
> if rhs then
> doesn't limit scope to block of use
True, but:
do local _, _, rhs = string.find(s, "<lhs>(<rhs>)")
if rhs then
-- ...
end
end
does.