I dun a DIP, possibly the best DIP ever
Steven Schveighoffer
schveiguy at gmail.com
Fri Apr 24 21:41:57 UTC 2020
On 4/24/20 4:55 PM, Walter Bright wrote:
> On 4/24/2020 10:10 AM, Steven Schveighoffer wrote:
>> I think the ellipsis version is superior simply because it has more
>> expressive power (see my posts elsewhere). An ideal proposal would
>> allow all things to be handled within one expression, but the ellipsis
>> is better in that it is unambiguous and does not break code.
>
> My issue is finding the best way to do this. Adding powerful syntax
> "just because we can" leads to an unusable language. Queue my opposition
> to AST macros.
It's not just the expressive power, but the simple expressiveness of the
array syntax is missing. There are too many ambiguities without adding
syntax because expressions that use tuples can already work with them.
The simplest is "make me an array of all these values"
[tup * 2]
But I don't see how the compiler knows which parts of the expression are
part of the expansion, and which parts aren't. I would fully expect the
above to result in:
([tup[0] * 2], [tup[1] * 2], ...)
And if it doesn't, then the compiler is making odd arbitrary decisions
as to which part of the expression is expandable.
Which means, essentially, the odd bizarre cases are doable, but the
useful ones are not.
The ellipsis doesn't do much in terms of functionality, but it gives you
a place to tag "this is what I want you to expand", so the compiler
makes the right decisions.
>> And actually, with a staticIota-like thing you could do every third
>> tuple member quite easily.
>>
>> alias everyThird = staticIota!(2, Tup.length, 3); // start, end, step
>>
>> alias everyThirdMember = (Tup...[everyThird])...;
>
> Touche. Well done.
>
> Let's not fall into the mode of only looking at the way C++ did it and
> not seeing other ways. C++ has problems (like not having arrays) that
> lead it in different directions for solving array-like problems.
I'm fully on board with breaking with C++ when it doesn't make sense. In
the case of the array syntax, I think it's just not workable.
> What do other languages do? How are things like this expressed in
> mathematics?
Math is a great inspiration: https://en.wikipedia.org/wiki/Sequence
Lots of positional notation, but you can see it uses an ellipsis to
denote "continues on".
The question is, how can we denote "apply this expression to every
element using these tuples". That's the goal. I don't know how we can do
it with any more brevity or readability than adding a specific operator
for it or adding a symbol for it.
>
>
>> staticIota is kind of another primitive that is super-useful, and
>> would be easy for the compiler to provide.
>
> Where does one stop in adding operators to the language?
You can do staticIota without language help. Just like you can do ALL of
this without language help. The point where you stop is when it doesn't
give you a 10-50x speedup in compilation and 50% reduction in memory by
letting the compiler take care of it.
Note that I'm not saying we can't do staticIota in library code. But
really, "count from 0 to N" is such a simple thing for a computer to do,
it seems really wasteful to have to do it via symbol tables and CTFE.
> Another approach to resolving the original problem (template
> instantiation bloat) is for the compiler to recognize templates like
> AliasSeq as "special" and implement them directly.
>
>
> For example, AliasSeq is defined as:
>
> template AliasSeq(TList...) { alias AliasSeq = TList; }
>
> This pattern is so simple it can be recognized by the compiler. (Having
> std.meta.AliasSeq being a special name known to the compiler is not
> necessary.)
> The compiler already recognizes certain patterns, such as the expression
> that does a rotate, and then generates the CPU rotate instruction for it.
Not arguing with that. The faster D can get, the better, regardless of
whether we add any other syntax features.
One thing I would say is that AliasSeq is going to be identical for
every instantiation, so there is no reason to store it in the symbol
table. Just generate it every time, and then you cut down on a ton of
template memory usage. Same thing could be said for a staticIota.
-Steve
More information about the Digitalmars-d
mailing list