About expanding do end expression's behavior #139
Replies: 11 comments 24 replies
-
It best to use a keyword, it's more clear.
Didn't click with me, list of possible of replacing
Lot of ugly options, the motivation behind the change is to allow to allow returning from function inside do expressions, so this can be used with expression macros, allowing it to do more interesting things. |
Beta Was this translation helpful? Give feedback.
-
I just thought about a option without introducing new keyword local i = 0
local a = (do
if i == 1 then
(return 'one')
else
(return 'two')
end
end) Although feels odd, but at least no new keywords. |
Beta Was this translation helpful? Give feedback.
-
Two options that came in mind:
local i = 0
local a = evalscope
if i == 1 then
evalresult 'one'
else
evalresult 'two'
end
end |
Beta Was this translation helpful? Give feedback.
-
Does this make sense as keyword? local i = 0
local a = (do
if i == 1 then
answer 'one'
else
answer 'two'
end
end) I have also tried with local i = 0
local a = (do
if i == 1 then
reply 'one'
else
reply 'two'
end
end) and looks decent too... |
Beta Was this translation helpful? Give feedback.
-
What if instead of a keyword we just use local i = 2
local s = (
if i == 1 then
return 'one'
elseif i == 2 then
return 'two'
else
return 'other'
end) |
Beta Was this translation helpful? Give feedback.
-
@edubart what is the limitation you have with the use of One thing in Rust that confused me initially but then thought it made absolute sense was the use of "naked" values as part of expression: fn main() {
// variable binding
let x = 5;
// expression;
x;
x + 1;
15;
} Maybe this could work for local i = 0
local a = (do
if i == 1 then
'one'
else
'two'
end
end) |
Beta Was this translation helpful? Give feedback.
-
I have a better propose if you don't mind: Old proposed way: local i = 0
local a = (do
if i == 1 then
(return 'one')
else
(return 'two')
end
end) New shorter way that makes sense at least with the aforementioned example: local i = 0
local a = evalexpr(i == 1 and 'one' or 'two') |
Beta Was this translation helpful? Give feedback.
-
@edubart is this the expected behavior for the following code? require 'io'
do
local i = 0
local a = (do
if i == 0 then
return 'zero'
end
end)
io.printf("i = %d, a = %s\n", i, a)
end Why am I forced to use an require 'io'
do
local i = 0
local a = (do
if i == 0 then
return 'zero'
else
return 'unknown'
end
end)
io.printf("i = %d, a = %s\n", i, a)
end |
Beta Was this translation helpful? Give feedback.
-
I've decided to not introduce any new keyword, the local i = 0
local a = (do
if i == 1 then
in 'one'
else
in 'other'
end
end) Rationale:
|
Beta Was this translation helpful? Give feedback.
-
@edubart can you provide an actual case you are currently dealing with that forces you to introduce a new mechanism to simplify possible restrictive behavior somehow? |
Beta Was this translation helpful? Give feedback.
-
Actual case use case is to a require 'io'
-- Macro for quick error handling.
## local function try(expr)
local res, errmsg: string = #[expr]#
if #errmsg > 0 then
-- the following gets the first return type for the function the macro is currently parsing
local R: type = #[context.state.funcscope.funcsym.type.rettypes[1]]#
return R(), errmsg -- returns an empty value plus an error message
end
in res -- inject back the result of the try macro
## end
-- Read file, returns contents plus and error message.
local function readfile(name: string): (string, string)
local file <close> = #[try]#(io.open(name)) -- if `io.open()` fails the function will return early with the error
local contents = #[try]#(file:read('a')) -- if `read()` fails the function will return early with the error
return contents, ''
end
-- Load multiple files, returns the contents plus an error message.
local function concatfiles3(f1: string, f2: string, f3: string): (string, string)
local file1 = #[try]#(readfile(f1)) -- if `readfile` fails returns early with an error code
local file2 = #[try]#(readfile(f2)) -- if `readfile` fails returns early with an error code
local file3 = #[try]#(readfile(f3)) -- if `readfile` fails returns early with an error code
return file1..file2..file3, ''
end
print(concatfiles3('file1', 'file2', 'file3')) The benefit is to avoid typing lots of ifs and returns for checking each error code, this will make easier to make some libraries that needs to handle lot of errors. This is working with the latest commit. You have seen macros like this recently in SerenityOS/serenity#10303 |
Beta Was this translation helpful? Give feedback.
-
Since I have just deleted Discord to reduce mental noise, I have decided to open this thread to continue from where you left this conversation about expanding
do end
's expression behavior.In my humble opinion, you have a couple of options:
<~
oremitexpr
.Beta Was this translation helpful? Give feedback.
All reactions