lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Agreed on the foot-shooting ability. Your example is somewhat wrong though: You wouldn't have to list them all. You could still truncate to the first return value by surrounding the _expression_ in parenthesis:

local fa, ga, gb = (f()), g()
"What if f or g change in the future to return more or less values?"

Excellent point. Many Lua APIs that are extended but must keep backwards compatibility add (1) additional params and (2) additional return values to existing functions. If Lua were changed to behave as proposed, this would most likely not work and break people's code. Lua's current behavior can actually be considered questionable and I remember shooting myself in the foot with it at least once.

On 27.07.22 13:53, siiky wrote:
Hi Rodrigo,

local a,b,c,d = f(),g()

would simply do a=1,b=2,c=3,d=nil instead of the current
a=1,b=3,c=nil,d=nil.
I can only see a ton of foot-shooting-ability... It's not obvious where
the values come from. It could be that f() provides a,b,c,d, or a,b,c,
or a,b, or a, or none of them; with g() providing the rest of them (or not!)

IMO this would lead to code that is very difficult to understand and to
maintain (read next).

What do you do if you want to ignore some of the return values?

function f() return 1,2,3,4 end
function g() return 5,6 end

You would have to list them all:

local fa,fb,fc,fd, ga,gb = f(), g()

What if f or g change in the future to return more or less values?

s(f(),g()) -> calls s(1,2,3) instead of s(1,3).

Would it be more convenient and predictable?
I would think not, that it would the exact opposite of more convenient
and predictible.

Without something like Scheme's `values` and related supporting
procedures+macros (R5RS, §6.4 Control features), Python's approach
(using tuples to fake it) is probably the best compromise, where

def f():
  return 1,2,3,4

is shorthand for

def f():
  return (1,2,3,4)


In Scheme this would be the "equivalent" code:

(define (f) (values 1 2 3 4))

And you'd explicitly "destructure" the returned values with, for
example, `receive`:

(receive (a b c d) (f)
  ; a=1, b=2, c=3, d=4
  )

or

(receive (a b . rest) (f)
  ; a=1, b=2, rest=(3 4)
  )


(whether multiple values are silently ignored or an error is
implementation dependent)


R5RS: https://schemers.org/Documents/Standards/R5RS/HTML
receive: https://srfi.schemers.org/srfi-8/srfi-8.html


siiky