memory management and the standard library

H. S. Teoh hsteoh at quickfur.ath.cx
Thu Mar 14 23:06:19 UTC 2019


On Thu, Mar 14, 2019 at 09:32:21PM +0000, JN via Digitalmars-d wrote:
[...]
> I think if D3 was to be successful, it'd have to be a bit more
> opinionated. I don't mean the language has to become a OOP behemoth
> (I'd love that though haha) or a functional monadic transformer
> combinator, but it'd be nice to better define a scope of the language
> and be able to answer a question "Can D do XYZ?" with "No, it's not
> useful and you shouldn't do it this way".

TBH I like the fact that D is not OOP-centric, because IMNSHO OOP is
overhyped far beyond its usefulness.  It has its place, but shoehorning
everything into an OO paradigm just because it's the cool thing to do,
is silly and leads to stupidity like singleton classes (nothing more
than politically-correct euphemism for global functions and global
variables) and excessive boilerplate.

And I like the fact that you can write functional-like code in D without
being bound in the straitjacket of strict functional purity and
immutable values.  Again, such a thing is useful for certain things and
has its place, but I'd hate to be forced to write *everything* that way
just because the language dictates so.

One reason I chose to use D over other languages is because I'm sick and
tired of opinionated languages dictating what I can or cannot do. I want
to be able to what makes sense for the problem domain, not to waste time
fighting with a language insists that I have to do it Their Way or the
highway.

I think a lot of the perceived complexity problems in D come from later
additions that invalidate earlier assumptions.  For example, the core
language was originally designed with the GC being an inherent part of
it, and the foundations of Phobos were laid upon that assumption.  Then
the no-GC crowd clamored and clamored for @nogc, so they got @nogc, and
suddenly we realized that Phobos was completely incompatible with @nogc,
and core language features like arrays, AA's, and exceptions didn't play
nice with it too.  But since @nogc is now officially supported, people
inevitably clamored for @nogc code to be put on equal footing with
GC-reliant code.  Hence a lot of churn just to "liberate" Phobos from
the GC. And anyone who has worked with "enterprise" code knows what
happens when a foundational assumption of a large, entrenched codebase
is invalidated: an explosion of code complexity, special cases, and a
labyrinth of dark corners for bugs to hide in.

Similarly, before the range-based idiom entered into the language, you
have things like std.string and std.array with freely-allocating
functions.  In order to retain backward compatibility, a lot of range
functions with similar semantics had to be named differently, leading to
ugly names like .joiner (rather than .join), .splitter (rather than
.split), and so on.

Had all these features been integrated into the original language
design, these special cases and complexities would not be like they are
today.

OTOH, though, these twists and turns in the development of the language
are also an integral part of what it is; UFCS, for example, came about
from a clever hack added in order to make built-in arrays compatible
with the then newly-introduced range API. Later on, people clamored for
this "hack" to be extended to other types and become officially
accepted. It was a huge success IMO. Nowadays, I can't imagine writing D
code without UFCS.

But still, you can see the seams where UFCS didn't quite fit with the
original core language, e.g., the way it interacts with cross-module
symbol resolution, operator overloading, etc..

Redesigning the language with all these things built into its core would
eliminate these special cases. But it would also be a huge, monumental
task, because each of these features, simple in appearance, actually
imply a vast amount of complexity. No thanks to combinatorial explosion,
any non-trivial set of features inevitably has unexpected corner cases
that may behave differently from what one might expect, and the desire
to cater to human intuition is always at odds with making the language
simpler and more orthogonal.


> Also, some language features seem dubious or hardly used at all. Does
> anyone really use contracts? I know they're sweet and Eiffel and
> everything, but does anyone ACTUALLY use them and doesn't stick to
> good old asserts?

I do.  They're useful for documenting the intent of APIs, whereas I
generally use asserts for internal, implementation-specific assumptions.


> Perhaps rather than implementing (and supporting! each feature has to
> work well with other features which adds support overhead) such
> features, it'd be more useful to add features like struct
> initialization outside of assginments, which feels to me like a much
> nicer improvement to the language.

What do you mean by struct initialization outside of assignments? D
already supports struct initialization syntax of the form S(...) inside
expressions.


T

-- 
Those who don't understand D are condemned to reinvent it, poorly. -- Daniel N


More information about the Digitalmars-d mailing list