Adding a Return() function

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Adding a Return() function

Soni "They/Them" L.
You know, we have error(), but it uses pcall... How can I add a Return() function, coupled to the core? (because I'm pretty sure it's impossible to do it with a lib)
-- 
Disclaimer: these emails are public and can be accessed from <TODO: get a non-DHCP IP and put it here>. If you do not agree with this, DO NOT REPLY.
Reply | Threaded
Open this post in threaded view
|

Re: Adding a Return() function

Sean Conner
It was thus said that the Great Soni L. once stated:
> You know, we have error(), but it uses pcall... How can I add a Return()
> function, coupled to the core? (because I'm pretty sure it's impossible
> to do it with a lib)

  Could you go into more detail about the problem that this will solve?  Or
at least, how it would look in source?

  -spc


Reply | Threaded
Open this post in threaded view
|

Re: Adding a Return() function

Soni "They/Them" L.

On 16/12/14 11:18 PM, Sean Conner wrote:

> It was thus said that the Great Soni L. once stated:
>> You know, we have error(), but it uses pcall... How can I add a Return()
>> function, coupled to the core? (because I'm pretty sure it's impossible
>> to do it with a lib)
>    Could you go into more detail about the problem that this will solve?  Or
> at least, how it would look in source?
>
>    -spc
>
>
if x or Return(nil, "missing x") then ... end

vs

if not x then
   return nil, "missing x"
else
   ...
end

It's literally a function like error() tightly coupled to the core, and
doesn't replace the return statement.

--
Disclaimer: these emails are public and can be accessed from <TODO: get a non-DHCP IP and put it here>. If you do not agree with this, DO NOT REPLY.


Reply | Threaded
Open this post in threaded view
|

Re: Adding a Return() function

Javier Guerra Giraldez
On Tue, Dec 16, 2014 at 8:38 PM, Soni L. <[hidden email]> wrote:
> if x or Return(nil, "missing x") then ... end
>
> vs
>
> if not x then
>   return nil, "missing x"
> else
>   ...
> end


vs.

if not x then return nil, "missing x" end
....    -- no need for 'else'

--
Javier

Reply | Threaded
Open this post in threaded view
|

Re: Adding a Return() function

Hao Wu


On Tuesday, December 16, 2014, Javier Guerra Giraldez <[hidden email]> wrote:
On Tue, Dec 16, 2014 at 8:38 PM, Soni L. <<a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;fakedme@gmail.com&#39;)">fakedme@...> wrote:
> if x or Return(nil, "missing x") then ... end
>
> vs
>
> if not x then
>   return nil, "missing x"
> else
>   ...
> end


vs.

if not x then return nil, "missing x" end
....    -- no need for 'else'

I think OP's point is return can be a function so it can be baked into the expression v.s. a single statement, for simplicity. 
 
--
Javier

Reply | Threaded
Open this post in threaded view
|

Re: Adding a Return() function

Javier Guerra Giraldez
On Wed, Dec 17, 2014 at 2:25 AM, Hao Wu <[hidden email]> wrote:
> I think OP's point is return can be a function so it can be baked into the
> expression v.s. a single statement, for simplicity.


yes, i was just pointing a third option that is shorter, more readable
(IMHO) and currently valid.

when any function has some 'fail fast' condition(s), i like to add one
or more such 'guard lines' as close to the top as possible.  also, if
the "then" clause ends with a return, i don't put an "else" for the
rest of the function, avoiding useless indentation and too many 'ends'
at the end.

function division(x,y)
    if y==0 then return nil, "division by zero" end
    return x / y
end

instead of:

function division(x,y)
    if y==0 then
        return nil, "division by zero"
    else
        return x/y
    end
end

the OP proposal would be:

function division(x,y)
    if y!=0 or Return(nil, "division by zero") then
        return x/y
    end
end

which i think is much less readable than either of the others, and not
shorter than the first one.

--
Javier

Reply | Threaded
Open this post in threaded view
|

Re: Adding a Return() function

Thierry@spoludo
Well, we have assert and we have error and no macro nor typing constraints . Error has a ‎parameter for the level of error, but it rather means depth in the callstack. 
‎Assert returns the evaluation and is fatal.
Maybe there is room for generalization ‎at the language level?

So I will Just muse on not deeply thought concepts.

<- condition [, message [, level ]] -> ‎ non fatal, optional (by interpreter command line argument) , ie error like, but returns the condition evaluation like assert or exit the function with nil, message

‎<+ condition [, message [, level ]] +> same as above but always checked 

‎<* condition [, message [, level ]] *>  same as assert but with a level parameter.

Why not ‎keep the function call or use a keyword ? Mainly because of willing to cover type contraints but introducing keywords may be better. 

function ‎divide(
  a, 
  b <+ b ! = 0 and b +>, -- implicit assign in grammar context,
 fn <- type(fn) == "string" and fn -> -- can we check both constraint always and return cumulated messages ? Can we avoid "and fn"?

‎ local f = <* ‎io.open(fn, "w"), "can't write in "..fn *> -- keep assert keyword as an alias?
 return a/b
end

  Original Message  
From: Javier Guerra Giraldez
Sent: mercredi 17 décembre 2014 10:03
To: Lua mailing list
Reply To: Lua mailing list
Subject: Re: Adding a Return() function

On Wed, Dec 17, 2014 at 2:25 AM, Hao Wu <[hidden email]> wrote:
> I think OP's point is return can be a function so it can be baked into the
> expression v.s. a single statement, for simplicity.


yes, i was just pointing a third option that is shorter, more readable
(IMHO) and currently valid.

when any function has some 'fail fast' condition(s), i like to add one
or more such 'guard lines' as close to the top as possible. also, if
the "then" clause ends with a return, i don't put an "else" for the
rest of the function, avoiding useless indentation and too many 'ends'
at the end.

function division(x,y)
if y==0 then return nil, "division by zero" end
return x / y
end

instead of:

function division(x,y)
if y==0 then
return nil, "division by zero"
else
return x/y
end
end

the OP proposal would be:

function division(x,y)
if y!=0 or Return(nil, "division by zero") then
return x/y
end
end

which i think is much less readable than either of the others, and not
shorter than the first one.

--
Javier


Reply | Threaded
Open this post in threaded view
|

Re: Adding a Return() function

Marco Mastropaolo
Personally I find the "if" statement so much more readable, that I'd discard any alternative on that ground alone.

I agree with Javier - input validation and failfasts at the beginning of the function, with if statements.

Having "return" as an expression would also cause a mess of difficult to understand behaviors.. like for example :

> return nil, Return(0)   -- does it return.. what ?
> f(Return(0)); -- is f ever called ?
> t[Return(0)] = f(Return(1)) + f(Return(2))  -- .. what ?

If there's really a need to save keystrokes on such scenarios I'd suggest a "on" pattern which just takes a single statement instead of a block like:

> on divisor == 0 return nil, "error"

> on divisor == 0 do return nil, "error"

or something like that.

But then, I don't see such a need :) 

Of course, my 2 cents.





On Wed, Dec 17, 2014 at 10:15 AM, Thierry@spoludo <[hidden email]> wrote:
Well, we have assert and we have error and no macro nor typing constraints . Error has a ‎parameter for the level of error, but it rather means depth in the callstack. 
‎Assert returns the evaluation and is fatal.
Maybe there is room for generalization ‎at the language level?

So I will Just muse on not deeply thought concepts.

<- condition [, message [, level ]] -> ‎ non fatal, optional (by interpreter command line argument) , ie error like, but returns the condition evaluation like assert or exit the function with nil, message

‎<+ condition [, message [, level ]] +> same as above but always checked 

‎<* condition [, message [, level ]] *>  same as assert but with a level parameter.

Why not ‎keep the function call or use a keyword ? Mainly because of willing to cover type contraints but introducing keywords may be better. 

function ‎divide(
  a, 
  b <+ b ! = 0 and b +>, -- implicit assign in grammar context,
 fn <- type(fn) == "string" and fn -> -- can we check both constraint always and return cumulated messages ? Can we avoid "and fn"?

‎ local f = <* ‎io.open(fn, "w"), "can't write in "..fn *> -- keep assert keyword as an alias?
 return a/b
end

  Original Message  
From: Javier Guerra Giraldez
Sent: mercredi 17 décembre 2014 10:03
To: Lua mailing list
Reply To: Lua mailing list
Subject: Re: Adding a Return() function

On Wed, Dec 17, 2014 at 2:25 AM, Hao Wu <[hidden email]> wrote:
> I think OP's point is return can be a function so it can be baked into the
> expression v.s. a single statement, for simplicity.


yes, i was just pointing a third option that is shorter, more readable
(IMHO) and currently valid.

when any function has some 'fail fast' condition(s), i like to add one
or more such 'guard lines' as close to the top as possible. also, if
the "then" clause ends with a return, i don't put an "else" for the
rest of the function, avoiding useless indentation and too many 'ends'
at the end.

function division(x,y)
if y==0 then return nil, "division by zero" end
return x / y
end

instead of:

function division(x,y)
if y==0 then
return nil, "division by zero"
else
return x/y
end
end

the OP proposal would be:

function division(x,y)
if y!=0 or Return(nil, "division by zero") then
return x/y
end
end

which i think is much less readable than either of the others, and not
shorter than the first one.

--
Javier


Reply | Threaded
Open this post in threaded view
|

Re: Adding a Return() function

Paige DePol
Marco Mastropaolo <[hidden email]> wrote:

> Personally I find the "if" statement so much more readable, that I'd
> discard any alternative on that ground alone.
>
> I agree with Javier - input validation and failfasts at the beginning of
> the function, with if statements.
>
> Having "return" as an expression would also cause a mess of difficult to
> understand behaviors.. like for example :
>
> > return nil, Return(0) -- does it return.. what ?
> > f(Return(0)); -- is f ever called ?
> > t[Return(0)] = f(Return(1)) + f(Return(2)) -- .. what ?
>
> If there's really a need to save keystrokes on such scenarios I'd suggest
> a "on" pattern which just takes a single statement instead of a block
> like:
>
> > on divisor == 0 return nil, "error"
>
> > on divisor == 0 do return nil, "error"
>
> or something like that.
>
> But then, I don't see such a need :)
>
> Of course, my 2 cents.

This is actually the approach I took with Lunia (my custom version of Lua)
as I disliked having a single 'return' or 'goto' inside a 'then/end' block.

Therefore in Lunia the following are possible:

if x == 1 goto label;
if x == 1 break;
if x == 1 return true;

Which, to me, looks nicer than this:

if x == 1 then goto label end
if x == 1 then break end
if x == 1 then return true end

Of course, with this shortcut style 'else' and 'elseif' are not possible,
nor does the shortcut-if syntax require an 'end' statement.

Also note that this syntax only allows specific keywords to replace the
'then' keyword after the 'if' expression, not arbitrary statements.

Your suggestion of a new 'on' keyword would allow for single statement
versions of the 'if' statement, however, I found that almost all of my
use-cases for a shortcut-if syntax involved 'goto', 'break' and 'return'
and the rest could just use the traditional 'then/end' syntax.

~pmd


Reply | Threaded
Open this post in threaded view
|

Re: Adding a Return() function

Soni "They/Them" L.
In reply to this post by Marco Mastropaolo

On 17/12/14 08:25 AM, Marco Mastropaolo wrote:
Personally I find the "if" statement so much more readable, that I'd discard any alternative on that ground alone.

I agree with Javier - input validation and failfasts at the beginning of the function, with if statements.

Having "return" as an expression would also cause a mess of difficult to understand behaviors.. like for example :

> return nil, Return(0)   -- does it return.. what ?
returns 0
> f(Return(0)); -- is f ever called ?
returns 0, f doesn't get called (due to the fact that Return gets called first and then the returned values are passed to f -- except Return never returns)
> t[Return(0)] = f(Return(1)) + f(Return(2))  -- .. what ?
UB? (Lua could evaluate f(Return(1)) first, or f(Return(2)) first? altho I haven't read the manual enough >.> in theory it could even evaluate Return(0) first and store the result for later usage)
This is basically the same as t[error(0)] = f(error(1)) + f(error(2)) >.>

If there's really a need to save keystrokes on such scenarios I'd suggest a "on" pattern which just takes a single statement instead of a block like:

> on divisor == 0 return nil, "error"

> on divisor == 0 do return nil, "error"

or something like that.

But then, I don't see such a need :) 

Of course, my 2 cents.





On Wed, Dec 17, 2014 at 10:15 AM, Thierry@spoludo <[hidden email]> wrote:
Well, we have assert and we have error and no macro nor typing constraints . Error has a ‎parameter for the level of error, but it rather means depth in the callstack. 
‎Assert returns the evaluation and is fatal.
Maybe there is room for generalization ‎at the language level?

So I will Just muse on not deeply thought concepts.

<- condition [, message [, level ]] -> ‎ non fatal, optional (by interpreter command line argument) , ie error like, but returns the condition evaluation like assert or exit the function with nil, message

‎<+ condition [, message [, level ]] +> same as above but always checked 

‎<* condition [, message [, level ]] *>  same as assert but with a level parameter.

Why not ‎keep the function call or use a keyword ? Mainly because of willing to cover type contraints but introducing keywords may be better. 

function ‎divide(
  a, 
  b <+ b ! = 0 and b +>, -- implicit assign in grammar context,
 fn <- type(fn) == "string" and fn -> -- can we check both constraint always and return cumulated messages ? Can we avoid "and fn"?

‎ local f = <* ‎io.open(fn, "w"), "can't write in "..fn *> -- keep assert keyword as an alias?
 return a/b
end

  Original Message  
From: Javier Guerra Giraldez
Sent: mercredi 17 décembre 2014 10:03
To: Lua mailing list
Reply To: Lua mailing list
Subject: Re: Adding a Return() function

On Wed, Dec 17, 2014 at 2:25 AM, Hao Wu <[hidden email]> wrote:
> I think OP's point is return can be a function so it can be baked into the
> expression v.s. a single statement, for simplicity.


yes, i was just pointing a third option that is shorter, more readable
(IMHO) and currently valid.

when any function has some 'fail fast' condition(s), i like to add one
or more such 'guard lines' as close to the top as possible. also, if
the "then" clause ends with a return, i don't put an "else" for the
rest of the function, avoiding useless indentation and too many 'ends'
at the end.

function division(x,y)
if y==0 then return nil, "division by zero" end
return x / y
end

instead of:

function division(x,y)
if y==0 then
return nil, "division by zero"
else
return x/y
end
end

the OP proposal would be:

function division(x,y)
if y!=0 or Return(nil, "division by zero") then
return x/y
end
end

which i think is much less readable than either of the others, and not
shorter than the first one.

--
Javier



-- 
Disclaimer: these emails are public and can be accessed from <TODO: get a non-DHCP IP and put it here>. If you do not agree with this, DO NOT REPLY.