I know the name Result is standard in Rust, Elm, and OCaml (among others, probably) but a few things have always bothered me about it:
result = ... to just be "the result of this computation, which I will use later" and the existence of the type Result makes it look like something named "result" should be a Result even when it often isn't (I personally often use the name answer = instead of result = for this reason, but I notice this really hasn't caught on, and I just read a lot of other people's code, especially in Rust, that says result = or res = when referring to non-Results and it bothers me)Result when the essence of what it's representing is not "this operation's result, whatever that might be" but rather "this operation's result, or else an error if the operation failed" - like whenever I explain Result to someone who's never used it before, I always explain it in terms of failure and errors, and it's weird that the name does not suggest that it's about failure in any wayI recently found out that Scala uses the name Try (as in "give it a try") for a type that represents operations that can fail
I'm curious about the idea of renaming Result to Try because it addresses all of my concerns above:
result = or res = it will no longer be confusing no matter what its type is (and nobody writes try =)try/catchexamples:
List.last : List(elem) -> Try(elem, [WasEmpty])
Str.from_utf8 : List(U8) -> Try(Str, [BadUtf8(Utf8Err)])
obviously I have a lot of muscle memory around Result, but I also had a lot of muscle memory around String, and I found I got used to Str quickly and then it was fine.
I'm curious what others think of this idea!
I like the idea. I've also always disliked the tension with result = ... where the thing on the rhs might not actually be a Result
To me it feels fine, but just feels like weirdness for no gain. Result is so ubiquitous that it doesn't seem work changing.
I think it only feels ubiquitous if you're into Elm, OCaml, or Rust.
I'm pretty sure 95% of programmers either know it as a Rust-specific name or don't know Rust and have never heard of it :smile:
oh hm Swift has Result too, that's a big one :thinking:
Yeah, I guess that is fair. In c++ it is scatter....ErrorOr for example is one version. In go, you get a tuple with on part being an error type. Python prefers exceptions error and custom result types are pretty awful. What does JS/TS do?
exceptions by default; I believe the most popular way to do this sort of thing right now (it changes every few years) is currently Effect.js, which uses Either
I guess of note, it's super easy to say "you're used to Result, but here it's spelled Try" or "you're used to Either, but here it's spelled Try and the argument order is reversed"
as an aside, I think it's funny that Effect.js keeps Haskell's Either argument order of putting the error type first, even though there's no benefit to doing it that way (unlike in Haskell, where it's important for giving partially-applied Either types instances like Functor and having mapping over them work as desired)
but if you don't have partially-applied types, there's no real reason to do that. I assume the reason Elm originally kept Haskell's ordering was in case Elm ever got HKP (which was an open question circa 2013)
Yeah, this seems with trying
the essence of what it's representing is not "this operation's result, whatever that might be" but rather "this operation's result, or else an error if the operation failed"
Worth giving it a go. This feels like a reasonable argument to me - even if its a little bit of wierdness.
Try sounds better than Result, even though I’m quite familiar with elm/rust.
I think the only real complaint I have with Try is that it doesn't sound like a data structure and it is unclear what it is made of. Like I would not be surprised if a Try was equivalent t a Promise and contained something lazily evaluated or that was not yet complete.
Probably a bias of being used to names. And having heard phrases like "A result is either a value or an error`.
Also, minor aside still related to naming: Try sounds like it should have the sub enums be
Success and Failure, not Ok and Err.
yeah fair points, although to be fair I think both of them would apply to Result if I were hearing about it for the first time :laughing:
I wouldn't want to change Ok and Err personally. They're clear and concise and I don't have any complaints about them like I do with Result :smile:
Yeah... I probably am just too used to result
And yeah, Ok and Err are short and easy to understand. I like them. I just think they fit Try a little worse.
Richard Feldman schrieb:
exceptions by default; I believe the most popular way to do this sort of thing right now (it changes every few years) is currently Effect.js, which uses Either
That’s effect.ts not js, right? And there you rarely use either itself per my knowledge, you’d usually use the effect type itself (https://effect.website/docs/getting-started/the-effect-type/)
I think the only real complaint I have with Try is that it doesn't sound like a data structure and it is unclear what it is made of.
I feel the same way.
I've read your first paragraph and I was about to suggest scala's Try. I've always wondered why rust didn't pick it over Result. Super concise, and can be thought of as a name
My only confusion is that "try" is an act, and "result" is an outcome of the act. Try gives me lazy evaluation feeling.
I'm not a native speaker so maybe my language understanding is wrong, but to me try also does not sound like something I would get as a return from something I try to do.
What about Maybe? Since we don't have an equivalent of Elms Maybe the type is free to mean: maybe it was ok, maybe there is an error. At least to me it sounds more natural to get "maybe" as an answer to "do something".
Try.try
Just reading through the definition I actually like effect ("a change which is a result or consequence of an action or other cause.") which can either be a success or a failure 🤷🏼♂️
fwiw Try is both a noun and a verb ("try this") vs "gave it a try") - so I think of it as the latter - "what was returned after we gave this operation a try"
Johan Lövgren said:
Try.try
oh yeah I forgot to mention, this is something else I like about Try!
today we have Result.try, but I think Try.and_then both uses the normal name for that and also makes more sense: "try this, and then if it errors, try that"
Am in agreement with the thoughts about Try sounding like a (deferred / Promise-like) action rather than the outcome. I also seem to read it as a command ("try this") but that could be familiarity as Brendan says.
Out of curiosity, I looked through synonyms for the two groups but it wasn't fruitful:
Most are already in use or too colloquial. (Perhaps Outcome or Out?)
Richard Feldman said:
- it's also kind of weird that the type is called
Resultwhen the essence of what it's representing is not "this operation's result, whatever that might be" but rather "this operation's result, or else an error if the operation failed" - like whenever I explainResultto someone who's never used it before, I always explain it in terms of failure and errors, and it's weird that the name does not suggest that it's about failure in any way
Are these conflicting, or just different uses for Result? I.e. - the fuzzy distinction between cases where Err is used to represent ~exceptional circumstances without using exceptions (network or file system errors?) vs part of the codomain (regex matching, business rules), and these two uses map to these two definitions.
I don't think there's any important distinction between those examples
they can all fail, that's what matters!
to me the distinction that matters is "do we want to support graceful userspace recovery from this failure?" - e.g. to crash or not
like OOM is a crash, division by zero has ended up being a crash (after we attempted to not make a crash and discovered that crash is better in practice), pushing so many elements to a list that we run out of length in isize::MAX, etc.
I don't think there's any important distinction between those examples
they can all fail, that's what matters!
That makes sense I agree. I'm not sure about Try but I'm no longer sure about Result either :laughing:
I agree with the issues of Result but also I consistently read Try as a verb, probably because of try/catch, which may be a stumbling block for newcomers (active users would probably adjust). For some reason I read Attempt as a noun, so it clears that bar for me, but it's not as terse. Effect muddies the waters regarding what "effectful functions" are (if that's how Roc will explain impure functions).
Overall I'm neutral on all options as they all have their pros/cons :shrug:
It's quite odd but Tried is one character shorter and not an imperative verb?
If brevity is key (setting aside the issues with "Result"), perhaps Res is ok, given that it is contextualized by Ok and an already-shortened Err.
besides it being very concise, a thing I like about Try is that Scala already did the experiment of whether people get used to it vs find it confusing in practice, and it seems to be fine for them!
I don't mean to harp on (I actually don't mind Try that much!) but isn't Scala's choice to use "Try" influenced by its usage in wrapping throwing expressions?
val dividend = Try(StdIn.readLine("Enter an Int that you'd like to divide:\n").toInt)
The inner can raise, and so Try (the object) catches and converts to Success or Failure. "Try" is very natural here as a verb, which must have influenced the naming of the type and how easy it was for people to get used to it.
however, Try in scala is not exactly the same what Result is in roc afaiu. one justification of having exactly Try name is that its calling semantics is readable Try(throwable_expression) which makes sense in scala but not in roc. I mean, I don't feel Try in roc comes from the same philosophy it comes in scala. e.g. I see how Try associates with try/catch from java but roc doesn't have exceptions
it's not exactly the same, but it's a type that gets returned to indicate an operation might fail, and that's how it would be used here too.
I think it's safe to assume ~100% of people coming to Roc have used try/catch on other languages, so I think if that's a helpful association, it would be helpful here too :smile:
Fallible comes to mind
That sounds very fancy :p
The cambridge dictionary has human as synonym for fallible. To me that would be a hilarious type name.
"This function returns the Human type. This is indicative of a potential failure. You have to always check your Humans for errors."
I think of Try primarily as a verb also (I'm not a native English speaker). On the other hand, after you say "give it a try", and I remind myself of this sentence occasionally, it isn't weird. It is probably as helpful of an association with try-catch as zig's try-catch. Yes, it's about error handling, but it's semantics are completely different. I don't know whether that's helped Zig beginners.
On the other hand, I've also felt the tension of my result named variables not being of type Result. With inlay_hints in my editor, it would be better. I'd know the type from a glance without annotations and could see it's not a Result. Since Roc doesn't need type annotations, and inlay hints aren't ubiquitous (heard some ppl prefer agentic completions and turn off the lsp; reviewing a short PR on the github website), Try would help disambiguating that. I think once people get used to it, it'd be better than Result, because of it's brevity. Not just writing it, since you see that type so often, it'd shorten the type annotations quiet well. Kinda embarrassed I've never thought of answer as my var name.
I think I'd probably get used to it quickly, and I love the short name for such a key type. I also misread it as a verb until it was pointed out to me in conversation above that 'try' is of course a noun as well, but I think even then the intent behind the name is pretty clear.
I immediately read Try as in "the first try, the next try etc" etc, but still, it's about a process, not about the outcome. When I see Try, I think of a computation that would be lazily evaluated when I unwrap it.
On the other hand, the Try structure is equivalent to some computation, which is a try indeed, so I can calm myself :smile:
Just gonna throw out a list to see if anything feels nice:
AttemptTryErrOr/SuccessOrCouldFail/MightFail/CanFail (Maybe something short and 2 word could be really clear?)OkOrErrMaybeErrNone feel amazing, though something two word and short may be clearer....
but all feels minor to me
Combinations like „SuccessOr“ for me rather sound like methods for fallbacks (it either succeeds or is this). „MaybeErr“ atleast to me could then also simply be „Maybe“, don’t see that much benefit in adding „Err“.
I personally would from the list rather gravitate to something in the direction of attempt instead of the ones that „focus purely“ on the fact of it can fail, I‘d assume the failure itself is part of the expected business flow at quite a few places, it‘s more of a question where to handle that it can go sideways 🤷🏻♂️
Attempt is the clearest to me. I think of it as a noun right away. Despite that, I still prefer Try, because it's short. I would not want to be in a pair programming session where Result is called ErrOr.
-So yeah, this function returns an error
-You mean an error or an err-or?
:smile:
I think ErrOr really only makes sense with classes and inheritance. Cause you have an Err class, or some other specific subclass.
So you would never says, it return an error. You would said it returns an err-or User (for ErrOr(User)).
But that still is not great and definitely does not work in roc where we have to specify the exact error type.
Similarly with try, as you would only be constructing using variants (Ok(x)) - there wouldn't be confusion from using try like Try(x) (reminiscent of try! macro from Rust, Try() in Scala, or try/catch control flow).
I do find the type annotation confusing though:
convert: Foo -> Try(Bar, ConverterError)
Is this more obvious to new learners than Result? It does seem more related to errors as a word, but that is counteracted to me by not looking like a data structure.
All else equal - it is nice and short, so perhaps "it tries to return a Bar" could help make it feel natural?
I'll also add Kotlin as another language that has Result in its std lib
Brendan Hansknecht said:
I think
ErrOrreally only makes sense with classes and inheritance. Cause you have anErrclass, or some other specific subclass.So you would never says, it return an error. You would said it returns an err-or User (for
ErrOr(User)).But that still is not great and definitely does not work in roc where we have to specify the exact error type.
ErrOr(User) reads nice, but yes mostly till you need to specify the error type.ErrOr(User, [UserNotFound]) actually doesn't look that bad, but still this naming pattern would be better for an Option like type, but there isn't one in Roc. NilOr(User), NoneOr(User) reads like english.
What if it just is the Or type?
Or(User, [UserNotFound])
That would be really concise
I don't think many of the methods would make sense for a generic Or type. thing.map_err(...) thing.and_then.
Of course you would learn either way...but this type definitely is meant to be biased.
I think Res can also be great, just because it's shorter. Probably no matter what it is called you can't avoid the need to explain that "result" of the computation might be ok or error
I don’t have a problem reading Result as “the result of this operation, which could be an error or the value I wanted,” but it’s also really easy to reach for result as a name for the result of a computation that can’t fail.
My knee-jerk reaction to Try is that it’s easiest to read as a verb and that it would be easy to want to see a Try value as some lazily evaluated thing.
But I’m used to languages with try as a keyword that means “try this thing.” And I also have preexisting knowledge of how Result is used in e.g. Elm and Rust. And with my preesixting knowledge, Try immediately makes me think of error handling, or something that might fail. Result in English doesn’t imply the possibility of failure by itself, hence our tendency to use it as a name for values.
I’m not sure if I have an opinion here. The more I think about Try the more I think it might be worth the experiment.
Fwiw, I also thought maybe Out (short for outcome) could work, though it could also be seen as short for Output which may not be what we want? Res could be short “response” in addition to “result,” so that seems less than ideal.
Has Verdict been suggested? It sounds a little dramatic, but I think I'd have a more accurate first impression of what it might be than with Try.
Try has been on main for awhile now, so we'll see how it goes! :smile:
I'm gonna close this as resolved; we can open a new thread in the future if anyone thinks we should change it after we've had some time to actually try it
Richard Feldman has marked this topic as resolved.
Last updated: Jun 16 2026 at 16:19 UTC