3 ms·
I would kill for these languages features in Go
by shepherdjerred 3y ago
I would kill for these languages features in Go
- neonsunset 3y agoThat's what C# offers (except true* Rust-style enums). The latter will be there in one of the future versions and is in an active design phase, which luckily focuses on tagged-union implementation strategy. With that said, you can already easily use one of the Option/Result libraries or write your own structure - switching on either is trivial (though you have to sometimes choose between zero-cost-ness and convenience). It already has struct generics, iterator expressions (LINQ), switch pattern matching, good C interop and easy concurrency primitives (no WaitGroup nonsense, also has Channel<T>). Oh, and also portable SIMD, C pointers and very strong performance in general. * True as in proper tagged unions with either a tag or another type of discriminant and aliased layout, instead of tag + flattening all constituent parts into a one jumbo struct. Or making it an opaque pointer to a box (like Java does, or C# if you go inheritance/interface route). These don't count. I'm curious about Borgo's lowering strategy for enums, but given Go doesn't have those, I'm not holding my breath and expecting something like F# struct unions at best.
- mdaniel 3y agoAs someone who is "C# curious," but haven't been able to keep up with all the horrific number of rebrands of the "new, open, .net, core, framework", what is the C# equivalent of $(for GOOS in linux darwin; do for GOARCH in amd64 arm64; do dotnet build -o thing_${GOOS}-${GOARCH}; done; done)?
- nrr 3y agoThat's spelled `dotnet publish -r ${GOOS}-${GOARCH}` with the new ahead-of-time (branded Native AOT) compilation features installed and enabled. It isn't without a whole list of caveats if you're used to Go's way of doing things though. See <https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/ https://learn.microsoft.com/en-us/dotnet/core/deploying/nati...> for details.
- mdaniel 3y agoYou're very kind, thank you For others wanting to play along at home: $ docker run --name net8 --rm -it mcr.microsoft.com/dotnet/sdk:8.0-jammy-arm64v8 bash -c ' cd /root dotnet new -d -o console0 console cd console0 dotnet publish --nologo --self-contained -v d -r osx-arm64 -o console0-darwin-arm64 sleep 600 ' although it didn't shake out $ docker cp net8:/root/console0/console0-darwin-arm64/console0 ./console0 $ ./console0 Killed: 9 I tried with and without --self-contained and the biggest difference was that self-contained emitted a bazillion .dll files and without just emitted the binary. I case the context isn't obvious, $(dotnet new console) is a skeleton for the infamous WriteLine("Hello, World") without doing crazy whacko stuff
- neonsunset 3y agoFor simple JIT-based but fully self-contained binaries, without adding any properties to .csproj, the command is a bit mouthful and is as follows dotnet publish -p:PublishSingleFile=true -p:PublishTrimmed=true -o {folder} (you can put -p: arguments in .csproj too as XML attrs in <PropertyGroup>...) This will give you JIT-based "trimmed" binary (other languages call it tree shaking). You don't need to specify RID explicitly unless it's different from the one you are currently using. For simple applications, publishing as AOT (without opting in the csproj for that) is dotnet publish -p:PublishAot=true -o {folder} Add -p:OptimizationPreference=Speed and -p:IlcInstructionSet=native to taste. Official docs: https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-publish#examples https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-p...
- mdaniel 3y agoYou're also very kind, and I realized that it's possible there were a bazillion "watch out"s on the docs and was just trying the <PublishAot>true trick when I saw your comment However, it seems this brings my docker experiment to an abrupt halt, and is going to be some Holy Fucking Shit to re-implement that $(for GOOS) loop in any hypothetical CI system given the resulting explosion /usr/bin/sh: 2: /tmp/MSBuildTemproot/tmp194e0a13157b47889b36abb0ce96cd2d.exec.cmd: xcodebuild: not found
- neonsunset 3y agoThe sibling comment pretty much sums it up. But if you want more detail, read on: Generally, there are three publishing options that each make sense depending on scenario: JIT + host runtime: by definition portable, includes slim launcher executable for convenience, the platform for which can be specified with e.g. -r osx-arm64[0]. JIT + self-contained runtime: this includes IL assemblies and runtime together, either within a single file or otherwise (so it looks like AOT, just one bin/exe). This requires specifying RID, like in the previous option, for cross-compilation. AOT: statically linked native binary, cross-OS compilation is not supported officially[1] because macOS is painful in general, and Windows<->Linux/FreeBSD is a configuration nightmare - IL AOT Compiler depends on Clang or MSVC and a native linker so it is subject to restrictions of those as a start. But it can be done and there are alternate, more focused toolchains, that offer it, like Bflat[1]. If you just want a hello world AOT application, then the shortest path to that is `dotnet new console --aot && dotnet publish -o {folder}`. Otherwise, the options above are selected based on the needs either via build properties or CLI arguments. I don't know which use case you have - let me know if you have something specific in mind ("Just like in Go" may or may not be optimal choice depending on scenario). [0] https://learn.microsoft.com/en-us/dotnet/core/rid-catalog https://learn.microsoft.com/en-us/dotnet/core/rid-catalog [1] https://github.com/bflattened/bflat https://github.com/bflattened/bflat (can also build UEFI binaries, lol)
- orthoxerox 3y agoIt's not the best solution, but an analyzer like [0] covers most of the cases for reference types. For enums and struct DUs in general we'll have to wait for language (or even runtime) support. [0] https://github.com/shuebner/ClosedTypeHierarchyDiagnosticSuppressor https://github.com/shuebner/ClosedTypeHierarchyDiagnosticSup...
- shepherdjerred 3y agoTo clarify, my team uses Go and prefers to stick with "idiomatic" Go. So, while we could implement our own types, there would be pushback. As an example I liked lo [0] but my team was resistant because it's not considered idomatic. If were up to me we'd be using a language with a better type system :) [0]: https://github.com/samber/lo https://github.com/samber/lo