bearophile wrote:
Steve Teale:

I realize that some people with an IQ of 580 will find my questions naive and 
misguided - not to mention impertinent, but it seems to me that one of the 
responsibilities of being a leader is to explain to less gifted followers what the 
fuck is going on.<

If you read the book by Andrei you will probably find enough explanations. But 
we can also write a Wiki page (see at end of this post).

---------------------

Robert Fraser:

I was just suggesting we need a better syntax, but I realized we have one: 
__traits(compiles).<

__traits() isn't a good looking syntax, and its semantic looks almost like a 
random conflation/accretion of too many different things (and some of them can 
be done better in other ways).

For example in my dlibs I have templates for the following purposes (and most 
of them are present in Tango too):
isAssociativeArray
isFloating
isIntegral
isStaticArray
isUnsigned

So instead of writing:
__traits(isStaticArray, x)

I write in D1:
IsStaticArray!(x)

In D2 you can write:
IsStaticArray!x

That looks better than the traits.
(The syntax of is() too looks like an accretion of mixed things).


Why Andrei isn't using this is the real mystery.<

Maybe he agrees with me that __traits is not nice looking :-) Those underscores 
make it look like a temporary functionality.

is(typeof()) has purposes similar to __traits(compiles, ). Having two syntaxes 
to do the same thing may be bad.

Let's try using traits as you suggest. This it he original written by Steve 
Teale (copied from elsewhere):

template isInputRange(R) {
    enum bool isInputRange = is(typeof(
    {
        R r;              // can define a range object
        if (r.empty) {}   // can test for empty
        r.popFront;       // can invoke next
        auto h = r.front; // can get the front of the range
    }()));
}

This may be the traits version (there is no () after the {} after the 
"compiles"):

template isInputRange(R) {
    enum bool isInputRange = __traits(compiles, {
        R r;              // can define a range object
        if (r.empty) {}   // can test for empty
        r.popFront;       // can invoke next
        auto h = r.front; // can get the front of the range
    });
}

I don't know if this is correct, but if it's correct, is it better looking? It 
looks almost the same to me.

Both traits() and is() need a more clean and logic redesign, to move elsewhere 
some of their purposes, and to avoid duplication in their purposes.
Andrei has shown to be able to improve the API of the regex module, so maybe he 
can find a better design for is() and traits().

If types become first-class at compile time, of type "type", then you can 
remove some purposes from is() too, you can do:
type t1 = int;
type t2 = float;
static if (t1 != t2) {...

Instead of:
alias int t1;
alias float t2;
static if (!is(t1 == t2)) {...

--------------------------

Derek Parnell:

Thank you Derek Parnell for your nice summary about ranges: with to your post 
my understanding of this topic has gone from 10% to 15% :-)

There are things I don't understand from what you have written:

OutputRange - This is an InputRange with the extra capability of being able to add 
elements to the range. In addition to the InputRange methods, it must also provide 
a method that adds a new element to the range, such that it becomes the current 
element. That method must be called 'put(E)' where 'E' is the new element.<

I guess a single linked list can be seen as an OutputRange then. You can add an 
item where you are and scan it forward (unfortunately linked listes today are 
dead, they are never an efficient solution on modern CPUs)
In what othr situations you may use/need an OutputRange? In a file, as in a stack, you can only add in a very specific point (the end, in files, or replace the current item).

ForwardRange - This is an InputRange with the extra capability of being able 
checkpoint the current first 'cursor' position simply by copying the range. When 
you copy an plain InputRange the copied range starts again from the absolute first 
element, but a copied ForwardRange starts at whatever was the current first 
element in the source range.<

I don't understand and I don't know what checkpointing may mean there.

I suggest to explain those things better, and then add 3 or more examples (very 
different from each other, complete, real-world and 
ready-to-be-copied-pasted-and-run, like you can find in every page of Borland 
Delphi documentation) for each kind of range. And then to put the page on the D 
Wiki :-)


Now I admit that these are not method names I would have choosen, as I would have 
preferred names more like<

Andrei has shown that inventing very good names for those methods isn't easy... 
 And putting lot of uppercase letters in the middle of those names isn't nice, 
nor handy, and it's visually noisy.

Bye,
bearophile

we all know that D's compile-time features are a complete mess.
also, duck-typing IMHO has no place in a statically typed language, that's just inconsistent for the language as a whole and confusing for the users.


Reply via email to