Jump to page: 1 2
Thread overview
splitter, compilation issue
Oct 27, 2015
sigod
Oct 27, 2015
Ali Çehreli
Oct 27, 2015
sigod
Oct 27, 2015
Adam D. Ruppe
Oct 27, 2015
Ali Çehreli
Oct 27, 2015
Jonathan M Davis
Oct 27, 2015
sigod
Oct 27, 2015
sigod
Oct 27, 2015
Adam D. Ruppe
Oct 27, 2015
sigod
Oct 28, 2015
sigod
Oct 28, 2015
Adam D. Ruppe
October 27, 2015
Here's simple code:

	import std.algorithm;
	import std.array;
	import std.file;
	
	void main(string[] args)
	{
		auto t = args[1].readText()
			.splitter('\n')
			.filter!(e => e.length)
			.split("---")
		;
	}

Looks like it should work, but it won't compile. DMD 2.068.2 fails with this error:

	Error: template std.algorithm.iteration.splitter cannot deduce function from argument types !()(FilterResult!(__lambda2, Result), string), candidates are:
	...
	Error: template instance std.array.split!(FilterResult!(__lambda2, Result), string) error instantiating

It compiles if I insert `.array` before `.split(...`.

Am I missing something? Or it's a bug? I've tried to make a brief search in the bug tracker, but didn't found anything.

P.S. dpaste gives very strange error:

	/d712/f815.d(8): Error: unterminated character constant
	/d712/f815.d(9): Error: unterminated character constant
	... and so on

October 27, 2015
On 10/27/2015 01:58 PM, sigod wrote:
> Here's simple code:
>
>      import std.algorithm;
>      import std.array;
>      import std.file;
>
>      void main(string[] args)
>      {
>          auto t = args[1].readText()
>              .splitter('\n')
>              .filter!(e => e.length)
>              .split("---")
>          ;
>      }
>
> Looks like it should work

split's documentation says that it requires a ForwardRange but the output of filter is an InputRange. (I can't imagine now why split has that requirement.)

Ali

October 27, 2015
On Tuesday, 27 October 2015 at 21:45:10 UTC, Ali Çehreli wrote:
> On 10/27/2015 01:58 PM, sigod wrote:
>> Here's simple code:
>>
>>      import std.algorithm;
>>      import std.array;
>>      import std.file;
>>
>>      void main(string[] args)
>>      {
>>          auto t = args[1].readText()
>>              .splitter('\n')
>>              .filter!(e => e.length)
>>              .split("---")
>>          ;
>>      }
>>
>> Looks like it should work
>
> split's documentation says that it requires a ForwardRange but the output of filter is an InputRange. (I can't imagine now why split has that requirement.)
>
> Ali

It still doesn't work.

	src\phobos\std\array.d(1562): Error: template std.algorithm.iteration.splitter cannot deduce function from argument types !()(Result, string)

Sorry, I should've simplified example more.
October 27, 2015
On Tuesday, October 27, 2015 20:58:56 sigod via Digitalmars-d-learn wrote:
> Here's simple code:
>
>   import std.algorithm;
>   import std.array;
>   import std.file;
>
>   void main(string[] args)
>   {
>       auto t = args[1].readText()
>           .splitter('\n')
>           .filter!(e => e.length)
>           .split("---")
>       ;
>   }
>
> Looks like it should work, but it won't compile. DMD 2.068.2 fails with this error:
>
>   Error: template std.algorithm.iteration.splitter cannot deduce
> function from argument types !()(FilterResult!(__lambda2,
> Result), string), candidates are:
>   ...
>   Error: template instance
> std.array.split!(FilterResult!(__lambda2, Result), string) error
> instantiating
>
> It compiles if I insert `.array` before `.split(...`.
>
> Am I missing something? Or it's a bug? I've tried to make a brief search in the bug tracker, but didn't found anything.
>
> P.S. dpaste gives very strange error:
>
>   /d712/f815.d(8): Error: unterminated character constant
>   /d712/f815.d(9): Error: unterminated character constant
>   ... and so on

Well, split calls splitter, and it doesn't make much of an attempt to check its arguments in its template constraint, mostly passing the buck onto splitter, since it's really just a wrapper around splitter that calls array on the result. You could actually reduce your code down to something more like

auto t = "hello".filter!"true"().splitter(" ");

and you'd have the same problem. And looking at splitter's template constraint, it requires either a narrow string (which the result of filter is not) or a range for which hasSlicing is true (which is not the case for the result of filter). Whether splitter could be implemented without that (e.g. returning a range of Take), I don't know, but it's pretty clear that the current implementation requires slicing, and if you're using filter, that means that you'd need to do something like use array to convert it to a range which _can_ be sliced to pass to split or splitter.

- Jonathan M Davis

October 27, 2015
On Tuesday, 27 October 2015 at 21:45:10 UTC, Ali Çehreli wrote:
> split's documentation says that it requires a ForwardRange but the output of filter is an InputRange. (I can't imagine now why split has that requirement.)

You need to .save at the beginning so when you hit the split point, it can present the whole string as front. You don't know if you've hit the split point until after you've done a fair amount of popFront calls, so if you haven't saved it before, it is impossible to return the first element before the splitter string.
October 27, 2015
On 10/27/2015 02:55 PM, Adam D. Ruppe wrote:
> On Tuesday, 27 October 2015 at 21:45:10 UTC, Ali Çehreli wrote:
>> split's documentation says that it requires a ForwardRange but the
>> output of filter is an InputRange. (I can't imagine now why split has
>> that requirement.)
>
> You need to .save at the beginning so when you hit the split point, it
> can present the whole string as front. You don't know if you've hit the
> split point until after you've done a fair amount of popFront calls, so
> if you haven't saved it before, it is impossible to return the first
> element before the splitter string.

I knew that! :p

Ali

October 27, 2015
On Tuesday, 27 October 2015 at 21:54:33 UTC, Jonathan M Davis wrote:
> Well, split calls splitter, and it doesn't make much of an attempt to check its arguments in its template constraint, mostly passing the buck onto splitter, since it's really just a wrapper around splitter that calls array on the result.

Looks like one more way to improve documentation.

October 27, 2015
Well, problem boils down to `splitter` having a greater constraints than most functions can meet.

Thanks everyone for clarification.

P.S. Maybe I should repost my question on SO? I really thought it was a bug, so I posted it here.
October 27, 2015
On Tuesday, 27 October 2015 at 22:18:55 UTC, sigod wrote:
> P.S. Maybe I should repost my question on SO? I really thought it was a bug, so I posted it here.

You could, but I'd say the same thing there - it is no bug, the algorithm legitimately needs that functionality to split successfully. At the same time, filter legitimately needs to /drop/ that functionality to work efficiently.

So the error kinda sucks (maybe i should write this as a tip, whenever you see that pattern, adding a .array can work around it), but it isn't a bug.


The reason splitter doesn't try to automatically buffer or something like that is that std.algorithm tries to be as low cost as possible in all cases, and asks you to be aware of and pay the cost when it needs to occur.

So if it needs a buffer and can't get one for free, it fails to compile, so you are aware of the problem and can provide one that works best for you (or just stick in .array somewhere to do an easy, generic solution)
October 27, 2015
On Tuesday, 27 October 2015 at 22:33:32 UTC, Adam D. Ruppe wrote:
> On Tuesday, 27 October 2015 at 22:18:55 UTC, sigod wrote:
>> P.S. Maybe I should repost my question on SO? I really thought it was a bug, so I posted it here.
>
> You could, but I'd say the same thing there

I don't expect different answer there. Main idea is to increase language presence and therefore popularity.

I saw someone (I think it was Martin Nowak) somewhere saying that maybe we should move questions from Learn forum to SO.

> or just stick in .array somewhere to do an easy, generic solution

Which completely works in this case. Since I'm writing just a code generation tool, which I'll need to use just a few times.
« First   ‹ Prev
1 2