shiika
shiika copied to clipboard
Allow `?` for method suffix?
I've not decided whether to allow ?
as method suffix (like Ruby) or not.
If allowed, the method must return Bool
.
The reason not to introduce this is Rust's ?
operator.
If Shiika won't have exceptions and stick to Result<T, E>
, there should be something like ?
in Rust.
My concern is that they may conflicts in syntax or make the code cryptic... but considering foo?
does not return Result
(because it returns Bool
), maybe it's ok?
Just some code that shows that it might actually be confusing:
class A
def full? -> bool
true
end
def empty -> Result<Int>
# Not sure if this is the syntax...
Result.ok(5)
end
end
class B
def use_a -> Result<Int>
a = A.new
# ...
# Imagine this being a larger function body, not only like 5 lines
b = a.full? # Holds bool
c = a.empty? # Holds
# More code
Result.ok(1)
end
end
Depending on how "far away" the code that uses both these syntax is, it might be hard to understand properly. If one already forgot the context (a method returning Result) they might assume that both return a boolean.
Good point. Having two different ?
(no, three, because there is ? :
) seems too confusing.
So the options are:
- Add method name suffix
?
only (= Ruby) - Add
?
for Result only - Add method name suffix
?
+ another facility for Result- Rust had
try!
macro before?
is introduced. - Scala's
for
expression can be used to simplify computation with Either, Future, etc. - Go2 may have something for this problem
- etc.
- Rust had
It depends on whether you want to stick more to Ruby or Rust. If it's Ruby, I'd say the method suffix is probably the right choice. If it's Rust, the ?
operator should stick.
Go2 looks definitely better than Go(1) and the pure boilerplate of error handling was why I left the language untouched after I tried it out a couple of times. Although for me, it is still too verbose. I think Rust does it better while still being able to keep the same "power level" due to mapping of error types.
Swift has the guard
keyword: https://stackoverflow.com/questions/30791488/swifts-guard-keyword
Maybe something like this? Feels neither Rust-y nor Ruby-y (:smile:) but might work:
class A
def returns_error -> Result<Int, ()>
Result.ok(5)
end
def early_return_if_error -> Result<Int, ()>
guard v = returns_error # or v = guard returns_error || v = check returns_error
Result.ok(v * 2)
end
end
I would like to suggest expr.try
(pick any keyword for try
), which works same as expr?
and is parsed same as expr.await
.
Having both ident?
and expr?
is technically okay. To do so, compiler implementation needs some effort. A possible way is that lexer reads ident?
as ident+operator and compiler combines them later if ident
doesn't exist. (I don't think the effort and language complexity are worthwhile for ?
operator.)
res = returns_error.try
. Looks good to me!