Jump to page: 1 2
Thread overview
What is a sink delegate?
Sep 30, 2014
Gary Willoughby
Sep 30, 2014
Adam D. Ruppe
Oct 10, 2014
Joel
Oct 10, 2014
thedeemon
Oct 10, 2014
Hjkp
Oct 10, 2014
VaZyJeanPierre
Oct 11, 2014
Joel
Oct 10, 2014
Ali Çehreli
Oct 10, 2014
Ali Çehreli
September 30, 2014
What is a sink delegate?

Discussed here:
http://forum.dlang.org/thread/m0bdgg$1t7j$1@digitalmars.com?page=6#post-m0emvc:242av5:241:40digitalmars.com
September 30, 2014
On Tuesday, 30 September 2014 at 17:22:44 UTC, Gary Willoughby wrote:
> What is a sink delegate?

Instead of

string toString() { return "foo"; }

for example, you would use:

void toString(void delegate(string) sink) { sink("foo"); }

The sink argument there is then free to view and discard the data or to make a private copy using whatever scheme it desires.
September 30, 2014
On 9/30/14 1:22 PM, Gary Willoughby wrote:
> What is a sink delegate?
>
> Discussed here:
> http://forum.dlang.org/thread/m0bdgg$1t7j$1@digitalmars.com?page=6#post-m0emvc:242av5:241:40digitalmars.com
>

Aside from Adam's answer, the term 'sink' means to draw out something, as in 'heat sink'. So basically a sink delegate is a place to put the string data.

-Steve
October 10, 2014
On Tuesday, 30 September 2014 at 17:27:09 UTC, Adam D. Ruppe wrote:
> On Tuesday, 30 September 2014 at 17:22:44 UTC, Gary Willoughby wrote:
>> What is a sink delegate?
>
> Instead of
>
> string toString() { return "foo"; }
>
> for example, you would use:
>
> void toString(void delegate(string) sink) { sink("foo"); }
>
> The sink argument there is then free to view and discard the data or to make a private copy using whatever scheme it desires.


How do you use that toString? Maybe an example? Below is my failed effort.

import std.stdio;

struct Try {
	string name;
	long age;
	
	void toString(void delegate(string) sink) {
		sink("foo");
	}
}

void main() {
	Try t = Try("Joel", 35);
	writeln(t);
}
October 10, 2014
On Friday, 10 October 2014 at 03:06:33 UTC, Joel wrote:

> How do you use that toString? Maybe an example?

void main() {
 	Try t = Try("Joel", 35);
	t.toString(s => writeln(s));
}

October 10, 2014
On 10/09/2014 08:06 PM, Joel wrote:
> On Tuesday, 30 September 2014 at 17:27:09 UTC, Adam D. Ruppe wrote:
>> On Tuesday, 30 September 2014 at 17:22:44 UTC, Gary Willoughby wrote:
>>> What is a sink delegate?
>>
>> Instead of
>>
>> string toString() { return "foo"; }
>>
>> for example, you would use:
>>
>> void toString(void delegate(string) sink) { sink("foo"); }
>>
>> The sink argument there is then free to view and discard the data or
>> to make a private copy using whatever scheme it desires.
>
>
> How do you use that toString? Maybe an example? Below is my failed effort.
>
> import std.stdio;
>
> struct Try {
>      string name;
>      long age;
>
>      void toString(void delegate(string) sink) {
>          sink("foo");
>      }
> }
>
> void main() {
>      Try t = Try("Joel", 35);
>      writeln(t);
> }

The signature of that toString is different from what I have been seeing and using. The following works:

    void toString(void delegate(const(char)[]) sink) const {

Ali

October 10, 2014
On Friday, 10 October 2014 at 04:42:04 UTC, thedeemon wrote:
> On Friday, 10 October 2014 at 03:06:33 UTC, Joel wrote:
>
>> How do you use that toString? Maybe an example?
>
> void main() {
>  	Try t = Try("Joel", 35);
> 	t.toString(s => writeln(s));
> }

I think that the problem pointed by the OP is that toString is usually used automatically for struct in std.conv when it's implemented. I'm myself quite dubitatif in front of this syntax, even if IIRC during one talk of the DConf 2014 someone claim that's it's faster.

October 10, 2014
On 10/10/14 1:00 AM, Ali Çehreli wrote:
> On 10/09/2014 08:06 PM, Joel wrote:
>> On Tuesday, 30 September 2014 at 17:27:09 UTC, Adam D. Ruppe wrote:
>>> On Tuesday, 30 September 2014 at 17:22:44 UTC, Gary Willoughby wrote:
>>>> What is a sink delegate?
>>>
>>> Instead of
>>>
>>> string toString() { return "foo"; }
>>>
>>> for example, you would use:
>>>
>>> void toString(void delegate(string) sink) { sink("foo"); }
>>>
>>> The sink argument there is then free to view and discard the data or
>>> to make a private copy using whatever scheme it desires.
>>
>>
>> How do you use that toString? Maybe an example? Below is my failed
>> effort.
>>
>> import std.stdio;
>>
>> struct Try {
>>      string name;
>>      long age;
>>
>>      void toString(void delegate(string) sink) {
>>          sink("foo");
>>      }
>> }
>>
>> void main() {
>>      Try t = Try("Joel", 35);
>>      writeln(t);
>> }
>
> The signature of that toString is different from what I have been seeing
> and using. The following works:
>
>      void toString(void delegate(const(char)[]) sink) const {

The delegate parameter is what is important. The function that is going to be passed in takes a const(char)[], which actually should, but does not, implicitly cast to a delegate(string) (see issue https://issues.dlang.org/show_bug.cgi?id=3075).

The const outside is irrelevant to whether it will accept it or not, that is a contract between the toString function and your object. If you want a non-const toString, I think that should work.

(actually, testing it...) Yep, it works without the const on the outside.

-Steve
October 10, 2014
On 10/10/2014 06:30 AM, Steven Schveighoffer wrote:

> On 10/10/14 1:00 AM, Ali Çehreli wrote:
>> On 10/09/2014 08:06 PM, Joel wrote:
>>> On Tuesday, 30 September 2014 at 17:27:09 UTC, Adam D. Ruppe wrote:
>>>> On Tuesday, 30 September 2014 at 17:22:44 UTC, Gary Willoughby wrote:
>>>>> What is a sink delegate?
>>>>
>>>> Instead of
>>>>
>>>> string toString() { return "foo"; }
>>>>
>>>> for example, you would use:
>>>>
>>>> void toString(void delegate(string) sink) { sink("foo"); }
>>>>
>>>> The sink argument there is then free to view and discard the data or
>>>> to make a private copy using whatever scheme it desires.
>>>
>>>
>>> How do you use that toString? Maybe an example? Below is my failed
>>> effort.
>>>
>>> import std.stdio;
>>>
>>> struct Try {
>>>      string name;
>>>      long age;
>>>
>>>      void toString(void delegate(string) sink) {
>>>          sink("foo");
>>>      }
>>> }
>>>
>>> void main() {
>>>      Try t = Try("Joel", 35);
>>>      writeln(t);
>>> }
>>
>> The signature of that toString is different from what I have been seeing
>> and using. The following works:
>>
>>      void toString(void delegate(const(char)[]) sink) const {
>
> The delegate parameter is what is important. The function that is going
> to be passed in takes a const(char)[],

That is what I meant.

> which actually should, but does
> not, implicitly cast to a delegate(string) (see issue
> https://issues.dlang.org/show_bug.cgi?id=3075).
>
> The const outside is irrelevant to whether it will accept it or not,
> that is a contract between the toString function and your object. If you
> want a non-const toString, I think that should work.
>
> (actually, testing it...) Yep, it works without the const on the outside.

But not for const objects. The following program does not call the user defined toString:

import std.stdio;
import std.conv;

struct S
{
    int i;

    void toString(void delegate(const(char)[]) sink)
    {
        sink(i.to!string);
    }
}

void main()
{
    const c = S(42);
    writeln(c);
}

Add a const at the end, now it calls the user defined one.

>
> -Steve

Ali

October 10, 2014
On 10/10/14 11:20 AM, Ali Çehreli wrote:
> On 10/10/2014 06:30 AM, Steven Schveighoffer wrote:
>
>  > The const outside is irrelevant to whether it will accept it or not,
>  > that is a contract between the toString function and your object. If you
>  > want a non-const toString, I think that should work.
>  >
>  > (actually, testing it...) Yep, it works without the const on the
> outside.
>
> But not for const objects.

I think that's what I said :) It's a contract between the toString function and your object, it has nothing to do with writeln accepting the function. There are some quirky requirements for certain "magic" functions in phobos that have to be exactly a certain signature for the compiler to use it.

Now, obviously, the toy example can be labeled const. But not one that might, say, cache some state in order to compute the output.

> The following program does not call the user
> defined toString:
>
> import std.stdio;
> import std.conv;
>
> struct S
> {
>      int i;
>
>      void toString(void delegate(const(char)[]) sink)
>      {
>          sink(i.to!string);

Don't do this. Do this instead:

import std.format;
sink.formattedWrite(i);

The former allocates memory on the heap, just to throw it away. You are completely losing the benefit of the sink.

-Steve
« First   ‹ Prev
1 2