Worst ideas/features in programming languages?

H. S. Teoh hsteoh at quickfur.ath.cx
Tue Oct 12 19:41:57 UTC 2021


On Mon, Oct 11, 2021 at 03:59:10PM +0000, Atila Neves via Digitalmars-d wrote:
> I'm brainstorming about what I'll talk about at DConf, and during a
> conversation with Walter I thought it might be cool to talk about:
> 
> * Worst features implemented in a non-toy language

>From languages I know:

- C:
   - Implicit decay of array to pointer.
   - Null-terminated strings (corruption of your string data == buffer
     overflow exploit waiting to happen).
   - Pointer syntax: the `*` grammatically attaches to the identifier
     rather than the type name, which causes all sorts of totally
     needless syntactic convolutions like the unreadable function
     pointer syntax. (Yes, I know how it works, I've been writing them
     for 20+ years and I know them like the back of my hand; but it is
     nevertheless a Bad Idea(tm).)  Not to mention how easily beginners
     mess it up.

- C++:
   - Template syntax (using `<>` for template parameters/arguments has
     got to be the worst syntax choice made in the last 30 years, making
     C++ unlexible until it's first parsed).
   - Null-terminated strings (one of the worst things to inherit from
     C).
   - Free-for-all, wild-wild-west operator overloading that lets you
     define, e.g., <, <=, >, >= in completely inconsistent, incompatible
     ways. Not to mention the amount of boilerplate necessary to
     implement these operators in a consistent way, leading to more
     opportunities for human error.

- Perl:
   - Sigils: $x, @x, %x refer to different things. Worse yet, $x{y}
     dereferences %x, not $x, and $x[y] dereferences @x rather than $x.
     (Argh...)
     (I actually *like* the rationale behind sigils, but the way they're
     implemented is just ... argh...)

- JS:
   - Dynamic typing.  Leads to all kinds of bugs and runtime exceptions
     that eventually compel you to write checks, that ultimately boil
     down to reinventing static typing in an ad hoc way.  As someone
     once said, dynamic typing is just static typing with only a single
     type.
   - `===` vs `==`.
   - WAT-eliciting behavior of built-in operators: like `[] + []`
     producing an empty string, `[] + {}` producing `[object Object]`
     (which is a *string*, not an actual object!) and `{} + []`
     producing 0.


> * Worst features (in your opinion) in D

- The integer promotion/casting mess. I understand that C compatibility
  is very important, but things have seriously gone off the rails when
  you get things like:

	ubyte x;
	x = -x; // compile error

- Autodecoding.

- Half-baked features like `shared`. It kinda-sorta works, its behaviour
  is by design, casts are intentional, etc.. But it leaves you with the
  feeling of incompleteness.  It promises thread safety (or at least to
  help towards that goal), but when you use it you feel like you're
  given parts of some IKEA furniture without nails, screws, or bolts,
  which you have to provide on your own (and of course, assembly is also
  DIY, and if it falls apart it's your fault, not ours).

- In the same vein, @property.  It's been how many years now, when are
  we going to get a comprehensive solution (or, at the very least, when
  will this sad creature with missing limbs finally be euthanized for
  mercy's sake)?


> * Features you'd like to see in D
[...]

- C++ concepts-like feature of specifying the expected interface of a
  template parameter.
   - Yes, sig constraints fit the bill, kinda-sorta.  But it leads to
     poor, unhelpful error messages.  Yes, this can be fixed by using
     static if, pragma(msg), etc., but this requires a lot of extra work
     on the part of the user which should have been handled by the
     language.
   - Yes, there's a dub package that kinda-sorta does this. But again,
     this is something that should have been done by the language.

- More procedural type manipulations.  `static foreach` is great; it
  eliminated a bunch of cases where you'd need to use recursive
  templates. It'd be nice to have procedural manipulations of
  types/aliases/etc. as well.  Kinda like Stefan's type functions, but
  more integrated into the language and streamlined with other D
  features.  Basically, get rid of recursive templates except where
  they're absolutely, unavoidably, necessary.

- More complete outworking of features that require deep language
  support, like `shared` or @property or [insert your favorite
  half-baked D feature here].  Provide a comprehensive package that
  actually enables you to get stuff done without having to buy your own
  nails, your own hammer, and assemble things yourself, and that provide
  some solid guarantees that doesn't just leave you holding the pieces
  when things break.

- Extend `if (auto x = initializer())` to apply to complex conditions as
  well, e.g.:

  	if (someClause && (auto x = initializer()) && (auto y =
		initializer2())) {
		/* use x and y here */
	}


T

-- 
Turning your clock 15 minutes ahead won't cure lateness---you're just making time go faster!


More information about the Digitalmars-d mailing list