View mode: basic / threaded / horizontal-split · Log in · Help
May 10, 2012
Re: Constraints
On 5/10/12 4:41 AM, "İbrahim Gökhan YANIKLAR" <yanikibo@gmail.com>" wrote:

Unrelated, but your name appears in Thunderbird as

=?UTF-8?B?IsSwYnJhaGltIEfDtmtoYW4=?= YANIKLAR"

I think this is Thunderbird's fault because forum.dlang.org shows it 
properly. Nevertheless I thought you should know.


Andrei
May 10, 2012
Re: Constraints
On 2012-05-10 16:46, Andrei Alexandrescu wrote:
> On 5/10/12 4:41 AM, "İbrahim Gökhan YANIKLAR" <yanikibo@gmail.com>" wrote:
>
> Unrelated, but your name appears in Thunderbird as
>
> =?UTF-8?B?IsSwYnJhaGltIEfDtmtoYW4=?= YANIKLAR"
>
> I think this is Thunderbird's fault because forum.dlang.org shows it
> properly. Nevertheless I thought you should know.
>
>
> Andrei

I have no problem in Thunderbird 12, Mac OS X 10.7.

-- 
/Jacob Carlborg
May 10, 2012
Re: Constraints
On May 10, 2012, at 7:46 AM, Andrei Alexandrescu wrote:

> On 5/10/12 4:41 AM, "İbrahim Gökhan YANIKLAR" <yanikibo@gmail.com>" wrote:
> 
> Unrelated, but your name appears in Thunderbird as
> 
> =?UTF-8?B?IsSwYnJhaGltIEfDtmtoYW4=?= YANIKLAR"
> 
> I think this is Thunderbird's fault because forum.dlang.org shows it properly. Nevertheless I thought you should know.

I haven't seen an email client yet that fully supports Q-encoding (well, except the one I wrote of course ;-)).  At a glance, that looks correctly formatted.  In short, the underlying data is in UTF-8, and the "B" means that the payload is encoded as Base64.  If anyone cares to file a bug with Thunderbird, it's RFC 2047.  To be fair to the Thunderbird folks, the problem may actually be that they're doing the full RFC required validation to determine if something is Q-encoded.  The sad truth is that basically no clients obey all the formatting rules, and nearly all the required validation has to be disabled or a huge percentage of stuff meant to be Q-encoded is rejected as invalid and displayed as-is.
May 10, 2012
Re: Constraints
On Thursday, May 10, 2012 09:46:42 Andrei Alexandrescu wrote:
> On 5/10/12 4:41 AM, "İbrahim Gökhan YANIKLAR" <yanikibo@gmail.com>" wrote:
> 
> Unrelated, but your name appears in Thunderbird as
> 
> =?UTF-8?B?IsSwYnJhaGltIEfDtmtoYW4=?= YANIKLAR"
> 
> I think this is Thunderbird's fault because forum.dlang.org shows it
> properly. Nevertheless I thought you should know.

Kmail does the same. It didn't even occur to me that that ridiculous string 
_wasn't_ his username. I was tempted to point out how ridicilous a name it was 
but didn't want to be rude.

- Jonathan M Davis
May 10, 2012
Re: Constraints
On 05/10/2012 09:50 AM, Jacob Carlborg wrote:
> On 2012-05-10 16:46, Andrei Alexandrescu wrote:
>> On 5/10/12 4:41 AM, "İbrahim Gökhan YANIKLAR" <yanikibo@gmail.com>"
>> wrote:
>>
>> Unrelated, but your name appears in Thunderbird as
>>
>> =?UTF-8?B?IsSwYnJhaGltIEfDtmtoYW4=?= YANIKLAR"
>>
>> I think this is Thunderbird's fault because forum.dlang.org shows it
>> properly. Nevertheless I thought you should know.
>>
>>
>> Andrei
>
> I have no problem in Thunderbird 12, Mac OS X 10.7.
>

No problem in Thunderbird 11.0.1 on a lightweight Ubuntu.

Ali

-- 
D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html
May 10, 2012
Re: Constraints
On Thursday, 10 May 2012 at 14:44:00 UTC, Chris Cain wrote:
> I do kind of like your way better, as it's more succinct and 
> clear. As of right now I rarely use classes in D because they 
> just aren't necessary in most cases, and using structs with 
> templates is nearly as powerful and (probably) generates faster 
> code (although, probably fatter code as well as it has to make 
> several versions of the same functions depending on the types).
>
> With your idea, it seems like I would have even less need for 
> classes because you can specify "interfaces" to that generic 
> code.
>
> That all said, I think your code is tiny bit unrealistic in 
> terms of usage for these things which make them look far more 
> useful than they really would be. Take, for instance, some 
> actual code:
>
> https://gist.github.com/2d32de50d2e856c00e9d#file_insert_back.d
>
> So, in this case, I see no potential savings at all. I'd still 
> have to have "isImplicitlyConvertible" in there and therefore 
> I'd still need the current constraint on the method. My 
> insertFront method is more complicated:
>
> https://gist.github.com/2d32de50d2e856c00e9d#file_insert_front.d

isImplicitlyConvertible have to be there because it belongs to a 
template parameter out of the member function template parameters.

> But even though it's more complicated, I'd also like to see how 
> your method would simplify this as well.


void insertFront(U : T)(U item) { ... }

void insertFront(Range : CBidirectionalRange)(Range r)
	if(isImplicitlyConvertible!(ElementType!Range, T)) { ... }

void insertFront(Range : CInputRange)(Range r)
	if(isImplicitlyConvertible!(ElementType!Range, T)) { ... }



> Overall, I think it sounds nice in theory, but I'm just not 
> sure how effective it will be in practice.
>
> I hope I'm not asking too much of you... I'm not trying to 
> discourage you, I'm asking genuine questions about how this 
> will work on more realistic code.
>
> On Thursday, 10 May 2012 at 09:43:00 UTC, İbrahim Gökhan 
> YANIKLAR wrote:
>> concept CInputRange(R)
>> {
>> 	static assert (isDefinable!R);
>> 	static assert (isRange!R);
>> 	bool empty();
>> 	void popFront();
>> 	ElementType!R front();
>> }
>
> Also, something that would _have_ to be solved is ElementType!R 
> ... as of right now, ElementType!R figures out what a range 
> holds by what its front() property returns. So, I think this 
> definition would be invalid.
>

It can be fixed like that:

concept CInputRange(R, E)
{
	static assert (isDefinable!R);
	static assert (isRange!R);
	bool empty();
	void popFront();
	E front();
}

concept CForwardRange(R, E) : CInputRange!(R, E)
{
	R save();
}

concept CBidirectionalRange(R, E) : CForwardRange!(R, E)
{
	void popBack();
	E back();
}

concept CRandomAccessRange(R, E) : CBidirectionalRange!(R, E)
	if (!isInfinite!R)
{
	static assert (is(typeof(R.init[1])));
	static assert(hasLength!R);
	static assert(!isNarrowString!R);
}

concept CRandomAccessRange(R, E) : CForwardRange!(R, E)
	if (isInfinite!R)
{
	static assert (is(typeof(R.init[1])));
}


The first template parameter is reserved for "typeof(this)",
the others are deduced automatically.

> However, once we can show that this will improve things on real 
> code and these things are sorted out, I wouldn't mind seeing 
> this in the language.

When we prefer generic programming rather than oop (where oop is 
applicable), we will absolutely need an interface to make things 
as simple and practical as oop.
Interfaces are not used always for polymorphism, sometimes we 
need only an interface to satisfy common needs. Sometimes the 
current status of D canalizes us to use classes and interfaces 
although it is not effective.
The concept concept may meet these needs. :)
May 10, 2012
Re: Constraints
>
> void insertFront(U : T)(U item) { ... }
>
> void insertFront(Range : CBidirectionalRange)(Range r)
> 	if(isImplicitlyConvertible!(ElementType!Range, T)) { ... }
>
> void insertFront(Range : CInputRange)(Range r)
> 	if(isImplicitlyConvertible!(ElementType!Range, T)) { ... }
>

An alternative solution:


concept CInputRange(R, E, T = E)
{
	static assert (isDefinable!R);
	static assert (isRange!R);
	bool empty();
	void popFront();
	E front();
	static assert (isImplicitlyConvertible!(E, T));
}

concept CForwardRange(R, E, T = E) : CInputRange!(R, E, T)
{
	R save();
}

concept CBidirectionalRange(R, E, T = E) : CForwardRange!(R, E, T)
{
	void popBack();
	E back();
}

concept CRandomAccessRange(R, E, T = E) : CBidirectionalRange!(R, 
E, T)
	if (!isInfinite!R)
{
	static assert (is(typeof(R.init[1])));
	static assert(hasLength!R);
	static assert(!isNarrowString!R);
}

concept CRandomAccessRange(R, E, T = E) : CForwardRange!(R, E, T)
	if (isInfinite!R)
{
	static assert (is(typeof(R.init[1])));
}


Then we can use this concepts in your functions like:


void insertFront(U : T)(U item) { ... }

void insertFront(Range : CBidirectionalRange!T)(Range r) { ... }

void insertFront(Range : CInputRange!T)(Range r) { ... }

The rule is simple:
Do not specify the first parameter (e.g. "R": reserved for 
typeof(this)) and the automatically deduced parameters (e.g. "E": 
deduced from return type of "front()").
May 11, 2012
Re: Constraints
"Ibrahim Gokhan YANIKLAR" , dans le message (digitalmars.D:166850), a
écrit :

I would even have:

concept CInputRange(E)
{
	alias E ElementType;
	static assert (isDefinable!typeof(this));
	static assert (isRange!typeof(this));
	@property bool empty();
	@property void popFront();
	@property ElementType front();
}

Concepts allows to state your intent when you create a type. It self 
documents the code more nicely that a static assert. It would be 
much easier for newcomers to understand concepts. Finally, by creating a 
hierarchy, concepts allows to determine which is the more specialized 
template. Even if it is not a priority to add this to the langage, I 
don't think it is just syntactic sugar.


Several problems should be solved though:

concept CInfiniteRange(E) : CInputRange(E)
{
// empty was declared to be a property, here it is an enum.
     enum bool empty = false;
// or:
     final bool empty() { return false; }
}

struct SimpleCounter(E) : CInfiniteRange(E)
{
// front was declared as a property, here it is a member variable
   E front = 0;
   void popFront() { ++front; }
//or:
   E front_ = 0;
   @property E front() const { return front_; } // now front is const
   @property void popFront() { ++front_; }
}

It will not be obvious to define what is allowed and what is not so that 
the flexibility of current template constraints is reached, while 
keeping the definition natural.

-- 
Christophe
May 11, 2012
Re: Constraints
On Friday, 11 May 2012 at 07:58:54 UTC, 
travert@phare.normalesup.org (Christophe Travert) wrote:
> "Ibrahim Gokhan YANIKLAR" , dans le message 
> (digitalmars.D:166850), a
>  écrit :
>
> I would even have:
>
> concept CInputRange(E)
> {
> 	alias E ElementType;
> 	static assert (isDefinable!typeof(this));
> 	static assert (isRange!typeof(this));
> 	@property bool empty();
> 	@property void popFront();
> 	@property ElementType front();
> }
>
> Concepts allows to state your intent when you create a type. It 
> self
> documents the code more nicely that a static assert. It would be
> much easier for newcomers to understand concepts. Finally, by 
> creating a
> hierarchy, concepts allows to determine which is the more 
> specialized
> template. Even if it is not a priority to add this to the 
> langage, I
> don't think it is just syntactic sugar.
>
>
> Several problems should be solved though:
>
> concept CInfiniteRange(E) : CInputRange(E)
> {
> // empty was declared to be a property, here it is an enum.
>       enum bool empty = false;
> // or:
>       final bool empty() { return false; }
> }
>
> struct SimpleCounter(E) : CInfiniteRange(E)
> {
> // front was declared as a property, here it is a member 
> variable
>     E front = 0;
>     void popFront() { ++front; }
> //or:
>     E front_ = 0;
>     @property E front() const { return front_; } // now front 
> is const
>     @property void popFront() { ++front_; }
> }
>
> It will not be obvious to define what is allowed and what is 
> not so that
> the flexibility of current template constraints is reached, 
> while
> keeping the definition natural.


Fixed:


concept CInputRange(R, E, T = E)
{
	static assert (isDefinable!R);
	static assert (isRange!R);
	@property bool empty();
	void popFront();
	@property E front();
	static assert (isImplicitlyConvertible!(E, T));
}

concept CForwardRange(R, E, T = E) : CInputRange!(R, E, T)
{
	@property R save();
}

concept CBidirectionalRange(R, E, T = E) : CForwardRange!(R, E, T)
{
	void popBack();
	@property E back();
}

concept CRandomAccessRange(R, E, T = E) : CBidirectionalRange!(R, 
E, T)
	if (!isInfinite!R)
{
	static assert (is(typeof(R.init[1])));
	static assert(hasLength!R);
	static assert(!isNarrowString!R);
}

concept CRandomAccessRange(R, E, T = E) : CForwardRange!(R, E, T)
	if (isInfinite!R)
{
	static assert (is(typeof(R.init[1])));
}


Using the first template parameter as typeof(this) is more 
effective.
The ElementType ( E ) can be deduced from the type ( or return 
type ) of front.
When we declare front as a property, it should match both 
property functions and enums.
Next ›   Last »
1 2 3
Top | Discussion index | About this forum | D home