>>159
I'm unemployed for a reason.
>>160
I do cuz I'm crazy.
Well, nil never appears as a value in ..., and the only keys are the integer indecies of the arguments, but there is a serious problem in that if the user calls the function with nil values in the arguments, then ... will only go up to the first nil argument and stop, cutting the arguments short. This can be solved by using a different value than nil to represent nil, although this is very inconvenient. If Lua didn't have this problem with ..., the hack wouldn't be necessary.
#!/usr/bin/lua
function make_value(v)
return function() return v end,
function(new_v) v = new_v end
end
struct_nil = {}
function make_struct(...)
local functions = {}
for i,v in ipairs({...}) do
local getter, setter
if v == struct_nil then
getter, setter = make_value(nil)
else
getter, setter = make_value(v)
end
table.insert(functions, getter)
table.insert(functions, setter)
end
return unpack(functions)
end
function main()
local get_name, set_name,
get_age, set_age,
get_gender, set_gender = make_struct('John', struct_nil, 'male')
print(get_name()) --> prints John
print(get_age()) --> prints nil
set_age(56)
print(get_age()) --> prints 56
end
main()
This is really irritating though, because if you wanted to create a struct using the return values of functions that may return nil, you'll have to compose the function with one that checks for nil values.
function struct_feild(v)
if v == nil then
return struct_nil
else
return v
end
end
person = {make_struct('John', 45, 'male', struct_field(get_other_guy_address()))}
So now if other_guy is homeless and doesn't have an address, it wont crash out the person struct, and person will also not have an address. (if you are wondering why there are { } around the make_struct call, putting a function call inside of an array will collect the multiple return values in the array).
I was going to do it again in scheme, but the multiple return value semantics in scheme are so complicated that it is more convenient to just store your structs as arrays and make your own getters and setters:
(define (make-person name age gender)
(vector name age gender))
(define (person-get-name self) (vector-ref self 0))
(define (person-get-age self) (vector-ref self 1))
(define (person-get-gender self) (vector-ref self 2))
(define (person-set-name self v) (vector-set! self 0 v))
(define (person-set-age self v) (vector-set! self 1 v))
(define (person-set-gender self v) (vector-set! self 2 v))
I forget if scheme has built in support for structures. It wouldn't be hard to implement a mechanism like this using macros.
>>161
your god can't save you from a massive pile of returned closures. There is no escape from their lexical bindings.