3 ms·
> I've done plenty of freelance projects in F# over the past few years and enjoy it Could you give some examples of what did you do in F#? Did you choose F# ju
by narimiran 9y ago
> I've done plenty of freelance projects in F# over the past few years and enjoy it
Could you give some examples of what did you do in F#? Did you choose F# just because you wanted to see if you can do it in it, or did F# have some advantages over other (functional) languages?
> It takes a while to figure out your style however. (...) Some people end up with "C# in F#" (...) And until you figure that out, it's hard to be as productive as in a language you already know.
My plan is to avoid as much as possible "writing Python in F#", because I choose F# as an opportunity to learn something new/different (which might transfer to writing better Python later). Any tips for this?
- pkese 9y agoSo far I've used F# form smaller projects, basically anywhere there's any un-trivial problem. Just the fact that the editor helps you write correct and concise code means that once you correct the mistakes that the editor (Ionide) higlights for you, things will just compile and work out of the box. Compared to Python, I'd assume that 1) I write a bit less code to solve the same problem in F# as I would in Python, 2) it takes a bit more time, but it is more fun, 3) once it compiles, there are seldom any bugs. So technically you trade some of programming speed for less time spent in debugging and writing test code. In the end, you are way faster and more productive. Especially once the code base starts getting bigger, the type system starts bringing in extra benefits. Major point is that detecting and correcting bugs in editor is faster than in compilation, and in compilation is better than at testing. So compared to Python, you get 2 orders of magnitude of better and faster development.
- daxfohl 9y agoMy main project over the last few years has been a photobooth, so I've done server-side in suave (I LOVE suave compared to any other .net framework), client-side in WPF (F# experience in WPF is meh), and a bundle of other mini projects. I did it in F# because it was interesting, not because it was more productive at the time. My personal landing point is about #6 in the turtles article. I still like classes and interfaces and think they fit perfectly well. However, inheritance is something I avoid completely now. The effect can be done much more flexibly and transparently by several other means. But one great thing about classes is that you get nice autocomplete when you type `myservice.`. And note I only use OO for "services"; data is data is data. So if you're doing DB stuff, prefer an anemic data model and a platform that supports it (so Dapper rather than EF or NHibernate). Basically do `db.Save(myData)` rather than `myData.Save()`. Another big change I've noticed is I don't use "private" functions much anymore. In OO I spent a lot more energy making sure that people using my classes couldn't use them wrongly. They could only do exactly what the requirements allowed. I think OO mindset (at least in C#/Java, maybe Python is different) makes you paranoid and guides you to putting "app code" into what should be "libraries". This sometimes made e.g. unit testing more of a pain; you can't test your "validate" functions directly because they're private. Now I tend to open most everything up and let developers do what they want with my code, but I add a few helper functions to cover the common cases to guide them in the right direction. In general I consider everything a library now; the only "app-specific" code I write goes in `main` function that glues everything together. Of course I still don't open functions that expose contained services, or that leave things in an inconsistent state, but that's about all. And of course embrace immutability and recursion (or the library functions that do it for you). Probably the most annoying thing for you, especially coming from Python, will be "similar records". So you'd need a `User` that just has raw data, `UserDb` that maybe has that plus an ID/DateAdded/DateModified, a `UserOut` that maybe has that minus PasswordHash, a `UserIn` that maybe has RawPassword/RawPasswordAgain, etc, and conversions between them all. Not to mention if you want different schemes for jsonNaming, db_naming, RecordNaming, etc. I've yet to come up with a happy typesafe way of doing this.
- vram22 9y ago> So you'd need a `User` that just has raw data, `UserDb` that maybe has that plus an ID/DateAdded/DateModified, a `UserOut` that maybe has that minus PasswordHash, a `UserIn` that maybe has RawPassword/RawPasswordAgain, etc, and conversions between them all. Why is this needed in F#? Something to do with immutability?
- daxfohl 9y agoThis assumes you want to use records for your data: records don't have inheritance. So whereas in C# you could create a UserDb that extends User with the Id/DateAdded fields, in F# that's not idiomatic. I am sure there could be a good way to automate this using type providers, but I haven't tried it yet.
- daxfohl 9y agoI created a gist of the pattern I've found to be most successful when doing an app in F#. https://gist.github.com/daxfohl/0183db108924ee87440928cb803dcfc3 https://gist.github.com/daxfohl/0183db108924ee87440928cb803d...