|
View:
New views
20 Messages
—
Rating Filter:
Alert me
|
| < Prev | 1 - 2 | Next > |
|
|
A better 'Fluent interface', pleaseI've been a huge fan of syntactic sugar, and lately I've started to
implement it in my own interfaces. But after doing so I've found myself getting more and more critical lately. Over the months I've been watching the rising popularity of "fluent interfaces", a notion which everyone here is familiar with. Unfortunately, I feel that the execution in many cases has been a bit weird if not smelly. A few of the things that bug me: 1) Chaining is not fluent, even if fluent might support chaining. http://en.wikipedia.org/wiki/Fluent_interface IMO the published sample is garbage. Chaining in itself does not make for readability and the community is severely abusing mere chaining with this misunderstanding. There's nothing less readable about myObject.SetValueX(1); myObject.SetValueY(2); than myObject.SetValueX(1).SetValueY(2); In my opinion, this actually makes it less readable because these are distinct statements of execution that are being slurred together. As I posted in the Discussion view on that page, I agree with the opinion of someone else's comment, a better sample is: IConfiguration config = ConfigurationFluent.Create().Color("blue").Height(1).Length(2).Depth(3); This is ONE statement that's well-described. 2) Lambdas are not necessarily fluent, although well-formatted lambda expressions can be made to look readable. Fluent interfaces exist for readability. Lambda expressions exist for ease of composing delegates. Let's not confuse them. When I see a hodgepodge of lambda expresses describing how something is configured, I cringe, especially when they are nested. Those buggers are NOT easily readable. Maybe (probably) it's because I'm still making the adjustment to lambda expressions. But "more readable", such scenarios certainly are not, at least to me. Put it in another way, if the syntax is not *more* in the direction of my mother being able to decipher it (even though she never would anyway), it's not a fluent interface. 3) IMO an interface should never abandon a few simple classic rules, as programmers do read these interfaces, too, and we have to debug, and we have to understand what's doing what, and we have to deal with multi-threaded circumetances. For example, - Never have a fluent interface that is invoked without an object instance (unless it's a factory interface that configures and returns an object that does the actual work). - Never name an object a verb. - etc. Any more suggestions on #3? Any suggestions in general? I get hung up on some of these "fluent interfaces" as sometimes they are distractingly peculiar and sometimes downright sloppy. For.Example.I.Strongly.Dislike.Dot.Notation.Where.SimplyUsingCasingWouldSuff ice, it becomes a debugging and API theoretical understanding nightmare on the programmatic level and sometimes there's absolutely no point for it. Jon |
|
|
Re: A better 'Fluent interface', pleaseI have to agree, simple method chaining ala JQuery is one thing but the
fluent interface thing has been over done in .NET and is probably a du jour phenomenon that such circles succumb to. I think it is the lamdas or over use of lamdas that makes me feel queasy when looking at some of them. The following is one such that exhibits how unfluent a fluent interface can be: http://codebetter.com/blogs/dru.sellers/archive/2009/05/29/dropkick-an-idea-for-deployments.aspx The formatting is part of the fluent interface and the formatting is unfortunately in the author's head. I can only think how much time you would waste with the tab key to get that to format correctly. A static language is not a good candidate for a Dsl. Cheers Paul Cowan Cutting-Edge Solutions (Scotland) http://thesoftwaresimpleton.blogspot.com/ 2009/9/30 Jon Davis <jon@...> > > > I’ve been a huge fan of syntactic sugar, and lately I’ve started to > implement it in my own interfaces. But after doing so I’ve found myself > getting more and more critical lately. > > > > Over the months I’ve been watching the rising popularity of “fluent > interfaces”, a notion which everyone here is familiar with. Unfortunately, I > feel that the execution in many cases has been a bit weird if not smelly. A > few of the things that bug me: > > > > 1) Chaining is not fluent, even if fluent might support chaining. > > > > http://en.wikipedia.org/wiki/Fluent_interface > > > > IMO the published sample is garbage. Chaining in itself does not make for > readability and the community is severely abusing mere chaining with this > misunderstanding. There's nothing less readable about > > > > myObject.SetValueX(1); > > myObject.SetValueY(2); > > > > than > > > > myObject.SetValueX(1).SetValueY(2); > > > > In my opinion, this actually makes it less readable because these are > distinct statements of execution that are being slurred together. As I > posted in the Discussion view on that page, I agree with the opinion of > someone else’s comment, a better sample is: > > > > IConfiguration config = > ConfigurationFluent.Create().Color("blue").Height(1).Length(2).Depth(3); > > > > This is ONE statement that’s well-described. > > > > 2) Lambdas are not necessarily fluent, although well-formatted lambda > expressions can be made to look readable. Fluent interfaces exist for > readability. Lambda expressions exist for ease of composing delegates. Let’s > not confuse them. When I see a hodgepodge of lambda expresses describing how > something is configured, I cringe, especially when they are nested. Those > buggers are NOT easily readable. Maybe (probably) it’s because I’m still > making the adjustment to lambda expressions. But “more readable”, such > scenarios certainly are not, at least to me. Put it in another way, if the > syntax is not **more** in the direction of my mother being able to > decipher it (even though she never would anyway), it’s not a fluent > interface. > > > > 3) IMO an interface should never abandon a few simple classic rules, as > programmers do read these interfaces, too, and we have to debug, and we have > to understand what’s doing what, and we have to deal with multi-threaded > circumetances. For example, > > - Never have a fluent interface that is invoked without an object instance > (unless it’s a factory interface that configures and returns an object that > does the actual work). > > - Never name an object a verb. > > - etc. > > > > Any more suggestions on #3? Any suggestions in general? > > > > I get hung up on some of these “fluent interfaces” as sometimes they are > distractingly peculiar and sometimes downright sloppy. > For.Example.I.Strongly.Dislike.Dot.Notation.Where.SimplyUsingCasingWouldSuffice, > it becomes a debugging and API theoretical understanding nightmare on the > programmatic level and sometimes there’s absolutely no point for it. > > > > Jon > > > |
|
|
RE: A better 'Fluent interface', pleaseI personally think they have a great place in test code. It goes without
saying that if a test is easy to read, it makes your life much easier. I came across this yesterday, which I think this is wicked: http://sharptestex.codeplex.com/ Being able to do: myList.Should().Contain("item 1"); much more readable than Assert.That(myList, new ContainsConstraint("item 1")) When I wrote NBuilder I wanted a developer to be able to open a test and see easily what was happening. I wanted it to read like English, as much as possible. NBuilder's interface: var products = Builder<Product> .CreateListOfSize(10) .WhereTheFirst(2) .Have(x => x.Title = "My title") .And(x => x.AddedDate = January.The1st.At(08, 00) ) .AndTheNext(2) .Have(x => x.Title = "another title") .Build() Consider the alternative: var builder = new Builder<Product>(); builder.CreateListOfSize(10); var range1 = new RangeDeclaration<Product>(0, 2); range1.Set(x => x.Title = "My title"); range1.Set(x => x.AddedDate = new DateTime(2009, 01, 01, 08, 00, 00)); /* blah */ builder.AddDeclaration(range1); builder.AddDeclaration(range2); var products = builder.Build(); It's not only easier to read the first one, it's a lot easier and faster to write. From: altdotnet@... [mailto:altdotnet@...] On Behalf Of Jon Davis Sent: 30 September 2009 11:14 To: altdotnet@... Subject: [altdotnet] A better 'Fluent interface', please I've been a huge fan of syntactic sugar, and lately I've started to implement it in my own interfaces. But after doing so I've found myself getting more and more critical lately. Over the months I've been watching the rising popularity of "fluent interfaces", a notion which everyone here is familiar with. Unfortunately, I feel that the execution in many cases has been a bit weird if not smelly. A few of the things that bug me: 1) Chaining is not fluent, even if fluent might support chaining. http://en.wikipedia.org/wiki/Fluent_interface IMO the published sample is garbage. Chaining in itself does not make for readability and the community is severely abusing mere chaining with this misunderstanding. There's nothing less readable about myObject.SetValueX(1); myObject.SetValueY(2); than myObject.SetValueX(1).SetValueY(2); In my opinion, this actually makes it less readable because these are distinct statements of execution that are being slurred together. As I posted in the Discussion view on that page, I agree with the opinion of someone else's comment, a better sample is: IConfiguration config = ConfigurationFluent.Create().Color("blue").Height(1).Length(2).Depth(3); This is ONE statement that's well-described. 2) Lambdas are not necessarily fluent, although well-formatted lambda expressions can be made to look readable. Fluent interfaces exist for readability. Lambda expressions exist for ease of composing delegates. Let's not confuse them. When I see a hodgepodge of lambda expresses describing how something is configured, I cringe, especially when they are nested. Those buggers are NOT easily readable. Maybe (probably) it's because I'm still making the adjustment to lambda expressions. But "more readable", such scenarios certainly are not, at least to me. Put it in another way, if the syntax is not *more* in the direction of my mother being able to decipher it (even though she never would anyway), it's not a fluent interface. 3) IMO an interface should never abandon a few simple classic rules, as programmers do read these interfaces, too, and we have to debug, and we have to understand what's doing what, and we have to deal with multi-threaded circumetances. For example, - Never have a fluent interface that is invoked without an object instance (unless it's a factory interface that configures and returns an object that does the actual work). - Never name an object a verb. - etc. Any more suggestions on #3? Any suggestions in general? I get hung up on some of these "fluent interfaces" as sometimes they are distractingly peculiar and sometimes downright sloppy. For.Example.I.Strongly.Dislike.Dot.Notation.Where.SimplyUsingCasingWouldSuff ice, it becomes a debugging and API theoretical understanding nightmare on the programmatic level and sometimes there's absolutely no point for it. Jon |
|
|
RE: A better 'Fluent interface', pleaseHi Gareth,
Being able to do: myList.Should().Contain("item 1"); much more readable than Assert.That(myList, new ContainsConstraint("item 1")) But - IMO - not much better than Assert.That(myList, Contains("item 1")) // NUnitLite and NUnit 3.0 syntax or Assert.That(myList.Contains("item 1")) // One of the proposals for NUnit 3.0 I prefer both of those for several reasons: 1) "Should" reminds me of the old distinction between real requirements ("must") and optional ones. It seems like a bad choice for a situation where an error will cause the test to end with a failure. However, I must admit that the ship has probably sailed on that one, since BDD folks have made "Should" a word to use for hard requirements. 2) Use of a separate method to indicate what to do when a particular constraint fails seems to me a better design and clearer in readability. If I mix Assert.That, Assume.That and Check.That (the last is a 3.0 proposal) in the same method, the different dispositions of failures stand out much more clearly than if I used separate extension metnods on the actual value. 3) I can make the syntax work - at least partially - in .NET 2.0 for those who must use it. 4) It isn't accessible in all .Net languages. That's relatively minor, however. BTW, the two-word prefix is an implementation detail. It's not required if you don't mind your test inheriting from a base class... Require(mylist, Contains("item")) Assume(mylist, Contains("item")) Check(mylist, Contains("item")) ... or the equivalent dotted syntax. Charlie |
|
|
Re: A better 'Fluent interface', pleaseI'm glad to see this discussion. I've been seeing this kind of language
abuse for some time now and thought I was the only one who thought it was a step backwards. I get the feeling that people are trying very hard to replace xml with something worse sometimes. But for every bad example, there is a good one. It's all a learning process at the end of the day. --Ian On Wed, Sep 30, 2009 at 5:38 AM, Paul Cowan <dagda1@...> wrote: > > > I have to agree, simple method chaining ala JQuery is one thing but the > fluent interface thing has been over done in .NET and is probably a du jour > phenomenon that such circles succumb to. > > I think it is the lamdas or over use of lamdas that makes me feel queasy > when looking at some of them. > > The following is one such that exhibits how unfluent a fluent interface can > be: > > > http://codebetter.com/blogs/dru.sellers/archive/2009/05/29/dropkick-an-idea-for-deployments.aspx > > The formatting is part of the fluent interface and the formatting is > unfortunately in the author's head. > > I can only think how much time you would waste with the tab key to get that > to format correctly. > > A static language is not a good candidate for a Dsl. > > Cheers > > Paul Cowan > > Cutting-Edge Solutions (Scotland) > > http://thesoftwaresimpleton.blogspot.com/ > > > > 2009/9/30 Jon Davis <jon@...> > > >> >> I’ve been a huge fan of syntactic sugar, and lately I’ve started to >> implement it in my own interfaces. But after doing so I’ve found myself >> getting more and more critical lately. >> >> >> >> Over the months I’ve been watching the rising popularity of “fluent >> interfaces”, a notion which everyone here is familiar with. Unfortunately, I >> feel that the execution in many cases has been a bit weird if not smelly. A >> few of the things that bug me: >> >> >> >> 1) Chaining is not fluent, even if fluent might support chaining. >> >> >> >> http://en.wikipedia.org/wiki/Fluent_interface >> >> >> >> IMO the published sample is garbage. Chaining in itself does not make for >> readability and the community is severely abusing mere chaining with this >> misunderstanding. There's nothing less readable about >> >> >> >> myObject.SetValueX(1); >> >> myObject.SetValueY(2); >> >> >> >> than >> >> >> >> myObject.SetValueX(1).SetValueY(2); >> >> >> >> In my opinion, this actually makes it less readable because these are >> distinct statements of execution that are being slurred together. As I >> posted in the Discussion view on that page, I agree with the opinion of >> someone else’s comment, a better sample is: >> >> >> >> IConfiguration config = >> ConfigurationFluent.Create().Color("blue").Height(1).Length(2).Depth(3); >> >> >> >> This is ONE statement that’s well-described. >> >> >> >> 2) Lambdas are not necessarily fluent, although well-formatted lambda >> expressions can be made to look readable. Fluent interfaces exist for >> readability. Lambda expressions exist for ease of composing delegates. Let’s >> not confuse them. When I see a hodgepodge of lambda expresses describing how >> something is configured, I cringe, especially when they are nested. Those >> buggers are NOT easily readable. Maybe (probably) it’s because I’m still >> making the adjustment to lambda expressions. But “more readable”, such >> scenarios certainly are not, at least to me. Put it in another way, if the >> syntax is not **more** in the direction of my mother being able to >> decipher it (even though she never would anyway), it’s not a fluent >> interface. >> >> >> >> 3) IMO an interface should never abandon a few simple classic rules, as >> programmers do read these interfaces, too, and we have to debug, and we have >> to understand what’s doing what, and we have to deal with multi-threaded >> circumetances. For example, >> >> - Never have a fluent interface that is invoked without an object instance >> (unless it’s a factory interface that configures and returns an object that >> does the actual work). >> >> - Never name an object a verb. >> >> - etc. >> >> >> >> Any more suggestions on #3? Any suggestions in general? >> >> >> >> I get hung up on some of these “fluent interfaces” as sometimes they are >> distractingly peculiar and sometimes downright sloppy. >> For.Example.I.Strongly.Dislike.Dot.Notation.Where.SimplyUsingCasingWouldSuffice, >> it becomes a debugging and API theoretical understanding nightmare on the >> programmatic level and sometimes there’s absolutely no point for it. >> >> >> >> Jon >> >> > > > > |
|
|
Re: A better 'Fluent interface', pleaseWould like to chime in here - fluent interfaces that are easy to read
are nice but that shouldn't be the goal. The goal should be making code easy to write. Fluency is an output; we achieve fluency writing the code not reading it. One who can only read a foreign language does not claim to be fluent in it. On Wed, Sep 30, 2009 at 6:05 AM, Gareth Down <g@...> wrote: > > > I personally think they have a great place in test code. It goes without saying that if a test is easy to read, it makes your life much easier. > > > > I came across this yesterday, which I think this is wicked: > > > > http://sharptestex.codeplex.com/ > > > > Being able to do: myList.Should().Contain("item 1"); much more readable than Assert.That(myList, new ContainsConstraint("item 1")) > > > > When I wrote NBuilder I wanted a developer to be able to open a test and see easily what was happening. I wanted it to read like English, as much as possible. > > > > > > NBuilder's interface: > > > > var products = Builder<Product> > > .CreateListOfSize(10) > > .WhereTheFirst(2) > > .Have(x => x.Title = "My title") > > .And(x => x.AddedDate = January.The1st.At(08, 00) ) > > .AndTheNext(2) > > .Have(x => x.Title = "another title") > > .Build() > > > > > > Consider the alternative: > > > > > > var builder = new Builder<Product>(); > > > > builder.CreateListOfSize(10); > > > > var range1 = new RangeDeclaration<Product>(0, 2); > > range1.Set(x => x.Title = "My title"); > > range1.Set(x => x.AddedDate = new DateTime(2009, 01, 01, 08, 00, 00)); > > > > /* blah */ > > > > builder.AddDeclaration(range1); > > builder.AddDeclaration(range2); > > > > var products = builder.Build(); > > > > > > It's not only easier to read the first one, it's a lot easier and faster to write. > > > > > > From: altdotnet@... [mailto:altdotnet@...] On Behalf Of Jon Davis > Sent: 30 September 2009 11:14 > To: altdotnet@... > Subject: [altdotnet] A better 'Fluent interface', please > > > > > I’ve been a huge fan of syntactic sugar, and lately I’ve started to implement it in my own interfaces. But after doing so I’ve found myself getting more and more critical lately. > > > > Over the months I’ve been watching the rising popularity of “fluent interfaces”, a notion which everyone here is familiar with. Unfortunately, I feel that the execution in many cases has been a bit weird if not smelly. A few of the things that bug me: > > > > 1) Chaining is not fluent, even if fluent might support chaining. > > > > http://en.wikipedia.org/wiki/Fluent_interface > > > > IMO the published sample is garbage. Chaining in itself does not make for readability and the community is severely abusing mere chaining with this misunderstanding. There's nothing less readable about > > > > myObject.SetValueX(1); > > myObject.SetValueY(2); > > > > than > > > > myObject.SetValueX(1).SetValueY(2); > > > > In my opinion, this actually makes it less readable because these are distinct statements of execution that are being slurred together. As I posted in the Discussion view on that page, I agree with the opinion of someone else’s comment, a better sample is: > > > > IConfiguration config = ConfigurationFluent.Create().Color("blue").Height(1).Length(2).Depth(3); > > > > This is ONE statement that’s well-described. > > > > 2) Lambdas are not necessarily fluent, although well-formatted lambda expressions can be made to look readable. Fluent interfaces exist for readability. Lambda expressions exist for ease of composing delegates. Let’s not confuse them. When I see a hodgepodge of lambda expresses describing how something is configured, I cringe, especially when they are nested. Those buggers are NOT easily readable. Maybe (probably) it’s because I’m still making the adjustment to lambda expressions. But “more readable”, such scenarios certainly are not, at least to me. Put it in another way, if the syntax is not *more* in the direction of my mother being able to decipher it (even though she never would anyway), it’s not a fluent interface. > > > > 3) IMO an interface should never abandon a few simple classic rules, as programmers do read these interfaces, too, and we have to debug, and we have to understand what’s doing what, and we have to deal with multi-threaded circumetances. For example, > > - Never have a fluent interface that is invoked without an object instance (unless it’s a factory interface that configures and returns an object that does the actual work). > > - Never name an object a verb. > > - etc. > > > > Any more suggestions on #3? Any suggestions in general? > > > > I get hung up on some of these “fluent interfaces” as sometimes they are distractingly peculiar and sometimes downright sloppy. For.Example.I.Strongly.Dislike.Dot.Notation.Where.SimplyUsingCasingWouldSuffice, it becomes a debugging and API theoretical understanding nightmare on the programmatic level and sometimes there’s absolutely no point for it. > > > > Jon > > > > > ------------------------------------ Yahoo! Groups Links <*> To visit your group on the web, go to: http://groups.yahoo.com/group/altdotnet/ <*> Your email settings: Individual Email | Traditional <*> To change settings online go to: http://groups.yahoo.com/group/altdotnet/join (Yahoo! ID required) <*> To change settings via email: mailto:altdotnet-digest@... mailto:altdotnet-fullfeatured@... <*> To unsubscribe from this group, send an email to: altdotnet-unsubscribe@... <*> Your use of Yahoo! Groups is subject to: http://docs.yahoo.com/info/terms/ |
|
|
RE: A better 'Fluent interface', pleaseYes I agree - you may have missed this I put right at the bottom:
"It's not only easier to read the first one, it's a lot easier and faster to write." I don't think making them easy to write is the only goal though, readability is just as important. If you have to come back to a test after months, you don't want to have to spend too long working out what is happening. I think of it in the same way steve krug says you shouldn't have to think about how websites work in "don't make me think". You shouldn't have to think when you write it and you shouldn't have to think when you read it back. It should be obvious with no or minimal thought what the code does. I personally don't think, in some cases, a few extra keystrokes hurts to make code more readable. To use the nunit example again: Assert.True(value); is slightly easier to write but I always choose: Assert.That(value, Is.True); because, for me, it's just slightly easier to read. Perhaps it's just down to preference. Maybe the rule should be wherever there's a fluent interface there should be a 'normal' alternative. -----Original Message----- From: altdotnet@... [mailto:altdotnet@...] On Behalf Of Matt Hinze Sent: 30 September 2009 16:45 To: altdotnet@... Subject: Re: [altdotnet] A better 'Fluent interface', please Would like to chime in here - fluent interfaces that are easy to read are nice but that shouldn't be the goal. The goal should be making code easy to write. Fluency is an output; we achieve fluency writing the code not reading it. One who can only read a foreign language does not claim to be fluent in it. On Wed, Sep 30, 2009 at 6:05 AM, Gareth Down <g@...> wrote: > > > I personally think they have a great place in test code. It goes without saying that if a test is easy to read, it makes your life much easier. > > > > I came across this yesterday, which I think this is wicked: > > > > http://sharptestex.codeplex.com/ > > > > Being able to do: myList.Should().Contain("item 1"); much more readable > > > > When I wrote NBuilder I wanted a developer to be able to open a test and see easily what was happening. I wanted it to read like English, as much as possible. > > > > > > NBuilder's interface: > > > > var products = Builder<Product> > > .CreateListOfSize(10) > > .WhereTheFirst(2) > > .Have(x => x.Title = "My title") > > .And(x => x.AddedDate = January.The1st.At(08, 00) ) > > .AndTheNext(2) > > .Have(x => x.Title = "another title") > > .Build() > > > > > > Consider the alternative: > > > > > > var builder = new Builder<Product>(); > > > > builder.CreateListOfSize(10); > > > > var range1 = new RangeDeclaration<Product>(0, 2); > > range1.Set(x => x.Title = "My title"); > > range1.Set(x => x.AddedDate = new DateTime(2009, 01, 01, 08, 00, 00)); > > > > /* blah */ > > > > builder.AddDeclaration(range1); > > builder.AddDeclaration(range2); > > > > var products = builder.Build(); > > > > > > It's not only easier to read the first one, it's a lot easier and faster > > > > > > From: altdotnet@... [mailto:altdotnet@...] On Behalf Of Jon Davis > Sent: 30 September 2009 11:14 > To: altdotnet@... > Subject: [altdotnet] A better 'Fluent interface', please > > > > > Ive been a huge fan of syntactic sugar, and lately Ive started to implement it in my own interfaces. But after doing so Ive found myself getting more and more critical lately. > > > > Over the months Ive been watching the rising popularity of fluent interfaces, a notion which everyone here is familiar with. Unfortunately, I feel that the execution in many cases has been a bit weird if not smelly. A few of the things that bug me: > > > > 1) Chaining is not fluent, even if fluent might support chaining. > > > > http://en.wikipedia.org/wiki/Fluent_interface > > > > IMO the published sample is garbage. Chaining in itself does not make for misunderstanding. There's nothing less readable about > > > > myObject.SetValueX(1); > > myObject.SetValueY(2); > > > > than > > > > myObject.SetValueX(1).SetValueY(2); > > > > In my opinion, this actually makes it less readable because these are posted in the Discussion view on that page, I agree with the opinion of someone elses comment, a better sample is: > > > > IConfiguration config = ConfigurationFluent.Create().Color("blue").Height(1).Length(2).Depth(3); > > > > This is ONE statement thats well-described. > > > > 2) Lambdas are not necessarily fluent, although well-formatted lambda expressions can be made to look readable. Fluent interfaces exist for readability. Lambda expressions exist for ease of composing delegates. Lets not confuse them. When I see a hodgepodge of lambda expresses describing how something is configured, I cringe, especially when they are nested. Those buggers are NOT easily readable. Maybe (probably) its because Im still making the adjustment to lambda expressions. But more readable, such scenarios certainly are not, at least to me. Put it in another way, if the syntax is not *more* in the direction of my mother being able to decipher it (even though she never would anyway), its not a fluent interface. > > > > 3) IMO an interface should never abandon a few simple classic rules, as programmers do read these interfaces, too, and we have to debug, and we have to understand whats doing what, and we have to deal with multi-threaded circumetances. For example, > > - Never have a fluent interface that is invoked without an object instance (unless its a factory interface that configures and returns an object that does the actual work). > > - Never name an object a verb. > > - etc. > > > > Any more suggestions on #3? Any suggestions in general? > > > > I get hung up on some of these fluent interfaces as sometimes they are For.Example.I.Strongly.Dislike.Dot.Notation.Where.SimplyUsingCasingWouldSuff ice, it becomes a debugging and API theoretical understanding nightmare on the programmatic level and sometimes theres absolutely no point for it. > > > > Jon > > > > > ------------------------------------ Yahoo! Groups Links |
|
|
RE: A better 'Fluent interface', pleaseHi Charlie
I agree - I prefer both of those too. I didn't realise that syntax was coming up. Also, thinking about it more, it's nice for the lines where the assertions are happening to actually begin with 'Assert' so you can identify them more easily. But how would Assert.That(myList.Contains(item)) work though since there is already a Contains method on List<T>? The extension method will never be called? If you used the List<T> Contains method wouldn't you just get a message saying "expected true but was false", rather than it saying the list didn't contain the item? Or would you be using some reflection trickery? Just curious. I know there's the backwards compatibility and other languages argument, but I think there's definitely something to be said for the way fluent interfaces written using extension methods allow others to easily extend the interface for their own use without having to use inheritance etc. What's yours/ anyone else's feeling on that? Gareth From: altdotnet@... [mailto:altdotnet@...] On Behalf Of Charlie Poole Sent: 30 September 2009 15:46 To: altdotnet@... Subject: RE: [altdotnet] A better 'Fluent interface', please Hi Gareth, Being able to do: myList.Should().Contain("item 1"); much more readable than Assert.That(myList, new ContainsConstraint("item 1")) But - IMO - not much better than Assert.That(myList, Contains("item 1")) // NUnitLite and NUnit 3.0 syntax or Assert.That(myList.Contains("item 1")) // One of the proposals for NUnit 3.0 I prefer both of those for several reasons: 1) "Should" reminds me of the old distinction between real requirements ("must") and optional ones. It seems like a bad choice for a situation where an error will cause the test to end with a failure. However, I must admit that the ship has probably sailed on that one, since BDD folks have made "Should" a word to use for hard requirements. 2) Use of a separate method to indicate what to do when a particular constraint fails seems to me a better design and clearer in readability. If I mix Assert.That, Assume.That and Check.That (the last is a 3.0 proposal) in the same method, the different dispositions of failures stand out much more clearly than if I used separate extension metnods on the actual value. 3) I can make the syntax work - at least partially - in .NET 2.0 for those who must use it. 4) It isn't accessible in all .Net languages. That's relatively minor, however. BTW, the two-word prefix is an implementation detail. It's not required if you don't mind your test inheriting from a base class... Require(mylist, Contains("item")) Assume(mylist, Contains("item")) Check(mylist, Contains("item")) ... or the equivalent dotted syntax. Charlie |
|
|
Re: A better 'Fluent interface', please>
> Would like to chime in here - fluent interfaces that are easy to read > are nice but that shouldn't be the goal. The goal should be making > code easy to write. > Can I just state that I completely disagree with this statement. If you just want code that is easy to write, go get regular expressions. I want code that is easily readable First! Easy to maintain Second. Easy to write Third. Now, where many Fluent Interfaces have issues is in Easy to Debug (chained methods are not easy to debug). But I'm hoping VS2010 will fix some of that. On Wed, Sep 30, 2009 at 9:44 AM, Matt Hinze <mhinze@...> wrote: > Would like to chime in here - fluent interfaces that are easy to read > are nice but that shouldn't be the goal. The goal should be making > code easy to write. > > Fluency is an output; we achieve fluency writing the code not reading > it. One who can only read a foreign language does not claim to be > fluent in it. > > On Wed, Sep 30, 2009 at 6:05 AM, Gareth Down <g@...> wrote: > > > > > > I personally think they have a great place in test code. It goes without > saying that if a test is easy to read, it makes your life much easier. > > > > > > > > I came across this yesterday, which I think this is wicked: > > > > > > > > http://sharptestex.codeplex.com/ > > > > > > > > Being able to do: myList.Should().Contain("item 1"); much more readable > than Assert.That(myList, new ContainsConstraint("item 1")) > > > > > > > > When I wrote NBuilder I wanted a developer to be able to open a test and > see easily what was happening. I wanted it to read like English, as much as > possible. > > > > > > > > > > > > NBuilder's interface: > > > > > > > > var products = Builder<Product> > > > > .CreateListOfSize(10) > > > > .WhereTheFirst(2) > > > > .Have(x => x.Title = "My title") > > > > .And(x => x.AddedDate = January.The1st.At(08, 00) ) > > > > .AndTheNext(2) > > > > .Have(x => x.Title = "another title") > > > > .Build() > > > > > > > > > > > > Consider the alternative: > > > > > > > > > > > > var builder = new Builder<Product>(); > > > > > > > > builder.CreateListOfSize(10); > > > > > > > > var range1 = new RangeDeclaration<Product>(0, 2); > > > > range1.Set(x => x.Title = "My title"); > > > > range1.Set(x => x.AddedDate = new DateTime(2009, 01, 01, 08, 00, 00)); > > > > > > > > /* blah */ > > > > > > > > builder.AddDeclaration(range1); > > > > builder.AddDeclaration(range2); > > > > > > > > var products = builder.Build(); > > > > > > > > > > > > It's not only easier to read the first one, it's a lot easier and faster > to write. > > > > > > > > > > > > From: altdotnet@... [mailto:altdotnet@...] On > Behalf Of Jon Davis > > Sent: 30 September 2009 11:14 > > To: altdotnet@... > > Subject: [altdotnet] A better 'Fluent interface', please > > > > > > > > > > I’ve been a huge fan of syntactic sugar, and lately I’ve started to > implement it in my own interfaces. But after doing so I’ve found myself > getting more and more critical lately. > > > > > > > > Over the months I’ve been watching the rising popularity of “fluent > interfaces”, a notion which everyone here is familiar with. Unfortunately, I > feel that the execution in many cases has been a bit weird if not smelly. A > few of the things that bug me: > > > > > > > > 1) Chaining is not fluent, even if fluent might support chaining. > > > > > > > > http://en.wikipedia.org/wiki/Fluent_interface > > > > > > > > IMO the published sample is garbage. Chaining in itself does not make for > readability and the community is severely abusing mere chaining with this > misunderstanding. There's nothing less readable about > > > > > > > > myObject.SetValueX(1); > > > > myObject.SetValueY(2); > > > > > > > > than > > > > > > > > myObject.SetValueX(1).SetValueY(2); > > > > > > > > In my opinion, this actually makes it less readable because these are > distinct statements of execution that are being slurred together. As I > posted in the Discussion view on that page, I agree with the opinion of > someone else’s comment, a better sample is: > > > > > > > > IConfiguration config = > ConfigurationFluent.Create().Color("blue").Height(1).Length(2).Depth(3); > > > > > > > > This is ONE statement that’s well-described. > > > > > > > > 2) Lambdas are not necessarily fluent, although well-formatted lambda > expressions can be made to look readable. Fluent interfaces exist for > readability. Lambda expressions exist for ease of composing delegates. Let’s > not confuse them. When I see a hodgepodge of lambda expresses describing how > something is configured, I cringe, especially when they are nested. Those > buggers are NOT easily readable. Maybe (probably) it’s because I’m still > making the adjustment to lambda expressions. But “more readable”, such > scenarios certainly are not, at least to me. Put it in another way, if the > syntax is not *more* in the direction of my mother being able to decipher it > (even though she never would anyway), it’s not a fluent interface. > > > > > > > > 3) IMO an interface should never abandon a few simple classic rules, as > programmers do read these interfaces, too, and we have to debug, and we have > to understand what’s doing what, and we have to deal with multi-threaded > circumetances. For example, > > > > - Never have a fluent interface that is invoked without an object > instance (unless it’s a factory interface that configures and returns an > object that does the actual work). > > > > - Never name an object a verb. > > > > - etc. > > > > > > > > Any more suggestions on #3? Any suggestions in general? > > > > > > > > I get hung up on some of these “fluent interfaces” as sometimes they are > distractingly peculiar and sometimes downright sloppy. > For.Example.I.Strongly.Dislike.Dot.Notation.Where.SimplyUsingCasingWouldSuffice, > it becomes a debugging and API theoretical understanding nightmare on the > programmatic level and sometimes there’s absolutely no point for it. > > > > > > > > Jon > > > > > > > > > > > > > ------------------------------------ > > Yahoo! Groups Links > > > > -- -------------------------------- Christopher Brandsma http://www.ChrisBrandsma.com http://www.ElegantCode.com |
|
|
Re: A better 'Fluent interface', pleaseI agree 100% with Chris on this one. Easy to write is completely useless
if you can't read it quickly and understand what it's doing. Remember, you write it once, but you have to read it many, many times. I'd rather it be expensive for me once, than expensive every time I look at it! Kelly Chris Brandsma <chris.brandsma@...> Sent by: altdotnet@... 09/30/2009 10:31 AM Please respond to altdotnet@... To altdotnet@... cc Subject Re: [altdotnet] A better 'Fluent interface', please Would like to chime in here - fluent interfaces that are easy to read are nice but that shouldn't be the goal. The goal should be making code easy to write. Can I just state that I completely disagree with this statement. If you just want code that is easy to write, go get regular expressions. I want code that is easily readable First! Easy to maintain Second. Easy to write Third. Now, where many Fluent Interfaces have issues is in Easy to Debug (chained methods are not easy to debug). But I'm hoping VS2010 will fix some of that. On Wed, Sep 30, 2009 at 9:44 AM, Matt Hinze <mhinze@...> wrote: Would like to chime in here - fluent interfaces that are easy to read are nice but that shouldn't be the goal. The goal should be making code easy to write. Fluency is an output; we achieve fluency writing the code not reading it. One who can only read a foreign language does not claim to be fluent in it. On Wed, Sep 30, 2009 at 6:05 AM, Gareth Down <g@...> wrote: > > > I personally think they have a great place in test code. It goes without saying that if a test is easy to read, it makes your life much easier. > > > > I came across this yesterday, which I think this is wicked: > > > > http://sharptestex.codeplex.com/ > > > > Being able to do: myList.Should().Contain("item 1"); much more readable > > > > When I wrote NBuilder I wanted a developer to be able to open a test and see easily what was happening. I wanted it to read like English, as much as possible. > > > > > > NBuilder's interface: > > > > var products = Builder<Product> > > .CreateListOfSize(10) > > .WhereTheFirst(2) > > .Have(x => x.Title = "My title") > > .And(x => x.AddedDate = January.The1st.At(08, 00) ) > > .AndTheNext(2) > > .Have(x => x.Title = "another title") > > .Build() > > > > > > Consider the alternative: > > > > > > var builder = new Builder<Product>(); > > > > builder.CreateListOfSize(10); > > > > var range1 = new RangeDeclaration<Product>(0, 2); > > range1.Set(x => x.Title = "My title"); > > range1.Set(x => x.AddedDate = new DateTime(2009, 01, 01, 08, 00, 00)); > > > > /* blah */ > > > > builder.AddDeclaration(range1); > > builder.AddDeclaration(range2); > > > > var products = builder.Build(); > > > > > > It's not only easier to read the first one, it's a lot easier and faster > > > > > > From: altdotnet@... [mailto:altdotnet@...] On Behalf Of Jon Davis > Sent: 30 September 2009 11:14 > To: altdotnet@... > Subject: [altdotnet] A better 'Fluent interface', please > > > > > I’ve been a huge fan of syntactic sugar, and lately I’ve started to implement it in my own interfaces. But after doing so I’ve found myself getting more and more critical lately. > > > > Over the months I’ve been watching the rising popularity of “fluent interfaces”, a notion which everyone here is familiar with. Unfortunately, I feel that the execution in many cases has been a bit weird if not smelly. A few of the things that bug me: > > > > 1) Chaining is not fluent, even if fluent might support chaining. > > > > http://en.wikipedia.org/wiki/Fluent_interface > > > > IMO the published sample is garbage. Chaining in itself does not make this misunderstanding. There's nothing less readable about > > > > myObject.SetValueX(1); > > myObject.SetValueY(2); > > > > than > > > > myObject.SetValueX(1).SetValueY(2); > > > > In my opinion, this actually makes it less readable because these are posted in the Discussion view on that page, I agree with the opinion of someone else’s comment, a better sample is: > > > > IConfiguration config = ConfigurationFluent.Create().Color("blue").Height(1).Length(2).Depth(3); > > > > This is ONE statement that’s well-described. > > > > 2) Lambdas are not necessarily fluent, although well-formatted lambda expressions can be made to look readable. Fluent interfaces exist for readability. Lambda expressions exist for ease of composing delegates. Let’s not confuse them. When I see a hodgepodge of lambda expresses describing how something is configured, I cringe, especially when they are nested. Those buggers are NOT easily readable. Maybe (probably) it’s because I’m still making the adjustment to lambda expressions. But “more readable”, such scenarios certainly are not, at least to me. Put it in another way, if the syntax is not *more* in the direction of my mother being able to decipher it (even though she never would anyway), it’s not a fluent interface. > > > > 3) IMO an interface should never abandon a few simple classic rules, as programmers do read these interfaces, too, and we have to debug, and we have to understand what’s doing what, and we have to deal with multi-threaded circumetances. For example, > > - Never have a fluent interface that is invoked without an object instance (unless it’s a factory interface that configures and returns an object that does the actual work). > > - Never name an object a verb. > > - etc. > > > > Any more suggestions on #3? Any suggestions in general? > > > > I get hung up on some of these “fluent interfaces” as sometimes they are For.Example.I.Strongly.Dislike.Dot.Notation.Where.SimplyUsingCasingWouldSuffice, it becomes a debugging and API theoretical understanding nightmare on the programmatic level and sometimes there’s absolutely no point for it. > > > > Jon > > > > > ------------------------------------ Yahoo! Groups Links -- -------------------------------- Christopher Brandsma http://www.ChrisBrandsma.com http://www.ElegantCode.com ************************************************************************************** This communication is intended solely for the addressee and is confidential. If you are not the intended recipient, any disclosure, copying, distribution or any action taken or omitted to be taken in reliance on it, is prohibited and may be unlawful. Unless indicated to the contrary: it does not constitute professional advice or opinions upon which reliance may be made by the addressee or any other party, and it should be considered to be a work in progress. Unless otherwise noted in this email or its attachments, this communication does not form a Statement of Actuarial Opinion under American Academy of Actuaries guidelines. ************************************************************************************** |
|
|
Re: A better 'Fluent interface', pleaseJust to point out that "easy" and "readable" are subjective. Jon has
criticized the fluent api of one of my projects (at my request). He made good points, but ultimately I'll probably stick with what I find most comfortable. Although, I always try to be open to criticism such as flawed fluent syntax, because that's how we learn. Josh C. 480-270-4578 | josh [at] computeristsolutions [dot] com | http://computeristsolutions.com On Wed, Sep 30, 2009 at 10:44 AM, Kelly Leahy <kelly.leahy@...>wrote: > > > > I agree 100% with Chris on this one. Easy to write is completely useless > if you can't read it quickly and understand what it's doing. Remember, you > write it once, but you have to read it many, many times. I'd rather it be > expensive for me once, than expensive every time I look at it! > > Kelly > > > > *Chris Brandsma <chris.brandsma@...> * > > Sent by: altdotnet@... > > 09/30/2009 10:31 AM > Please respond to > altdotnet@... > > To > altdotnet@... cc > Subject > Re: [altdotnet] A better 'Fluent interface', please > > > > > > > Would like to chime in here - fluent interfaces that are easy to read > are nice but that shouldn't be the goal. The goal should be making > code easy to write. > > > Can I just state that I completely disagree with this statement. If you > just want code that is easy to write, go get regular expressions. > > I want code that is easily readable First! Easy to maintain Second. Easy > to write Third. > > Now, where many Fluent Interfaces have issues is in Easy to Debug (chained > methods are not easy to debug). But I'm hoping VS2010 will fix some of > that. > > > On Wed, Sep 30, 2009 at 9:44 AM, Matt Hinze <*mhinze@...*<mhinze@...>> > wrote: > Would like to chime in here - fluent interfaces that are easy to read > are nice but that shouldn't be the goal. The goal should be making > code easy to write. > > Fluency is an output; we achieve fluency writing the code not reading > it. One who can only read a foreign language does not claim to be > fluent in it. > > On Wed, Sep 30, 2009 at 6:05 AM, Gareth Down <*g@...*<g@...>> > wrote: > > > > > > I personally think they have a great place in test code. It goes without > saying that if a test is easy to read, it makes your life much easier. > > > > > > > > I came across this yesterday, which I think this is wicked: > > > > > > > > *http://sharptestex.codeplex.com/* <http://sharptestex.codeplex.com/> > > > > > > > > Being able to do: myList.Should().Contain("item 1"); much more readable > than Assert.That(myList, new ContainsConstraint("item 1")) > > > > > > > > When I wrote NBuilder I wanted a developer to be able to open a test and > see easily what was happening. I wanted it to read like English, as much as > possible. > > > > > > > > > > > > NBuilder's interface: > > > > > > > > var products = Builder<Product> > > > > .CreateListOfSize(10) > > > > .WhereTheFirst(2) > > > > .Have(x => x.Title = "My title") > > > > .And(x => x.AddedDate = *January.The1st.At*<http://january.the1st.at/>(08, > 00) ) > > > > .AndTheNext(2) > > > > .Have(x => x.Title = "another title") > > > > .Build() > > > > > > > > > > > > Consider the alternative: > > > > > > > > > > > > var builder = new Builder<Product>(); > > > > > > > > builder.CreateListOfSize(10); > > > > > > > > var range1 = new RangeDeclaration<Product>(0, 2); > > > > range1.Set(x => x.Title = "My title"); > > > > range1.Set(x => x.AddedDate = new DateTime(2009, 01, 01, 08, 00, 00)); > > > > > > > > /* blah */ > > > > > > > > builder.AddDeclaration(range1); > > > > builder.AddDeclaration(range2); > > > > > > > > var products = builder.Build(); > > > > > > > > > > > > It's not only easier to read the first one, it's a lot easier and faster > to write. > > > > > > > > > > > > From: *altdotnet@...* <altdotnet@...> [mailto:* > altdotnet@...* <altdotnet@...>] On Behalf Of Jon > Davis > > Sent: 30 September 2009 11:14 > > To: *altdotnet@...* <altdotnet@...> > > Subject: [altdotnet] A better 'Fluent interface', please > > > > > > > > > > I’ve been a huge fan of syntactic sugar, and lately I’ve started to > implement it in my own interfaces. But after doing so I’ve found myself > getting more and more critical lately. > > > > > > > > Over the months I’ve been watching the rising popularity of “fluent > interfaces”, a notion which everyone here is familiar with. Unfortunately, I > feel that the execution in many cases has been a bit weird if not smelly. A > few of the things that bug me: > > > > > > > > 1) Chaining is not fluent, even if fluent might support chaining. > > > > > > > > *http://en.wikipedia.org/wiki/Fluent_interface*<http://en.wikipedia.org/wiki/Fluent_interface> > > > > > > > > IMO the published sample is garbage. Chaining in itself does not make for > readability and the community is severely abusing mere chaining with this > misunderstanding. There's nothing less readable about > > > > > > > > myObject.SetValueX(1); > > > > myObject.SetValueY(2); > > > > > > > > than > > > > > > > > myObject.SetValueX(1).SetValueY(2); > > > > > > > > In my opinion, this actually makes it less readable because these are > distinct statements of execution that are being slurred together. As I > posted in the Discussion view on that page, I agree with the opinion of > someone else’s comment, a better sample is: > > > > > > > > IConfiguration config = > ConfigurationFluent.Create().Color("blue").Height(1).Length(2).Depth(3); > > > > > > > > This is ONE statement that’s well-described. > > > > > > > > 2) Lambdas are not necessarily fluent, although well-formatted lambda > expressions can be made to look readable. Fluent interfaces exist for > readability. Lambda expressions exist for ease of composing delegates. Let’s > not confuse them. When I see a hodgepodge of lambda expresses describing how > something is configured, I cringe, especially when they are nested. Those > buggers are NOT easily readable. Maybe (probably) it’s because I’m still > making the adjustment to lambda expressions. But “more readable”, such > scenarios certainly are not, at least to me. Put it in another way, if the > syntax is not *more* in the direction of my mother being able to decipher it > (even though she never would anyway), it’s not a fluent interface. > > > > > > > > 3) IMO an interface should never abandon a few simple classic rules, as > programmers do read these interfaces, too, and we have to debug, and we have > to understand what’s doing what, and we have to deal with multi-threaded > circumetances. For example, > > > > - Never have a fluent interface that is invoked without an object > instance (unless it’s a factory interface that configures and returns an > object that does the actual work). > > > > - Never name an object a verb. > > > > - etc. > > > > > > > > Any more suggestions on #3? Any suggestions in general? > > > > > > > > I get hung up on some of these “fluent interfaces” as sometimes they are > distractingly peculiar and sometimes downright sloppy. > For.Example.I.Strongly.Dislike.Dot.Notation.Where.SimplyUsingCasingWouldSuffice, > it becomes a debugging and API theoretical understanding nightmare on the > programmatic level and sometimes there’s absolutely no point for it. > > > > > > > > Jon > > > > > > > > > > > > > ------------------------------------ > > Yahoo! Groups Links > > > > > > > -- > -------------------------------- > Christopher Brandsma * > **http://www.ChrisBrandsma.com* <http://www.chrisbrandsma.com/>* > **http://www.ElegantCode.com* <http://www.elegantcode.com/> > > > > > > ************************************************************************************** > This communication is intended solely for the addressee and is > confidential. If you are not the intended recipient, any disclosure, > copying, distribution or any action taken or omitted to be taken in > reliance on it, is prohibited and may be unlawful. Unless indicated > to the contrary: it does not constitute professional advice or opinions > upon which reliance may be made by the addressee or any other party, > and it should be considered to be a work in progress. Unless otherwise > noted in this email or its attachments, this communication does not form > a Statement of Actuarial Opinion under American Academy of Actuaries > guidelines. > > ************************************************************************************** > > > |
|
|
Re: A better 'Fluent interface', pleaseI disagree with this. I read a lot more code than I write and a lot
of the code I read is not code I wrote. James On Wed, Sep 30, 2009 at 10:44 AM, Matt Hinze <mhinze@...> wrote: > Would like to chime in here - fluent interfaces that are easy to read > are nice but that shouldn't be the goal. The goal should be making > code easy to write. > > Fluency is an output; we achieve fluency writing the code not reading > it. One who can only read a foreign language does not claim to be > fluent in it. > > On Wed, Sep 30, 2009 at 6:05 AM, Gareth Down <g@...> wrote: >> >> >> I personally think they have a great place in test code. It goes without saying that if a test is easy to read, it makes your life much easier. >> >> >> >> I came across this yesterday, which I think this is wicked: >> >> >> >> http://sharptestex.codeplex.com/ >> >> >> >> Being able to do: myList.Should().Contain("item 1"); much more readable than Assert.That(myList, new ContainsConstraint("item 1")) >> >> >> >> When I wrote NBuilder I wanted a developer to be able to open a test and see easily what was happening. I wanted it to read like English, as much as possible. >> >> >> >> >> >> NBuilder's interface: >> >> >> >> var products = Builder<Product> >> >> .CreateListOfSize(10) >> >> .WhereTheFirst(2) >> >> .Have(x => x.Title = "My title") >> >> .And(x => x.AddedDate = January.The1st.At(08, 00) ) >> >> .AndTheNext(2) >> >> .Have(x => x.Title = "another title") >> >> .Build() >> >> >> >> >> >> Consider the alternative: >> >> >> >> >> >> var builder = new Builder<Product>(); >> >> >> >> builder.CreateListOfSize(10); >> >> >> >> var range1 = new RangeDeclaration<Product>(0, 2); >> >> range1.Set(x => x.Title = "My title"); >> >> range1.Set(x => x.AddedDate = new DateTime(2009, 01, 01, 08, 00, 00)); >> >> >> >> /* blah */ >> >> >> >> builder.AddDeclaration(range1); >> >> builder.AddDeclaration(range2); >> >> >> >> var products = builder.Build(); >> >> >> >> >> >> It's not only easier to read the first one, it's a lot easier and faster to write. >> >> >> >> >> >> From: altdotnet@... [mailto:altdotnet@...] On Behalf Of Jon Davis >> Sent: 30 September 2009 11:14 >> To: altdotnet@... >> Subject: [altdotnet] A better 'Fluent interface', please >> >> >> >> >> I’ve been a huge fan of syntactic sugar, and lately I’ve started to implement it in my own interfaces. But after doing so I’ve found myself getting more and more critical lately. >> >> >> >> Over the months I’ve been watching the rising popularity of “fluent interfaces”, a notion which everyone here is familiar with. Unfortunately, I feel that the execution in many cases has been a bit weird if not smelly. A few of the things that bug me: >> >> >> >> 1) Chaining is not fluent, even if fluent might support chaining. >> >> >> >> http://en.wikipedia.org/wiki/Fluent_interface >> >> >> >> IMO the published sample is garbage. Chaining in itself does not make for readability and the community is severely abusing mere chaining with this misunderstanding. There's nothing less readable about >> >> >> >> myObject.SetValueX(1); >> >> myObject.SetValueY(2); >> >> >> >> than >> >> >> >> myObject.SetValueX(1).SetValueY(2); >> >> >> >> In my opinion, this actually makes it less readable because these are distinct statements of execution that are being slurred together. As I posted in the Discussion view on that page, I agree with the opinion of someone else’s comment, a better sample is: >> >> >> >> IConfiguration config = ConfigurationFluent.Create().Color("blue").Height(1).Length(2).Depth(3); >> >> >> >> This is ONE statement that’s well-described. >> >> >> >> 2) Lambdas are not necessarily fluent, although well-formatted lambda expressions can be made to look readable. Fluent interfaces exist for readability. Lambda expressions exist for ease of composing delegates. Let’s not confuse them. When I see a hodgepodge of lambda expresses describing how something is configured, I cringe, especially when they are nested. Those buggers are NOT easily readable. Maybe (probably) it’s because I’m still making the adjustment to lambda expressions. But “more readable”, such scenarios certainly are not, at least to me. Put it in another way, if the syntax is not *more* in the direction of my mother being able to decipher it (even though she never would anyway), it’s not a fluent interface. >> >> >> >> 3) IMO an interface should never abandon a few simple classic rules, as programmers do read these interfaces, too, and we have to debug, and we have to understand what’s doing what, and we have to deal with multi-threaded circumetances. For example, >> >> - Never have a fluent interface that is invoked without an object instance (unless it’s a factory interface that configures and returns an object that does the actual work). >> >> - Never name an object a verb. >> >> - etc. >> >> >> >> Any more suggestions on #3? Any suggestions in general? >> >> >> >> I get hung up on some of these “fluent interfaces” as sometimes they are distractingly peculiar and sometimes downright sloppy. For.Example.I.Strongly.Dislike.Dot.Notation.Where.SimplyUsingCasingWouldSuffice, it becomes a debugging and API theoretical understanding nightmare on the programmatic level and sometimes there’s absolutely no point for it. >> >> >> >> Jon >> >> >> >> >> > > > ------------------------------------ > > Yahoo! Groups Links > > > > ------------------------------------ Yahoo! Groups Links <*> To visit your group on the web, go to: http://groups.yahoo.com/group/altdotnet/ <*> Your email settings: Individual Email | Traditional <*> To change settings online go to: http://groups.yahoo.com/group/altdotnet/join (Yahoo! ID required) <*> To change settings via email: mailto:altdotnet-digest@... mailto:altdotnet-fullfeatured@... <*> To unsubscribe from this group, send an email to: altdotnet-unsubscribe@... <*> Your use of Yahoo! Groups is subject to: http://docs.yahoo.com/info/terms/ |
|
|
Re: A better 'Fluent interface', please--- In altdotnet@..., Josh Coffman <joshcoffman@...> wrote:
> > Just to point out that "easy" and "readable" are subjective. Jon has > criticized the fluent api of one of my projects (at my request). He made > good points, but ultimately I'll probably stick with what I find most > comfortable. Although, I always try to be open to criticism such as flawed > fluent syntax, because that's how we learn. > > Josh C. > 480-270-4578 | josh [at] computeristsolutions [dot] com | > http://computeristsolutions.com For the record, yours wasn't the example that motivated me to post. It was more like something with a couple details that were "that last little straw" (very minor, overall, though, it's very good) after months of one seeing one thing after another where people are writing "fluent" stuff but that frankly makes C# look like something I can no longer take seriously. Jon |
|
|
Re: A better 'Fluent interface', pleaseNot to be combative but to understand: what exactly do you disagree with?
On Wed, Sep 30, 2009 at 1:47 PM, James Hicks <jhicks0300@...> wrote: > I disagree with this. I read a lot more code than I write and a lot > of the code I read is not code I wrote. > > James > > On Wed, Sep 30, 2009 at 10:44 AM, Matt Hinze <mhinze@...> wrote: >> Would like to chime in here - fluent interfaces that are easy to read >> are nice but that shouldn't be the goal. The goal should be making >> code easy to write. >> >> Fluency is an output; we achieve fluency writing the code not reading >> it. One who can only read a foreign language does not claim to be >> fluent in it. >> >> On Wed, Sep 30, 2009 at 6:05 AM, Gareth Down <g@...> wrote: >>> >>> >>> I personally think they have a great place in test code. It goes without saying that if a test is easy to read, it makes your life much easier. >>> >>> >>> >>> I came across this yesterday, which I think this is wicked: >>> >>> >>> >>> http://sharptestex.codeplex.com/ >>> >>> >>> >>> Being able to do: myList.Should().Contain("item 1"); much more readable than Assert.That(myList, new ContainsConstraint("item 1")) >>> >>> >>> >>> When I wrote NBuilder I wanted a developer to be able to open a test and see easily what was happening. I wanted it to read like English, as much as possible. >>> >>> >>> >>> >>> >>> NBuilder's interface: >>> >>> >>> >>> var products = Builder<Product> >>> >>> .CreateListOfSize(10) >>> >>> .WhereTheFirst(2) >>> >>> .Have(x => x.Title = "My title") >>> >>> .And(x => x.AddedDate = January.The1st.At(08, 00) ) >>> >>> .AndTheNext(2) >>> >>> .Have(x => x.Title = "another title") >>> >>> .Build() >>> >>> >>> >>> >>> >>> Consider the alternative: >>> >>> >>> >>> >>> >>> var builder = new Builder<Product>(); >>> >>> >>> >>> builder.CreateListOfSize(10); >>> >>> >>> >>> var range1 = new RangeDeclaration<Product>(0, 2); >>> >>> range1.Set(x => x.Title = "My title"); >>> >>> range1.Set(x => x.AddedDate = new DateTime(2009, 01, 01, 08, 00, 00)); >>> >>> >>> >>> /* blah */ >>> >>> >>> >>> builder.AddDeclaration(range1); >>> >>> builder.AddDeclaration(range2); >>> >>> >>> >>> var products = builder.Build(); >>> >>> >>> >>> >>> >>> It's not only easier to read the first one, it's a lot easier and faster to write. >>> >>> >>> >>> >>> >>> From: altdotnet@... [mailto:altdotnet@...] On Behalf Of Jon Davis >>> Sent: 30 September 2009 11:14 >>> To: altdotnet@... >>> Subject: [altdotnet] A better 'Fluent interface', please >>> >>> >>> >>> >>> I’ve been a huge fan of syntactic sugar, and lately I’ve started to implement it in my own interfaces. But after doing so I’ve found myself getting more and more critical lately. >>> >>> >>> >>> Over the months I’ve been watching the rising popularity of “fluent interfaces”, a notion which everyone here is familiar with. Unfortunately, I feel that the execution in many cases has been a bit weird if not smelly. A few of the things that bug me: >>> >>> >>> >>> 1) Chaining is not fluent, even if fluent might support chaining. >>> >>> >>> >>> http://en.wikipedia.org/wiki/Fluent_interface >>> >>> >>> >>> IMO the published sample is garbage. Chaining in itself does not make for readability and the community is severely abusing mere chaining with this misunderstanding. There's nothing less readable about >>> >>> >>> >>> myObject.SetValueX(1); >>> >>> myObject.SetValueY(2); >>> >>> >>> >>> than >>> >>> >>> >>> myObject.SetValueX(1).SetValueY(2); >>> >>> >>> >>> In my opinion, this actually makes it less readable because these are distinct statements of execution that are being slurred together. As I posted in the Discussion view on that page, I agree with the opinion of someone else’s comment, a better sample is: >>> >>> >>> >>> IConfiguration config = ConfigurationFluent.Create().Color("blue").Height(1).Length(2).Depth(3); >>> >>> >>> >>> This is ONE statement that’s well-described. >>> >>> >>> >>> 2) Lambdas are not necessarily fluent, although well-formatted lambda expressions can be made to look readable. Fluent interfaces exist for readability. Lambda expressions exist for ease of composing delegates. Let’s not confuse them. When I see a hodgepodge of lambda expresses describing how something is configured, I cringe, especially when they are nested. Those buggers are NOT easily readable. Maybe (probably) it’s because I’m still making the adjustment to lambda expressions. But “more readable”, such scenarios certainly are not, at least to me. Put it in another way, if the syntax is not *more* in the direction of my mother being able to decipher it (even though she never would anyway), it’s not a fluent interface. >>> >>> >>> >>> 3) IMO an interface should never abandon a few simple classic rules, as programmers do read these interfaces, too, and we have to debug, and we have to understand what’s doing what, and we have to deal with multi-threaded circumetances. For example, >>> >>> - Never have a fluent interface that is invoked without an object instance (unless it’s a factory interface that configures and returns an object that does the actual work). >>> >>> - Never name an object a verb. >>> >>> - etc. >>> >>> >>> >>> Any more suggestions on #3? Any suggestions in general? >>> >>> >>> >>> I get hung up on some of these “fluent interfaces” as sometimes they are distractingly peculiar and sometimes downright sloppy. For.Example.I.Strongly.Dislike.Dot.Notation.Where.SimplyUsingCasingWouldSuffice, it becomes a debugging and API theoretical understanding nightmare on the programmatic level and sometimes there’s absolutely no point for it. >>> >>> >>> >>> Jon >>> >>> >>> >>> >>> >> >> >> ------------------------------------ >> >> Yahoo! Groups Links >> >> >> >> > > > ------------------------------------ > > Yahoo! Groups Links > > > > ------------------------------------ Yahoo! Groups Links <*> To visit your group on the web, go to: http://groups.yahoo.com/group/altdotnet/ <*> Your email settings: Individual Email | Traditional <*> To change settings online go to: http://groups.yahoo.com/group/altdotnet/join (Yahoo! ID required) <*> To change settings via email: mailto:altdotnet-digest@... mailto:altdotnet-fullfeatured@... <*> To unsubscribe from this group, send an email to: altdotnet-unsubscribe@... <*> Your use of Yahoo! Groups is subject to: http://docs.yahoo.com/info/terms/ |
|
|
RE: A better 'Fluent interface', pleasePerhaps it's just down to preference. Maybe the rule should be wherever
there's a fluent interface there should be a 'normal' alternative. That's it exactly! I agree that doing a fluent interface is not as simple as chaining. A fluent interface should for lack of a better word flow. It takes a conscious effort to make a truly fluent API but it should be mapped onto an existing API rather than being the only API. I think Evans talks about distilling your API to a DSL/Fluent Interface in DDD. |
|
|
Re: A better 'Fluent interface', pleaseI have to disagree, too. "Fluent interfaces" are not an output (writing code), the phrase was a term coined by Eric Evans and Martin Fowler (as linked to Wikipedia in my OP) and it means "a way of implementing an object oriented API in a way that aims to provide for more readable code." (Mind you, that was the only part of that Wikipedia article that I agreed with.)
What's sickening is that the overly "fluent interface" code samples I've seen lately involve deeply nested indentation and absolutely no structure, just a mashup of semi-plain-English, dot-spaced gobblygook with as much content in a single terminated statement as possible. I can definitely see where such interfaces were easy to write. But easier to read? No, not for me. And I don't see these habits as being pertinent to the definition. Syntactic sugar for the developer, though? Yes. So long as there are alternative, conventional ways of coding the same thing. Jon --- In altdotnet@..., Matt Hinze <mhinze@...> wrote: > > Not to be combative but to understand: what exactly do you disagree with? > > On Wed, Sep 30, 2009 at 1:47 PM, James Hicks <jhicks0300@...> wrote: > > I disagree with this. I read a lot more code than I write and a lot > > of the code I read is not code I wrote. > > > > James > > > > On Wed, Sep 30, 2009 at 10:44 AM, Matt Hinze <mhinze@...> wrote: > >> Would like to chime in here - fluent interfaces that are easy to read > >> are nice but that shouldn't be the goal. The goal should be making > >> code easy to write. > >> > >> Fluency is an output; we achieve fluency writing the code not reading > >> it. One who can only read a foreign language does not claim to be > >> fluent in it. > >> |
|
|
Re: A better 'Fluent interface', please--- In altdotnet@..., Paul Cowan <dagda1@...> wrote:
> > I have to agree, simple method chaining ala JQuery is one thing but the > fluent interface thing has been over done in .NET and is probably a du jour > phenomenon that such circles succumb to. > > I think it is the lamdas or over use of lamdas that makes me feel queasy > when looking at some of them. > > The following is one such that exhibits how unfluent a fluent interface can > be: > > http://codebetter.com/blogs/dru.sellers/archive/2009/05/29/dropkick-an-idea-for-deployments.aspx > > The formatting is part of the fluent interface and the formatting is > unfortunately in the author's head. > > I can only think how much time you would waste with the tab key to get that > to format correctly. > Welcome to the world of ReSharper (I'd assume CodeRush as well). Not giving an opinion on the sample. Just the silly tab comment. |
|
|
Re: Re: A better 'Fluent interface', please>> Welcome to the world of ReSharper (I'd assume CodeRush as well). Not
giving an opinion on the sample. Visual studio will rearrange my HTML, does not make it good html. Cheers Paul Cowan Cutting-Edge Solutions (Scotland) http://thesoftwaresimpleton.blogspot.com/ 2009/9/30 courtrilleshane <shanecourtrille@...> > > > --- In altdotnet@... <altdotnet%40yahoogroups.com>, Paul Cowan > <dagda1@...> wrote: > > > > I have to agree, simple method chaining ala JQuery is one thing but the > > fluent interface thing has been over done in .NET and is probably a du > jour > > phenomenon that such circles succumb to. > > > > I think it is the lamdas or over use of lamdas that makes me feel queasy > > when looking at some of them. > > > > The following is one such that exhibits how unfluent a fluent interface > can > > be: > > > > > http://codebetter.com/blogs/dru.sellers/archive/2009/05/29/dropkick-an-idea-for-deployments.aspx > > > > The formatting is part of the fluent interface and the formatting is > > unfortunately in the author's head. > > > > I can only think how much time you would waste with the tab key to get > that > > to format correctly. > > > <snip> > > Welcome to the world of ReSharper (I'd assume CodeRush as well). Not giving > an opinion on the sample. Just the silly tab comment. > > > |
|
|
Re: Re: A better 'Fluent interface', pleaseSo.. you guys disagree with my opinion that "discoverability" and
"flow" - writing the code - should be more important than common-language-style readability when designing a fluent interface? That's the only opinion I intended to offer... By the way, it's not impossible for Fowler and Evans to have gotten something slightly wrong, nor is it impossible that the community has, after some time, more correctly understood concepts they introduced. On Wed, Sep 30, 2009 at 2:34 PM, jond_123 <jon@...> wrote: > I have to disagree, too. "Fluent interfaces" are not an output (writing code), the phrase was a term coined by Eric Evans and Martin Fowler (as linked to Wikipedia in my OP) and it means "a way of implementing an object oriented API in a way that aims to provide for more readable code." (Mind you, that was the only part of that Wikipedia article that I agreed with.) > > What's sickening is that the overly "fluent interface" code samples I've seen lately involve deeply nested indentation and absolutely no structure, just a mashup of semi-plain-English, dot-spaced gobblygook with as much content in a single terminated statement as possible. I can definitely see where such interfaces were easy to write. But easier to read? No, not for me. And I don't see these habits as being pertinent to the definition. > > Syntactic sugar for the developer, though? Yes. So long as there are alternative, conventional ways of coding the same thing. > > Jon > > --- In altdotnet@..., Matt Hinze <mhinze@...> wrote: >> >> Not to be combative but to understand: what exactly do you disagree with? >> >> On Wed, Sep 30, 2009 at 1:47 PM, James Hicks <jhicks0300@...> wrote: >> > I disagree with this. I read a lot more code than I write and a lot >> > of the code I read is not code I wrote. >> > >> > James >> > >> > On Wed, Sep 30, 2009 at 10:44 AM, Matt Hinze <mhinze@...> wrote: >> >> Would like to chime in here - fluent interfaces that are easy to read >> >> are nice but that shouldn't be the goal. The goal should be making >> >> code easy to write. >> >> >> >> Fluency is an output; we achieve fluency writing the code not reading >> >> it. One who can only read a foreign language does not claim to be >> >> fluent in it. >> >> > > > > ------------------------------------ > > Yahoo! Groups Links > > > > |
|
|
Re: Re: A better 'Fluent interface', pleaseI thought fowler or evans or both called fluent interfaces train wrecks.
Discoverability is indeed a good use case but I find the over use of lamdas in C# fluent interfaces do not add anything to discoverability, just unecessary noise. FI's should be simple and small and as has been previously mentioned not be the only way into the API. Cheers Paul Cowan Cutting-Edge Solutions (Scotland) http://thesoftwaresimpleton.blogspot.com/ 2009/9/30 Matt Hinze <mhinze@...> > > > So.. you guys disagree with my opinion that "discoverability" and > "flow" - writing the code - should be more important than > common-language-style readability when designing a fluent interface? > That's the only opinion I intended to offer... > > By the way, it's not impossible for Fowler and Evans to have gotten > something slightly wrong, nor is it impossible that the community has, > after some time, more correctly understood concepts they introduced. > > On Wed, Sep 30, 2009 at 2:34 PM, jond_123 <jon@...<jon%40jondavis.net>> > wrote: > > I have to disagree, too. "Fluent interfaces" are not an output (writing > code), the phrase was a term coined by Eric Evans and Martin Fowler (as > linked to Wikipedia in my OP) and it means "a way of implementing an object > oriented API in a way that aims to provide for more readable code." (Mind > you, that was the only part of that Wikipedia article that I agreed with.) > > > > What's sickening is that the overly "fluent interface" code samples I've > seen lately involve deeply nested indentation and absolutely no structure, > just a mashup of semi-plain-English, dot-spaced gobblygook with as much > content in a single terminated statement as possible. I can definitely see > where such interfaces were easy to write. But easier to read? No, not for > me. And I don't see these habits as being pertinent to the definition. > > > > Syntactic sugar for the developer, though? Yes. So long as there are > alternative, conventional ways of coding the same thing. > > > > Jon > > > > --- In altdotnet@... <altdotnet%40yahoogroups.com>, Matt > Hinze <mhinze@...> wrote: > >> > >> Not to be combative but to understand: what exactly do you disagree > with? > >> > >> On Wed, Sep 30, 2009 at 1:47 PM, James Hicks <jhicks0300@...> wrote: > >> > I disagree with this. I read a lot more code than I write and a lot > >> > of the code I read is not code I wrote. > >> > > >> > James > >> > > >> > On Wed, Sep 30, 2009 at 10:44 AM, Matt Hinze <mhinze@...> wrote: > >> >> Would like to chime in here - fluent interfaces that are easy to read > >> >> are nice but that shouldn't be the goal. The goal should be making > >> >> code easy to write. > >> >> > >> >> Fluency is an output; we achieve fluency writing the code not reading > >> >> it. One who can only read a foreign language does not claim to be > >> >> fluent in it. > >> >> > > > > > > > > ------------------------------------ > > > > Yahoo! Groups Links > > > > > > > > > > > |
| < Prev | 1 - 2 | Next > |
| Free embeddable forum powered by Nabble | Forum Help |