Thread overview | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 13, 2013 D Ranges | ||||
---|---|---|---|---|
| ||||
A short report on component programming and ranges. A lot of my code deals with transforming and reformatting input, e.g. text is split into sentences and words for grammatical parsing (part of speech) and phonetic transcriptions. I'm using D ranges and component programming and I'm quite happy with "one-liners" like foreach (bySentence().byWord().byWhateverFormat().byReformatAgain()) { // Whatever } The code is much easier to maintain, neater and more efficient within each component. Sometimes, however, I wonder how I should design my ranges. It is hard to decide whether to use them as pure pipes or semi-output ranges. "Semi" because they're not sinks as defined by put() but still they can hold data (an array of reformatted strings for example) that could be accessed by using Range.data. I'm not sure as regards "best practice" and whether or not I'm wasting resources by storing data internally. On the other hand, it might be handy to have access to the data stored internally. Does anyone have a rough guide to D ranges? Like Case 1: Use XYZ, Case 2: Use ZYX etc. (I've read this tutorial http://ddili.org/ders/d.en/ranges.html, and I'd like to thank Ali for that! It helped me a lot.) Another issue I've come across is how to integrate CP and ranges into an OO framework. I figure that ranges are good work horses, but it makes sense to keep the overall logic in an OO fashion. Or could it be that D's structs and ranges will replace OOP as we no it (a class-free system). |
September 13, 2013 Re: D Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris | Chris: > A short report on component programming and ranges. > > A lot of my code deals with transforming and reformatting input, e.g. text is split into sentences and words for grammatical parsing (part of speech) and phonetic transcriptions. I'm using D ranges and component programming and I'm quite happy with "one-liners" like > > foreach (bySentence().byWord().byWhateverFormat().byReformatAgain()) { > // Whatever > } In most cases today you are free to omit those (): foreach (bySentence.byWord.byWhateverFormat.byReformatAgain) { Bye, bearophile |
September 13, 2013 Re: D Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Friday, 13 September 2013 at 13:31:18 UTC, bearophile wrote:
> In most cases today you are free to omit those ():
>
> foreach (bySentence.byWord.byWhateverFormat.byReformatAgain) {
>
> Bye,
> bearophile
...but you shouldn't if you care about readability (leave at least the last pair in the line) :P
|
September 13, 2013 Re: D Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Friday, 13 September 2013 at 13:42:07 UTC, Dicebot wrote:
> On Friday, 13 September 2013 at 13:31:18 UTC, bearophile wrote:
>> In most cases today you are free to omit those ():
>>
>> foreach (bySentence.byWord.byWhateverFormat.byReformatAgain) {
>>
>> Bye,
>> bearophile
>
> ...but you shouldn't if you care about readability (leave at least the last pair in the line) :P
It also helps other people (and me) to realize that it actually _does_ something and doesn't just return a value. Often (not always of course), if you omit the brackets it returns a value without doing anything. But that's just a personal convention I might abandon further down the road.
|
September 13, 2013 Re: D Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Friday, 13 September 2013 at 13:42:07 UTC, Dicebot wrote:
> On Friday, 13 September 2013 at 13:31:18 UTC, bearophile wrote:
>> In most cases today you are free to omit those ():
>>
>> foreach (bySentence.byWord.byWhateverFormat.byReformatAgain) {
>>
>> Bye,
>> bearophile
>
> ...but you shouldn't if you care about readability (leave at least the last pair in the line) :P
That is my gideline as well. Keep at least the last one.
|
September 13, 2013 Re: D Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris | On Friday, 13 September 2013 at 14:39:29 UTC, Chris wrote:
> On Friday, 13 September 2013 at 13:42:07 UTC, Dicebot wrote:
>> On Friday, 13 September 2013 at 13:31:18 UTC, bearophile wrote:
>>> In most cases today you are free to omit those ():
>>>
>>> foreach (bySentence.byWord.byWhateverFormat.byReformatAgain) {
>>>
>>> Bye,
>>> bearophile
>>
>> ...but you shouldn't if you care about readability (leave at least the last pair in the line) :P
>
> It also helps other people (and me) to realize that it actually _does_ something and doesn't just return a value. Often (not always of course), if you omit the brackets it returns a value without doing anything. But that's just a personal convention I might abandon further down the road.
Since most ranges in std.algorithm are lazy they are usually not doing anything but setting a few members and returning a new range, often without having even touched the input range. Thinking about it I think I may start using () to denote eager versus lazy ranges in my UFCS chains.
|
September 13, 2013 Re: D Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Brad Anderson | On Friday, 13 September 2013 at 17:35:21 UTC, Brad Anderson wrote:
> On Friday, 13 September 2013 at 14:39:29 UTC, Chris wrote:
>> On Friday, 13 September 2013 at 13:42:07 UTC, Dicebot wrote:
>>> On Friday, 13 September 2013 at 13:31:18 UTC, bearophile wrote:
>>>> In most cases today you are free to omit those ():
>>>>
>>>> foreach (bySentence.byWord.byWhateverFormat.byReformatAgain) {
>>>>
>>>> Bye,
>>>> bearophile
>>>
>>> ...but you shouldn't if you care about readability (leave at least the last pair in the line) :P
>>
>> It also helps other people (and me) to realize that it actually _does_ something and doesn't just return a value. Often (not always of course), if you omit the brackets it returns a value without doing anything. But that's just a personal convention I might abandon further down the road.
>
> Since most ranges in std.algorithm are lazy they are usually not doing anything but setting a few members and returning a new range, often without having even touched the input range. Thinking about it I think I may start using () to denote eager versus lazy ranges in my UFCS chains.
This reminds me, I have to check whether my ranges are lazy enough (like myself).
|
September 14, 2013 Re: D Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris | On Friday, 13 September 2013 at 11:31:24 UTC, Chris wrote: > Sometimes, however, I wonder how I should design my ranges. It is hard to decide whether to use them as pure pipes or semi-output ranges. "Semi" because they're not sinks as defined by put() but still they can hold data (an array of reformatted strings for example) that could be accessed by using Range.data. I'm not sure as regards "best practice" and whether or not I'm wasting resources by storing data internally. On the other hand, it might be handy to have access to the data stored internally. Does anyone have a rough guide to D ranges? Like Case 1: Use XYZ, Case 2: Use ZYX etc. > (I've read this tutorial http://ddili.org/ders/d.en/ranges.html, and I'd like to thank Ali for that! It helped me a lot.) There isn't a guide in the manner you desire. In my experience I generally don't hold any more data than the value returned by front (to prevent recalculation). Right now I don't recall what situations I've needed to store the intermediary data, but I know how you feel about having a input rang which is like an output range simply returning a range to provide the chaining ability. I also generally don't find a need to specify output ranges. Output ranges are the end of the line so they kill component programming > Another issue I've come across is how to integrate CP and ranges into an OO framework. I figure that ranges are good work horses, but it makes sense to keep the overall logic in an OO fashion. Or could it be that D's structs and ranges will replace OOP as we no it (a class-free system). I spent much of my initial time programming in Java, so I have a good grasp of the constructs behind OOP (and a little bit of the prototyping style known to be in Javascript). I also think I have a pretty good grasp on designing for OOP, though I do have a lot I could learn. I hate OOP. I believe it has a place in software design, I just haven't found it yet. Templates cause a lot of problem, though I need to look into using the trick using /final/. Trying to do inheritance when your interface defines that it takes a range or returns a range. Though generics in C# work quite nicely. The other issue I have is that OOP is very resistant to change and testing. It is hard enough to get all the data needed for your test cases, then throw in designing mock objects and blah blah, it quickly becomes a mess. And even if you skip all the testing aspects, if you want to make changes there is a giant structure you're making changes for. Yes had I done a better job designing my structure up front to allow for such change I wouldn't be in this mess... Anyway, my recommendation isn't to build up a class structure just because that is what you would do in another language. Figure out if the usability provided by inheritance is what you want, if not struct with helper functions seems to be simplest in development and maintenance. Destroy. |
September 14, 2013 Re: D Ranges | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | On Saturday, September 14, 2013 04:10:09 Jesse Phillips wrote:
> Anyway, my recommendation isn't to build up a class structure just because that is what you would do in another language. Figure out if the usability provided by inheritance is what you want, if not struct with helper functions seems to be simplest in development and maintenance. Destroy.
I find that I use classes very rarely in D. Once in a while, I need polymorphism, and in that situation, I use classes, but at least in the types of programs that I've usually been writing, polymorphism has rarely made much sense. Structs deal with most everything just fine.
Classes definitely have their uses, but IMHO, they should not be the first tool to pull out of your toolbox when writing a D program. Just use them when you actually need them.
- Jonathan M Davis
|
September 14, 2013 Re: D Ranges | ||||
---|---|---|---|---|
| ||||
On Fri, Sep 13, 2013 at 10:49:23PM -0400, Jonathan M Davis wrote: > On Saturday, September 14, 2013 04:10:09 Jesse Phillips wrote: > > Anyway, my recommendation isn't to build up a class structure just because that is what you would do in another language. Figure out if the usability provided by inheritance is what you want, if not struct with helper functions seems to be simplest in development and maintenance. Destroy. > > I find that I use classes very rarely in D. Once in a while, I need polymorphism, and in that situation, I use classes, but at least in the types of programs that I've usually been writing, polymorphism has rarely made much sense. Structs deal with most everything just fine. > > Classes definitely have their uses, but IMHO, they should not be the first tool to pull out of your toolbox when writing a D program. Just use them when you actually need them. [...] I've found myself hovering between structs and classes when writing D code. I almost always use structs for ranges, just because value types incur less overhead, which does add up when you use a lot of UFCS chaining. OTOH, I find myself switching to classes just to get the reference semantics in other cases, even if I never actually do any inheritance. Trying to do reference semantics with structs, while certainly possible, is just too error-prone IME. Just a few days ago, I encountered what looked like a nasty functionality bug in my program, only to eventually discover that it was caused by a missing 'ref' in a function's struct parameter, so updates to the struct didn't persist as the code assumed it would. I found myself seriously considering using classes instead, just for the default ref semantics. While D's decision to make structs value-only and classes ref-only is certainly clever, it also introduces some tricky gotchas for the unwary. T -- May you live all the days of your life. -- Jonathan Swift |
Copyright © 1999-2021 by the D Language Foundation