Terminal.Gui icon indicating copy to clipboard operation
Terminal.Gui copied to clipboard

F# the ustring API makes it annoying to use F#.

Open migueldeicaza opened this issue 7 years ago • 6 comments

We might need to introduce string overloads

migueldeicaza avatar May 18 '18 02:05 migueldeicaza

I just ran into this myself. My gut was to look for a constructor on ustring that takes a string literal now I'm looking for the most reasonable short term solution.

jpierson avatar Aug 22 '18 01:08 jpierson

To help explain to others who may not be fully in on what makes this annoying in F# is to look at an example case in F# from the Sample in the README where we are instantiating an instance of the Terminal.Gui.Window class.

var win = new Window (new Rect (0, 1, top.Frame.Width, top.Frame.Height-1), "MyApp");
let win = new Window(new Rect(0, 1, top.Frame.Width, top.Frame.Height - 1), NStack.ustring.op_Implicit "MyApp")

Notice the need in the F# example to call the underlying compiled name for the implicit string to ustring operator op_Implicit. Not the end of the world but having this bit of the code read something like ustring "MyApp" without having to introduce any helper functions would make this library feel a bit more natural in F#.

jpierson avatar Aug 22 '18 02:08 jpierson

Isn't the more functional approach in F# to pipe the value, such as "foobar" |> ustring?

ebekker avatar Aug 22 '18 16:08 ebekker

@ebekker, that definitely looks valid as long as ustring is not a constructor but whether it's more functional or not I think is subjective. I typically use the pipe forward operator for larger chains of transformations.

In this case since there are no additional parenthesis for needed for the prefix notation I think it comes down to which one is less characters and thus noise.

"foobar" |> ustring

v.s.

ustring "foobar"

jpierson avatar Aug 23 '18 02:08 jpierson

Yeah, I think I might need to make ustring just an internal API, and an optional API everywhere :-(

migueldeicaza avatar Aug 29 '18 03:08 migueldeicaza

You run into the same issue using SharpDX. That's why I always define an implicit conversion operator:

let inline (!>) (x:^a) : ^b = ((^a or ^b) : (static member op_Implicit : ^a -> ^b) x)

Then you just write !> "blabla" and don't need to worry what the target type is. Example usage here: https://gist.github.com/asik/ce229023fb0eb153bde6aacc384d8ac4

Agreed it would be better to avoid needing this, but just to say there's a half-decent workaround.

asik avatar Apr 29 '19 21:04 asik

Changed title of this Issue from "F# the ustring API makes it annoying to use F#".

In v2.0 we should remove the dependency on ustring (at least externally) and use System.Rune instead. While ustring is neat, the fact that artifacts of it are exposed via the public Terminal.Gui API is problematic (F# support just being one). Another example is just simple usage of the API requires users to import NStack (see the C# Example in the main README).

tig avatar Oct 14 '22 22:10 tig