www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Reflections on using Go instead of D

reply jfondren <julian.fondren gmail.com> writes:
Howdy,

I've been using Go recently, for the following reasons:

1. I want to quickly deploy and run a program across an 
excessively diverse
range of Linux systems and also Windows, without needing a build 
farm.

2. I'd like the program to be a completely static binary.

3. I'd like the program to make HTTPS connections and maybe query 
a local sqlite database.

4. I'd like it to not be Rust (because: my previous choice was 
Rust; this is a program that cares a lot about potentially 
malicious filenames; Rust's string type zoo was exhausting to 
deal with and I caught myself wasting tons of time on Rust 
micro-problems that didn't benefit the program).

That's it. The previous-previous choice was D, because I was 
aware that cross-compiling to Windows was possible, and because 
I'd already worked out how to use Docker and Alpine's ldc to 
build static binaries.

So, what happened with D?

Take static binaries: they're the default in Go, they're what the 
community expects, so not only does most everything work normally 
in a static build, but when dynamic linking seems to be required 
you can find that someone's already put the effort in to avoid 
it: for example, there's a Go port of sqlite: 
https://pkg.go.dev/modernc.org/sqlite

And in D?

```
RUN apk add ldc dub alpine-sdk openssl-dev zlib-dev 
llvm-libunwind-static curl-static

buildType "static" {
     dflags "--static" "-L--eh-frame-hdr"
}
```

That's part of the Dockerfile and part of the dub.sdl that 
already represent several problems overcome--I didn't know about 
that 'eh' frame flag until I was searching the forum for build 
errors. This gives me a static binary with

```
??:? <ERROR: Unable to retrieve function name> [0xffbeef]
```

spam on an uncaught exception, and I still couldn't get 
std.net.curl to not complain about being unable to dynamically 
load libraries despite it clearly having code for a static build.


There are a couple of different lessons to be taken from this, 
but the one I suggest is that D could use something like an 
application support tier list. D's a general-purpose programming 
language so you can technically do anything at all in it, so call 
"you can technically do that" tier 4 and start elaborating on 
higher tiers where a kind of program in a kind of environment is 
kind of reasonably done with some specific libraries.

e.g., want to make https requests?
1. std.net.curl is in Phobos and only needs system libcurl, 
libssl, etc.
2. vibe.vibe.requestHTTP can work with system libssl or the D 
port of Botan
3. arsd-official:http can work with system libssl, with a caveat 
about 32-bit windows

The value I would've gotten out of some clear information like 
this is that I would've started with vibe+botan and maybe not 
have had any problems at all. As it was, when I realized I hit a 
wall, I'd already wasted tons of time and didn't want to risk 
wasting any more time even seeing if vibe would work. The value 
of such information for users of D is that it alleviates that 
fear, so that other languages are no longer the safe option.

The value of such information for D devs or D advocates is
1. it encourages use of D where D is already a pretty good option
2. it encourages users to be more prepared to help advance the 
language if they're consciously doing something that D has little 
support for

D has little support for, getting burned by the lack of support, 
and going away
4. it highlights support gaps as room for improvement that isn't 
DIPs or fixing bugs

With all that said, I don't think I've seen any language produce 
such a thing. My actual inspiration was Zig's release tierlist 
which is only about the compiler and standard library's 
suitability for different architectures.

Another lesson is obviously "you should have multiple languages 
in your toolbox and Go is just super good at this one thing and 
you can use D or other languages for other things", but this 
perspective doesn't leave much room for D in the end.
Jul 11 2022
next sibling parent reply AnimusPEXUS <animuspexus protonmail.com> writes:
On Tuesday, 12 July 2022 at 02:42:00 UTC, jfondren wrote:
 Howdy,
I've stopped using Go somewhere at middle 2021 and I used it from 2016. and I think Go code generation (templating/go generate) is awful and I'm won't going back. If I'll go somewhere from D , it will be Rust or C++ in both cases because of job opportunities. As for topic "Go vs D", well, Go's basic interfacing strategy (like IO interface) is somewhat more unified and channels, `select{}` blocks are also makes life much easier. also, maybe, ImportGo in D would be fun :D
Jul 11 2022
parent reply Siarhei Siamashka <siarhei.siamashka gmail.com> writes:
On Tuesday, 12 July 2022 at 04:52:33 UTC, AnimusPEXUS wrote:
 I've stopped using Go somewhere at middle 2021 and I used it 
 from 2016. and I think Go code generation (templating/go 
 generate) is awful and I'm won't going back.
Have you stopped using Go before or after the 1.18 release, which introduced generics? Something like https://blog.boot.dev/golang/how-to-use-golangs-generics/
 If I'll go somewhere from D , it will be Rust or C++ in both 
 cases because of job opportunities.
Are you generally trying to use a single language for everything or do you switch between multiple languages depending on the task? Is your current use of D a paid job? I agree that when the job requires some specific programming language, then not much can be done about it. We can't just pick a single language and stick with it. Being familiar with multiple programming languages is a practical necessity nowadays.
Jul 11 2022
parent reply user1234 <user1234 12.de> writes:
On Tuesday, 12 July 2022 at 05:23:12 UTC, Siarhei Siamashka wrote:
 On Tuesday, 12 July 2022 at 04:52:33 UTC, AnimusPEXUS wrote:
 I've stopped using Go somewhere at middle 2021 and I used it 
 from 2016. and I think Go code generation (templating/go 
 generate) is awful and I'm won't going back.
Have you stopped using Go before or after the 1.18 release, which introduced generics? Something like https://blog.boot.dev/golang/how-to-use-golangs-generics/
From what I've read Go generics are not fully monomorphic. I've read there's a layer of indirection for non-basic types. Maybe that's what AnimusPEXUS meant by "aweful" ?
Jul 12 2022
parent user1234 <user1234 12.de> writes:
On Tuesday, 12 July 2022 at 07:16:59 UTC, user1234 wrote:
 On Tuesday, 12 July 2022 at 05:23:12 UTC, Siarhei Siamashka 
 wrote:
 On Tuesday, 12 July 2022 at 04:52:33 UTC, AnimusPEXUS wrote:
 I've stopped using Go somewhere at middle 2021 and I used it 
 from 2016. and I think Go code generation (templating/go 
 generate) is awful and I'm won't going back.
Have you stopped using Go before or after the 1.18 release, which introduced generics? Something like https://blog.boot.dev/golang/how-to-use-golangs-generics/
From what I've read Go generics are not fully monomorphic. I've read there's a layer of indirection for non-basic types. Maybe that's what AnimusPEXUS meant by "aweful" ?
Source : https://planetscale.com/blog/generics-can-make-your-go-code-slower
Jul 12 2022
prev sibling next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 12 July 2022 at 02:42:00 UTC, jfondren wrote:
 Another lesson is obviously "you should have multiple languages 
 in your toolbox and Go is just super good at this one thing and 
 you can use D or other languages for other things", but this 
 perspective doesn't leave much room for D in the end.
Most popular languages are good for some specific purpose. D has some of the same issues as C++/C, but those languages are best when used with other languages, which makes them versatile ( by adoption frequency ). D and Go try to be versatile on their own, but that requires a significant effort. Go has succeeded for some domains by putting in that focused effort. If being versatile and productive are the most important metrics then Python is hard to beat... In reality, most application software could be done in Python + TypeScript + C with good user satisfaction, but bridging between langages feels tedious so developers look for that one solution...
Jul 12 2022
prev sibling next sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Tuesday, 12 July 2022 at 02:42:00 UTC, jfondren wrote:
 2. I'd like the program to be a completely static binary.
This generally isn't worth the effort. Just using the oldest glibc you want to support and dynamic loading openssl will generally achieve the same task - newer glibcs tend to work with programs built against older ones, but not vice versa. So building something on a new distro makes it look really incompatible, but building on an old one works fine. I've also never actually seen a Go program be a static build...
 Take static binaries: they're the default in Go,
idk maybe it is just my system but this is an out-of-the-box go install with all the default settings: me arsd:~/test$ go build hello.go me arsd:~/test$ ./hello hello world from go me arsd:~/test$ ldd ./hello linux-vdso.so.1 (0x00007ffe1fff6000) libgo.so.14 => /usr/lib64/libgo.so.14 (0x00007fdee7566000) libm.so.6 => /lib64/libm.so.6 (0x00007fdee7419000) libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007fdee73ff000) libc.so.6 => /lib64/libc.so.6 (0x00007fdee721a000) /lib64/ld-linux-x86-64.so.2 (0x00007fdee8cb5000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fdee71f8000) That's nearly identical to D: me arsd:~/test$ dmd hellobasic.d me arsd:~/test$ ldd hellobasic linux-vdso.so.1 (0x00007fff4bdd0000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f52dcb50000) libm.so.6 => /lib64/libm.so.6 (0x00007f52dca03000) librt.so.1 => /lib64/librt.so.1 (0x00007f52dc9f9000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f52dc9f4000) libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007f52dc9da000) libc.so.6 => /lib64/libc.so.6 (0x00007f52dc7f5000) /lib64/ld-linux-x86-64.so.2 (0x00007f52dcbce000) Can you do that test on your computer? Maybe it is just a config thing in my setup.
 3. arsd-official:http can work with system libssl, with a 
 caveat about 32-bit windows
Oh that's actually an obsolete note, I should remove that. I fixed it last year so it just works now. BTW one of the problems with ssl is you also need the certificates... it is unlikely to work correctly with a self-contained static build anyway. I wonder just how Go does it...
Jul 12 2022
next sibling parent ryuukk_ <ryuukk.dev gmail.com> writes:
On Tuesday, 12 July 2022 at 12:42:50 UTC, Adam D Ruppe wrote:
 BTW one of the problems with ssl is you also need the 
 certificates... it is unlikely to work correctly with a 
 self-contained static build anyway. I wonder just how Go does 
 it...
Are you sure about this? I static link openssl on windows, and i have no problems dealing with HTTPS/WSS urls, i'm not an expect there, but to me it just works (server has free letsencrypt certificates, maybe that's why, i still have no clue how all this works today lol)
Jul 12 2022
prev sibling parent reply jfondren <julian.fondren gmail.com> writes:
On Tuesday, 12 July 2022 at 12:42:50 UTC, Adam D Ruppe wrote:
 This generally isn't worth the effort. Just using the oldest 
 glibc you want to support and dynamic loading openssl will 
 generally achieve the same task
This is very fair, but with Go *my* effort is minimal enough that it's worth it to not deal with the problem at all, and it's not zero-effort either to use the oldest glibc I want to support. If I had a legitimately old system I'd have to find an old enough dmd to work on it, and building an old glibc on a new system sounds like a pain: https://www.lordaro.co.uk/posts/2018-08-26-compiling-glibc.html Still, this probably would've worked out a lot better than trying to work with static D.
 idk maybe it is just my system but this is an out-of-the-box go 
 install with all the default settings:
Is that OpenBSD? On some platforms Go gave up on static builds because the ABI was too unstable (OpenBSD) or wrong for other reasons (macOS). On Linux the default is "not a dynamic executable", and you'd have to pull in a C library dependency to break that.
 BTW one of the problems with ssl is you also need the 
 certificates... it is unlikely to work correctly with a 
 self-contained static build anyway. I wonder just how Go does 
 it...
It cheats and grabs system certs from standard locations.
Jul 12 2022
parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Tuesday, 12 July 2022 at 13:31:56 UTC, jfondren wrote:
 If I had a legitimately old system I'd have to find an old 
 enough dmd to work on it
Yeah, I hit that once, it is a bit of a pain. But just keeping around a thing from a few years ago tends to work pretty well most the time.
 Is that OpenBSD?
Slackware Linux. Maybe they did a different configure flag but their general policy is to closely follow upstream. But even Go applications I've downloaded from other sources follow the same pattern... oh well. I do know someone was using the musl libc with D (they sent me bug reports about cgi.d i had to fix to be compatible with it), idk the details though. Maybe we should make an article about that.
 It cheats and grabs system certs from standard locations.
Yeah, I added support for pulling Windows certs out of the system to my http2.d somewhat recently too... I think that was this year. So it can use both the openssl bundles and the separate Windows set. Worked really pretty well. My lib also dynamic loads and detects incompatible versions, so it can adapt to 1.0 or 1.1 and such at runtime and just work. But then openssl put out a 3.0 which has more random troubles. Ugh. But I'll prolly be able to adapt to that at some point too. Still, I've found dynamic loading openssl is the best way to use it - static versions get outdated and websites move on to different algorithms, load-time linking hits incompatibilities. So runtime branching, while more work, gives best results.
Jul 12 2022
parent SealabJaster <sealabjaster gmail.com> writes:
On Tuesday, 12 July 2022 at 14:26:45 UTC, Adam D Ruppe wrote:
 My lib also dynamic loads and detects incompatible versions, so 
 it can adapt to 1.0 or 1.1 and such at runtime and just work.

 But then openssl put out a 3.0 which has more random troubles. 
 Ugh. But I'll prolly be able to adapt to that at some point too.

 Still, I've found dynamic loading openssl is the best way to 
 use it - static versions get outdated and websites move on to 
 different algorithms, load-time linking hits incompatibilities. 
 So runtime branching, while more work, gives best results.
Slightly off topic, but I've found https://github.com/Mbed-TLS/mbedtls a lot easier to work with than OpenSSL. I like having things as statically linked as possible, and OpenSSL was a pain to say the least to get working with Meson. MbedTLS was still a bit of a pain, but wasn't as _much_ of a pain. Also I struggled quite a lot getting dstep to fully work with OpenSSL. It works without issue on MbedTLS.
Jul 12 2022
prev sibling next sibling parent reply SealabJaster <sealabjaster gmail.com> writes:
On Tuesday, 12 July 2022 at 02:42:00 UTC, jfondren wrote:
 Howdy,

 I've been using Go recently, for the following reasons:

 1. I want to quickly deploy and run a program across an 
 excessively diverse
 range of Linux systems and also Windows, without needing a 
 build farm.
I definitely wish it were a bit easier to get this done.
 2. I'd like the program to be a completely static binary.
I tried a while back to make a core -betterC library that didn't need libc, but kind of dropped it since 1. I had no idea what I was doing at the best of times, and 2. I was running into an issue I had no idea or willpower to fix.
 3. I'd like the program to make HTTPS connections and maybe 
 query a local sqlite database.
This is especially true with -betterC. I've taken a strange liking to it despite being a GC-fanboy. I'm currently working on a private -betterC library to handle my needs (HTTP client with SSH capabilities; threaded HTTP server with a request pipeline; datastructures because hashmaps, arrays, and dynamic strings are apparently too high a bar for native -betterC support in Phobos...)
 ...
Don't have much else to comment, but just wanted to let you know I read the rest :) I'd like to also add: While I love writing Go, I hate certain aspects of it that D might really shine through in: * I hate that mocking libraries are either external code generation tools or just look and feel like hacks. * Similarly, writing tests in Go, while it's streamlined similar to how D has `unittest`, the tests themselves can be quite strainful to write. Ginkgo and Gomega make it a lot better, but there's still room for improvement. * While generics have made the issue a lot less painful, it's still not nice having to make things an `interface{}/any` just to have some form of reusability in algorithms. Also god I love how easy Goroutines are to use.
Jul 12 2022
next sibling parent SealabJaster <sealabjaster gmail.com> writes:
On Tuesday, 12 July 2022 at 15:56:39 UTC, SealabJaster wrote:
 ...
Sorry for the triple post but there's also one last thing that sticks out to me: Go provides a parser for the language within the standard library, which I imagine makes it much easier for tooling to be created and maintained.
Jul 12 2022
prev sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 12 July 2022 at 15:56:39 UTC, SealabJaster wrote:
 * I hate that mocking libraries are either external code 
 generation tools or just look and feel like hacks.
How is this better in D? A mocked unit should be a drop in replacement...
 * Similarly, writing tests in Go, while it's streamlined 
 similar to how D has `unittest`, the tests themselves can be 
 quite strainful to write.
In what way? D’s `unittest` does not do much? I usually don’t use testing libraries as writing my own does not take much time. Unless you want automated integration tests for user interfaces...
 * While generics have made the issue a lot less painful, it's 
 still not nice having to make things an `interface{}/any` just 
 to have some form of reusability in algorithms.
Are you talking about generic libraries? Reusable algorithms tend not to be a big issue for applications? What kind of software do you build? What I dislike is the auto generated documentation. D also has this issue. Well written docs are so much better. Write the docs when speccing out the API! Using doc generation for a standard library is just a terrible idea. Three reasons to dislike Go: no real exceptions, lacking inheritance, annoying API docs (or APIs). Builtin concurrency is good, but I seldom would use go routines in practice, so not sure if it is the best concept for «system» programs.
Jul 12 2022
next sibling parent jfondren <julian.fondren gmail.com> writes:
On Wednesday, 13 July 2022 at 05:39:24 UTC, Ola Fosheim Grøstad 
wrote:
 * Similarly, writing tests in Go, while it's streamlined 
 similar to how D has `unittest`, the tests themselves can be 
 quite strainful to write.
In what way? D’s `unittest` does not do much?
In D you have a unittest block, you put some code and assert()s in it, you're done. D requires more work if you want some passed unittests" for however many specific tests accomplished, or nicer handling of failure). Go has a more featureful test runner by default, but it doesn't have assert(), you need reflect.DeepEqual for cases that would just be == in d, you don't have an analog of std.exceptions' assertThrown and assertNotThrown. So instead of an instant ```d unittest { assert(f(1) == 2); } ``` right with your f() definition, you tend to have something like this in another file: ```go func TestF(t *testing.T) { want := 2 got := f(1) if want != got { t.Errorf("f(1) = %v; wanted %v", got, want) } } ``` and then ```go func testF(t *testing.T) { assert := func(fmt string, want int, got int) { if want != got { t.Errrof(fmt, got, want) } } assert("f(1) = %v; wanted %v", f(1), 2) assert("f(2) = %v; wanted %v", f(2), 3) } ``` and then maybe you realize that assert() should be calling f() in this case so that you can loop over a large range of inputs, so you write more of your own test framework code which feels very natural to do (and is more work to do). And actually, this Go is not already not comparable to D as this will give you nice messages instead of "file.d(123): [unittest] unittest failure" which just tells you what file and line to look at. Comparable Go would just be ```go func TestF(t *testing.T) { if f(1) != 2 { t.Fail() } } ``` which is *still* providing a readable test name. And after you've written all this code, it's just unnatural to not at least use t.Errorf() None of this is a huge chore. Nor is D's super-minimal testing an attractive thing to stick with as projects grow vs. switching to silly or unit-threaded or the like. But the minimal amount of effort demanded to have tests is definitely higher in Go. The result should be that random Go tests, when you have them, are more professional and useful than random D tests, but that random D code is more likely to have tests. Certainly if you have some trivial single-file utility, Go already needs a second file dub script that performs its trivial utility function by default and then can be called in a special way to run its tests.
Jul 13 2022
prev sibling parent reply jfondren <julian.fondren gmail.com> writes:
On Wednesday, 13 July 2022 at 05:39:24 UTC, Ola Fosheim Grøstad 
wrote:
 What I dislike is the auto generated documentation. D also has 
 this issue.

 Well written docs are so much better. Write the docs when 
 speccing out the API!

 Using doc generation for a standard library is just a terrible 
 idea.
In both languages it's possible for a tech writer to put a lot of well written documentation around the autogenerated stuff. Rust's stdlib docs are also 'generated' and they're steller, and all that prose is in giant comments in the files: https://doc.rust-lang.org/std/index.html Having an amount of doc generation permits nice tooling to go with all that well written text that somebody could write if they wanted. For example from go, given this file: ```go package main import "fmt" // add 1 to a number func f(n int) int { return n + 1 } func main() { fmt.Println(f(1)) } ``` You can query its documentation at the command line: ``` go$ go doc -u f func f(n int) int add 1 to a number go$ go doc -u main func main() go$ go doc fmt.Println package fmt // import "fmt" func Println(a ...any) (n int, err error) Println formats using the default formats for its operands and writes to standard output. Spaces are always added between operands and a newline is appended. It returns the number of bytes written and any write error encountered. ``` which could exist for D, or rather it probably does between dmd -D and dscanner and other IDE support that just isn't as immediate.
Jul 13 2022
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 13 July 2022 at 07:56:14 UTC, jfondren wrote:
 In both languages it's possible for a tech writer to put a lot 
 of well written documentation around the autogenerated stuff.
I don’t use Rust, but autogenerated tend to lead to poor structure, too long documents (or too small). I don’t want bloat, I want just the right info at the right time with the ability to request more details when needed without scrolling... Good documentation is difficult to create, but worth it as standard libs dont change much.
 Rust's stdlib docs are also 'generated' and they're steller, 
 and all that prose is in giant comments in the files: 
 https://doc.rust-lang.org/std/index.html
Ok, looks bloated on this iphone, but I haven’t used it so it might be ok in real use. It provides examples, which is good, but I don’t want examples unless I request it... I want documentation that expands on the topic on my request. I understand that this cannot be done for regular libs, but I think one can raise the bar for std libs.
Jul 13 2022
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 13 July 2022 at 08:21:53 UTC, Ola Fosheim Grøstad 
wrote:
 Ok, looks bloated on this iphone, but I haven’t used it so it 
 might be ok in real use.
Just look at the documentation for something as simple as Vec: https://doc.rust-lang.org/std/vec/struct.Vec.html You can click the «[-]» to collapse it, but it is still many many maaaany pages with no topical breakdown. So you have to scroll-scroll-scroll and skim-skim-skim to find something that might fit what you need for a basic vector? When you expand it you get a big bulk of text, most of which I don't need and shouldn't be in a reference guide. This is why I would say that the documentation should be written when the API is designed. If the resulting «ideal» documentation becomes this verbose and hard to skim through then that could mean that the API/abstraction is flawed or too complex. In the case of Vec, it is more likely the documentation that is too bloated and lacks organizing. Writing good documentation is difficult…
Jul 13 2022
prev sibling parent Paulo Pinto <pjmlp progtools.org> writes:
On Wednesday, 13 July 2022 at 08:21:53 UTC, Ola Fosheim Grøstad 
wrote:
 On Wednesday, 13 July 2022 at 07:56:14 UTC, jfondren wrote:
 [...]
I don’t use Rust, but autogenerated tend to lead to poor structure, too long documents (or too small). I don’t want bloat, I want just the right info at the right time with the ability to request more details when needed without scrolling... Good documentation is difficult to create, but worth it as standard libs dont change much.
 [...]
Ok, looks bloated on this iphone, but I haven’t used it so it might be ok in real use. It provides examples, which is good, but I don’t want examples unless I request it... I want documentation that expands on the topic on my request. I understand that this cannot be done for regular libs, but I think one can raise the bar for std libs.
Rustdoc examples also work as unit tests, which means they are always in sync with the code https://doc.rust-lang.org/rustdoc/write-documentation/documentation-tests.html
Jul 13 2022
prev sibling parent reply Bienlein <ffm2002 web.de> writes:
If Go fullfils your performance requirements you can also get 

options. Java19 now also has what they call "virtual threads" 
which are made to deliver the same as Goroutines (comunicating 
sequential processes). See project Loom: 
https://openjdk.org/projects/loom/
Jul 13 2022
parent reply ryuukk_ <ryuukk.dev gmail.com> writes:
On Wednesday, 13 July 2022 at 11:52:45 UTC, Bienlein wrote:
 If Go fullfils your performance requirements you can also get 

 options. Java19 now also has what they call "virtual threads" 
 which are made to deliver the same as Goroutines (comunicating 
 sequential processes). See project Loom: 
 https://openjdk.org/projects/loom/
As well as Valhalla, Tagged Union, Pattern Matching, Foreign Memory Access, GraalVM AOT compiler They are willing to dust their house and move forward to catch up We have lot to learn from that, and that'll be interesting to see if that'll be enough to give Java a new fresh life like Python 3
Jul 13 2022
parent ryuukk_ <ryuukk.dev gmail.com> writes:
On Wednesday, 13 July 2022 at 20:58:34 UTC, ryuukk_ wrote:
 On Wednesday, 13 July 2022 at 11:52:45 UTC, Bienlein wrote:
 If Go fullfils your performance requirements you can also get 

 options. Java19 now also has what they call "virtual threads" 
 which are made to deliver the same as Goroutines (comunicating 
 sequential processes). See project Loom: 
 https://openjdk.org/projects/loom/
As well as Valhalla, Tagged Union, Pattern Matching, Foreign Memory Access, GraalVM AOT compiler They are willing to dust their house and move forward to catch up We have lot to learn from that, and that'll be interesting to see if that'll be enough to give Java a new fresh life like Python 3
Programming languages are like traditional languages, they must evolve and adapt otherwise they slowly die with demography Go also was willing to adopt generics despite being against it at the beginning, that proves the point above
Jul 13 2022