What are (were) the most difficult parts of D?

H. S. Teoh hsteoh at quickfur.ath.cx
Thu May 12 16:39:56 UTC 2022


On Thu, May 12, 2022 at 12:13:32PM +0000, Basile B. via Digitalmars-d-learn wrote:
[...]
> Problem is more (from https://dlang.org/spec/expression.html#is_expression)
> 
> ```
> is ( Type : TypeSpecialization , TemplateParameterList )
> is ( Type == TypeSpecialization , TemplateParameterList )
> is ( Type Identifier : TypeSpecialization , TemplateParameterList )
> is ( Type Identifier == TypeSpecialization , TemplateParameterList )
> ```
> 
> I never remember those variants, because basically you never need
> them...  They were required for std.traits and that's it.

Not true. I use these all the time in generic code. Basically, they
allow you to do IFTI-like template pattern-matching using static-if's.
This is eminently useful for inspecting incoming types in template
functions. For example, in serialization code, I would do something
like:

	auto serialize(T)(T data) {
		static if (is(T == string))
		{
			... // straightforward string encoding
		}
		else static if (is(T : U[], U))
			// this means: "T matches the pattern `U[]`,
			// where U is some arbitrary type"
		{
			... // non-string array encoding
			// note that in this block, `U` is defined to be
			// the array element; very convenient for
			// further type dissection
		}
		else static if (is(T : U[V], U, V))
			// this means: "T matches the pattern `U[V]`,
			// where U and V are arbitrary types"
		{
			... // AA encoding
			// similarly, in this block U is the value type
			// and V is the key type, very convenient for
			// further type dissection
		}
		else static if (is(T : MyType!(U), string U))
			// this means: "T matches the pattern
			// `MyType!(U)` where U is some string"
		{
			... // special handling for instantiations of
			    // MyType with string argument
			// in this block, U == string
		}
		... // and so on
	}

I concede that the documentation isn't exactly easy to understand on a
first read; it took me many tries before it "clicked".  But once you
understand the general pattern, most of the cases make sense and is
pretty predictable.

There *are* one or two special cases, granted, but those are exceptional
and there are already std.traits wrappers that expose a friendlier API.
The worst offender in this category is __parameters, about which I wrote
years ago here:

	https://forum.dlang.org/thread/vpjpqfiqxkmeavtxhyla@forum.dlang.org

Still, putting this ugly special case aside, the rest of is(...) syntax
mostly conforms to the above pattern, and is readily understandable once
you learn the pattern.


T

-- 
Written on the window of a clothing store: No shirt, no shoes, no service.


More information about the Digitalmars-d-learn mailing list