If you were to start a new commercial project today, what language would you choose?
This is left intentionally open-ended. I know that the answer would depend drastically on the application domain. That’s part of the point. Hopefully this engenders discussion for lots of different domains.
The idea is to determine which languages are both mature enough in their implementation(s) and standard libary(ies) to be considered that might have flown under the radar, so that viable languages that might be lesser-known can potentially get some exposure.
I’d choose Python. It’s not the best language, but I know it very well, I know its ecosystem very well, I know I can “easily” find other engineers to help me (and affordable) if I need. So, simply put, Python would be the best tool to make money, in my case.
Hey, who you’re calling cheap!?
Joke aside, do you mean affordable on the sense of there’s lot of people that know python so the scarcity doesn’t drive up salaries above average, or python developer salaries are below average?
It’s an established language and platform, so there are no surprises with cost. Python is now commonplace, and while it will go into decline at some point, it will be relatively gradual. People won’t be surprised. There are plenty of companies that are stuck with platforms that have declined more quickly, but still need to be maintained long-term. Some JS frameworks like Angular are here in some markets.
In terms of average salaries, there is an expectation that established platforms will not be able to sustain salaries at the level they were when the platform was up and coming. The next cool thing is somewhat unknown, so developers can justify higher salaries because they are supposed to be working on the higher risk frontier.
When it comes to an individual you need to be doing more than Python to get a higher than average salary. Or, be paid to work remotely for a company that can sustain a higher salary (e.g. get a closer to SF salary, but live in the Midwest). If salary isn’t your primary goal, you now have more opportunities to practice Python because of greater market penetration. If salary is your goal, then the best plan is to be closer to the bleeding edge, and have a broader/deeper skillset.
Does no one get in trouble with clients or management due to the later costs of Python? Having to put effort into keeping the software working when Python makes backward-incompatible changes that other languages are less likely to make. Spending time after-the-fact on mypy when the software gets large. Dealing with some aspect of the program being too slow.
You are taking that out of context, but I understand your perspective. My point is that there is no surprises from the ecosystem going away, or declining rapidly, which then has a knock-on impact on the market.
Python applications can have many surprises in terms of costs later on as you point out. That said, I think a large part of that is to do with the inability of people to set proper expectations.
Anyone with experience, should realise that the convenience of Python comes with cost. They should highlight these trade-offs in some manner with other stakeholders. Whether it’s stretching Python, or someone creating an over-engineered monstrosity with some other framework for a company with no expertise in it, it really comes back to professionalism. There are real costs when we avoid discussion of the issues, or don’t document them, but people seem to press on regardless.
At other times we have to just accept that people with relatively little experience will make important decisions. We have to accept them and develop a plan for resolving the issues. If these decisions are happening continuously around us, then moving on, or developing better influencing skills seem to be the only options.
Ruby because it’s home for me. Julia because it is really neat. Nim because of simplicity.
Rust.
The dev experience is so much nicer than my usual C/C++. After spending a lot of time writing and doing code reviews of C, C++, and rust, I am pretty convinced that it is much easier to write correct code the first time in rust than it is in the others, and rust has equally nice performance properties but is much easier to deploy.
I spend most of my day working on high performance network software. I care about safety, correctness, and performance (in that order). The rust compiler pretty much takes care of the first item without any help from me, makes it very easy to achieve the second one, and is just as good as the alternatives for the third.
I’m curious if you’ve ever tried another — non C/C++/Rust — language (anything garbage collected or dynamically typed) for projects where you don’t necessarily care about the fastest runtime? Is that ever relevant, or do you really only work on “high performance network software”?
I work in games, and my experience is very similar to mortimer. I would go rust with no hestitation.
I’ve done a lot of C# with Unity, and quite a bit of Go. I’d pick Rust over both of them any day of the week.
The big thing with C# in games is that you lack control, and also have to do generally more memory management than even C++, working around the garbage collector is not fun.
Sure, there is some stuff where performance doesn’t matter too much, and for those we’re free to choose something else. Python is pretty popular in this space, though even for these things I’d still consider using Rust instead just because the compiler makes it harder to screw up error handling and such.
I did a transparent network proxy in ruby once, and that was super nice because ruby is super nice, but if I were to do it again today then I’d pick Rust. Most of the code wasn’t something you’d get from a library, and the vast bulk of bugs I had to handle would have been squashed by a better type system (this thing that is usually a hash is suddenly an array!) and better error handling (this thing you thought would work did not, and now you have a nil object!). Ruby (also python) just don’t help you at all with these things because it’s dynamically typed and will usually return nil to indicate error (or python will sometimes throw, which is just offensive). This paradigm where the programmer has to manually identify all the places where errors can happen by reading the documentation, and then actually remember to do the check at runtime is really failure prone - inevitably someone does not remember to check and then you get mystery failures at runtime in prod. Rust’s Result and Option types force the programmer to deal with things going wrong, and translate the vast bulk of these runtime errors into compile time errors (or super-obvious-at-code-review-time
unwrap()
s that you can tell them to go handle correctly).I haven’t really done any professional Java dev, but the people I know who do Java dev seem happy with it. They don’t have any complaints about performance - and they deploy in places where performance matters. When they do complain about Java, they complain about the bloat (?) of the ecosystem. FactoryFactoryFactories, 200 line backtraces, needless layers of abstraction, etc.. I don’t think they’re looking to change, so they must be happy enough. When I did Java in school I remember lots of NullPointerExceptions though, so I assume the same complaint I have about ruby / python / C / C++ error handling would apply to Java.
For personal projects, it was usually ruby (because ruby is super nice), but lately all the new stuff is Rust because the error handling is so much better and it’s easier to deploy. Even when I don’t care about it being fast I do care about it being correct.
Another reason: Attract good developers!
That’s the flipside of all the good techical reasons, plus actually some of the bad - learning curve and newness.
There are too few Rust and Haskell jobs, ok many C and C++ jobs, and absurdly many Java jobs.
In order to validate the ‘learning curve for newbies’ concern, I actually gave Rust to a new employee (fresh out of uni) to see what would happen. They had a background in Java and hadn’t heard of Rust before then. I gave them a small project and suggested they try Rust, then sat back to see what happened. They were productive in about a week, had finished the project in about two weeks, and that project has been running in production ever since without any additional care or feeding for over a year now. This experience really cemented for me that Rust isn’t that hard to learn, even for newbies. The employee also seemed to enjoy it (this is a bit of an understatement), so if new staff can be both productive and happy then I’m not too concerned about learning curves and stuff.
Vast majority of people that write about Rust online mention fighting the borrow checker. Your new folks didn’t have that problem?
Having helped both a few co-workers and a fresh intern with answering rust questions as they learned it, I’ve come up with a theory: Fighting the borrow checker is a symptom of having internalized manual memory management in some previous language before learning rust. And especially severe cases of it is from having internalised some aspect of manual memory management wrong. People who don’t have that are much more likely to be open to listening to the compiler than people who “know” they’re already implementing it right & they just need to “convince the compiler”.
I find that I can often
.clone()
my way out of problems for now and still be correct.Sometime later I can revisit the design to get better performance.
Oh yes, new people fight the borrow checker but it just isn’t that bad (at least not in my experience) and they seem to get past it quickly. The compiler emits really excellent error messages so it’s easy to see what’s wrong, and once they get their heads around what kinds of things the borrow checker is concerned about they just adapt and get work done.
I felt that I wasn’t fighting it. It was difficult, but the compiler was so helpful that it felt more like the compiler was teaching me.
(That said, I was coming from Clojure, which has terrible compilation errors.)
Not sure about his employee’s perspective. But, I’m new to writing in Rust, and I think the frustration with the borrow checker is not understanding (or maybe just not liking?) what it is trying to do. My experience has been that at first I wanted to just try to build something in Rust and work through the documentation as I go. In that case the borrow checker was very frustrating and I wanted to just stop. But, instead I worked my way through the Rust book and the examples. Now I’ve picked up the project again, and it isn’t nearly as frustrating because I understand what the borrow checker and ownership stuff is trying to do. I’m enjoying working on the project now.
Counter anecdota – we have a team at $job that works entirely in rust, and common complains from the team are:
We aren’t hiring many folks direct from uni though – so perhaps counter-intuively, having more experience in other languages may make learning rust more difficult for some, and not less? Unsure.
Pragmatically: C
Ideally: Forth or Scheme
I like simplicity and consistency, so most of the recent languages, for me, are simply painful to use
I’d choose Common Lisp because it’s what I use unless I have a reason to choose something else.
TypeScript has been hard to beat for me recently.
Now that tooling has matured to the point of having a fairly no-thinking-required project boilerplate story (prettier, eslint, jest, debugging in VS Code, Dockerfile,
tsc
config, etc.), I find that it’s the language I’m able to get productive in fastest. I get the whole JavaScript ecosystem at my disposal, have every possible kind of tooling/library/etc. you I may need available, and get to work in a modern typed language with support for my favorite patterns and helper libraries (Funfix, Ramda, Lodash). Cross-platform compat for free, pretty much everyone knows it enough to where they can contribute or at least debug some issue on their own. Types can be shared between the backend and frontend with little effort, and the same language can be used for both (TypeScript + React is my go-to for the frontend).Other than that, the only real other thing I’ll use for webapp backends is Rust. The Rust+Rocket+Diesel+Postgres stack is compelling as well, but the speed at which I can create features is not at the level of TypeScript.
Elixir for web-based projects, medium-to-large programs, and programs that need to be reliable, or will benefit from parallelism (so: most projects).
Python for extremely small programs or scripts, or when I’m on a team (everyone in my life uses Python for pretty much everything).
OCaml for when I can luxuriate a bit, want it to go fast, and hate myself a little.
Python is amazing for scripts and glue, and also for integration testing! Our team uses Pytest and Behave to make sure our services play well together.
If the project would be server side I would opt for Go. It is very straightforward to set up any type of network communication along with a ton of third party libraries that cover all your needs.
In any other domain I would reach for Rust which may sound fashionable but I think there is a great amount of traction for it. The most appealing feature is the stabilization of usable asynchronous primitives which turn callback-centered code into more of an imperative flow. Not to mention the amount of confidence you get by having a compiler that ensures memory safety.
I like Nim. Wrote some important code at work recently, to do some json->mysql stuff over a socket.
Java without a shadow of a doubt.
I can understand why the JVM is attractive, but why Java over Kotlin, Scala or Clojure?
I love Scala the language, but can’t deal with the compile times from scratch, and Java seems to be getting all the good features of Scala slowly. I very much prefer static types, which rules out clojure. Kotlin I would consider, but it’s much more likely to go away or stop being developed than Java, being totally controlled by one small company. Kotlin’s JavaScript target is attractive though - I wonder how it compares to gwt/j2cl especially in jsinterop?
Java or Kotlin.
But it usually ends with Java because I am trying to solve a problem, not learn a language.
And also because my favorite IDE doesn’t support Kotlin.
Really?
Never had that impression about the latter part.
It feels like every presentation of new Java features consists of
I see a connection behind this yearly occurrence, Oracle devs somehow don’t. ¯\_(ツ)_/¯
So yeah, it gets a bit better (as long as you follow the ideology of “adding features improves a language”), but the design feels cobbled together, completely focused on navigating the ever-narrowing path between growing technical debt and past bad decisions, with no focus on making better decisions in the future.
It’s all “the feature is like this, because this is the only way we could make it work”, not “the feature is like this, because this is how it should work”.
I’ve been programming Java since 1.4 and in that time we’ve gotten:
Soon we’ll be getting inline (value) types which will make Java first class for matrix based calculations, and fibers/continuations which will remove the main feature Go has over Java.
I would use Python, mostly because it’s what I know, and because I have seen many people get proficient in it very quickly.
It’s not the fastest thing, or the safest, but being able to debug broken-ness is very valuable, and lots of stuff about the language makes it really nice to write “simple” code
Go, because it’s simple and I have static binaries that just work and because it has somewhat sane dependency management. Oh and because at least for now it seems reasonably stable.
But most importantly: Not an “add all the features you can imagine” language, that pulls in whatever is currently hyped or considered to be a must have, with no actual reason. So code hopefully will be readable in ten years and things will not be looking and working differently, because of fashion trends.
What kind of “currently hyped” features are you thinking of? Cause the usual suspects, say, generics and sum types, have been around for at least 45 years now. They’re not just “hype”.
No, I am not talking about the lack of generics and sum types, especially given that the stance concerning those doesn’t seem to be something that will never change.
I mean the fact that many programming languages, let’s take Java or JavaScript (no hate on either of those, but they are famous and around for long enough to be good examples I think) keep adding ways of expressing the same thing. I can certainly see the appeal, as someone who started out with Perl. However, reading through large code bases in day to day work, I see fashion trends on how to do the very same thing.
Maybe features is a too broad term, but there are what I’d consider mostly fashion waves on how to approach things. Adding all sorts of OO features and every programmer eager to use them for everything, then there is a tend of functional programming and everyone converts simple, perfectly fine into mappings, uses lambda in every second line. Later, despite not new people start to rewrite everything into one line if statements and move the condition to the end of the line.
Those are trends and I am sure one could go through big, old code bases to see that.
What this leads to in the end is that big programming languages, that “survive” (have a sizable developer community) tend to accumulate these features of doing the very same thing, in a way that some often young or at least hipp language is doing it.
Also I don’t think hype is actually something that’s related to time of invention. It’s not true in fashion/hype outside of IT and it certainly isn’t true in IT. See functional programming vs LISP or concepts like MVS and Smalltalk. There have certainly been phases of when people in the large approved of them and when they didn’t. Same goes for things like minimalsm, vs covering all cases, for monoliths vs modularity, frameworks vs (small) libraries, smart static vs smart dynamic typing, whether RPC is seen as a good pattern or a bad one, etc.
EDIT: Just to be clear. I am not convinced that Go will not go down that path as well. It just currently sounds to me like the intention is not to do so.
Also I am not saying that it’s bad per se, to copy great things. Not at all. It’s the accumulation and over-use of these features, especially when someone maybe not so experienced wants to use that new feature or technique that can result in hard to maintain code. In Go that tends to be the over-use of the go statement and channels.
I think I mostly agree with you that Go maintainers seem, more than usual, intent on keeping the language small and not add features over time just because of “fashion”. I think a few other languages are like this (including new ones, like Zig which explicitly strives to be as simple or simpler than C). On the other hand, I hope that the current balance of the pendulum towards static types, type inference, etc. is not just fashion but just more people understand that they are the One True Way™ ;-)
Lately, I’ve been doing all of my initial prototyping in Julia. Actually, now that I think about it, I’ve been doing everything in Julia! I highly recommend checking it out if you haven’t already. It feels a lot like an improved Python. I’ve found it great for all of the computational neuroscience work I do as well as my side projects.
I generally prototype in Julia as well, and it’s really just the “time to first plot” that causes me to migrate projects elsewhere.
I start most of my new projects in English although lately I’ve started learning 中文 so maybe that’ll change eventually
C++, why? Because I’ll be able to run the project in 10 or 20 years from now.
Also, if you haven’t tried programming in C++11 or newer, you might be pleasantly surprised by how much easier it now.
if you use dependencies, you better vendor them though, because otherwise who knows if they’ll still compile in 20y?
As opposed to if it was made in Rust?
Yes, I am not confident a Rust program I write now will run in 20 years.
It seems like a bizarre criteria to discount an amazing improvement in the space of lower-level languages. I’m a bit jaded atm because my university is forcing me to write C++ code so I can’t imagine why someone would voluntarily choose it over Rust for personal projects over that criteria. Personal preference and experience sure, but that alone…
I had the opinion you do about C++ for a long time (especially since a lot of the people I admire on here and the orange site have very strong opinions about it), but I tried it again and it is satisfyingly high-level with recent revisions and tooling has improved drastically. Rust might be the language of the future, but the amount of change that has occurred in the ecosystem (as with any newer language) could reasonably dissuade someone from selecting it for a long-term project.
These days, I’d argue you’re not at all crazy for choosing to write a personal project in C++, especially if you’re interested in keeping it running for as long as possible and you like the language. Rust is also a valid choice.
C++ does have nice tooling and nice libraries, and the best C interop ever (duh), but every time I have to debug a weird runtime issue I wish everything was written in either Rust or something with GC. (Recent example from a project I contribute to: creating a dangling pointer by accessing a field >_<)
Also header files are very frustrating and ugly. In a language with classes, I want to see a Java/C#/D style class definition, not one where function bodies are split into a different file.
C++ has a really simple memory model. Custom types act like native types. Everything is uniform.
And honestly, pointers are just really powerful and C++ has a generalization of pointers called iterators which are even more powerful!
Also, modern C++ is actually really easy to use. The libraries are just really good.
+1. I’m a huge Rust advocate but until there are more implementations following a spec (which still doesn’t exist), I’m really with you on this one.
What C++11 material do you suggest to get a quick overview of common practices and idioms?
A Tour of C++ is pretty much the definitive short overview of modern C++. It isn’t designed to teach you everything, but if you’ve already used C++ and are just looking for an overview of what’s changed since pre-C++11, it’s probably the book you’re looking for. The second edition covers C++17 and some features expected to land in C++20, as well as some good historical context and plenty of non-trivial examples.
If you’re ever in the position of learning C++ or JavaScript today, it’s probably better to start with the recent standards because the way C++ is written since the 2011 standard and the way JS is written since ES5 or so is very different from the old-school style. Most other languages don’t have such a sharp divide between “new” and “old”.
I’m well versed in this :) I’m a JS survivor and veteran now.
The spec exists: it’s the source code of the Rust compiler. Alternatives just gotta be behaviorally equivalent. ;)
Yeah I expected someone to say this. This issue with this statement is the huge, massive conversation you can have about it :) I won’t give my opinion, but you can already probably tell what I think about it.
For a company doing webshit, I’d ship something hacked together with Node and static pages. If it got enough traction, I’d do second prototype in Elixir and static pages plus ajax as needed. Bash and docker for ops stuff.
I’d pick this because it’s easy to find/train developers in those languages, and because they have benefits for either moving quickly (JS) or not having to backtrack (Elixir). The fancy stuff I don’t expect to have a need for, so no Rust or Elm or whatever else.
For a new commercial project, you want to save your innovation tokens for the business side–use the tools that fit your hand the best. Computers are so good nowadays that performance basically doesn’t matter, and customers getting value from you could care less about theoretical correctness or provability.
To stay on the safe side I’d probably pick PHP + Laravel as that’s the stack that I know the most confidently.
Depending on the project, I may use Elixir for realtime, Swift for mobile/desktop, or Nuxt.js for static sites.
For me it’s PHP + Symfony for web stuff, for static sites Sculpin.
Anything else PHP (CLI)/Python/Node, depending on what I want to do.
Nice, I’ve always wanted to give Symfony a try but it seems unnecessary for me to learn two PHP frameworks.
Node / React / Nextjs if working with other devs.
Clojure if working on my own (but not ClojureScript).
Not cljs because you will not want to have any js? Or is there some other reason to avoid it?
Haven’t had a great experience with the tooling. IME it was slow to build, unreliable reloads, and had complex build configs. Maybe need to give it another try since it’s been a few years though. I might have become spoiled by create-react-app too.
Edit: also the JS community is a many orders of magnitude larger. If I need any lib I’m pretty sure it exists. The same isn’t true for cljs. I realize I can consume plain js from cljs but I don’t remember that being very fun either.
Shadow-cljs is great (for working with npm packages and otherwise), but granted, the tooling has its rough edges. In my experience cljs is much better suited for React than es6.
The small community is also a blessing at times: package maintainers tend to be passionate and eager to help. I attribute that to not having to cater for the masses as with more mainstream languages.
Interesting. I have been thinking about converting my ES/React dashboard frontend for https://yetibot.com to cljs. Maybe time to give it another shot :)
@dancek I am a bit torn tbh. I love the lang and agree sharing would be great. Up till now I haven’t had to do much client side on clj projects though so it didn’t matter.
Are you using one of the React wrappers for cljs or do you consume it directly?
We’re using reagent as the React wrapper, and re-frame for state management. Re-frame is similar to redux but has a better philosophy for some things. There are others but I have no experience with them; I imagine there have been some new ideas.
If you happen to try the cljc approach I really recommend reitit for routing, both in the backend and frontend. We share the backend route tree with frontend and have spec-based validation in all http endpoints. Those are really awesome features compared to any other web technology I’ve tried.
Cool. I’ve wanted to try that stack. When I last did cljs we used om.next which was very unfun, to say the least.
Do you do any server side rendering with shared code (what they sometimes call isomorphic) or is it all on the client?
No, all the react runs in browser. We do generate a couple of html pages on server side with some hiccup renderer, I forget which one. The app is only for logged in users so we don’t need to consider crawlers.
Got it. Seems reasonable. One thing I love about Nextjs is SSR everywhere, whether you need it or not.
[Comment removed by author]
As you said, it entirely depends on the type of project. Some languages are more apt for specific tasks than others. But judging by the ‘commercial’ part, I think I’d go with Clojure or Elixir if I’m writing something meant to handle heavy burden. If it’s a smaller task, say, I need to hack together a development tool, I’d probably use Racket or just Scheme.
I’m curious, how would you describe to a non-Racket user how Racket’s good for making dev tools?
The standard library is fairly rich and extensive. 90% of the time, there’s a module that covers your use-case with a well-documented high-level API. You can just skip the boilerplate and use the DSL exposed to you, and even extend and customise it with Racket’s powerful metaprogramming tools if it doesn’t exactly fit your needs.
For such a vague question, beats me. I’d first want to research the problem domain some more. What systems will I have to interact with, and what protocols do they support? Is it all normal, common stuff with good lib support in every popular language, or is it a niche thing where the only really good lib is in one particular language/framework? For ex, if you have to work with SQL Server and ActiveDirectory and deploy on a Windows server, you’re setting yourself up for a world of pain and misery if you use anything but MS stuff, ideally C#.
Are you an in-house developer, or an external consultant, expecting to build something and then leave it to in-house team to run? You should probably pick whatever the company team knows best, absent a strong reason to use some other thing. Or at least something that’s reasonably easy to hire in, instead of some cool super-niche thing that you’re playing with this week.
Is it web stuff, or mobile, or desktop? That’ll inform a lot. I’m fairly sure from what I’ve read lately that, if you’re doing mobile, you’re best off using the platform’s primary language - Kotlin for Android, Swift for iOS, or else just stick to the web. For desktop apps, getting things to work and look right in anything but the primary language can be a real drag - hello Swift, Obj-C, C++/MFC, C# with WinForms or WPF. Or just go Electron and eat the extra app size.
I will say that for web, I’m inclined to pick Ruby on Rails first, absent some strong reason to use something else - perhaps there’s an awesome lib for something critical I need to do in Python. There’s just such nice support built-in for common standard stuff in Rails, and a huge pile of battle-tested gems to do most anything else.
Most other languages have their well known domains. Python with Pandas and other such things seems to be quite popular for hardcore data analysis stuff, so I think I’d need to look at that closer if that’s what the project is all about. I’m feeling rather fond of Rust lately for CLI stuff where speed and real multithreading is important. Still overall, you should be able to take what you know about the language ecosystem and the problem you’re dealing with, and make a choice.
Markdown or Asciidoc.
Hire an initial team and let them find a vibe together, set a couple of boundaries and let them decide what’s best for them to work together with. But someone needs to not all that down.
I have a personal preference towards Rust or Ruby, but yeah, I’m biased.
I dig this response. And to be honest, makes me think about my desire to do things my way and how that can get in the way of working together.
Java for a commercial project because:
For commercial or enterprise projects, I want the least amount of surprises. Will devs be able to work on the project? Yes. Will it run? Yes. Will I be able to find people, frameworks and libs to do their tasks? Yes.
Because I work on enterprise stuff with microservices and other delicious buzzwordy things, I would add:
Monitoring a Java process is… not exactly smooth? In my opinion it’s not as plug’n’play as it ought to be, with wildly different techniques being involved depending on the context.
Testing is dead simple. JUnit with Mockito, maybe some Cucumber. TDD all the things!
On another note, I guess all of my points could also be applied to Go. I can’t say for sure because I haven’t learnt the language yet, so I can’t compare.
D. It’s expressive, I can write it fast, the binary runs fast, and I never have to write too much code to begin with.
Then again, I’m biased.
C
…what? It’s still the best in this world of bloated sh#t!
All right, all right… C++ then.
depends on how big a team I had and what the domain was. probably one of racket, ruby, ocaml or d though - I use the first three for my personal projects and find them very productive, and I’ve tinkered a bit with d and feel it would be really good for a place where I’d otherwise use c++, though i would want to make sure it had all the libraries I needed first.
for somewhere the jvm or clr would be handy, particular with a larger team, I’d go with clojure, kotlin or a mix of f# and c#.
If I have a clear plan, then Rust, otherwise D.
In contrast to Rust but similar to Python, D lets you “sketch”. Later you can tighten the type constraints to find errors.
Common Lisp or C.
Common Lisp, because it has the fastest write-test cycle I know of, while still giving lots of compilation warnings (when we compile one function with a keystroke), it has more libraries than you think, I love the comfy and consistent syntax, and we can build executables. I wouldn’t go with Python anymore, I am not happy with the development workflow, the type checking and the deployment story (specially if I want to deploy a fleet of apps). I am lurking into other languages, but they always miss something CL has :] Oh, and I really want to try the hot reload capacity. I must be great for small updates. With Python if I want to deploy a quickfix it impacts the app’s availability (by not much, but users still face a buggy app for a couple of minutes).
For a web project, I’d probably reach for akka-http or http4s in Scala to do something largely API-based or Ruby on Rails if it was a full web app. If I was building enterprise software with long-running service in it or a native desktop or mobile app, I’d probably go with Rust or the preferred language for a particular platform if the app was scoped to only that platform (e.g. C# for Windows, Swift for macOS or iOS, Kotlin for Android, whatever-I-want for everything else).
Here is my extremely subjective and polarizing opinion of which programming languages should be avoided for new projects. Not because they are bad, but because there are better replacements for each use I can think of:
Comments describing why a language would be an even better fit for a specific use case are warmly welcome. Prove me wrong! :)
For nim specifically, I think that CLI tools are much easier on the small end than in Go/C++, due to the availability of the terminal module and cligen. Combine this with the easier deployment story vis a vis python, and it’s done very nicely for writing CLI tools for Windows for me.
But, Nim is also the first new language I’ve had in a long time that just feels nice to write. It’s templates, in particular, are very handy for DSL-lite sorts of things. It handily beats go for CLI tools, IMO.
C++20 and even C++17 compiler and standard library support isn’t there even among the big three compilers (GCC, Clang, VS) let alone the numerous other compilers out there.
This just makes no sense at all, really. Rust has nothing in common with Common Lisp or Scheme, which really have very little in common with each other baring very basic syntactic similarities.
I upgraded my team’s main work project from C++11 to C++17 a few months ago. There was a bit of bother getting it to build with all three compilers and for iOS/Mac/Android/Linux/Windows, but it wasn’t a big deal.
The only missing thing I recall is that the files library isn’t available for Mac/iOS versions prior to last year’s (OS X 10.15 / iOS 13). So we don’t use it.
And I’m sure I’m not alone in having heard “But we don’t want to force the customer to upgrade his compiler, so we’ll keep compiling with the old one”.
“GCC has almost full support for the latest revision of the C++ standard, which was published in 2017. “.
I don’t see how that has any relevance to what I said. I am talking about the intersection of the support for the major three compilers and standard library implementations.
Not to mention that not everyone can run the most recent version of the compiler. It’s not unreasonable to stick with the latest LTS release of Ubuntu as your desktop operating system in a work environment, which would mean you’re using GCC 7.4, which supported most of C++17 but not all of it and almost nothing from C++2a. I’m sure there are plenty of people still using GCC 6.3 on Debian stretch. RHEL 6 is still in support until November and is on GCC 4.6, RHEL 7 is on GCC 4.8 (yuck).
The original question was about new projects, though, not the people stuck with GCC 6.3.
I don’t think those two things are mutually exclusive. Working on a new project doesn’t mean you have a new computer.
I disagree. They have “functional programming” in common. Also, I believe Clojure can be used wherever people were considering using Common Lisp or Scheme for a new project. The exceptions would be where Common Lisp would have better performance than Clojure, and better performance would be needed, but then Rust could be used instead.
There are compilers that provide excellent performance while still using functional programming, like Stalin for Scheme or MLTon for Standard ML, but I think Rust is more approachable, especially for new hires.
Common Lisp is a multi-paradigm practical engineering language. Scheme.. isn’t any of those things.
Both support tail recursion and are functional programming languages.
In either case, I can’t think of any scenario where either Scheme or Common Lisp would excel over either Clojure or Rust. Can you?
Can you perhaps share a great use case or something positive about one of your favourite languages?
No, only scheme guarantees it. Some CL implementations provide it under some conditions. For example SBCL won’t do TCE with a high debug setting.
Again no. It has the concept of generalized places which is all about mutation. It has variables with dynamic scope which violates referential transparency, etc.
It is clear you know very little about CL. Maybe you should learn more about it before opining?
Common Lisp is also a functional programming language. It is not wrong.
How about an argument to back up your claim instead of just repeating it?
What affordances does Common Lisp provide to support the functional paradigm? Tail Call Elimination? No. Currying? No. Lazy evaluation? No. Higher order functions is the only one I can think off.
https://en.wikipedia.org/wiki/Common_Lisp
The overall point I’m making in the top level comment is not that Common Lisp is defined as this or that, or that Scheme is defined as this or that, though. The point is that I can think of no use for Common Lisp or Scheme that can’t be done better by either Clojure or Rust. Can you? If so, please explain why.
Every scenario. Clojure runs on the JVM and Rust is a very new and unstable language.
[ This is my opinion. As such it is not objective. I am not making absolute statements that I assert apply to everyone, the scope is explicitly Me :) ]
Python. I recognize that for many people Python is the peanut butter & jelly of programming languages, but I would choose it for the following reasons:
I just started a new project in Go. Rust is interesting as well, but Go performance in adequate. Python (with typing) could be an option if the project never needed more than one core. Browser bits need to be javascript or something that compiles to javascript. I’m not convinced with WASM yet. It’s unfortunately a way to deliver “binary blobs” to the browser, on this I have to agree with FSF.
What’s your opinion on obfuscated and minified JavaScript? That’s what most commercial web apps are. I’m not convinced that super-compact and difficult-to-understand JS is much better than a binary blob. Either way, it’s a ton of work to reverse-engineer.
Nearly as bad. I think rms/fsf has a point here
You can deliver WASM with source maps and debug symbols, which even gives users a convenient format to find out which part of the binary is which (if they trust you that the source files belong together).
Yes, if you want to. But it’s also possible to not provide source maps or source
As with every other binary, including the browser that you are running. Also, I’m confused why the form suddenly matters in the browser. Both minified and generated (readable!) JavaScript exist, but are also useless for inspecting. The general idea behind the GPL and software freedom is that you can ask for the source that is running and have a right to receive it. Independent of format: WASM, pure JS, or JS generated by the Typescript compiler.
BTW, I have quite a while tried to find a stance of FSF/RMS on WASM or even minified binaries and have found none. Can you please point me to one?
I know of the general stance that JavaScript is often poorly licensed and browser should include a mode that denies running non-free JavaScript, but that has nothing to do with any of the above problems.
I get your meaning. But it’s quite rare for javascript source to be available. And I don’t see why wasm source would be any better available.
JS source is very often available for free software, it is is rarely available for non-FOSS.
The technology is just no part in this. WASM won’t change the needle in any way.
Depending on the domain, I think I’d pick one of:
First Rust, then C. If scripting is necessary, I use Lua as a supporting language.
I still use C for the very specific case of using
dlopen
to optionally load libraries and use C APIs, then I expose a much simpler version of the API to Rust.Following @mortimer’s example, I care about correctness, performance and safety, in that order, which I think suits game development.
I am a little late to the game and mostly second what others wrote
General PurposeRust hands down. It has with Cargo a great package manager that enables one to move from a single package to a multi project workspace. Rust speaks C and has offers bindings for Python, Ruby and others. This makes it ideal for library development. The small runtime or even no runtime support is great for embedded and system critical development. Their async stack is growing which makes it easier for backend development. It has fast startup times which makes it a nice tool for CLIs. It has a high learning curve, though.
Python for small, quick and dirty scripts. As it runs mostly on all machines without much effort.
This is a little harsh from me.
For most of the same reasons as Rust; it’s just that Go came out five(?) years earlier; so it was in a pretty unique space as a new statically-typed statically-compiled language with good memory management and a strong package manager. It was getting a lot of attention from my co-workers by 2011, and I broke down and started using it in 2012.
If Rust and Go had come out at the same time, I’m not sure how things would have gone. Rust has a lot going for it, but Go does have a shallower learning curve.
C or Go (depending on the project)
For a commercial project I would personally choose:
For a non-commercial project I would use language(s) that bring me joy:
I think the results in this thread really speak to the bias we have in the community here towards Rust. The social clout of the Rust community is really fascinating, it’s managed to become a very hype-driven social-media-driven language.
It’s been hard work :). Also 🦀❤️🦞
I would say choosing a language that prioritizes what Rust prioritizes and, to some degree, differs itself from other languages is a legitimate reason, not merely bias driven by social media.
If it were a web project, I’d almost certainly go with .NET core. C# has a lot of powerful libraries and features available for it, it’s what I know well.
For a tool that involved a lot of CLI stuff, probably Nim, since it can hook into most C libraries, and since it’s very pleasant to write (at least for me).
For a video game, definitely Godot.
Probably Rust, although I wish the compiler could be (a lot) faster.
Rust > Python > Go
Rust, because it’s what I am most familiar with now and for me is at a good-enough point to do my typical work (machine learning and natural language processing). It’s also the language I like the most besides (Oca)ML and Haskell. Python is second. I don’t really like Python, but it has a great ecosystem with numpy, PyTorch, matplotlib, etc. Go is nice for server-side work when Rust does not have the necessary ecosystem bits and Python is too slow.
How do you go about using Rust for machine learning/NLP? From my experience, that is firmly in the hand of python, for better or worse, but I’d be interested in how Rust is developing in that space.
I/we primarily use ndarray and tch-rs (a binding for libtorch). Since the ecosystem is not very mature yet, I have also implemented quite a lot of stuff myself (such as porting stuff from Hugging Face Transformers).
I don’t do commercial development stuff, but if I was going to start a hobby project I’d probably choose Ada. I like the linting that’s built in, the syntax, and how coherently designed it feels.
I’m still not very good with it yet, though, so pragmatically this wouldn’t be a great plan.
For the past 2 years I have mostly prototyped new projects with Bash. The worst part is that i never get around to rewrite it in something proper thus I have a lot of bash.
Man, I hate bash.
It depends on a project and availability of required libraries. If I need performance I’ll choose Go or C and embed Lua or TCL for extendability. And I’ll choose Python or Shell for a prototype.
It’s been go for the last few years, but more recently i’m leaning into Rust.
OCaml & ReasonML :-)
It usually depends on a project more, some languages fit more than others. But I decided to use Ruby for most of my projects – I can easily re-use most of the stuff I’ve been using in other project, I know library ecosystem well enough and I’m productive with it.
But personally, I lean towards Clojure/Elm/Elixir more and more. Just don’t feel that I’m productive enough with those.
For anything web related I love Java + Spring Boot. It’s quite boring (in a good way) and there’s just the right amount of magic with annotations to keep things short-ish but still understandable.
Go if it doesn’t have to execute in a browser and the runtime is not a hindrance (and it usually isn’t).
C, C++, or Rust if a more minimal runtime is needed. Which is/are picked likely depends on what libraries are available and needed.
C and C++ are non-starters if the application must talk to the internet. I consider it malpractice to write internet-facing software in languages with manual memory management, given how hard we know it is to do correctly. (edit: I’m referring to building new software from scratch, not maintaining the existing software we rely on)
I’d find something else to work on if the problem lies outside of these domains.
C++ has automatic memory management with smart pointers. In fact, most of the languages that are garbage collected behind the scenes have runtimes written in C++ to manage memory.
Is it malpractice to be using operating systems, language runtimes, and other software mostly written by C and C++?
The real malpractice is proprietary software if anything. Or the fact that we have allowed private companies to install backdoors in all our computer systems.
See the edit (I assume you replied before seeing it).
C++ smart pointers still have safety issues. They do not prevent use-after-free bugs. They do not prevent data races (admittedly, Go programs can have data races as well, with all of the same safety concerns). And they don’t do anything about the other large uncharted areas of the C and C++ standards labeled Undefined Behavior.
It’s important to minimize the existence of this unsafe code if we care about secure systems, particularly for internet-facing applications. Some higher-level languages that promise memory and type safety do have runtimes built in unsafe languages, or use the unsafe features of their host language, and failure to keep invariants has caused real issues with these runtimes and code generation in the past. However, these are much smaller and relatively easy to audit for correctness, than auditing an entire ecosystem of C code.
I guess it depends on who we are talking about when we say “we care about secure system”.
If we are talking about regular people: I would argue social engineering (phishing) and backdoors from government agencies via corporations are a bigger concern than random hackers on the internet.
If we are talking about tech employees: I would argue social engineering and backdoors from government agencies are a bigger concern than random hackers on the internet.
Doesn’t matter how safe your system is memory-wise if it is weakly engineered from a human perspective.
I watched a great presentation that showed how to replicate the FastPass UI within the browser at a pixel perfect level. FastPass can be written in the most secure language, but it’s UI is flawed.
I’m not sure I agree with you. A chain of zero-days could have you pnwed just by visiting a compromised website—certainly something we want to avoid. However, I’m not convinced that Rust is the solution to all our security woes. When Redox OS asked for people to test it, they found all sorts of security bugs. Maybe writing it in Rust minimized some of them, maybe not.
I don’t think backdoors from government agencies are nearly as big of an issue as zero-days stocked up by government agencies.
It’s much easier for said agencies and companies to simply add the backdoor instead of trying to find zero-days don’t you think?
You don’t have to like or use C or C++. But to describe using them as malpractice is just offensive trolling.
If that came across as trolling, I didn’t mean it that way. This was a post asking for opinions, and that is my honest opinion. I’m also not completely against the use of C and C++, but you must consider attack surface, and the internet is an extremely large one.
C#. It’s expressive, has OO stuff if you like that, functional aspects, interop.
I’ve been programming for 10 years, and I just keep crawling back to .NET and C#. It’s just so hard to beat. The debugging experience is fantastic both for desktop and web and azure websites. Recently I had to build a desktop application and I was able to crank out a fairly complicated application that operates against a sql server database with over 100 tables - each with at least 20 fields. There are so many classes, I feel like doing this in javascript/typescript would’ve been a huge mess.
When it comes to authoring desktop apps in particular, Visual Studio and Delphi are 100x better than everything else I’ve seen.
Go
Another vote here for C#. With .NET Core, I can develop and deploy a wide range of different application types (web sites, microservices, etc) on Linux. I get the full benefit of team members being able to develop with Visual Studio on Windows, while I can live comfortably on my Linux machine with Visual Studio Code or whatever I want.
English.
:)
SQL + PL/pgSQL for core business logic, combined with PL/Python for things that get to unwieldy otherwise and for writing tests.
For adjacent services, Python if I need that huge ecosystem, otherwise I’d like to experiment with Haskell or F#. Or Julia.
For more complex logic that is hard to make composable in imperative or functional languages, I go for Answer Set Programming (clingo/clasp).
And for web frontend: Elm!
For a GUI application, Swift. (Because no way in hell am I going to write front-end code for Windows/Android/Linux.)
For anything where I needed to reuse a lot of code I’ve already written, C++, because bridging would be a pain.
For new code … if I had room in the schedule, I’d break down and finish learning Rust, knowing that I’d be in for a few weeks of frustration and awkwardly looking up APIs.
[Comment removed by author]
It depends on the project. My favorite language in general is Rust, but I’m finding myself starting more projects with Go recently. I mostly develop web applications, and Go just feels a lot easier for that. But, I also (at least partially) attribute this to my lack of knowledge in the Rust domain.
Considering many of my new projects are half about kicking the tires on a new language I’m not sure I would have a consistent answer here.
Purely commercial?
Python, Go, Typescript, or Java, in that order. Easy to hire for, garbage collected, large sets of packages available. With the exception of python, statically typed.
I do mostly web stuff so for me it’s always Elm. I’ve been more productive with my 1 year of Elm experience than my 4 years of React experience.
Go: no need to worry about memory management, deployment, or dependency management. Vendor all your modules, deploy as a static binary & reduce the stress in your life!
For the sake of maintainability and a very rich ecosystem, plus being easy to write: Clojure.
If I can’t afford to run a JVM: Go.
If I want to run on embedded machines: Lua or C.
If I’m trying to embed a language in another project, nothing beats TCL, a custom Forth, and Lua, in roughly that order.
For a project where I intend to be the only programmer, or only grow the team to a handful of people, probably Lua (and some C if necessary).
For a larger project, I would choose depending on a lot of factors. Probably one of Python, Erlang or C. TypeScript if it’s in the browser, but I’d probably avoid doing something too large in the browser :)
Swift for Apple stuffs. Rust for everything else.
Like you say, it’d depend on the project, but at work we’ve used Kotlin for most of our recent new projects, and it has gone swimmingly. It’d be high on my candidate list for anything that could reasonably be run on the JVM.
It has near-perfect bidirectional interoperability with the immense Java ecosystem, so the library angle is hard to beat. Compared to Java (and I say this as someone who writes both Kotlin and Java 11 code almost daily) it has a more sophisticated type system, puts functional programming much more front-and-center in the language design, and includes a thoughtful selection of modern language features without going overboard and adding every crazy thing someone asks for.
There is some multiplatform support but it’s still pretty immature; for now I consider Kotlin a JVM language. For some projects, the JVM is not a good fit, so I would pick something else for those. But the JVM is great for a wide variety of use cases.
I don’t start commercial projects (trying to get people to buy things & writing things that people who aren’t me want enough to pay for are both things I hate), & anything I do that is actually being sold will generally be part of my day job (in which case I have very little control over the tech stack). But, I start projects all the time, and a lot of them could be made commercial (if I hated myself or was sufficiently desperate).
Generally, I will write an initial prototype as a shell script (unless a GUI is required or I need to deal with a complicated non-line-based format or protocol that doesn’t already have good command-line-accessible tooling – ex., if I need to parse XML), then rewrite in python. Then, I might rewrite again in another language (depending on what I needed – if python’s too heavy & I don’t need to deal with big tables, I’ll do lua; if I need better support for parallelism then maybe julia).
I’m primarily a web developer these days, so my ideal stack at the moment consists of:
I’m beginning to learn GraphQL, though, which would replace the REST part of my apps.
If it needs to be fast and has a very specific job: Rust.
If it’s a prototype for a interactive application: TypeScript.
Python if it’s a REST api and I want to keep working on it long time, Ruby on Rails is if it’s a small project to get something up and running, Typescript if it’s a graphQL API, Rust for any other case.
It depends (obviously) on requirements and characteristics of the project. Shortly:
I would probably chose Go over Python (what I usually code in) because of: