The three that I have recent professional experience with are CLR (aka .NET), JVM (aka Java/Kotlin/Groovy), and Python. I farted around in modern JS/ECMAScript, but backed out after giving it what...
The three that I have recent professional experience with are CLR (aka .NET), JVM (aka Java/Kotlin/Groovy), and Python. I farted around in modern JS/ECMAScript, but backed out after giving it what feel is a fair shake.
CLR has a fair number of packages, but trends towards commercial implementation of things that feel to me like there ought to be open libs for. Docs are middle of the road. Platform support is improving, but I still occasionally ran into stuff that felt like it ought to be core being bound to having a Windows host OS. I use it when necessary.
JVM has a truly vast ecosystem. Documentation tends to be on the good side. Some of the frameworks feel overwrought to me. Even though the language is chunky, it remains my favourite for heavy-lifting code that needs to serve production users at scale.
Python (since 3.1) is a delight for hacking out prototypes. Documentation ranges from comprehensive to terrible. The package ecosystem is comprehensive and convenient. My experience has been that package maintainers think very little of making big breaking changes in their interfaces.
Modern JS is getting there, but it carries a lot of warts from early versions of the language. The "===" operator made me giggle. If we get a "====" hyperequality operator in a future version, I'll laugh. The NPM ecosystem makes me weep openly, especially when doing upgrades. The severity and frequency of CVE's being published in NPM's ecosystem was what made me back out. Waking up to CVE-2023-12345 [Calling this package on even-numbered days causes incurable cancer] and the like was more than my old bones could carry.
These are all my personal experiences, with all the baggage they carry. I'm certain others will have differing opinions; that's half the fun of working in this industry.
This could be useful for comparing the contents of two identical objects with different memory references, so not matching ===, but obviously containing the exact same data. :v
"===="
This could be useful for comparing the contents of two identical objects with different memory references, so not matching ===, but obviously containing the exact same data. :v
Yes, but how do you distinguish if the inner objects are identical or simply equal? And what do you do about circular references? ============ has entered the chat.
Yes, but how do you distinguish if the inner objects are identical or simply equal? And what do you do about circular references?
I worked for ~2 years on a cloud service with a private react dashboard for monitoring the service. Every CVE I had was an obscure DDoS in an obscure library, which was a dependency of a...
I worked for ~2 years on a cloud service with a private react dashboard for monitoring the service. Every CVE I had was an obscure DDoS in an obscure library, which was a dependency of a dependency of a dependency of a dependency of a package I was using. I either had to wait for the patch to be applied down the whole chain or fix it myself tinkering with the package.json. I hated this, given that it is highly unlikely the issue was exploitable through the main package.
I have some experience with a few already mentioned here but I guess I will put in my two cents about Rust because I have explored it quite a bit recently. Rusts ecosystem is a breath of fresh...
I have some experience with a few already mentioned here but I guess I will put in my two cents about Rust because I have explored it quite a bit recently. Rusts ecosystem is a breath of fresh air. 90% of the time, it "just works". I mainly think this mainly has to do with the fact that Rust is a relatively new language which set out to be a "real" language from the get-go. This unlike many languages, where package managers and other tools were tacked on after the fact.
This fact means that for every tool, there is only one choice and it just works. Packages? Use Cargo. Docs? Every single package is documented on docs.rs by code comments. Linter? Use Clippy. I could go on, but I think the point is quite clear. Another advantage of Rusts ecosystem is the standardisation of certain features in a pluggable way. An example is async operations. Async is not in the standard library as such, but the interfaces are. This means that you can swap out your async backend as you like while keeping compatibility. Another point where the Rust ecosystem really shines is serialisation and deserialisation. The Serde crate is the de-facto standard and most crates have optional support for it.
A place where the ecosystem is still lacking is documentation for common use cases larger than one struct or function . Most crates have documentation on how to use one function or struct, but not on how they combine them. Another pain point is stability: some features that are sorely needed for more niche usecases are unstable and so, some crates need you or prefer you to use unstable Rust, but this is improving with time.
The fact that Rust packages are so easy to get high-quality documentation for by just writing code comments, and you can very easily include code examples in the comments which are actually...
The fact that Rust packages are so easy to get high-quality documentation for by just writing code comments, and you can very easily include code examples in the comments which are actually compiled and run as unit tests, is amazing to me. Such a simple concept that works really well and is a huge boon to the package ecosystem.
Never worked on rust but Python peeps have been doing that since ages with the help of Sphinx documentation package and Java peeps with Javadoc. Is this much different from any of those?
Never worked on rust but Python peeps have been doing that since ages with the help of Sphinx documentation package and Java peeps with Javadoc. Is this much different from any of those?
It's baked in the toolchain, I guess. Once you install Rust, you have it ready to use, and the official documentation mentions it early on, so you're inclined to use it.
It's baked in the toolchain, I guess. Once you install Rust, you have it ready to use, and the official documentation mentions it early on, so you're inclined to use it.
Same with Python so far, so maybe not that different. It's also part of the toolchain and I remember the first Python tutorial i read talking about using docstrings for documentation. Maybe...
Same with Python so far, so maybe not that different. It's also part of the toolchain and I remember the first Python tutorial i read talking about using docstrings for documentation.
Maybe there's a difference in implementation, but on the surface it sounds like the same thing.
I totally get what you mean. I had been playing around with Swift and one of the things I enjoyed about it was how prescribed everything was; it felt that all of my questions had “official”...
I totally get what you mean. I had been playing around with Swift and one of the things I enjoyed about it was how prescribed everything was; it felt that all of my questions had “official” answers instead of a bunch of different hacks to get things working. I only briefly looked into Rust but there is so much care into how things are designed that it feels pretty similar.
I love using Angular for JavaScript. The official documentation is great. My biggest problem is so many old StackOverflow answers use jQuery instead of newer features from ES6. There is almost...
I love using Angular for JavaScript. The official documentation is great. My biggest problem is so many old StackOverflow answers use jQuery instead of newer features from ES6. There is almost never a good reason to use var either.
The entire machine learning and data processing suites that have built up around Python are fantastic too. I personally like TensorFlow with the newer APIs. Pandas is very easy use (similar to R), and the graphing libraries are excellent for scientific papers. Seaborn makes some really pretty visualizations. All around excellent tooling. That said, the package management is still a pain even with an environment tool like Conda (relevant XKCD).
I recently stumbled on poetry for python. It's helped a ton with distributing scripts to other devs that use pip packages. They just need to have the version of python installed that you are using...
I recently stumbled on poetry for python. It's helped a ton with distributing scripts to other devs that use pip packages. They just need to have the version of python installed that you are using and it'll maintain a vm with all the dependencies and versions you have. Nothing magic but makes it much smoother imho.
For non programmer distribution I use pyinstaller on top of that to hand out a single click to run style for them.
All in all this set up is way better than what I had been able to find for perl scripts over the years so feels like a dream to me. It still needs some explanation to get the python version and poetry installed, but once done once, all scripts can use it from thst point forward and it is very easy to toss over a python script to others without fearing a long set up session.
I’m typically in the Ruby ecosystem, and generally packages are well maintained, well documented and members of the community are helpful. The big question for me is how often do I have to look at...
I’m typically in the Ruby ecosystem, and generally packages are well maintained, well documented and members of the community are helpful. The big question for me is how often do I have to look at the source code of a given library, and that’s pretty rare here. Also I don’t remember the stats but I’ve read the devs are better paid on average because it’s “niche” (despite being a popular general-purpose language).
I came to the same conclusion when I switched from Java to PHP. With Java I never needed to look at the source of libraries. With PHP it was pretty often. Good libraries have proper documentation...
I came to the same conclusion when I switched from Java to PHP. With Java I never needed to look at the source of libraries. With PHP it was pretty often. Good libraries have proper documentation and examples, something that lacked with the stuff we were using. The implementation in the framework was also pretty inconsistent, which made it hard to guess what the right way to use it was.
Sounds good but Microsoft seems to have taken a very weird direction in the last decade, especially with regard to Azure and Cloud. Why are they ignoring their core product - Windows Desktop OS...
Sounds good but Microsoft seems to have taken a very weird direction in the last decade, especially with regard to Azure and Cloud. Why are they ignoring their core product - Windows Desktop OS and related framework libraries like WinForms, WPF, etc.? The Windows Phone (Nokia) paradigm had great potential, I think MS could have salvaged it if they wanted to?
While I adore f# the ecosystem has some issues. Everything you want to do can be done but since a lot of the community assumes you’re coming from some other language it’s seldom written with great...
While I adore f# the ecosystem has some issues. Everything you want to do can be done but since a lot of the community assumes you’re coming from some other language it’s seldom written with great examples.
It’s a lot better than when I started but it’s frustrating when the documentation is out of date or you get a guide that’s 30% “thing goes here” comments.
The upsides of the language make this hurt a lot less than any other I’ve used, but I hate that it’ll probably never fully take off and achieve what it could be
Fully agree with your thoughts on F#. I love this language and all the cute little features it has, but it's really let down by the package ecosystem and poor tooling. I love how it's a functional...
Fully agree with your thoughts on F#. I love this language and all the cute little features it has, but it's really let down by the package ecosystem and poor tooling.
I love how it's a functional language that has a focus on "getting stuff done". Languages like Haskell are cool and all, but I can't help but feel like they're too academic for my tastes. F# fits really nicely into a sweet spot that I've not seen much in other languages. The designers did an excellent job of making it functional, powerful, and yet practical.
Even though it's functional-first, the OOP support is surprisingly good in F#. OOP so much more terse compared to C# and honestly there's an argument that F# does OOP better than C#, at least for the features it supports. It's a great experience to be able to use whatever paradigm fits the problem the best. Easily dropping down to imperative code to improve performance is also great. Somewhat ironically, the way F# pushes you towards functional code makes it really easy to swap out FP code with imperative code to improve performance.
I know other languages are starting to catch up, but F# also has a pretty good REPL experience. Getting immediate feedback while programming makes it so nice to experiment with code and understand how you wanna approach the problem. It's great that Rider has something similar for C# in the form of C# Interactive.
I wish units of measure would make their way into more languages, because it's so damn useful for domain modelling. Active patterns are great too - having logic to transform data into a sum type is amazingly useful for pattern matching. Also, type providers feel like a magical experience when you first try them out; it's a real eye-opener when you get autocomplete for your CSV or JSON.
There's a lot to really like about the language design for F#. Even though I'm a massive simp for ML-style language design and I might be a little biased, I genuinely do believe a lot of the features fit together so well. You can tell there's a lot of thought that has gone into making this language.
But at the same time, every time I use it for a larger project, I remember why it's such a pain to work with. The community is really small so you get way fewer high-quality packages, tooling, resources, documentation, and general support. You can count the number of high-quality packages for F# on one hand, and the tooling isn't great either.
I've had really shaky experiences with documentation for F# libraries. Saturn is a pretty popular web framework for F# but the documentation feels really limited for the tutorials. There are just 3 pages of tutorials and no full example project.
Rider is always improving with F# support but there's a night-and-day difference between Rider's refactoring tools in C# and F#. C# refactoring tools and IDE suggestions are so intelligent and have a very good understanding of code, meanwhile F# suggestions are so shallow and naive. I've not tried VSCode with F# so I don't know what the experience is like Ionide, but I can't imagine it's much better.
Fantomas, the F# community's preferred formatter, has so many issues and I've run into bugs a few times where reformatting a file changes the code's semantics or removes comments. For any formatter (and the community-preferred one especially), that's completely unacceptable behaviour. There's also a lack of certain features like being able to disable formatting for a section of code. Even just being able to tune what formatting gets applied is mostly missing, which is so frustrating because I hate the way it forces some formatting (e.g. sum types always get formatted to be on one line if the character limit isn't reached).
The interop with C# is great since you can use high-quality libraries and frameworks, but that should be a fallback option for when you can't F#-specific packages, and yet sometimes it feels like it's the default option. A lot of the time, you're expected to rely on C# packages and use the interop, which introduces some annoyances you wouldn't normally have with just F# (e.g. you have to deal with null now, yayyyy!).
In terms of language design, after getting a taste of Rust traits and Haskell typeclasses, I really wish F# had something similar. The language designers have said that's not happening and I understand their concerns, so oh well.
It's such a shame because this language deserves better and it can't really get there without community support, but Microsoft treats it like a second-class citizen and does a poor job of promoting it so it's unlikely things get much better for F#. I might give OCaml a try in the future for larger projects and see if it fares any better, but it would be hard to cheat on F# eheheh.
I can only really speak for Go and Python and have an untraditional programming background. I learned Python a little, then Go a lot, then learned more Python for work. I worked on Go...
I can only really speak for Go and Python and have an untraditional programming background. I learned Python a little, then Go a lot, then learned more Python for work. I worked on Go microservices and Python monolith, so not set up to love Python. I can't speak on 4. Overall:
Docs: Go's docs are great. They're standardized (godoc) and the language is typed, so it's easy to read and follow.
The general mindset of the maintainers about what is a net positive: They take the position that "we shouldn't do it this exact way just because that's available in Java / Python / etc." I like how much thought they put into things, even though stuff like the generics "will-they-won't-they" had frustrated people. The work they've done on consistent compilation across machines is also super impressive.
"KISS": I like the Go philosophy that code should be inherently clear, that writing your own loops (however tedious) is clearer to read than say, using a Python map function. It helps you step back and say, "If I need this and it's not there, is my code too complex?"
Problem Solving online: I don't quite recall... iirc, googling problems for Go would often bring up other languages as they were more popular. so for 3, I would say it's so-so. At the very least, problems tend to be clearer because I find exception handling is much clearer when errors as passed as objects (imo).
Management / Maintainability: I like that I never had to waste time debating styling and dependency management with tools like golint, govet, and Go Modules.
Go's only drawback to me is that you can't use it for everything. Because it's newer, support for things are also dicier. Don't use Go unless you're prepared to also say "We use the right language for the job;" you don't want to end up using "the Go version of <popular Python library> for <semi-niche dependency>" which is 1 cowboy's weekend project that hadn't been updated in 17 months. But if you can choose most of the stack, use Go (or something as good as it).
Python isn't inherently bad, but I think if you don't have the time to be attentive, you will produce bad code really fast. Again, I am biased because so much of my experience is with a monolith.
Docs: I don't like the various documentation formats / lack of explicit links to code snippets.
Management / Maintainability: I work on a Python monolith and dependency management has been a nightmare (we can't even migrate to Poetry; the project that did stopped working for people after a specific Poetry update). We also use like, 3 different linters and I don't know that our code is any better.
I don't think it's impressive that Python has 10 libraries for what are solved problems in other languages. We use a special library just for request validation due to lack of typing, and that itself uses Rust under the hood, which makes me think... can we just use Rust?
Problem Solving online: There is more help online for Python problems, but I found that I have more problems with Python than with Go, again due to lack of typing, flexible signatures, and complex feature adds.
However, probably most things you need have a library. I think if you have the time and discipline to write good Python and your task is of unknown complexity, Python isn't bad.
Mutable defaults are a nightmare to debug... I love Python, but the language is sometimes too simple and flexible for its own good. I'll defend the use of map though; sometimes it's more...
Mutable defaults are a nightmare to debug... I love Python, but the language is sometimes too simple and flexible for its own good.
I'll defend the use of map though; sometimes it's more straightforward to write in a declarative style rather than an imperative style. The intent of using map with an anonymous function is (usually) explicitly clear while a loop can do any number of things in each iteration. Functional languages use maps more than loops usually. Here's some more reading on the design philosophy in case you're curious: https://cswithbaddrawings.wordpress.com/2020/03/13/gain-confidence-with-declarative-programming/
The Laravel ecosystem is amazing. So many tools exist to make a lot of normally complicated tasks very simple. I cannot even begin to describe the amount of pre-built tools that exist. It's a...
The Laravel ecosystem is amazing. So many tools exist to make a lot of normally complicated tasks very simple. I cannot even begin to describe the amount of pre-built tools that exist. It's a massive ecosystem with great documentation and a lot of helpful people always ready to answer questions.
I'm self taught in AutoHotKey.... I'm the ultimate of lazy so my "coding" skills are: how do I hack together my user inputs to do my job. after 8 years of creating hotkeys, I have a script file I...
I'm self taught in AutoHotKey.... I'm the ultimate of lazy so my "coding" skills are: how do I hack together my user inputs to do my job. after 8 years of creating hotkeys, I have a script file I can't live without.
several hotkeys to open custom UIs, conditional scripts if a certain program is open before using alt keys to navigate the menus of an application. Much of my repetitive tasks are now simplified. If I type lmkqc into an email, it changes to "let me know if you have any questions or concerns." (a typical comment to end my emails).
I need to type a Work Order number into several different programs. this number is typed ~8 times in the period of 20 mins and then switches to a new semi random number. I have a hotkey to save a number. then a key to type it, a key to open a file folder with its name, a key to open that work order in a said application. all of these are used constantly so I don't have to devote my human RAM to remembering or writing down a number.
I can also rewrite windows hotkeys to be better. Win+E normally opens a new file folder. Win+E for me scrolls through open file explorer windows. if there isn't a file explorer window open, it will open up the most common folder I use in a new file explorer window. I then made shift+win+e to always create a new file explorer window.
I could nerd about this all day long...
I really want to learn more languages but AHK will always be my heart I'm afraid. my lazy brain is just wired for it.
The three that I have recent professional experience with are CLR (aka .NET), JVM (aka Java/Kotlin/Groovy), and Python. I farted around in modern JS/ECMAScript, but backed out after giving it what feel is a fair shake.
CLR has a fair number of packages, but trends towards commercial implementation of things that feel to me like there ought to be open libs for. Docs are middle of the road. Platform support is improving, but I still occasionally ran into stuff that felt like it ought to be core being bound to having a Windows host OS. I use it when necessary.
JVM has a truly vast ecosystem. Documentation tends to be on the good side. Some of the frameworks feel overwrought to me. Even though the language is chunky, it remains my favourite for heavy-lifting code that needs to serve production users at scale.
Python (since 3.1) is a delight for hacking out prototypes. Documentation ranges from comprehensive to terrible. The package ecosystem is comprehensive and convenient. My experience has been that package maintainers think very little of making big breaking changes in their interfaces.
Modern JS is getting there, but it carries a lot of warts from early versions of the language. The "===" operator made me giggle. If we get a "====" hyperequality operator in a future version, I'll laugh. The NPM ecosystem makes me weep openly, especially when doing upgrades. The severity and frequency of CVE's being published in NPM's ecosystem was what made me back out. Waking up to
CVE-2023-12345 [Calling this package on even-numbered days causes incurable cancer]
and the like was more than my old bones could carry.These are all my personal experiences, with all the baggage they carry. I'm certain others will have differing opinions; that's half the fun of working in this industry.
This could be useful for comparing the contents of two identical objects with different memory references, so not matching
===
, but obviously containing the exact same data. :vYes, but how do you distinguish if the inner objects are identical or simply equal? And what do you do about circular references?
============
has entered the chat.I worked for ~2 years on a cloud service with a private react dashboard for monitoring the service. Every CVE I had was an obscure DDoS in an obscure library, which was a dependency of a dependency of a dependency of a dependency of a package I was using. I either had to wait for the patch to be applied down the whole chain or fix it myself tinkering with the package.json. I hated this, given that it is highly unlikely the issue was exploitable through the main package.
I have some experience with a few already mentioned here but I guess I will put in my two cents about Rust because I have explored it quite a bit recently. Rusts ecosystem is a breath of fresh air. 90% of the time, it "just works". I mainly think this mainly has to do with the fact that Rust is a relatively new language which set out to be a "real" language from the get-go. This unlike many languages, where package managers and other tools were tacked on after the fact.
This fact means that for every tool, there is only one choice and it just works. Packages? Use Cargo. Docs? Every single package is documented on docs.rs by code comments. Linter? Use Clippy. I could go on, but I think the point is quite clear. Another advantage of Rusts ecosystem is the standardisation of certain features in a pluggable way. An example is async operations. Async is not in the standard library as such, but the interfaces are. This means that you can swap out your async backend as you like while keeping compatibility. Another point where the Rust ecosystem really shines is serialisation and deserialisation. The Serde crate is the de-facto standard and most crates have optional support for it.
A place where the ecosystem is still lacking is documentation for common use cases larger than one struct or function . Most crates have documentation on how to use one function or struct, but not on how they combine them. Another pain point is stability: some features that are sorely needed for more niche usecases are unstable and so, some crates need you or prefer you to use unstable Rust, but this is improving with time.
The fact that Rust packages are so easy to get high-quality documentation for by just writing code comments, and you can very easily include code examples in the comments which are actually compiled and run as unit tests, is amazing to me. Such a simple concept that works really well and is a huge boon to the package ecosystem.
Never worked on rust but Python peeps have been doing that since ages with the help of
Sphinx
documentation package and Java peeps with Javadoc. Is this much different from any of those?It's baked in the toolchain, I guess. Once you install Rust, you have it ready to use, and the official documentation mentions it early on, so you're inclined to use it.
Same with Python so far, so maybe not that different. It's also part of the toolchain and I remember the first Python tutorial i read talking about using docstrings for documentation.
Maybe there's a difference in implementation, but on the surface it sounds like the same thing.
I totally get what you mean. I had been playing around with Swift and one of the things I enjoyed about it was how prescribed everything was; it felt that all of my questions had “official” answers instead of a bunch of different hacks to get things working. I only briefly looked into Rust but there is so much care into how things are designed that it feels pretty similar.
I love using Angular for JavaScript. The official documentation is great. My biggest problem is so many old StackOverflow answers use jQuery instead of newer features from ES6. There is almost never a good reason to use
var
either.The entire machine learning and data processing suites that have built up around Python are fantastic too. I personally like TensorFlow with the newer APIs. Pandas is very easy use (similar to R), and the graphing libraries are excellent for scientific papers. Seaborn makes some really pretty visualizations. All around excellent tooling. That said, the package management is still a pain even with an environment tool like Conda (relevant XKCD).
I recently stumbled on poetry for python. It's helped a ton with distributing scripts to other devs that use pip packages. They just need to have the version of python installed that you are using and it'll maintain a vm with all the dependencies and versions you have. Nothing magic but makes it much smoother imho.
For non programmer distribution I use pyinstaller on top of that to hand out a single click to run style for them.
All in all this set up is way better than what I had been able to find for perl scripts over the years so feels like a dream to me. It still needs some explanation to get the python version and poetry installed, but once done once, all scripts can use it from thst point forward and it is very easy to toss over a python script to others without fearing a long set up session.
I’m typically in the Ruby ecosystem, and generally packages are well maintained, well documented and members of the community are helpful. The big question for me is how often do I have to look at the source code of a given library, and that’s pretty rare here. Also I don’t remember the stats but I’ve read the devs are better paid on average because it’s “niche” (despite being a popular general-purpose language).
Just chiming in to say I've been paid to write Ruby for the last 5-6 years and I absolutely love it.
I came to the same conclusion when I switched from Java to PHP. With Java I never needed to look at the source of libraries. With PHP it was pretty often. Good libraries have proper documentation and examples, something that lacked with the stuff we were using. The implementation in the framework was also pretty inconsistent, which made it hard to guess what the right way to use it was.
Sounds good but Microsoft seems to have taken a very weird direction in the last decade, especially with regard to Azure and Cloud. Why are they ignoring their core product - Windows Desktop OS and related framework libraries like WinForms, WPF, etc.? The Windows Phone (Nokia) paradigm had great potential, I think MS could have salvaged it if they wanted to?
While I adore f# the ecosystem has some issues. Everything you want to do can be done but since a lot of the community assumes you’re coming from some other language it’s seldom written with great examples.
It’s a lot better than when I started but it’s frustrating when the documentation is out of date or you get a guide that’s 30% “thing goes here” comments.
The upsides of the language make this hurt a lot less than any other I’ve used, but I hate that it’ll probably never fully take off and achieve what it could be
Fully agree with your thoughts on F#. I love this language and all the cute little features it has, but it's really let down by the package ecosystem and poor tooling.
I love how it's a functional language that has a focus on "getting stuff done". Languages like Haskell are cool and all, but I can't help but feel like they're too academic for my tastes. F# fits really nicely into a sweet spot that I've not seen much in other languages. The designers did an excellent job of making it functional, powerful, and yet practical.
Even though it's functional-first, the OOP support is surprisingly good in F#. OOP so much more terse compared to C# and honestly there's an argument that F# does OOP better than C#, at least for the features it supports. It's a great experience to be able to use whatever paradigm fits the problem the best. Easily dropping down to imperative code to improve performance is also great. Somewhat ironically, the way F# pushes you towards functional code makes it really easy to swap out FP code with imperative code to improve performance.
I know other languages are starting to catch up, but F# also has a pretty good REPL experience. Getting immediate feedback while programming makes it so nice to experiment with code and understand how you wanna approach the problem. It's great that Rider has something similar for C# in the form of C# Interactive.
I wish units of measure would make their way into more languages, because it's so damn useful for domain modelling. Active patterns are great too - having logic to transform data into a sum type is amazingly useful for pattern matching. Also, type providers feel like a magical experience when you first try them out; it's a real eye-opener when you get autocomplete for your CSV or JSON.
There's a lot to really like about the language design for F#. Even though I'm a massive simp for ML-style language design and I might be a little biased, I genuinely do believe a lot of the features fit together so well. You can tell there's a lot of thought that has gone into making this language.
But at the same time, every time I use it for a larger project, I remember why it's such a pain to work with. The community is really small so you get way fewer high-quality packages, tooling, resources, documentation, and general support. You can count the number of high-quality packages for F# on one hand, and the tooling isn't great either.
I've had really shaky experiences with documentation for F# libraries. Saturn is a pretty popular web framework for F# but the documentation feels really limited for the tutorials. There are just 3 pages of tutorials and no full example project.
Rider is always improving with F# support but there's a night-and-day difference between Rider's refactoring tools in C# and F#. C# refactoring tools and IDE suggestions are so intelligent and have a very good understanding of code, meanwhile F# suggestions are so shallow and naive. I've not tried VSCode with F# so I don't know what the experience is like Ionide, but I can't imagine it's much better.
Fantomas, the F# community's preferred formatter, has so many issues and I've run into bugs a few times where reformatting a file changes the code's semantics or removes comments. For any formatter (and the community-preferred one especially), that's completely unacceptable behaviour. There's also a lack of certain features like being able to disable formatting for a section of code. Even just being able to tune what formatting gets applied is mostly missing, which is so frustrating because I hate the way it forces some formatting (e.g. sum types always get formatted to be on one line if the character limit isn't reached).
The interop with C# is great since you can use high-quality libraries and frameworks, but that should be a fallback option for when you can't F#-specific packages, and yet sometimes it feels like it's the default option. A lot of the time, you're expected to rely on C# packages and use the interop, which introduces some annoyances you wouldn't normally have with just F# (e.g. you have to deal with null now, yayyyy!).
In terms of language design, after getting a taste of Rust traits and Haskell typeclasses, I really wish F# had something similar. The language designers have said that's not happening and I understand their concerns, so oh well.
It's such a shame because this language deserves better and it can't really get there without community support, but Microsoft treats it like a second-class citizen and does a poor job of promoting it so it's unlikely things get much better for F#. I might give OCaml a try in the future for larger projects and see if it fares any better, but it would be hard to cheat on F# eheheh.
I can only really speak for Go and Python and have an untraditional programming background. I learned Python a little, then Go a lot, then learned more Python for work. I worked on Go microservices and Python monolith, so not set up to love Python. I can't speak on 4. Overall:
map
function. It helps you step back and say, "If I need this and it's not there, is my code too complex?"golint
,govet
, and Go Modules.Go's only drawback to me is that you can't use it for everything. Because it's newer, support for things are also dicier. Don't use Go unless you're prepared to also say "We use the right language for the job;" you don't want to end up using "the Go version of <popular Python library> for <semi-niche dependency>" which is 1 cowboy's weekend project that hadn't been updated in 17 months. But if you can choose most of the stack, use Go (or something as good as it).
Python isn't inherently bad, but I think if you don't have the time to be attentive, you will produce bad code really fast. Again, I am biased because so much of my experience is with a monolith.
However, probably most things you need have a library. I think if you have the time and discipline to write good Python and your task is of unknown complexity, Python isn't bad.
Mutable defaults are a nightmare to debug... I love Python, but the language is sometimes too simple and flexible for its own good.
I'll defend the use of
map
though; sometimes it's more straightforward to write in a declarative style rather than an imperative style. The intent of using map with an anonymous function is (usually) explicitly clear while a loop can do any number of things in each iteration. Functional languages use maps more than loops usually. Here's some more reading on the design philosophy in case you're curious: https://cswithbaddrawings.wordpress.com/2020/03/13/gain-confidence-with-declarative-programming/The Laravel ecosystem is amazing. So many tools exist to make a lot of normally complicated tasks very simple. I cannot even begin to describe the amount of pre-built tools that exist. It's a massive ecosystem with great documentation and a lot of helpful people always ready to answer questions.
https://www.offerzen.com/blog/taylor-otwell-importance-of-documentation-and-developer-experience-in-laravel
I'm self taught in AutoHotKey.... I'm the ultimate of lazy so my "coding" skills are: how do I hack together my user inputs to do my job. after 8 years of creating hotkeys, I have a script file I can't live without.
several hotkeys to open custom UIs, conditional scripts if a certain program is open before using alt keys to navigate the menus of an application. Much of my repetitive tasks are now simplified. If I type lmkqc into an email, it changes to "let me know if you have any questions or concerns." (a typical comment to end my emails).
I need to type a Work Order number into several different programs. this number is typed ~8 times in the period of 20 mins and then switches to a new semi random number. I have a hotkey to save a number. then a key to type it, a key to open a file folder with its name, a key to open that work order in a said application. all of these are used constantly so I don't have to devote my human RAM to remembering or writing down a number.
I can also rewrite windows hotkeys to be better. Win+E normally opens a new file folder. Win+E for me scrolls through open file explorer windows. if there isn't a file explorer window open, it will open up the most common folder I use in a new file explorer window. I then made shift+win+e to always create a new file explorer window.
I could nerd about this all day long...
I really want to learn more languages but AHK will always be my heart I'm afraid. my lazy brain is just wired for it.