HN user

ntrel

11 karma
Posts0
Comments15
View on HN
No posts found.
Checked C 4 years ago

D doesn't store capacity in each slice. This allows a slice to fit in registers more often. Instead for GC allocated slices, the GC will store metadata before the first element of the allocation. That does make it slower to access, particularly when the slice points past the first element, but it is cached to speed up repeated accesses to the same allocation. Repeated appending can be further speeded up by using a dedicated Appender type.

Checked C 4 years ago

Because Go designers don't like OOP and didn't want low-level system programming as core features. They also were not keen on generic programming. Basically they wanted a simpler language. (Then they realized generics are useful, ironically their constraints add complexity). Also they wanted a segmented stack and coroutines + channels as language features.

Checked C 4 years ago

This compiles:

    ref ubyte[n*2] requires_ptr_twice_as_large_as_input(uint n)
    (
        const ref ubyte[n] input,
        ref ubyte[n*2] output,
    ) {
        output[0..n] = input[0..n];
        output[n..2*n] = input[0..n];
        return output;
    }

    void main()
    {
        ubyte[10] input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        ubyte[20] output;
        requires_ptr_twice_as_large_as_input!(10)(input, output);

        import std.stdio;
        writeln(output);
        assert(output == input ~ input);
    }

Why is your proposal better than this:

  import std.sumtype;
  
  void main(){
   struct A { int a; }
   struct B { string b; }
   struct C { bool c; }
   
   alias TaggedUnion = SumType!(A, B, C);
   
   auto tgu = TaggedUnion(B("hi"));
   int i = tgu.match!(
    (A a) => a.a,
    (B b) => b.b.length,
    (C c) => c.c * 5
   );
   assert(i == 2);
  }
If you miss out a `match` handler for any of A, B, C you get a compile-time error. Or you can use a generic handler which will be instantiated for any type not explicitly handled. https://dlang.org/phobos/std_sumtype.html

Arrays and slices really have nothing to do with generic programming. Java has poor generic support (type erasure) and C++ has poor syntax and a bad design for iterators. Languages with decent generics support have none of these problems.

If this is 'armchair criticism' why do Go's designers say they are considering adding generics support?

Lack of generics does not ease development speed. Generic programming is about safe reusability. (Development speed includes the test, debug, fix cycle).

No generics actually harms code clarity and destroys type safety.

Go is boring 14 years ago

> C++ has the best (imperative) language support for templates

D's template support is far superior: static if, constraints, compile-time function execution, string mixins, opDispatch. These features make templates much more practical and more powerful.

Go at SoundCloud 14 years ago

The problem is it's no better than C - the correct way is to return sum types, either values or errors. A good language would statically check that any returned values are only used when there are no errors, preventing invalid values being accessed.

This requires some flow analysis, but brings real benefit and safety.

Rust 0.3 released 14 years ago

> D's garbage collection is global, and either off or on

That makes it sound like you can't use GC and manual memory management together; you can - std.container uses manual memory management internally for max efficiency.

Rust 0.3 released 14 years ago

> things that were mutable are still mutable

`string` is immutable. You can use immutable everywhere if you like. C++ doesn't even have transitive const.

> templates are still templates

With constraints, unlike C++.

> hard-to-solve threading problems are just as hard to solve

Have you looked at D 2.0? Globals are thread-local by default, unlike C++. Implicit sharing is disallowed, unless immutable.

> region pointers

It's early days (perhaps I don't fully get region/borrowed pointers yet) but D's `scope` parameter keyword seems very similar. It prevents an argument escaping the function call.

> lack of nulls

This is the big one. Unfortunately D doesn't seem to have an answer on this. I understand Rust uses option/sum types for this, which seems like a great idea.