July 12, 2022
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.
July 12, 2022

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.

>
  1. 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.

>
  1. 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.

July 12, 2022

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.

July 13, 2022

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.

July 13, 2022

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 features from the test runner (like nicer output than "# modules 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

unittest {
    assert(f(1) == 2);
}

right with your f() definition, you tend to have something like this in another file:

func TestF(t *testing.T) {
    want := 2
    got := f(1)
    if want != got {
        t.Errorf("f(1) = %v; wanted %v", got, want)
    }
}

and then

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

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 just to have the tests, but with D you can make a #! /usr/bin/env dub script that performs its trivial utility function by default and then can be called in a special way to run its tests.

July 13, 2022

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:

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.

July 13, 2022

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.

July 13, 2022

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…

July 13, 2022

If Go fullfils your performance requirements you can also get along with Java or C#. In that way D and Rust are not the only 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/

July 13, 2022

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