Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 18, 2014 Should formattedWrite take the outputrange by ref? | ||||
---|---|---|---|---|
| ||||
I want to print a tree structure and need to keep track of the indention for different parts of the tree. My idea was to write a generic wrapper for an output range that outputs tabs when it encounters a newline. This wrapper has internal state and if I want to use formattedWrite with this wrapper than state changes don't propagate to the calling context because by value semantics. Short solution: I'm using a class now. But shouldn't formattedWrite take it's output range by ref? Does anyone else have a use case for this and might this cause any problems? |
January 18, 2014 Re: Should formattedWrite take the outputrange by ref? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tobias Pankrath | On Saturday, 18 January 2014 at 21:55:54 UTC, Tobias Pankrath wrote:
> I want to print a tree structure and need to keep track of the indention for different parts of the tree. My idea was to write a generic wrapper for an output range that outputs tabs when it encounters a newline. This wrapper has internal state and if I want to use formattedWrite with this wrapper than state changes don't propagate to the calling context because by value semantics.
>
> Short solution: I'm using a class now. But shouldn't formattedWrite take it's output range by ref? Does anyone else have a use case for this and might this cause any problems?
*I* think it should. File a report, and I'll see what I can do about it. The problem with these kinds of things though might be breaking existing code...
|
January 18, 2014 Re: Should formattedWrite take the outputrange by ref? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tobias Pankrath | On Saturday, 18 January 2014 at 21:55:54 UTC, Tobias Pankrath
wrote:
> I want to print a tree structure and need to keep track of the indention for different parts of the tree. My idea was to write a generic wrapper for an output range that outputs tabs when it encounters a newline. This wrapper has internal state and if I want to use formattedWrite with this wrapper than state changes don't propagate to the calling context because by value semantics.
>
> Short solution: I'm using a class now.
Alternatively, pass a pointer: formattedWrite(&writer, ...)
|
January 18, 2014 Re: Should formattedWrite take the outputrange by ref? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | monarch_dodra:
> *I* think it should. File a report, and I'll see what I can do about it. The problem with these kinds of things though might be breaking existing code...
Given the frequency of bugs caused by such functions that require a pointer to the data, I think that a breaking change is the smaller problem.
Bye,
bearophile
|
January 18, 2014 Re: Should formattedWrite take the outputrange by ref? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Saturday, 18 January 2014 at 22:58:59 UTC, bearophile wrote:
> monarch_dodra:
>
>> *I* think it should. File a report, and I'll see what I can do about it. The problem with these kinds of things though might be breaking existing code...
>
> Given the frequency of bugs caused by such functions that require a pointer to the data, I think that a breaking change is the smaller problem.
>
> Bye,
> bearophile
I actually didn't think that a ptr (to output range) would work. This way we can have best of both worlds and I'm happy with it.
|
January 19, 2014 Re: Should formattedWrite take the outputrange by ref? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tobias Pankrath | On Saturday, 18 January 2014 at 23:06:42 UTC, Tobias Pankrath wrote:
> I actually didn't think that a ptr (to output range) would work. This way we can have best of both worlds and I'm happy with it.
A fun fact is that since "." notation works with pointers, more often than not, if "T" verifies some trait "isOutputRange", more often than not, so will "T*".
But this is more of a by-product than an actual rule, and, as a rule of thumb, may not be something you want to rely on in a general sense. Limitations include:
Type checking: If "R" is a random access range, "R*" will only be an input range, because "p.save" will return an "R", and not an "R*" :/
Also, it is limited to member functions, and not generic UFCS: For example, while in the general sense, "R is input range" => "R* is input range", this will fail for "T[]*", because slices have a non-member popFront, so "p.popFront()" will not actually match a function, and "T[]*" will fail the input range validation :/
So, my conclusion, "*" might be a workable solution. But simply taking by ref would be cleaner, and make more sense as a whole.
|
January 19, 2014 Re: Should formattedWrite take the outputrange by ref? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Sunday, 19 January 2014 at 15:03:13 UTC, monarch_dodra wrote:
> So, my conclusion, "*" might be a workable solution. But simply taking by ref would be cleaner, and make more sense as a whole.
Or a special template constraint path for T*.
foo(T)(T t) if (is(T = Q*)) && manyOtherChecks!(Q)
foo(T)(T t) if (!is(T = Q*)) && manyOtherChecks!(T)
Maybe that will break less code.
|
January 19, 2014 Re: Should formattedWrite take the outputrange by ref? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tobias Pankrath | On Sunday, 19 January 2014 at 15:12:07 UTC, Tobias Pankrath wrote: > On Sunday, 19 January 2014 at 15:03:13 UTC, monarch_dodra wrote: > >> So, my conclusion, "*" might be a workable solution. But simply taking by ref would be cleaner, and make more sense as a whole. > > Or a special template constraint path for T*. > > foo(T)(T t) if (is(T = Q*)) && manyOtherChecks!(Q) > foo(T)(T t) if (!is(T = Q*)) && manyOtherChecks!(T) > > Maybe that will break less code. But maybe we really should go for taking the output range by reference. See https://d.puremagic.com/issues/show_bug.cgi?id=10291 https://d.puremagic.com/issues/show_bug.cgi?id=9102 Created a new report for this: https://d.puremagic.com/issues/show_bug.cgi?id=11951 |
January 19, 2014 Re: Should formattedWrite take the outputrange by ref? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tobias Pankrath | On Sunday, 19 January 2014 at 15:28:04 UTC, Tobias Pankrath wrote:
> On Sunday, 19 January 2014 at 15:12:07 UTC, Tobias Pankrath wrote:
>> On Sunday, 19 January 2014 at 15:03:13 UTC, monarch_dodra wrote:
>>
>>> So, my conclusion, "*" might be a workable solution. But simply taking by ref would be cleaner, and make more sense as a whole.
>>
>> Or a special template constraint path for T*.
>>
>> foo(T)(T t) if (is(T = Q*)) && manyOtherChecks!(Q)
>> foo(T)(T t) if (!is(T = Q*)) && manyOtherChecks!(T)
>>
>> Maybe that will break less code.
>
> But maybe we really should go for taking the output range by reference. See https://d.puremagic.com/issues/show_bug.cgi?id=10291
> https://d.puremagic.com/issues/show_bug.cgi?id=9102
>
> Created a new report for this: https://d.puremagic.com/issues/show_bug.cgi?id=11951
Thanks! I'll look into these.
|
September 03, 2014 Re: Should formattedWrite take the outputrange by ref? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | +1 I've been bitten by this also. |
Copyright © 1999-2021 by the D Language Foundation