Bug in D!!!

EntangledQuanta via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Sep 2 21:18:03 PDT 2017


On Sunday, 3 September 2017 at 02:39:19 UTC, Moritz Maxeiner 
wrote:
> On Saturday, 2 September 2017 at 23:12:35 UTC, EntangledQuanta 
> wrote:
>> On Saturday, 2 September 2017 at 21:19:31 UTC, Moritz Maxeiner 
>> wrote:
>>> On Saturday, 2 September 2017 at 00:00:43 UTC, 
>>> EntangledQuanta wrote:
>>>> On Friday, 1 September 2017 at 23:25:04 UTC, Jesse Phillips 
>>>> wrote:
>>>>> I've love being able to inherit and override generic 
>>>>> functions in C#. Unfortunately C# doesn't use templates and 
>>>>> I hit so many other issues where Generics just suck.
>>>>>
>>>>> I don't think it is appropriate to dismiss the need for the 
>>>>> compiler to generate a virtual function for every 
>>>>> instantiated T, after all, the compiler can't know you have 
>>>>> a finite known set of T unless you tell it.
>>>>>
>>>>> But lets assume we've told the compiler that it is 
>>>>> compiling all the source code and it does not need to 
>>>>> compile for future linking.
>>>>>
>>>>> First the compiler will need to make sure all virtual 
>>>>> functions can be generated for the derived classes. In this 
>>>>> case the compiler must note the template function and 
>>>>> validate all derived classes include it. That was easy.
>>>>>
>>>>> Next up each instantiation of the function needs a new 
>>>>> v-table entry in all derived classes. Current compiler 
>>>>> implementation will compile each module independently of 
>>>>> each other; so this feature could be specified to work 
>>>>> within the same module or new semantics can be written up 
>>>>> of how the compiler modifies already compiled modules and 
>>>>> those which reference the compiled modules (the object 
>>>>> sizes would be changing due to the v-table modifications)
>>>>>
>>>>> With those three simple changes to the language I think 
>>>>> that this feature will work for every T.
>>>>
>>>> Specifying that there will be no further linkage is the same 
>>>> as making T finite. T must be finite.
>>>>
>>>> C# uses generics/IR/CLR so it can do things at run time that 
>>>> is effectively compile time for D.
>>>>
>>>> By simply extending the grammar slightly in an intuitive 
>>>> way, we can get the explicit finite case, which is easy:
>>>>
>>>> foo(T in [A,B,C])()
>>>>
>>>> and possibly for your case
>>>>
>>>> foo(T in <module>)() would work
>>>>
>>>> or
>>>>
>>>> foo(T in <program>)()
>>>>
>>>> the `in` keyword makes sense here and is not used nor 
>>>> ambiguous, I believe.
>>>
>>> While I agree that `in` does make sense for the semantics 
>>> involved, it is already used to do a failable key lookup 
>>> (return pointer to value or null if not present) into an 
>>> associative array [1] and input contracts. It wouldn't be 
>>> ambiguous AFAICT, but having a keyword mean three different 
>>> things depending on context would make the language even more 
>>> complex (to read).
>>
>> Yes, but they are independent, are they not? Maybe not.
>>
>> foo(T in Typelist)()
>>
>> in, as used here is not a input contract and completely 
>> independent. I suppose for arrays it could be ambiguous.
>
> The contexts being independent of each other doesn't change 
> that we would still be overloading the same keyword with three 
> vastly different meanings. Two is already bad enough imho (and 
> if I had a good idea with what to replace the "in" for AA's I'd 
> propose removing that meaning).

Why? Don't you realize that the contexts matters and it's what 
separates the meaning? In truly unambiguous contexts, it 
shouldn't matter. It may require one to decipher the context, 
which takes time, but there is nothing inherently wrong with it 
and we are limited to how many symbols we use(unfortunately we 
are generally stuck with the querty keyboard design, else we 
could use symbols out the ying yang and make things much clearer, 
but even mathematics, which is a near perfect language, 
"overloads" symbols meanings).

You have to do this sort of thing when you limit the number of 
keywords you use. Again, ultimately it doesn't matter. A symbol 
is just a symbol. For me, as long as the context is clear, I 
don't see what kind of harm it can cause. You say it is bad, but 
you don't give the reasons why it is bad. If you like to think of 
`in` has having only one definition then the question is why? You 
are limiting yourself. The natural languages are abound with such 
multi-definitions. Usually in an ambiguous way and it can cause a 
lot of problems, but for computer languages, it can't(else we 
couldn't actually compile the programs). Context sensitive 
grammars are provably more expressive than context free.

https://en.wikipedia.org/wiki/Context-sensitive_grammar

Again, I'm not necessarily arguing for them, just saying that one 
shouldn't avoid them just to avoid them.


>
>>
>> For me, and this is just me, I do not find it ambiguous. I 
>> don't find different meanings ambiguous unless the context 
>> overlaps. Perceived ambiguity is not ambiguity, it's just 
>> ignorance... which can be overcome through learning. Hell, D 
>> has many cases where there are perceived ambiguities... as do 
>> most things.
>
> It's not about ambiguity for me, it's about readability. The 
> more significantly different meanings you overload some keyword 
> - or symbol, for that matter - with, the harder it becomes to 
> read.

I don't think that is true. Everything is hard to read. It's 
about experience. The more you experience something the more 
clear it becomes. Only with true  ambiguity is something 
impossible. I realize that in one can design a language to be 
hard to parse due to apparent ambiguities, but am I am talking 
about cases where they can be resolved immediately(at most a few 
milliseconds).

You are making general statements, and it is not that I disagree, 
but it depends on context(everything does). In this specific 
case, I think it is extremely clear what in means, so it is 
effectively like using a different token. Again, everyone is 
different though and have different experiences that help them 
parse things more naturally. I'm sure there are things that you 
might find easy that I would find hard. But that shouldn't stop 
me from learning about them. It makes me "smarter", to simplify 
the discussion.


>>
>> But in any case, I could care less about the exact syntax. 
>> It's just a suggestion that makes the most logical sense with 
>> regard to the standard usage of in. If it is truly unambiguous 
>> then it can be used.
>
> Well, yes, as I wrote, I think it is unambiguous (and can thus 
> be used), I just think it shouldn't be used.

Yes, but you have only given the reason that it shouldn't be used 
because you believe that one shouldn't overload keywords because 
it makes it harder to parse the meaning. My rebuttal, as I have 
said, is that it is not harder, so your argument is not valid. 
All you could do is claim that it is hard and we would have to 
find out who is more right.

I have a logical argument against your absolute restriction 
though... in that it causes one to have to use more symbols. I 
would imagine you are against stuff like using "in1", "in2", etc 
because they visibly are to close to each other.  If you want 
"maximum" readability you are going to have to mathematically 
define that in a precise way then could up with a grammar that 
expresses it. I think you'll find that the grammar will depend on 
each individual person. At best you could then take an average 
which satisfies most people up to some threshold... in which 
case, at some point in time later, that average will shift and 
your grammar will no longer be valid(it will no longer satisfy 
the average).

Again, it's not that I completely disagree with you on a 
practical level. Lines have to be drawn, but it's about where to 
precisely draw that line. Drawing it in the wrong place leads to 
certain solutions that are generally problematic. That's how we 
know they are wrong, we draw a line and later realize it cause a 
bunch of problems then we say "oh that was the wrong way to do 
it". Only with drawing a bunch of wrong lines can we determine 
which ones are the best and use that info to predict better 
locations.

>>
>> Another alternative is
>>
>> foo(T of Typelist)
>>
>> which, AFAIK, of is not used in D and even most programming 
>> languages. Another could be
>>
>> foo(T -> Typelist)
>>
>> or even
>>
>> foo(T from Typelist)
>
> I would much rather see it as a generalization of existing 
> template specialization syntax [1], which this is t.b.h. just a 
> superset of (current syntax allows limiting to exactly one, you 
> propose limiting to 'n'):
>
> ---
> foo(T: char)      // Existing syntax: Limit T to the single 
> type `char`
> foo(T: (A, B, C)) // New syntax:      Limit T to one of A, B, 
> or C
> ---

Yes, if this worked, I'd be fine with it. Again, I could care 
less. `:` == `in` for me as long as `:` has the correct meaning 
of "can be one of the following" or whatever.

But AFAIK, : is not "can be one of the following"(which is "in" 
or "element of" in the mathematical sense) but can also mean "is 
a derived type of".

All I'm after is the capability to do something elegantly, and 
when it doesn't exist, I "crave" that it does. I don't really 
care how it is done(but remember, it must be done elegantly). I 
am not "confused"(or whatever you want to call it) by symbolic 
notation. As long as it's clearly defined so I can learn the 
definition and it is not ambiguous.

There are all kinds of symbols that can be used, again, we are 
limited by querty(for speed, no one wants to have to use 
alt-codes in programming, there is a way around this but would 
scare most people).

e.g.,

T ∈ X is another expression(more mathematical, I assume that ∈ 
will be displayed correctly, it is Alt +2208) that could work, 
but ∈ is not ascii an so can't be used(not because it can't but 
because of peoples lack of will to progress out of the dark ages).

> Strictly speaking, this is exactly what template specialization 
> is for, it's just that the current one only supports a single 
> type instead of a set of types.
> Looking at the grammar rules, upgrading it like this is a 
> fairly small change, so the cost there should be minimal.
>

If that is the case then go for it ;) It is not a concern of 
mine. You tell me the syntax and I will use it. (I'd have no 
choice, of course, but if it's short and sweet then I won't have 
any problem).

The main reason I suggest syntax is because none exist and I 
assume, maybe wrongly, that people will get what I am saying 
easier than writing up some example library solution and 
demonstrating that.

if I say something like

class/struct { foo(T ∈ X)(); }

defines a virtual template function for all T in X. Which is 
equivalent to

class/struct
{
    foo(X1)();
    ...
    foo(Xn)();
}
  I assume that most people will understand, more or less the 
notation I used to be able to interpret what am trying to get at. 
It is a mix of psuedo-programming and mathematics, but it is not 
complex. ∈ might be a bit confusing but looking it up and 
learning about it will educate those that want to be educated and 
expand everyones ability to communicate better. I could, of 
course, be more precise, but I try to be precise only when it 
suits me(which may be fault, but, again, I only have so many 
hours in the day to do stuff).


>>
>> or whatever. Doesn't really matter. They all mean the same to 
>> me once the definition has been written in stone. Could use 
>> `foo(T eifjasldj Typelist)` for all I care.
>
> That's okay, but it does matter to me.


That's fine. I am willing to compromise. Lucky for you, 
symbols/tokens and context are not a big deal to me. Of course, I 
do like short and sweet, so I am biased too, but I have much more 
leeway it seems.


>> The import thing for me is that such a simple syntax exists 
>> rather than the "complex syntax's" that have already been 
>> given(which are ultimately syntax's as everything is at the 
>> end of the day).
>
> Quoting a certain person (you know who you are) from DConf 
> 2017: "Write a DIP".
> I'm quite happy to discuss this idea, but at the end of the 
> day, as it's not an insignificant change to the language 
> someone will to do the work and write a proposal.
>

My main issues with going through the trouble is that basically I 
have more important things to do. If I were going to try to get D 
to do all the changes I actually wanted, I'd be better off 
writing my own language the way I envision it and want it... but 
I don't have 10+ years to invest in such a beast and to do it 
right would require my full attention, which I'm not willing to 
give, because again, I have better things to do(things I really 
enjoy).

So, all I can do is hopefully stoke the fire enough to get 
someone else interested in the feature and have them do the work. 
If they don't, then they don't, that is fine. But I feel like 
I've done something to try to right a wrong.

>>
>>
>>> W.r.t. to the idea in general: I think something like that 
>>> could be valuable to have in the language, but since this 
>>> essentially amounts to syntactic sugar (AFAICT), but I'm not 
>>> (yet) convinced that with `static foreach` being included 
>>> it's worth the cost.
>>>
>>
>> Everything is syntactic sugar. So it isn't about if but how 
>> much. We are all coding in 0's and 1's whether we realize it 
>> or not. The point if syntax(or syntactic sugar) is to reduce 
>> the amount of 0's and 1's that we have to *effectively* code 
>> by grouping common patterns in to symbolic equivalents(by 
>> definition).
>
> AFAIK the difference between syntax sugar and enabling syntax 
> in PLs usually comes down to the former allowing you to express 
> concepts already representable by other constructs in the PL; 
> when encountered, the syntax sugar could be lowered by the 
> compiler to the more verbose syntax and still be both valid in 
> the PL and recognizable as the concept (while this is vague, a 
> prominent example would be lambdas in Java 8).

Yes, but everything is "lowered" it's just how you define it. It 
is all lowering to 0's and 1's. Syntactic sugar is colloquially 
used like you have defined it, but in the limit(the most general 
sense), it's just stuff. Why? Because what is sugar to one person 
is salt to another(this is hyperbole, of course, but you should 
be able to get my point).

e.g., You could define syntactic sugar to be enhancement that can 
be directly rewritten in to a currently expressible syntax in the 
language.

That is fine. But then what if that expressible syntax was also 
syntactic sugar? You end up with something like L(L(L(L(x)))) 
where L is a "lowering" and x is something that is not "lowered". 
But if you actually were able to trace the evolution of the 
compiler, You'd surely notice that x is just L(...L(y)...) for 
some y.

A programming language is simply something that takes a set of 
bits and transforms them to another set of bits. No more and no 
less. Everything else is "syntactic sugar". The definition may be 
so general as to be useless, but it is what a programming 
language is(mathematically at least).

Think about it a bit. How did programmers program before modern 
compilers came along? They used punch cards or levers, which are 
basically setting "bits" or various "function"(behaviors) that 
the machine would carry out. Certain functions and combinations 
of functions were deemed more useful and were combined in to 
"meta-functions" and given special bits to represent them. This 
process has been carried out ad-nauseam and we are were we are 
today because of this process(fundamentally)

But the point is, at each step, someone can claim that the 
current "simplifying" of complex functions in to a 
"meta-function" just "syntactic sugar". This process though is 
actually what creates the "power" in things. Same thing happens 
at the hardware level... same thing happens with atoms and 
molecules(except we are not in control of the rules of how those 
things combine).


>>
>> No one can judge the usefulness of syntax until it has been 
>> created because what determines how useful something is is its 
>> use. But you can't use something if it doesn't exist. I think 
>> many fail to get that.
>
> Why do you think that? Less than ten people have participated 
> in this thread so far.

I am not talking about just this thread, I am talking about in 
all threads and all things in which humans attempt to determine 
the use of something. e.g., the use of computers(used to be 
completely useless for most people because they failed to see the 
use in it(it wasn't useful to them)). The use of medicine... the 
use of a new born baby, the use of life. The use of a turtle. 
People judge use in terms of what it does for them on a 
"personal" level, and my point is, that this inability to see the 
use of something in an absolute sense(how useful is it to the 
whole, be it the whole of the D programming community, the whole 
of humanity, the whole of life, or whatever) is a sever 
shortcoming of almost all humans. It didn't creep up too much in 
this thread but I have definitely see in it other threads. Most 
first say "Well, hell, that won't help me, that is useless". They 
forget that it may be useless to them at that moment, but might 
be useful to them and might be useful to other people.

Why something is useless to someone, though, almost entirely 
depends on their use of it. You can't know how useful something 
is until you use it... and this is why so many people judge the 
use of something the way they do(They can't help it, it's sort of 
law of the universe).

Let me explain, as it might not be clear: Many people many years 
ago used to think X was useless. Today, those same people cannot 
live without X. Replace X with just about anything(computers, 
music, oop, etc). But if you asked those people back then they 
would have told you those things are useless. But through 
whatever means(the way life is) things change and things that 
were previously useless become useful. They didn't know that at 
first because they didn't use those things to find out if they 
were useful.

The same logic SHOULD be applied to everything. We don't know how 
useful something is until we use it *enough* to determine if it 
is useful. But this is not the logic most people use, including 
many people in the D community. They first judge, and almost 
exclusively(depends on the person), how it relates to their own 
person self. This is fundamentally wrong IMO and, while I don't 
have mathematical proof, I do have a lot of experience that tells 
me so(history being a good friend).


>
>> The initial questions should be: Is there a gap in the 
>> language? (Yes in this case). Can the gap be filled? (this is 
>> a theoretical/mathematical question that has to be answered.
>
>> Most people jump the gun here and make assumptions)
>
> Why do you assume that? I've not seen anyone here claiming 
> template parameter specialization to one of n types (which is 
> the idea I replied to) couldn't be done in theory, only that it 
> can't be done right now (the only claim as to that it can't be 
> done I noticed was w.r.t. (unspecialized) templates and virtual 
> functions, which is correct due to D supporting separate 
> compilation; specialized templates, however, should work in 
> theory).

Let me quote the first two responses:

"It can't work this way. You can try std.variant."

and

"It is not possible to have a function be both virtual and 
templated. A function template generates a new function 
definition every time that it's a called with a new set of 
template arguments. So, the actual functions are not known up 
front, and that fundamentally does not work with virtual 
functions, where the functions need to be known up front, and you 
get a different function by a look-up for occurring in the 
virtual function call table for the class. Templates and virtual 
functions simply don't mix. You're going to have to come up with 
a solution that does not try and mix templates and virtual 
functions."

Now, I realize I might have no been clear about things and maybe 
there is confusion/ambiguity in what I meant, how they 
interpreted it, or how I interpreted their response... but there 
is definitely no sense of "Yes, we can make this work in some 
way..." type of mentality.

e.g., "Templates and virtual functions simply don't mix."

That is an absolute statement. It isn't even qualified with "in 
D".

>> Does the gap need to be filled? Yes in this case, because all 
>> gaps ultimately need to be filled, but this then leads the 
>> practical issues:
>
> Actually, I disagree here. It only *needs* filling if enough 
> users of the language actually care about it not being there. 
> Otherwise, it's a *nice to have* (like generics and Go, or 
> memory safety and C :p ).

Yes, on some level you are right... but again, who's to judge? 
the current users or the future users? You have to take in to 
account the future users if you care about the future of D, 
because those will be the users of it and so the current users 
actually have only a certain percentage of weight. Also, who will 
be more informed about the capabilities and useful features of D? 
The current users or the future users? Surely when you first 
started using D, you were ignorant of many of the pro's and con's 
of D. Your future self(in regard to that time period when you 
first started using D) new a lot more about it? ie., you know 
more now than you did, and you will know more in the future than 
you do now. The great thing about knowledge it grows with time 
when watered. You stuck around with D, learned it each "day" and 
became more knowledgeable about it. At the time, there were 
people making decisions about the future of D features, and now 
you get to experience them and determine their usefulness 
PRECISELY because of those people in the past filling in the gaps.

EVERYTHING that D currently has it didn't have in the past. 
Hence, someone had to create it(Dip or no dip)... thank god they 
did, or D would just be a pimple on Walters brain.  But D can't 
progress any further unless the same principles are applied. Sure 
it is more bulky(complex) and sure not everything has to be 
implemented in the compiler to make progress... But the only way 
we can truly know what we should do is first to do things we 
think are correct(and don't do things we know are wrong).

So, when people say "this can't be done" and I know it damn well 
can, I will throw a little tantrum... maybe they will give me a 
cookie, who knows? Sure, I could be wrong... but I could also be 
right(just as much as they could be wrong or be right). This is 
why we talk about things, to combine our experiences and ideas to 
figure out how well something will work.  The main problem I see, 
in the D community, is that very little cooperation is done in 
those regards unless it's initiated by the core team(that isn't a 
bad thing in some sense but it isn't a good thing in another 
sense).

I guess some people just haven't learned the old proverb "Where 
there's a will, there's a way".

> [1] 
> https://dlang.org/spec/template.html#parameters_specialization

As I mentioned, and I'm unclear if it : behaves exactly that way 
or not, but : seems to do more than be inclusive. If it's current 
meaning can still work with virtual templated functions, then I 
think it would be even better.  But ultimately all this would 
have to be fleshed out properly before any real work could be 
done.







More information about the Digitalmars-d-learn mailing list