January 11, 2014 Re: Should this work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Saturday, 11 January 2014 at 03:49:28 UTC, Manu wrote: > On 11 January 2014 00:26, monarch_dodra >> *However*, depending on the range type (non-transitive), popping might >> instantaneously invalidate the element you are operating on (think >> "byLine", that returns a "char[]", not a "string"). >> > > Since you mentioned it here yesterday, I thought 'byLine' would be useful > this morning... but I can't find it! > This is an embarrassing theme. > > Does it actually exist, and I am even further retarded... or did you just > make that up? It's because not actually a range adaptor or string adaptor, but an stdio function: http://dlang.org/phobos/std_stdio.html http://dlang.org/phobos/std_stdio.html#.File.byChunk http://dlang.org/phobos/std_stdio.html#.File.byLine It's designed that way as to avoid allocating a new buffer. Related: That said, "std.algorithm.splitter" will lazily split a range of characters into lines, if you give it the "right" terminator. Unfortunately, it only accepts a single terminator, or a pred, so you can't do "splitter('\n' "\r\n")". You can also use "http://dlang.org/phobos/std_string.html#.splitLines" to eagerly and conveniently (and correctly) do this. |
January 11, 2014 Re: Should this work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Saturday, 11 January 2014 at 02:15:15 UTC, Manu wrote:
> That is the world today, that is where the bar is. D will be wildly
> successful on the day that programmers that have never seen it before can
> come along, effortlessly write whatever code they're trying to write,
> offered useful help by the compiler along the way, walk away feeling really
> smart and happy with their experience.
That is not a D I want to be part of.
Let's give a container library to someone that knows nothing of containers, they'll say "what's with all these 'red-black trees' and 'linked lists'? I just want to store a bunch of numbers!", so you streamline the design to one container that does everything in O(n) time or better. Much simpler than the user having to learn anything, and they can get things done effortlessly and feel smart and happy.
Let's get rid of value types and just heap allocate everything in the GC and make copies on every write. Much easier than learning about object lifetime and mutability.
Let's get rid of static typing and make D dynamically typed. Much easier than learning about type systems.
That's what D becomes if users aren't willing to RTFM. There are trade-offs in language/library design and D has traded some convenience for efficiency. You cannot have the high-performance and powerful modelling capabilities of ranges with unbounded convenience.
I'm not saying convenience isn't important, but things like ranges have subtleties, and need those subtleties to achieve the performance/power they were designed for. If you want that, you'll need to bite the bullet and learn, if you don't, then just go and write Python.
<3
|
January 11, 2014 Re: Should this work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Alexander Attachments:
| On 11 January 2014 21:29, Peter Alexander <peter.alexander.au@gmail.com>wrote: > On Saturday, 11 January 2014 at 02:15:15 UTC, Manu wrote: > >> That is the world today, that is where the bar is. D will be wildly >> successful on the day that programmers that have never seen it before can >> come along, effortlessly write whatever code they're trying to write, >> offered useful help by the compiler along the way, walk away feeling >> really >> smart and happy with their experience. >> > > That is not a D I want to be part of. > > Let's give a container library to someone that knows nothing of containers, they'll say "what's with all these 'red-black trees' and 'linked lists'? I just want to store a bunch of numbers!", so you streamline the design to one container that does everything in O(n) time or better. Much simpler than the user having to learn anything, and they can get things done effortlessly and feel smart and happy. > > Let's get rid of value types and just heap allocate everything in the GC and make copies on every write. Much easier than learning about object lifetime and mutability. > > Let's get rid of static typing and make D dynamically typed. Much easier than learning about type systems. > > That's what D becomes if users aren't willing to RTFM. There are trade-offs in language/library design and D has traded some convenience for efficiency. You cannot have the high-performance and powerful modelling capabilities of ranges with unbounded convenience. > > I'm not saying convenience isn't important, but things like ranges have subtleties, and need those subtleties to achieve the performance/power they were designed for. If you want that, you'll need to bite the bullet and learn, if you don't, then just go and write Python. > > <3 > *sigh* If you can't see value in intuitive design as a basic principle, then my points about people on this forum being so disconnected from the world of normal programmers is even more true than I thought. Particularly if you find the concept so threatening that you need to make dumb comments mocking the principle. I never suggested making technological concessions for the principle, just keep it in clear focus while designing your APIs. Do user testing, get better feedback, identify common pitfalls. I'm just talking about quality, and greater consideration wrt api design and more user testing before committing new features to the slate. |
January 11, 2014 Re: Should this work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Saturday, 11 January 2014 at 12:22:44 UTC, Manu wrote:
> *sigh*
>
> If you can't see value in intuitive design as a basic principle, then my
> points about people on this forum being so disconnected from the world of
> normal programmers is even more true than I thought.
> Particularly if you find the concept so threatening that you need to make
> dumb comments mocking the principle.
>
> I never suggested making technological concessions for the principle, just
> keep it in clear focus while designing your APIs. Do user testing, get
> better feedback, identify common pitfalls.
> I'm just talking about quality, and greater consideration wrt api design
> and more user testing before committing new features to the slate.
In our defense, I've found that whenever I *do* find the APIs lacking, it is in contrast to how powerful it is to begin with. I've done things in D I would have never *dreamed* of doing in C++. You kind of get used to "If it can be done, there's a D 1-liner for it". However, it's not actually the case. It doesn't necessarily mean the API is lacking though (IMO).
Also, the concepts of ranges and built in UTF is relatively new. In C++, there are a ton of string operations you are supposed to do via iterators and algorithms. However, once you take unicode into account, it tends to fall short, and you start realizing that a string specific function is necessary (because of UTF) when the standard "algorithm" approach used to be correct.
The very fact that a "string" is bidirectional and not random access (in terms of codepoints) is also something... you have to get used to.
|
January 11, 2014 Re: Should this work? | ||||
---|---|---|---|---|
| ||||
On 11 January 2014 01:37, Manu <turkeyman@gmail.com> wrote:
> On 11 January 2014 05:57, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>>
>> On 1/10/14 7:23 AM, Manu wrote:
>>>
>>> This is what I've done. I'm just surprised that such an obvious function
>>> doesn't exist, and suspect I was just retarded at phobos again.
>>> Having a function that does this is kinda important to simplify lots of
>>> expressions that otherwise need to be broken out across a bunch of lines.
>>
>>
>> I doubt it simplifies a lot.
>
>
> Well you can pass it as an argument, or use it as a term in an expression
> without splitting it across a whole bunch of lines.
> Yes, it really does simplify many expressions.
>
> I'm working on something where I go along munching tokens from the stream,
> and performing fairly arbitrary sequential logic on them.
> My code would be almost twice as long if I needed a second line to advance
> the range after each line where I consider the front token's value.
>
> It sucks particularly when there's 'if's involved:
>
> if(r.front == x)
> {
> r.popFront();
> x = r.front();
> r.popFront();
> }
> else
> {
> r.popFront();
> y = r.front();
> r.popFront();
> }
>
>
> Surely this is obviously better:
>
> if(r.getAndPopFront() == x)
> x = r.getAndPopFront();
> else
> y = r.getAndPopFront();
>
I recall mentioning something like this, way back in 2011 - possibly in IRC. People like the idea, no one actually sat down and wrote it. :-)
Regards
Iain
|
January 11, 2014 Re: Should this work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | Am Sat, 11 Jan 2014 10:40:25 +1000 schrieb Manu <turkeyman@gmail.com>: > On 11 January 2014 01:20, John Colvin <john.loughran.colvin@gmail.com>wrote: > > > On Friday, 10 January 2014 at 15:19:39 UTC, John Colvin wrote: > > > >> On Friday, 10 January 2014 at 15:05:18 UTC, monarch_dodra wrote: > >> > >>> On Friday, 10 January 2014 at 14:31:31 UTC, John Colvin wrote: > >>> > >>>> or if you want something short and simple, define a free function: > >>>> auto popFrontRet(R)(ref R range) > >>>> if(isInputRange!R) > >>>> { > >>>> range.popFront(); > >>>> assert(!range.empty); > >>>> return range.front; > >>>> } > >>>> > >>> > >>> *Unless* I'm mistaken, he was asking for something that returns the *popped* element? > >>> > >>> Re-reading the question, it does kind of sound a bit ambiguous now. > >>> > >> > >> Woops, of course: > >> > >> auto popFrontRet(R)(ref R range) > >> if(isInputRange!R) > >> { > >> auto tmp = range.front; > >> range.popFront(); > >> } > >> > >> > >> That also invalidates my second point to do with emptiness. > >> > > > > ugh, today is not my day: > > > > auto popFrontRet(R)(ref R range) > >> if(isInputRange!R) > >> { > >> auto tmp = range.front; > >> range.popFront(); > >> return tmp; > >> } > >> This returns garbage for ranges that reuse their internal buffer for performance reasons. E.g. byLine will overwrite what tmp points to in the call to popFront(); > Yes, this is what I did. It should be added to phobos, but I figured > there's a reason it's not there... > My point was, I want this more often than I want either of those other > primitives. I'm surprised it doesn't exist, and suspected I was just being > blind again. > > I also wrote popFrontRetN to capture more than one element from the start. What about take(n) or take(n).array() ? -- Marco |
January 11, 2014 Re: Should this work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | Am Sat, 11 Jan 2014 10:56:32 +1000 schrieb Manu <turkeyman@gmail.com>: > On 11 January 2014 02:28, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org > > wrote: > > > On 1/10/14 6:02 AM, Manu wrote: > > > >> I won't start another annoying thread. > >> > > > > Great idea. > > > > > > What's the go with popFront()... it returns nothing? > >> I almost always want to pop and return the front element. I can't find a function to do that... have I missed something again? > >> > > > > http://dlang.org/phobos/std_range.html#.dropOne > > > > What do you want us to do, RTFM to you? > > > > That's not what I want at all. > Maybe moveFront is what I want... but it's not clear. It doesn't really say > what it does in the docs. > Looking at the code, it's way more complex than I'd expect, and I can't see > anywhere that it pops it from the range, which leads me to suspect it's not > what I want either. I have no idea what moveFront is. I think it is a function to move items out of a container. I.e. move the ownership to the caller and leave the slot in the container in a harmless/.init state. -- Marco |
January 13, 2014 Re: Should this work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Fri, 10 Jan 2014 19:47:07 -0000, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote: > On Sat, Jan 11, 2014 at 02:14:41AM +1000, Manu wrote: > [...] >> One more, again here to reduce spam... >> >> 2 overloads exist: >> void func(const(char)* str); >> void func(const(char)[] str); >> >> Called with literal string: >> func("literal"); >> >> called with argument types (string) matches both. >> >> I appreciate the convenience of the automatic string literal -> >> const(char)* cast. But in this case, surely it should just choose the >> array version of the function, like it does it calling with a 'string' >> variable? The convenience should be just that, a convenience, not a >> hard rule...? > > File a bug against dmd for this? I agree that it should match the array > overload, not the pointer overload. I'm not sure if it's fixable, > though, due to the way overloads are resolved currently. But maybe Kenji > has a way. ;) I think this should remain an error, for the same reason as any other overload resolution error; you might have one, and add the second and silently behaviour changes - this is bad. Instead.. isn't the first overload strictly incorrect, unless that first overload expects a null terminated **UTF-8** string.. if it's a C function it should be const(ubyte)* str right? What overload does D select if you use that instead? R -- Using Opera's revolutionary email client: http://www.opera.com/mail/ |
January 17, 2014 Re: Should this work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | Am Mon, 13 Jan 2014 11:40:19 -0000 schrieb "Regan Heath" <regan@netmail.co.nz>: > On Fri, 10 Jan 2014 19:47:07 -0000, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote: > > > On Sat, Jan 11, 2014 at 02:14:41AM +1000, Manu wrote: > > [...] > >> One more, again here to reduce spam... > >> > >> 2 overloads exist: > >> void func(const(char)* str); > >> void func(const(char)[] str); > >> > >> Called with literal string: > >> func("literal"); > >> > >> called with argument types (string) matches both. > >> > >> I appreciate the convenience of the automatic string literal -> const(char)* cast. But in this case, surely it should just choose the array version of the function, like it does it calling with a 'string' variable? The convenience should be just that, a convenience, not a hard rule...? > > > > File a bug against dmd for this? I agree that it should match the array overload, not the pointer overload. I'm not sure if it's fixable, though, due to the way overloads are resolved currently. But maybe Kenji has a way. ;) > > I think this should remain an error, for the same reason as any other overload resolution error; you might have one, and add the second and silently behaviour changes - this is bad. > > Instead.. isn't the first overload strictly incorrect, unless that first overload expects a null terminated **UTF-8** string.. if it's a C function it should be const(ubyte)* str right? What overload does D select if you use that instead? > > R A few days ago I noticed - in shock :D - that I had this situation with a \0 terminated D string literal and totally expected the char* overload to be chosen! I want to object to your claim that C functions should take const(ubyte)*. When working in Windows that is correct due to the ANSI/Microsoft codepage madness, but on Mac OS X and Linux UTF-8 can be assumed. -- Marco |
January 17, 2014 Re: Should this work? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marco Leise | Am Fri, 17 Jan 2014 21:38:18 +0100 schrieb Marco Leise <Marco.Leise@gmx.de>: > Am Mon, 13 Jan 2014 11:40:19 -0000 > schrieb "Regan Heath" <regan@netmail.co.nz>: > > > On Fri, 10 Jan 2014 19:47:07 -0000, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote: > > > > > On Sat, Jan 11, 2014 at 02:14:41AM +1000, Manu wrote: > > > [...] > > >> One more, again here to reduce spam... > > >> > > >> 2 overloads exist: > > >> void func(const(char)* str); > > >> void func(const(char)[] str); > > >> > > >> Called with literal string: > > >> func("literal"); > > >> > > >> called with argument types (string) matches both. > > >> > > >> I appreciate the convenience of the automatic string literal -> const(char)* cast. But in this case, surely it should just choose the array version of the function, like it does it calling with a 'string' variable? The convenience should be just that, a convenience, not a hard rule...? > > > > > > File a bug against dmd for this? I agree that it should match the array overload, not the pointer overload. I'm not sure if it's fixable, though, due to the way overloads are resolved currently. But maybe Kenji has a way. ;) > > > > I think this should remain an error, for the same reason as any other overload resolution error; you might have one, and add the second and silently behaviour changes - this is bad. > > > > Instead.. isn't the first overload strictly incorrect, unless that first overload expects a null terminated **UTF-8** string.. if it's a C function it should be const(ubyte)* str right? What overload does D select if you use that instead? > > > > R > > A few days ago I noticed - in shock :D - that I had this situation with a \0 terminated D string literal and totally expected the char* overload to be chosen! > > I want to object to your claim that C functions should take const(ubyte)*. When working in Windows that is correct due to the ANSI/Microsoft codepage madness, but on Mac OS X and Linux UTF-8 can be assumed. Then again, technically you can still set any encoding you like, so my argument is moot and you are correct that const(ubyte)* should be used in any case. Heck, even most of Phobos probably passes UTF-8 directly into OS APIs without converting to the current locale. :p -- Marco |
Copyright © 1999-2021 by the D Language Foundation