-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add assignment bang operator #1181
Comments
Oh I like it :D Then it's also possible to do: let value =! something() instead of: let! value = something() But why not. I am totally fine with it. |
One of my concerns with this is that we add new syntax for each construct. The await syntax from C# is actually really smart as it handle all these cases with a single keyword. I don't have a good name for it yet, but let's call it bang! for now, we could could write:
and it would be similar to
or for your example:
It would work for if, match, function arguments, various computations. It would also not require extra methods on the builder as it can just use Bind, |
This has actually already been suggested here: #1070 |
Just seen and updated the issue description to link to that. |
For me, this looks like injecting some magic. I feel the example with 3x explicit let! and a simple record construction is more readable, as it makes clear there is something else going on. It's less surprising. |
Please, this would great. We could have things like pipe without an intermediate task {
bang! getNetworksAsync()
|> Array.iter (fun n -> DoSomethingWith n.ToString())
} This would be the same motivation as having This syntactic sugar would be extremelly useful. |
Just toying, but here's one idea: let validateCustomer (raw : RawCustomer) : Result<ValidatedCustomer, string> =
result {
return
{
Id = (validateCustomerId raw.CustomerId)!
Name = (validateName raw.Name)!
Country = (validateCountry raw.Country)!
}
} |
Need to be careful with it because with these The proposal is triggering the monadic behaviour, but when I think about that, specifically for setting records members, there cannot be dependencies between results of computing functions, so it ought to be applicative (think of validation scenarios as one of the examples)! |
I think the |
It's a valid custom operator today, so it's actually a breaking change. |
I have marked #1070 as approved-in-principle, which subsumes this one really. |
I propose we add the ability to bind within the context of an assignment to e.g. a record.
Given functions
validateCustomerId
,validateName
andvalidateCountry
, all of which take in a string and return someResult
(let's assume for now to keep things simple it'sResult<string, string>
) and you want to go from a "raw" (unvalidated) Customer to a "validated" Customer:Here's what a sample implementation with this feature might look like (I'm assuming that the computation expression already exists, see e.g. FSToolkit.ErrorHandling).
The existing way of approaching this problem in F# is to explicitly let bang for each validation function, bind to a symbol and then immediately afterwards assign into a record which is returned back out of the CE.
We've already seen support for
match!
to short-circuit a very similar pattern and I wonder if something like this would also be of use.Pros and Cons
The advantages of making this adjustment to F# are that code becomes a little more succinct, and we reduce boilerplate. From a pedagogic point of view, I think it would be easy to learn in the sense of "just put ! after the = whenever you have a result [or option or async etc.]) and it just works".
The disadvantages of making this adjustment to F# are another way to do things, an extra operator to learn, plus the effort to implement this. I also may be naively overlooking some breaking change that this could introduce or extra complexity in the compiler etc. - so am fully prepared for this to be shot down on the grounds of "this just isn't possible" (as well as "this is a terrible idea, let's forget about this" :-)).
Extra information
Estimated cost (XS, S, M, L, XL, XXL): S. I suspect that this is more a syntactic sugar level feature than adding something magical into the language.
Related suggestions: I've been directed to #1070 . This is a similar - but more ambitious - feature. If implemented, it would (I believe) solve this issue as well.
Affidavit (please submit!)
Please tick this by placing a cross in the box:
Please tick all that apply:
For Readers
If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.
The text was updated successfully, but these errors were encountered: