6 ms·
I disagree with this, you can sell F# to C# developers - things like type providers for SQL checking their query strings in compile time and no extra build step
by rubber_duck 9y ago
I disagree with this, you can sell F# to C# developers - things like type providers for SQL checking their query strings in compile time and no extra build step to produce SQL type definitions vs monstrosities such as Entity Framework... if they've been burned by ORMs to drop to stuff like Dapper they'll love F# type providers.
Immutable data is also becoming a common pattern even in C# but it's tedious as hell to write.
Functional programming is also seeping in but again tons of boiler plate.
Biggest problem with F# is that it has it's own warts + it's a big upfront switching cost and a steep learning curve but it offers many marginal improvements - when you sum those improvements it ends up being worth it IMO but that's a very hard sell.
- brianberns 9y agoC# developers in my shop loathe the SQL type provider because it requires them to have a compatible SQL Server database schema at build-time. The extra level of organization required is more than they can accept.
- rjbwork 9y agoDoes the F# SQL type provider integrate with the .sqlproj database projects that are in the solution, or do you have to have an actual running SQL database?
- brianberns 9y agoIt needs a connection string to a real database. http://fsprojects.github.io/FSharp.Data.SqlClient/ http://fsprojects.github.io/FSharp.Data.SqlClient/
- mbenoni7 9y agoThere's a new type provider out that takes a different approach by bundling a SQL parser: https://github.com/rspeele/Rezoom.SQL https://github.com/rspeele/Rezoom.SQL It can't check everything that the other providers can, but IMO you get most of the benefit without requiring any onerous build-time dependencies.
- brianberns 9y agoVery cool. Thank you.
- ice109 9y agothat kind of thing is a collosal mistake in my opinion - just on the face of it I/o at compile time seems very wrong.
- brianberns 9y agoWhy? Compilers have to read source files anyway. What's wrong with reading other stuff as well? For example, there are type providers for XAML, JSON, app.config, etc. Do they also seem wrong to you?
- bonesss 9y agoAn understandable position. Here's the context that makes it not a big deal: 1) If there is some fundamental issue with having a dev DB then you would just use another ORM, just like in C#. Really, this specific type provider is not an ORM, it's for SQL server data munging. Most every project I've seen in a decade has multiple dev DBs, many used in testing, many used for staging... being able to talk to a valid schema source should be relatively straightforward... but if it isnt then get a different type provider or use an ORM with explicit code generation. 2) Compile time guarantees about data sources is a huge source of comfort when dealing with DBs owned by external actors or teams. For data scientist, integrator, sys admins, and such the norm is connecting to operational DBs that you have very little control over. This specific Type Provider ensures that your scripts will not compile if there has been a breaking schema change. That means you're seeing these issues during deployment, not as costly runtime errors that may or may not corrupt your application state. Less debugging, more safety, better guarantees, immediate feedback on issues; all in realtime. To summarize: if compile time validation of JSON structures, XML structures, SQL Schema, or custom file formats creates some kind of pain, then don't use a provider of types that relies on analyzing data structures to create code :) For the other 99.9999% of the time type providers are a DREAM for working with external data sources, provide most of what we want ORMs for, and are very lightweight in comparison. It's rapid data exploration with built in prototyping. Very nice.
- tarmil 9y agoActually, for the providers from FSharp.Data.TypeProviders, it's only necessary when you need to pull a schema change. You can pass `LocalSchemaFile = "foo.ssdl", ForceUpdate = false` to the provider, and it will only try to connect to the database if the file foo.ssdl doesn't exist; if it does, then the provider just uses it to compute the schema. When the schema changes, you just need to set ForceUpdate to true, wait for the IDE to pull the changes from the server and write foo.ssdl, then set ForceUpdate back to false, and you can commit the changed file.
- com2kid 9y ago> Functional programming is also seeping in but again tons of boiler plate. The bar has moved so much on this one. I remember when C#'s wonderful lambda syntax, along with all the extension methods that LINQ added, qualified it as having pretty good functional programming support. Now that other languages have gone out and copied sane lambdas, and "Map" is in libraries left and right, C# has to keep reaching for that higher and higher bar.
- louthy 9y agoWhat does the higher bar look like to you? For me, the major missing features of C# are: * Immutable record types * ADTs with completeness pattern matching * Higher-kinds F# is also missing higher kinds, but can do the others. Did you have something else in mind?
- pjmlp 9y agoNone of them makes me write prettier GUIs or better use of EF.
- naasking 9y agoActually, higher kinds could make you write more composable and reusable GUIs. I don't see why "prettier" is the only metric of interest. Immutable records also makes it easier to share data safely, thus making scaling across cores easier in some cases, without worrying about plan interference.
- pjmlp 9y agoHow do you suggest to make use of higher kinds in Blend? Immutable records are already possible today in C#, even if a bit more verbose than on F#, plus EF code is anyway mostly generated.
- dep_b 9y agoI used type classes on JSON and it's like magic.
- Boothroid 9y agoI'm interested to know why you describe EF as a monstrosity? Genuine interest, I just started using EF for the first time a few weeks ago for a work project so I've only scratched the surface but it didn't seem terrible, although I did find that only being able to update all tables after a change to the database as opposed to a single table to be a bit of a limitation.
- cm2187 9y agoIf you use code first it's very easy to get in a corrupted state where it doesn't know how to update the database. Otherwise it speeds up the basic tasks then it gets in your way to write more sophisticated queries. I found that a good solution is to write a generic sql serialiser that does all the basic operations (insert, update, select, delete, read one or multiple from readers) and do the rest by hand. It avoids most of the tedious code/sql while not getting in your way to do things like transactions, bulk inserts, etc
- Boothroid 9y agoInteresting, thank you.
- maxxxxx 9y agoIn all the EF projects I have been on it caused weird issues after a while. Code first projects don't upgrade anymore or the order of saving is wrong or performance is bad. In pretty much all of them we ended up writing a simple wrapper around the database that was much easier to control.
- Boothroid 9y agoUseful info.
- jackmott 9y agoEF is great when things are small and simple. It is when things get big and complex that it can be a hindrance both to understanding what is happening (when does my code actually hit the database?) and how it happens (what query is being generated here?) Usually the result is performance problems.
- TensorMetric 9y agoThe real problem with F# is that it isn't supported everywhere C# is https://news.ycombinator.com/item?id=15026396 https://news.ycombinator.com/item?id=15026396
- louthy 9y ago> Immutable data is also becoming a common pattern even in C# but it's tedious as hell to write. I can simplify it for you: public class TestClass : Record<TestClass> { public readonly int X; public readonly string Y; public readonly Guid Z; public TestClass(int x, string y, Guid z) { X = x; Y = y; Z = z; } } That is an immutable type that has structural equality and ordering, a strong GetHashCode() implementation, as well as a default ToString() which previews the members, and serialization and deserialization constructs. It's a feature I recently added to language-ext [1]. If you need `With` functionality, then add the following member: public TestClass With(int? X = null, string Y = null, Guid? Z = null) => new TestClass(X ?? this.X, Y ?? this.Y, Z ?? this.Z); Then you can use named parameters to do partial updates: value = value.With(X: 456, Y: "World"); Obviously it's still more boilerplate than F#, but C# is never going to have significantly less until we get proper record types and ADTs. > Functional programming is also seeping in but again tons of boiler plate. Do you have an example? It's something I've worked on quite heavily over the past few years, so I'm always looking for areas to try and improve the lot of C# devs trying to write functionally. [1] https://github.com/louthy/language-ext/releases/tag/v2.1.0 https://github.com/louthy/language-ext/releases/tag/v2.1.0
- jdmichal 9y agoIn C# 6.0 you can also make them properties instead of fields, though I have no idea if this works with your "Record" class. public class TestClass { public int X { get; } public string Y { get; } public Guid Z { get; } public TestClass(int x, string y, Guid z) { X = x; Y = y; Z = z; } } And C# 7.0 shortens this to: public class TestClass( int X, string Y, Guid Z);
- louthy 9y ago> In C# 6.0 you can also make them properties instead of fields Why would I want to? It's more boilerplate for no gain. I have never understood the obsession with properties over fields. I realise that to some serialisation or interop libraries that rely on reflection to access properties it's important, but to my mind, those solutions should also support public fields. And obviously inheritance-land with interfaces, but I find writing in a functional style that interfaces tend to be a rarity rather than the default setting. > though I have no idea if this works with your "Record" class. Yes, field backed properties are supported in the structural equality and ordering. > And C# 7.0 shortens this to... It doesn't. That maybe coming in a later release, but neither C# 7.0 nor 7.1 support the record syntax.
- MrBuddyCasino 9y agoYou don't increase adoption by making the learning curve steeper. Rust does its best given the circumstances, but people's top complaint is that its hard to learn. Scala never went Mainstream because you can't hire developers, and training them takes many months. F# should not repeat that mistake.
- TensorMetric 9y agoAdoption of F# would not be a problem if it had .NET Native support and proper tooling https://news.ycombinator.com/item?id=15026396 https://news.ycombinator.com/item?id=15026396