fsharp / fslang-suggestions

The place to make suggestions, discuss and vote on F# language and core library features
345 stars 21 forks source link

New enclosing quotes for literals to enable unicode literals #1380

Open dark-valkyrix opened 2 weeks ago

dark-valkyrix commented 2 weeks ago

I propose we add an additional enclosing pair of quotes for literals : let ᐠmy literalᐟ= 0

that would be equivalent to : let ``my literal``= 0

`: unicode 0x0060 ᐠ: unicode 0x1420 ᐟ: unicode 0x141F

The existing way of approaching this problem in F# is to use double `` which can be cumbersome, especially when used for single characters outside the range of allowed ones for literals : let a= 1 ``⊕`` 2 let b= 1 ᐠ⊕ᐟ 2

For information, ᐠ and ᐟ are currently valid characters for literals, which makes this statement already valid : let z= 1 ᐠaddᐟ 2

The new feature would change that statement to : let z= 1 ``add`` 2

Pros and Cons

The advantages of making this adjustment to F# are the possibility to write more concise expressions.

The disadvantages of making this adjustment to F# are inexistent as this would be an additional feature with no breaking change.

Extra information

Estimated cost (XS, S, M, L, XL, XXL): XS

Related suggestions: n/a

Affidavit (please submit!)

Please tick these items 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 :+1: emoji on this issue. These counts are used to generally order the suggestions by engagement.

Tarmil commented 2 weeks ago

Or we could allow single backticks as equivalent of double.

(Or even any number of backticks, just like double quotes for strings)

dark-valkyrix commented 2 weeks ago

It would be a welcome improvement of course, but backticks are a little too small and they don't look so good :

let a= 1 `⊕` 2
let b= 1 ᐠ⊕ᐟ 2
realparadyne commented 2 weeks ago

How do you type unicode 0x1420 ?

How does that compare with typing a backtick that has key for it?

smoothdeveloper commented 2 weeks ago

an apl keyboard but for F# 🙂

I think on windows, with numeric keypad and alt key, you can input those by their numeric code.

image

dark-valkyrix commented 2 weeks ago

I understand that you can write hundreds lines (boilerplate?) of C# code a day but I spend much more time and energy on a single line of F# (which is why I love F# by the way), so I don't have a problem with copy/paste :)

Not being able to make F# look more mathematical is frustrating.

smoothdeveloper commented 2 weeks ago

@dark-valkyrix feel free to share more code samples, and show how F# is too close to C# rather than APL, I think this will help discussion for this suggestion.

dark-valkyrix commented 2 weeks ago

Sure, here's some basic code I have in mind :

        type Point=
             | ``P{x,y}`` of float * float
             | ``P{ρ∠θ}`` of float * float

        type Vector=
             | ``V{x,y}`` of float * float
             | ``V{ρ∠θ}`` of float * float

        let ``⨁`` vector point=
            match point, vector with

            | ``P{x,y}`` (px, py),
              ``V{x,y}`` (vx, vy) -> ``P{x,y}`` (px + vx, py + vy)

            | ``P{x,y}`` (px, py),
              ``V{ρ∠θ}`` (vρ, vθ) -> ``P{x,y}`` (px + vρ * cos vθ, py + vρ * sin vθ)

            | ``P{ρ∠θ}`` (pρ, pθ),
              ``V{x,y}`` (vx, vy) -> ``P{x,y}`` (pρ * cos pθ + vx, pρ * sin pθ + vy)

            | ``P{ρ∠θ}`` (pρ, pθ),
              ``V{ρ∠θ}`` (vρ, vθ) -> ``P{x,y}`` (pρ * cos pθ + vρ * cos vθ, pρ * sin pθ + vρ * sin vθ)

        let p1= ``P{x,y}`` (0.0, 0.0)
        let p2= ``P{ρ∠θ}`` (1.0, π/6)

        let v1= ``V{x,y}`` (0.0, 0.0)
        let v2= ``V{ρ∠θ}`` (1.0, π/4)

        let r1= p1
                |> ``⨁`` v1

That could be written like this (more compact and readable) :

        type Point=
             | ᐠP{x,y}ᐟ of float * float
             | ᐠP{ρ∠θ}ᐟ of float * float

        type Vector=
             | ᐠV{x,y}ᐟ of float * float
             | ᐠV{ρ∠θ}ᐟ of float * float

        let ᐠ⨁ᐟ vector point=
             match point, vector with

             | ᐠP{x,y}ᐟ (px, py),
               ᐠV{x,y}ᐟ (vx, vy) -> ᐠP{x,y}ᐟ (px + vx, py + vy)

             | ᐠP{x,y}ᐟ (px, py),
               ᐠV{ρ∠θ}ᐟ (vρ, vθ) -> ᐠP{x,y}ᐟ (px + vρ * cos vθ, py + vρ * sin vθ)

             | ᐠP{ρ∠θ}ᐟ (pρ, pθ),
               ᐠV{x,y}ᐟ (vx, vy) -> ᐠP{x,y}ᐟ (pρ * cos pθ + vx, pρ * sin pθ + vy)

             | ᐠP{ρ∠θ}ᐟ (pρ, pθ),
               ᐠV{ρ∠θ}ᐟ (vρ, vθ) -> ᐠP{x,y}ᐟ (pρ * cos pθ + vρ * cos vθ, pρ * sin pθ + vρ * sin vθ)

        let p1= ᐠP{x,y}ᐟ (0.0, 0.0)
        let p2= ᐠP{ρ∠θ}ᐟ (1.0, π/6)

        let v1= ᐠV{x,y}ᐟ (0.0, 0.0)
        let v2= ᐠV{ρ∠θ}ᐟ (1.0, π/4)

        let r1= p1
                |> ᐠ⨁ᐟ v1

Enhancement to infix operators can be the topic for a later case.

It is possible to write a super monad that operates on both points and vectors and define custom operators for use in computation expressions. That would look very nice without the necessity of double backticks.

Prunkles commented 2 weeks ago

It's not even monospace (in most fonts)

BentTranberg commented 2 weeks ago

I think it will be very little used, and for that reason it might easily cause confusion when used. Nothing wrong with the double backticks. They stand out, as they should.

The title of this issue makes no sense to me. It's identifiers, not literals. I don't see what enabling Unicode literals has to do with this.

LyndonGingerich commented 2 weeks ago

Could this problem be solved by creating a font with ligatures, like those JetBrains Mono has?

voronoipotato commented 2 weeks ago

font with ligatures, prettify symbols mode for emacs, conceal for nvim. In my opinion just I'm not in favor of any change where the syntax itself is a thing you can't type, and I was in favor of being able to make unicode infix operators. In retrospect I think using polish notation for "operators" has a much more obvious precedence so I don't care anymore.

dark-valkyrix commented 2 weeks ago

It's not even monospace (in most fonts)

Ok but default Visual Studio 2022 settings are just fine, looks great already

dark-valkyrix commented 2 weeks ago

I think it will be very little used, and for that reason it might easily cause confusion when used. Nothing wrong with the double backticks. They stand out, as they should.

The title of this issue makes no sense to me. It's identifiers, not literals. I don't see what enabling Unicode literals has to do with this.

You're right, that's about identifiers, not literals, my bad.

Very little used is perfectly fine, it is not as if F# was the most used language anyway, far from it. Functional programming is hard, and it will stay like this forever. It will never be a programming language for the masses. At least it can be wise to please the few people that will use it, don't you think?

dark-valkyrix commented 2 weeks ago

font with ligatures, prettify symbols mode for emacs, conceal for nvim. In my opinion just I'm not in favor of any change where the syntax itself is a thing you can't type, and I was in favor of being able to make unicode infix operators. In retrospect I think using polish notation for "operators" has a much more obvious precedence so I don't care anymore.

Font ligature is a solution, not as good as what I propose but that could be a step forward. How to implement this?

LyndonGingerich commented 2 weeks ago

Very little used is perfectly fine, it is not as if F# was the most used language anyway, far from it. Functional programming is hard, and it will stay like this forever. It will never be a programming language for the masses.

We still want to make it as popular (that is, useful to as many people) as possible. Our goal is, in fact, that F# be popular. Thus, we value simplicity and ease of use.

At least it can be wise to please the few people that will use it, don't you think?

Do many F# users want this? I don't get the impression that many programmers use special characters in their code.

Font ligature is a solution, not as good as what I propose but that could be a step forward. How to implement this?

Google is your friend.

You could alternatively write a transpiler to F# for your own superset language to which you could add whatever syntactic sugar you want. Or you could process each file with a text transform before building. But if you don't need to change anything but the appearance of a few characters, then modifying the view rather than the code sounds simplest to me.

I understand that you can write hundreds lines (boilerplate?) of C# code a day but I spend much more time and energy on a single line of F# (which is why I love F# by the way)

I don't think that many F# developers program this way. I think that most of us tend to avoid the extra work inherent in adding special symbols to the code. If I don't get stuff done, I don't get paid.

So I doubt that this feature would have much demand. And an extra feature is just waiting to conflict with some idea someone else has later.

But if it turns out that many people would use such a feature, then I'll retract my opinion.

voronoipotato commented 2 weeks ago

I don't want this feature and I would (and have) supported unicode operators for niche mathematical programming. I don't think this proposal is any easier or more convenient, and I think it's a solution looking for a problem. If you could find a sound way to avoid a surrounding symbol entirely, then I might be on board. Like maybe if the symbol is a single (rendered) unicode character you can omit the backticks. That I would support.