6 ms·
I used to think so too, until I tried Rust. By comparison, JavaScript (and by extension, TypeScript) is still lacking fundamental features and the library ecos
by spion 4y ago
I used to think so too, until I tried Rust.
By comparison, JavaScript (and by extension, TypeScript) is still lacking fundamental features and the library ecosystem situation is pretty bad.
I wish there was a modern language that took all the good non-manual-memory-management things from Rust and added a GC and some immutable data structures. Error handling, enums, macros (with compile_error! / diagnostics API), traits / approach to OOP, embedded tests, doctests and the relentless determination to add examples in the docs in general... Everything in Rust feels like "oh, they got this right too", which hasn't been the case for any other typed lanuage I've used in the past 15 years (including typescript, my previous favorite; purescript; go; haskell)
- deleted 4y ago[deleted]
- jdthedisciple 4y agoHave you tried C#? Sounds like it would fit your needs perfectly, additionally benefitting from a huge ecosystem behind it.
- rrishi 4y agoHow does the verbosity in C# compare to Java's? And are big C# codebases littered with annotations and "dependency inversion" Java Spring boilerplate-y crap? I ask because I have never delved into C# only heard it's Microsoft's Java. And I am no fan of the original Java at all so C# gives me pause.
- tester756 4y agoWe don't do annotation-oriented-programming in C# DI is almost always in web, but via constructor instead of annotations.
- theshrike79 4y agoC# is pretty much Java done right. Speaking as someone who started with Java 1.2 and saw all the crap that happened to it. C# is currently lightyears ahead of Java in every way, especially now that MS is not Micro$oft to people on the internet any more =)
- kaba0 4y ago> C# is currently lightyears ahead of Java in every way Let’s not claim things that can’t be objectively proven. C# does have much more features than Java, but that is not necessarily a plus in case of a programming language. There are features that are definitely better, but I am not bought that the whole would be. Plus, ecosystem-wise Java is much bigger and much more open-source. The runtime is also better on the JVM-side, though this is offset by C# expressing more low level details.
- postdb 4y agoAlso C# is really meant to run on MS servers (Azur). Yes you can compile C# asp core projects on Linux, but the hell of dll when the there are many projects in a solution is quit annoying. Development experience in C# without Visual Studio is quite cumbersome.
- theshrike79 4y agoNope. This is the M$ == bad era thinking. I've been doing C# on a MacBook with JetBrains Rider for years. Some code runs in Linux containers, some on AWS Lambda.
- pjmlp 4y agoNope, see you're using Rider, because VS4Mac and VSCode only offer a subset of Visual Studio capabilities for .NET development. I rather do .NET than Java, but the FOSS story isn't as Microsoft sells it, hence why on our agency .NET is mostly used on Windows projects, and usually loses against Java or node in UNIX like RFP, even after .NET Core reboot, because of dependencies and existing enterprise tooling.
- deleted 4y ago[deleted]
- cutler 4y agoC#11 defaults to nullability and has top-level functions giving it a big advantage over Java. The idiomatic Pascal case takes some getting used to but it's worth it.
- rrishi 4y agoThanks for the overview. Hopefully I can give the language a shot when time permits.
- WorldMaker 4y agoRecent versions of C# have expressly been working to minimize/eliminate verbosity. Things like namespace statements (rather than { } blocks), global usings, top-level statements, record types (by default structurally compared, immutable data structures defined often only by their constructor and nothing else), and much more. Similarly recent libraries such ASP.NET have been working hard to use more of these things to eliminate their own boilerplate. The latest ASP.NET templates use top-level statements and some global usings and are getting very lightweight in terms of starter-level code. .NET does have annotations and dependency inversion, but those too tend to avoid boilerplate more than create it. Few annotations are "required", depending on your domain and which libraries you are expecting to use. .NET now has a single, mostly standardized dependency injector that almost everyone has agreed to use (Microsoft.Extensions.DependencyInjection) at this point. It intentionally only supports a bare minimum of Dependency Injection needs and is nothing like the Kitchen Sink approach of something like Java's Spring. (For instance, zero out of the box support for wiring Dependency Injection via XML files. .NET's DI is always code driven, often in a Startup.cs, Program.cs, App.cs, or Main.cs file.) I've been increasingly finding in C# that I'm writing new code with zero templates and almost no snippets-expansion. (There will always be plenty of legacy code out there with much more verbosity, of course.) The easiest suggestion is to try it for yourself. The `dotnet` tool is cross-platform, generally an easy install, and its `dotnet new` command will help you try many easy template types. You can relatively easily work entirely in VS Code today (as opposed to older versions of C# often "needed" the full bulky Visual Studio install for templates, language servers, and other stuff).
- rrishi 4y agoThank you for such a well written and detailed response. Gave me a fair representation of C#. I do hope to try it maybe in recent future.
- MrJohz 4y agoC# doesn't have algebraic data types and pattern matching though, right? I'm not the same person, but at least for me that's one of the big advantages of Rust, and it's one of those features that outside of Rust you only really find in ML-family languages. I know it's possible to simulate it partially using sealed classes in some languages, but that's always seemed like a lot of boilerplate in comparison.
- roebk 4y agoPattern matching was recently added to C#. I can't say quite how well it's been embedded into the language. I always hear great things about F#, ADTs, pattern matching, nice type system and it integrates nicely into the rest of the .NET ecosystem.
- WorldMaker 4y agoC# has a lot of pattern-matching support today, including an expression-switch form: https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/pattern-matching https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals... C# can fake algebraic data types in some ways/some cases. Though if you are expecting to do a lot of it you are still better off in F# or C#/F# hybrid projects. (F# of course being a proper ML-family language.)
- virtualwhys 4y ago> it's one of those features that outside of Rust you only really find in ML-family languages Or in Scala, technically not an ML, but is as close as you'll get in a nominally typed language. enum RGB: case Red, Green, Blue def log(x: RGB) = x match case Red => print("red") case Green => print("green") // error, not exhaustive Obviously Scala can do a lot more, including GADTs, which Rust will never have until HKTs are supported. Ton of powerful languages to choose from these days, good times...
- spion 4y agoI did, and I should've listed it. Its my third favorite typed language. At the time I was trying it, its type system wasn't as expressive as TS is today (no algebraic data types, no Result<T> error modelling in the type system etc), but LINQ with its clean syntax and ease of use is something I've missed in every language since (scala `for` syntax looks really awkward by comparison).
- felipeccastro 4y agoHave you tried Crystal? I got the same "oh, they got this right too" feeling about everything as well.
- christophilus 4y agoCrystal is excellent. I just can’t handle the sluggish compilation times. Has that improved?
- felipeccastro 4y agoNope, but working with fewer/smaller dependencies (like Kemal) it seems more manageable. Also, the feedback from type system is much faster than the full build, so I've noticed I don't need to run the app to test every small change like I do with ruby. There is also an interpreter mode available for testing, but I haven't tried it yet since that currently requires building the language from source. I'm hoping the interpreter will solve that DX issue entirely once it's ready.
- jpgvm 4y agoFor me that's Kotlin. It's my general purpose language. I also use Rust everywhere Kotlin isn't suitable.
- evntdrvn 4y agoThat’s basically F#. It’s great.
- epolanski 4y agoWell he said better than most, not best of every.
- hatuthecat 4y agoYou’re basically describing Swift. Swift and Rust had a ton of cross pollination during their early years which led to those features developing similarly but memory management is a lot less targeted for extreme efficiency like Rust. Hopefully as the language continues to mature, the feasibility to use it outside of apple platforms also does because I really enjoy the language design.
- noisy_boy 4y agoDoes Swift has pattern matching and equivalent of Option/Result enums? I tried it casually but the documentation didn't feel great and things felt like they assumed familiarity with Apple's ecosystem.
- valleyer 4y agoPatterns: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/patterns/ https://docs.swift.org/swift-book/documentation/the-swift-pr... Optionals: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics#Optionals https://docs.swift.org/swift-book/documentation/the-swift-pr... Result: https://developer.apple.com/documentation/swift/result https://developer.apple.com/documentation/swift/result
- runeks 4y agoSwift also supports enumerations with associates values, which is super useful: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/enumerations/#Associated-Values https://docs.swift.org/swift-book/documentation/the-swift-pr...
- noisy_boy 4y agoThanks for the links - I did the Swift Tour and the language has indeed come a long way since I tried it last time; quite expressive and nice to write in. Hopefully it gains traction in non-Apple circles as well.
- iainmerrick 4y ago
- jiggawatts 4y agoI've been saying the same thing: We need an ahead-of-time compiled high level, business language. Something as efficient as Rust, but not designed for embedded microcontrollers or systems software. I feel like the entire industry has had a "kneejerk reaction" to C++ and its abysmally slow compile times. Everyone jumped onto the interpreter bandwagon and ended up throwing the baby out with the bathwater. It is definitely possible to have sub-second compile times for large, complex software! Just look at Jonathan Blow's Jai language. He can recompile and reload an entire 3D game engine in about that time. We can have our cake and eat it to. We can have efficient, compiled languages and still have safety and fast compilation.
- kaba0 4y ago> Everyone jumped onto the interpreter bandwagon I can only think of Ruby and Python that use a strictly interpreter mode (in their most common runtime). Java, C# use a hybrid solution, but for all practical purposes they are running as extremely efficient machine code, how is it not “efficient business language”?
- jiggawatts 4y agoThey're both JIT compiled, not ahead-of-time compiled. This severely limits the type of optimisations that they can perform, because they have to do it "on the fly" during runtime.
- kaba0 4y agoBeing pedantic, both have AOT compilers readily available. But sure, though I don’t really buy the argument that JIT compilers would “severely limit” the type of optimizations - there is no significant performance difference - if any - between AOT compiled managed languages and JIT-compiled ones. Sure, there are more constraints in case of a JIT, but it’s not like going in the other direction and letting gcc/clang chew 10x time more on the same program would give you a significant speedup, if any. Speculations (which are not possible AOT) may even reverse the fields. D, Haskell, OCaml, Go are all in the same ballpark as Java and C#, and even JS, hell, they may be better.
- kaba0 4y agoScala 3, or perhaps OCaml.
- cmrdporcupine 4y agoYou just described OCaml or StandardML. Or as others have said, F#, or maybe Scala. Or if you're feeling really brainy, Haskell. But Rust was, in its early days, basically inspired by the ML type system, its type inference model, and its pattern matching facilities. The first Rust compiler was written in OCaml.
- spion 4y agoHaskell doesn't (or didn't last time I tried it) have the documentation and example culture of Rust.
- laurencerowe 4y ago> I wish there was a modern language that took all the good non-manual-memory-management things from Rust and added a GC and some immutable data structures. This basically describes all of the recent ML – perhaps more specifically OCaml – influenced languages like Kotlin, Swift, F#. (Rust is also heavily influenced by OCaml but its distinguishing feature is manual memory management with lifetimes.) I do wish we had a good Linux/Posix option with as good of a package manager as Rust's cargo. Kotlin and Swift have some support but are largely focussed on the JVM and MacOS respectively. OCaml itself is of course an option here but its syntax and smaller ecosystem is a stumbling block. Reason is an attempt at a more familiar syntax for OCaml but that community is mostly focussed on transpilation to JavaScript with ReScript.
- spion 4y agoIts not quite that simple. Some of the things that Rust gets right are subtle, but typically punted by many other languages. Documentation containing fully working examples due to thos examples being run by doctests, for example, is kinda rare. Here is another more subtle but important example: flexible API for error conversion, powerful language features and macros together enable the language, in conjunction with libraries like https://docs.rs/anyhow/latest/anyhow/ https://docs.rs/anyhow/latest/anyhow/ which gets you the best of all worlds in error handling: concise `?` operator for writing error handling code, eas to add additional message context (using `with_context` from anyhohw), differentiating between functions that can and cannot throw in the types (Result<T>), and the ability to get exception style backtraces from Result, too (that last one seems to be rare) Another subtle QoL which is often overlooked when implementing macros: `compile_error!` (and soon even more powerful diagnostic API). With that, macros can report custom errors back to the programmer via the compiler and language service, rather than becoming an incomprehensible mess. For example, the peg parser macro will mark errors with infinite left-recursive rules that don't have caching set up with custom error messages.
- spion 4y agoAnd yeah I totally agree with you regarding `cargo`, in my mind thats also one of the things that don't seem to be related to the language but the quality of life improvements end up being huge.