F# .Net Editor Examples
F# .Net Editor Examples
zamak
Posts: 10Questions: 1Answers: 0
I've been using DataTables for around 2 years now and it's been fantastic! We're currently switching from PHP over to F# and I know there is a .Net version written in C#, but I was wondering if there were any examples of it working with F#. They're fairly interoperable so I imagine it's basically a 1:1 translation, but having a reference for more complex scenarios is really nice.
Answers
I'm sorry to say we don't have any examples. I've actually never written any F# myself (its on my todo list, along with Go and Rust), however, due to the Common Runtime Environment in .NET the DataTables.dll will still be useful in F#, I'm just not sure what the surrounding syntax will be I'm afraid.
If you do cook anything up, perhaps you could post it so others could see and benefit from it as well?
Thanks,
Allan
It's been a bit of a slog. Not only am I using F#, I am running on .Net 6 -- so .net core -- and I am using an F#-specific framework called Falco. It was a lot of research to figure out how to wire everything up, but I did it. Although, I've encountered a problem I haven't been able to solve.
The program type-checks and compiles, however when I hit the route, it doesn't send any data back. It's just a completely empty response. Any ideas?
I should note that I know the request from the client is formatted correctly because I've just re-pointed the existing frontend from our PHP backend to the new F# backend.
Editor.fs
Program.fs
What happens to
tireDataEditor
in Editor.fs? Does it get exported, or something else? Or can Program.fs access it from line 11 in there? That's not something I'm familiar with I'm afraid, but from experience with other languages and frameworks I'd expect Editor.fs to need to return or export something.Allan
Ah yes, this is common with ML-family languages like F#, OCaml, Haskell, SML, the language is expression based so the function gets assigned to the value of the last expression. There is no "return" keyword... except in special use-cases like in Asynchronous/Task programming. F# is also white-space sensitive so that's why there's also a lot of indentation. If you're familiar with python it should look pretty similar. Essentially, replace let with def.
Program.fs has Editor.fs in-scope and, like you said, is calling tireDataEditor on line 11.
I've discovered an error message. I thought I was printing off the entire object, but I guess it wasn't.
"The specified invariant name 'MySql.Data.MySqlClient' wasn't found in the list of registered .NET Data Providers."
What's strange is that I am not using MySql.Data.MySqlClient. I'm using MySqlConnector and I never registered that.
I'm guessing the library is hard-coded to use MySql.Data.MySqlClient I registered that, but since I was using MySqlConnector, there was a casting issue.
I'm pretty sure the consensus is the MySqlConnector will be the de facto mysql driver for .net going forward. You might want to update the library to allow for MySqlConnector instead. It'd be great if instead of that, you could just provide any arbitrary driver that implement the DbFactory pattern.
If you use the "mysql" option to create a
Database()
instance, then yes, that is the connector that it attempts to use.You could use this constructor to specify a different connector.
Ah - so are variables in other files not local? They are automatically exported and available for reference in other files?
Allan
No, I guess I misunderstood your question. Variables are local and behind namespaces, modules, and types. F# has
open
statements that are equivalent to C#'suse
statements. Since F# has full OOP support, you can declare an object with private fields/methods if you wanted to, basically the same way you would in C#. I think you can also do it with module functions as well, though I've never had the use-case for it. Since everything is immutable by default, having things be private really isn't a big concern since state is hard to change anyway.As an example, if the Editor class was written in F#, a more idiomatic way to do would be:
State is explicitly passed around and very rarely modified in-place so accessibility modifies become significantly less relevant. That's not to say they are never used, because they do have their place, they just don't really apply in the functional coding style.
I got it connected with the hard-coded MySql client. However I am still not getting any data. Currently just exploring the values from the returned object.
I can confirm that the DtResponse object does indeed hold the correct data from the DB. It's just something between calling it and consuming the object to be formatted into Json that there is an issue.
Many thanks for the run down there. I really must get around to trying it out sometime! I love functional programming in Javascript.
I'm afraid I don't have any suggestions for that final step there - if it is getting the JSON object but the controller isn't sending it back to the client-side, something in the controller? Be very interesting to know if you get a solution.
Allan
It honestly blew my mind at first what you can do with it.
F# is a nice middle-ground between the pedanticness of Haskell and the unsafety of C#. I don't think it's a fair comparison to see functional programming in an imperative/oo language like JavaScript to a language where it's first-class.
Like with C#/Java's idea that everything is an object, in F# everything is a function. Everything takes a function and returns a function. This allows for functions to be deconstructed and reconstructed on-the-fly and gives us something called currying.
It's hard to really show how just that is super powerful with out a lot of context, but this basically sets you up for a single-function for all dependency injection needs. Couple that with function composition or pipe operators and there's so much code clutter that gets eliminated. No more intermediate variables necessary!
I'm no expert with JS, but my experience with it, trying to do anything like the above is a significant pain and would require a lot more code.
Still haven't found a solution yet unfortunately, though I'm still digging.
Awesome - thank you. It is possible to curry in Javascript, but you are right, in F# functional programming is what the language is all about, so anything else is going to look poor compared to it .
Allan
Ok so I think I've been able to get a work-around. There is something strange going on with the built-in serializer. I am not sure why, but just passing the object directly from the .Data() method on the editor to Falco's serializer, which is defined as
just does not work. So what I did to get it to work is map the DtResponse object in an anonymous record with the exact same fields as the DtResponse object.
Now everything seems to be working! I have opened an issue on the Falco project to see if anyone else has experienced issues with serializing objects but for right now. I think the working solution was my 2nd post, we've just been chasing some weird bug.
Hopefully anyone needing examples can use this as a reference in the future.
That's superb - many thanks for sharing this with us
Allan