3 ms·
Thanks for reading the article! > I just can't see having three different general-purpose languages in my stack for a single app What about for a larger syste
by binarynate 5y ago
Thanks for reading the article!
> I just can't see having three different general-purpose languages in my stack for a single app
What about for a larger system (comprised of multiple projects) or for a company? I'll give an example. I'm currently developing a cloud-based product to allow multiple people to remotely view and control the same web browser (mostly for virtual and augmented reality). Performance is important due to the real-time communication aspect. The part that interfaces with Chromium is C++, but I want to write as much of the services as possible in a higher level language to speed up development and avoid memory-related footguns. So, I chose C# for the services in the hot path because it's more performant than Node and it's also easier to call into C++. However, the system is really comprised of multiple services, and I still use TypeScript + Node for parts that aren't performance critical, like lambda functions that control autoscaling and the customer-facing web panel.
> In particular, if TypeScript isn't performant enough for whatever I'm trying to do, then it seems likely that there'll be more performance bottlenecks in the future, and so just moving to a generically faster language won't be good enough; I need a language that offers precise control over performance, so that when future issues come up, I know I'll be able to solve them.
The tradeoff with going all-in on C++ or Rust (for me at least) is that it significantly slows down development. For me, it's really important to be able to move quickly when developing a new product, both because I want to get it to market quickly and because I know I'm going to have to make changes based on what I learn from the market. I can still move fast with C#, and I don't find having a third language as a significant burden (like I mention in the article, I think it's a lot like TypeScript). Also, since it interoperates with C++ easily, that makes it easier to move more pieces to native code in the future if needed.
- ameliaquining 5y agoI guess having more languages works better if you have a microservice architecture. I tend to think of microservices as mostly good for solving organizational problems (namely, the need for everyone who works on a monolithic binary to agree on releases), and so don't prefer to use them if I don't have those problems. That said, I still don't really understand why you'd use TypeScript on the server at all if you need C# for other services; the advantages (faster builds?) don't seem sufficient to cover the costs of additional investment in tooling, inability to share common code, etc. (even assuming that training and/or cognitive-switching costs aren't an issue). Unless you're running the same code both on the server and in the browser; in that case I would probably dispense with C# but I could see someone choosing the three-different-languages approach, at least until .NET's in-browser story gets better. For a company with multiple unrelated projects, it'd be a judgment call, weighing the benefits of not being locked into a single ecosystem against the costs of losing economies of scale. I don't think I have a good general principle. I'm also not super clear on how well C# interoperates with C++; I've used both languages, but not together. The article makes it sound like it only "just works" if the entire API surface is C-compatible, which seems extremely limiting and not like something I would want to do regularly. In particular, it sounds like it'd be necessary to write wrappers on both ends, so that you have idiomatic C++ or C# everywhere except at the boundary. This is what I meant above about C++-to-Rust interop not being good enough yet—it works, but you have to go through C. Is this in fact what it's like, or can C# code automatically use C++ APIs that involve classes, RAII, templates, etc.? I don't advocate going all-in on C++ or Rust for a typical app, but rather having a setup that allows easily dropping into it in order to optimize hot paths. Performance tuning in a managed runtime is really hard and I prefer to avoid it.
- binarynate 5y ago> I tend to think of microservices as mostly good for solving organizational problems Yeah, they're frequently used for that. In the case of my cloud service, though, there are multiple pieces that are beneficial to scale independently (browser servers, WebRTC servers, functions for orchestration, and functions for the user-facing web-based administration). I also want to put as much onto AWS Lambda as possible to simplify scaling, but the stateful browser and WebRTC services can't run on Lambda. > That said, I still don't really understand why you'd use TypeScript on the server at all if you need C# for other services That's fair. One reason is that I feel that I develop the fastest with TypeScript. Another is that I develop the web front-end in TypeScript and like being able to share code for the web-related parts. Another is that I like to leverage AWS Lambda for the non-stateful parts, and Lambda's cold start times for Node are lower than those for .NET, which can help provide lower latency for user-initiated web requests. > In particular, it sounds like it'd be necessary to write wrappers on both ends, so that you have idiomatic C++ or C# everywhere except at the boundary. Yeah, you're right. The parts that C# calls must C linkage, so C++ functions must be wrapped in `extern "C"`. My understanding is that C is the lingua franca between languages because it has a simple ABI, whereas the ABI for C++ is complex and may between compilers.
- jcelerier 5y agoEvery time I tried to write an app in multiple stacks, I ended up reverting to good ole' C++ for the whole thing. It allows as much (or even more, how many languages have generics over values) abstraction and high-level specification as more recent languages and has a wealth of libraries. Even for web apps, today I just make them in Qt and cross-compile as WASM.