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
Postfix operators #711
Comments
In theory I like this for A main concern is that most peoples' experience and expectations are around the postfix |
How would the compiler disambiguate between If that doesn't cause existing code to break, I'd be all for this, though, with similar flexibility as for prefix operators. I've had a few situations where postfix would have improved readability. PS, can you update the title in your proposal? It still says 'Title of suggestion'. |
I can see a potential parsing problem. How should
If multiple |
@rmunn Whitespace can actually currently change the meaning of an expression. Prefix operators have higher precedence than function arguments, but only when there is no whitespace. Otherwise it gets parsed as an infix operator. Also, there are some rare cases where whitespace is problematic, for instance, when These aren't necessarily bugs, just stating that some shift in meaning is apparently already baked in. |
Can this feature be possibly useful to override the OCaml (;) operator and use it instead for |> ignore ? this would be a great benefit for people transitioning from C# or javascript! |
@jkone27, I don't think you can override However, I don't think it'll help you much, if anything, unary operators have some of the highest precedences, and if postfix were allowed, I think they'll also get high precedence. Meaning, you'll have to wrap your statement into parenthesis for your operator to work as you intend. Having said all that, coming from C#, I think it's best that one of the first things to learn is to stop using semicolons. And each time you need More and more, I've come to find |
@abelbraaksma i know, but just consider when using opinionated .net libs in F# like aspnetcore, and especially for people transitioning to the language, example from a sample repo I did for my company: https://github.com/jkone27/FsharpWebApi/blob/master/FSharp/Startup.fs is the common usage of ; operator so common in F# code? as a frequency of usage? this is aspnetcore (which would be like a big percentage of .netcore market share), member _.Configure(app: IApplicationBuilder, env: IWebHostEnvironment) =
if env.IsDevelopment() then
app.UseDeveloperExceptionPage() |> ignore
app.UseHttpsRedirection() |> ignore
app.UseRouting() |> ignore
app.UseAuthorization() |> ignore
app.UseEndpoints(fun endpoints ->
endpoints.MapControllers() |> ignore
endpoints.MapGet("/", fun context -> context.Response.WriteAsync("Welcome to F#!")) |> ignore
) |> ignore
//needed for swagger
app.UseSwagger() |> ignore
app.UseSwaggerUI(fun c ->
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1")
) |> ignore
vs member _.Configure(app: IApplicationBuilder, env: IWebHostEnvironment) =
if env.IsDevelopment() then
!app.UseDeveloperExceptionPage()
!app.UseHttpsRedirection()
!app.UseRouting()
!app.UseAuthorization()
!app.UseEndpoints(fun endpoints ->
!endpoints.MapControllers()
!endpoints.MapGet("/", fun context -> context.Response.WriteAsync("Welcome to F#!"))
)
//needed for swagger
!app.UseSwagger()
!app.UseSwaggerUI(fun c ->
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1")
)
i know in ocaml ";" is chaning side-effect operations, but here it doesn't seem to work if i used it, as the compiler still shows me wriggles in the intelliense, Probably i should open a separate issue for this :) but anyway also having ! as postfix custom already solves quite a lot of this visual "stress" |
Why don't you use fluent calls just like C#? member _.Configure(app: IApplicationBuilder, env: IWebHostEnvironment) =
(if env.IsDevelopment() then app.UseDeveloperExceptionPage() else app)
.UseHttpsRedirection()
.UseRouting()
.UseAuthorization()
.UseEndpoints(fun endpoints ->
endpoints.MapControllers()
.MapGet("/", fun context -> context.Response.WriteAsync("Welcome to F#!"))
|> ignore
)
//needed for swagger
.UseSwagger()
.UseSwaggerUI(fun c ->
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1")
) |
I disagree, I find your code quite readable. The It's quite common in F# to locally override I had the same thought as @Happypig375, you can just use method chaining. Another alternative is to use Similar code can be seen with
No, it is very rare, as in most cases it clutters the code. Prefix operators are obvious, postfix, esp at end of lines or in the middle, are not, you easily glance over them. In 250K lines in one of my projects, I see it only 12 times for short |
I agree with both of you, I just say ppl coming from C# would find it more useful to have a ; (postfix) operator as well as from JS, because it's so hard-wired in their brain 🧠 😆
|
That's, unfortunately not going to work, even with such operator. In fact, you can leave But certainly, we've all been there, and indeed, when I switch between languages, I often forget about |
yeah I know F# (at least keywords) i am just struggling to make it friendly to C# people , it's not my "own" struggle :) , i believe i will keep for now ! prefix custom without nowarn, also i don't like wrapping stuff in parenthesis, it would also sounds "hacky" to C# people i believe. I was trying to make it look good to them 👍 thanks! |
@jkone27, I've been through the same struggle. For me, the biggest challenge was learning to think functional, and understanding functional domain modeling. Ultimately, letting go of classes and hierarchies was one of the best things that happened in my programming career. It subsequently improved my C# skills too. Esp. in the early days on that path, I learned a great deal from this book by Thomas Petricek: https://www.amazon.co.uk/dp/1933988924, if you don't already have it, I can suggest it, also for your co-workers. On DU's and monadic style, I found the explanation with the adage "in the box, out of the box" from https://fsharpforfunandprofit.com/ very helpful to understand bind, apply, map and friends. (though on the |
@abelbraaksma @Happypig375 thanks, the "concern" was more for an educational/teaching perspective, thanks. I know many sources that you quoted here already, but I think the language should be as friction-less as possible for entry-level folks we need to "initiate" (considering myself a level2 entrylevel guy haha) And the main reason was just that I rarely see usage of ";" operator in real code, that's why i thought it would be nice to be able to override it at will, for sure when you need the original you should just be able to use it. I also understand it's not possible to easily override ";" being in the core of the lang (coming from ocaml), and also that I still have no clue of the internals of the compiler unfortunately. But thanks a lot! Have a nice day guys : ) F# is awesome |
Really nice idea. A use case could be Rust like error handling for Result types: https://doc.rust-lang.org/edition-guide/rust-2018/error-handling-and-panics/the-question-mark-operator-for-easier-error-handling.html A post fix "?" operator would take a lot of noise from from F# code with many "return on error" cases. |
@secana I think the idiomatic way for that is computation expressions. |
I'm closing this as it is not planned to add further complexity to the set of available operators in F#, there is already too much unnecessary symbolic complexity (particularly which beginners are over-exposed to) and our aim will be to reduce it in various ways |
Postfix operators
I propose we allow
$
at the start of custom operators, but the operator will be postfix.Currently, the
$
operator by itself is an infix operator, but multi-symbol operators starting with$
is not supported. I'd like to take this opportunity to enable defining postfix operators in F#, something like:The rules are simple: If the operator starts with a
$
and is longer than one character, then the leading$
is stripped away when used.So,
static member ($$)
would become a postfix operator$
. Alternatively, it could become$$
, in line with how~
behaves currently.The existing way of approaching this problem in F# is maybe using a prefix operator, but why limit the types of operators when F# can be used as a DSL?
Pros and Cons
The advantages of making this adjustment to F# are:
++
and--
if they come from an imperative background3!
vsfact 3
,f 3!
vsfact 3 |> f
The disadvantages of making this adjustment to F# are
\
because it must not appear in operator usage as it is hard to read, but allowing it only as a operator-symbol-chain starting character seems reasonable.Extra information
Estimated cost (XS, S, M, L, XL, XXL): M~L
Related suggestions: (put links to related suggestions here)
Affidavit (please submit!)
Please tick this by placing a cross in the box:
Please tick all that apply:
The text was updated successfully, but these errors were encountered: