﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2021 (c) 2026</copyright><ttl>60</ttl><item><title>Colin Jack commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>@Tim Wilde - Obviously ignore me, you've already posted it: http://www.midnightcoder.net/Blog/viewpost.rails?postId=38
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment17</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment17</guid><pubDate>Tue, 04 Dec 2007 20:12:45 GMT</pubDate></item><item><title>Colin Jack commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>@Tim Wilde - Don't suppose you want to post the example so I could nose through it? :)
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment16</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment16</guid><pubDate>Tue, 04 Dec 2007 20:03:59 GMT</pubDate></item><item><title>Rhysc commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>Keep these DSL articles coming. I find them very interesting (i have never used a DSL)
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment15</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment15</guid><pubDate>Tue, 04 Dec 2007 11:07:45 GMT</pubDate></item><item><title>Tim Wilde commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>Thanks :)
  
  
I wish I could take the credit, but this is inspired by Anders Norås' "Behind the scenes of the planning DSL":
  
  
http://andersnoras.com/blogs/anoras/archive/2007/07/09/behind-the-scenes-of-the-planning-dsl.aspx
  
  
I'm still struggling to getting my head around DSLs. Probably more specifically, understanding where the line is between a fluent interface and a DSL. I think I'm trying to reconcile "external DSL" and "fluent interface", and I'm missing the "internal DSL" bit which would seem to complete the puzzle.
  
  
On the other hand, I don't want to get shouted at by Scott Bellware for muddying the definition of "Domain Specific Language"! :D
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment14</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment14</guid><pubDate>Mon, 03 Dec 2007 19:19:44 GMT</pubDate></item><item><title>Ayende Rahien commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>That is crazy smart, I didn't consider that!
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment13</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment13</guid><pubDate>Mon, 03 Dec 2007 18:58:18 GMT</pubDate></item><item><title>Tim Wilde commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>"The web site is only checked when the task is constructed"
  
  
The Web.Site() is just a convenience class for constructing a delegate, and so should be equivalent to your code. The static Site() method returns an instance of a WebSiteStateCheckDescriptor class which is constructed with the address. This then has a IsNotResponding() method which returns a delegate:
  
  
public StateCheckDelegate IsNotResponding()
  
{
  
	return delegate
  
	       {
  
		 // Should probably *actually* check the site, but...
  
	       	return address == "http://www.example.com";
  
	       };
  
}
  
  
"...the Notify() may be there as a convenience method for execution, but this should accept any arbitrary action."
  
  
Yeah, I slapped my forehead as I posted my last comment. I missed that completely. It should be pretty simple to fix similar to the If(...) code, though :)
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment12</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment12</guid><pubDate>Mon, 03 Dec 2007 18:51:18 GMT</pubDate></item><item><title>John &amp;quot;Z-Bo&amp;quot; Zabroski commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>Not just a way to record your thinking, but also a way to share your thoughts and get feedback. =)  I don't view it as research papers, either.  I see it as having a productive conversation.  Thanks again.  I inferred you were trying to put together a series on this and very much appreciate it.
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment11</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment11</guid><pubDate>Mon, 03 Dec 2007 04:54:43 GMT</pubDate></item><item><title>Ayende Rahien commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>John,
  
Those posts are not meant as research papers. They are ways to record my thinking.
  
This specific post is an introduction to a chapter that takes about the reasons for building domain specific languages. All the explanations that you can think of are going to be there, but they are not in this particular post.
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment10</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment10</guid><pubDate>Mon, 03 Dec 2007 04:13:51 GMT</pubDate></item><item><title>John &amp;quot;Z-Bo&amp;quot; Zabroski commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>Thank you again for such a nice reply.  The courtesy you extend is wonderful.
  
  
@"I _do_ expect you to do your research."
  
  
Hopefully, you also expect myself and your other readers to do critical thinking about provocative statements you make.   "The second version has far less line noise, it a lot more clearer, and allows me to grow my DSL as I get more information, without hitting the language limits" is a provocative statement.  However, provocative statements are *NOT* a substitute for critical thinking.  It's not just research readers should expect to do; readers need to do critical thinking and either debunk statements or assert why those statements are true!  That's what gives the blogosphere it's color.
  
  
Come to that, there is a difference between reading an API and understanding how to use it to accomplish its intended purpose, and studying multiple APIs and extracting commonalities from them as well as curious anomalies.  Similarly, there is a difference between discussing a diagram that show cases superb design, and discussing the principles of good design.  In each case, one is much harder than the other and I was looking for a jump start on that research after my initial plunge wasted my morning.
  
  
I hope I didn't come across as lazy.  It's just better for me to admit I am spinning my tires and ask you again for clearer direction.  I think Dave Chelimsky's "Story Runner in Plain English" alongside Jordan McKible's "If you aren't writing Matchers, you aren't using RSpec" illustrate there are greater ideas than simply DSL vs. Fluent Task.  Both take source code that has a Fluent Task flavor and transform it into something more like your DSL.  That suggests there are rules of thumb we can follow, ways to create DRYer code, &amp;c.  Things worth pursuing.  I like to call these rules "general solutions".  They're not instances of great design, instead they're principles *for* great design.  Power comes from within.
  
  
This mini-dialogue we've had has been useful to me, and hopefully my feedback has been constructive to you as well, and I'm sure your watchful eye lets nothing pass you by.  Thank you.
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment9</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment9</guid><pubDate>Mon, 03 Dec 2007 03:54:00 GMT</pubDate></item><item><title>Ayende Rahien commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>I _do_ expect you to do your research.
  
  
NBehave:
  
http://www.codeplex.com/NBehave/Wiki/View.aspx?title=Examples&amp;referringTitle=Home
  
  
transferStory
  
    .WithScenario("Savings account is in credit")
  
        .Given("my savings account balance is", 100, delegate(int accountBalance) { savings = new Account(accountBalance); })
  
            .And("my cash account balance is", 10, delegate(int accountBalance) { cash = new Account(accountBalance); })
  
        .When("I transfer to cash account", 20, delegate(int transferAmount) { savings.TransferTo(cash, transferAmount); })
  
        .Then("my savings account balance should be", 80, delegate(int expectedBalance) { Assert.AreEqual(expectedBalance, savings.Balance); })
  
            .And("my cash account balance should be", 30, delegate(int expectedBalance) { Assert.AreEqual(expectedBalance, cash.Balance); })
  
  
  
RSpec:
  
http://blog.davidchelimsky.net/articles/2007/10/21/story-runner-in-plain-english
  
  
Scenario "savings account is in credit" do
  
    Given "my savings account balance is", 100 do |balance|
  
      @savings_account = Account.new(balance)
  
    end
  
    And "my cash account balance is", 10 do |balance|
  
      @cash_account = Account.new(balance)
  
    end
  
    When "I transfer", 20 do |amount|
  
      @savings_account.transfer_to(@cash_account, amount)
  
    end
  
    Then "my savings account balance should be", 80 do |expected_amount|
  
      @savings_account.balance.should == expected_amount
  
    end
  
    And "my cash account balance should be", 30 do |expected_amount|
  
      @cash_account.balance.should == expected_amount
  
    end
  
end
  
  
RSpec with plain English:
  
http://blog.davidchelimsky.net/articles/2007/10/21/story-runner-in-plain-english
  
  
Scenario "savings account is in credit" do
  
    Given "my savings account balance is 100"
  
    And "my cash account balance is 10"
  
    When "I transfer 20"
  
    Then "my savings account balance should be 80"
  
    And "my cash account balance should be 30"
  
end
  
  
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment8</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment8</guid><pubDate>Mon, 03 Dec 2007 01:47:04 GMT</pubDate></item><item><title>John &amp;quot;Z-Bo&amp;quot; Zabroski commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>@"Please take a look at the difference between NBehave and RSpec for a good example."
  
  
Thank you very much.
  
  
I searched Google for "NBehave vs. RSpec", and after wasting a few hours searching, I can say there are no explicit comparisons that are instructive.  Maybe I'm lazy, but I'm looking to learn from an *expert* or someone more *experienced* than me.  For me to just agree with you like I know what you are talking about?  That would be naive of me and behavior like that encourages ignorance.  So I'm stuck between a rock and a hard place wondering *what really effects readability and maintainability of a DSL*
  
  
However, while searching, I did find Jordan McKible wrote an instructive blog post titled, "If you aren't writing Matchers, you aren't using RSpec" available at http://tuples.us/2007/10/23/if-you-arent-writing-matchers-you-arent-using-rspec/
  
  
Looking through an example *with an explanation* is way more instructive than the discriminate statement that languages have glass ceilings.  I strenuously encourage you not to make such statements, because it passes off the idea that by writing your information in a particular language you're doing design.  This is the same problem I see in some of your other posts, such as the one on Generic Specialization you linked to on your MSDN article about Inversion of Control (how I ended up on your blog in the first place).  You're using diagrams to convey concepts you could better describe by finding the general solution and putting it down into words.  Come to that, Mats Helander has a pretty good article on Domain Model Management (TLA=DMM) where he discusses what a generic solution to ORM persistence is really after.  This post is available at: http://www.matshelander.com/wordpress/?p=30
  
  
I encourage you to actually explore how true it is that there are "language limits", or if it's just limits in your thinking / our thinking.  Just comparing trivial pieces of code side by side doesn't really succeed.  Sorry, but it's the truth, and as a friendly visitor to your blog, I have an obligation to tell you the truth.  Again, thank you!
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment7</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment7</guid><pubDate>Mon, 03 Dec 2007 01:28:13 GMT</pubDate></item><item><title>Ayende Rahien commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>Tim,
  
Your version looks nicer, but it doesn't have the same semantics. The web site is only checked when the task is constructed, and the Notify() may be there as a convenience method for execution, but this should accept any arbitrary action.
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment6</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment6</guid><pubDate>Sun, 02 Dec 2007 21:46:42 GMT</pubDate></item><item><title>Ayende Rahien commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>Sendhil,
  
No argument here. I consider a Fluent Interface to be a degenerate form of a DSL, constrained by limits of a language.
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment5</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment5</guid><pubDate>Sun, 02 Dec 2007 11:40:34 GMT</pubDate></item><item><title>Ayende Rahien commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>John,
  
sorry about that, that is a bug in the post :-), and I fixed it.
  
  
As for language limits. Please take a look at the difference between NBehave and RSpec for a good example.
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment4</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment4</guid><pubDate>Sun, 02 Dec 2007 09:44:59 GMT</pubDate></item><item><title>Sendhil commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>Just to nitpick, 
  
  
Both the examples you have specified are DSLs.
  
Please refer:
  
http://www.mockobjects.com/files/evolving_an_edsl.ooplsa2006.pdf.
  
  
Also I will quote an example from http://martinfowler.com/dslwip/Intro.html
  
  
    event ("doorClosed",  "D1CL");
  
    event ("drawOpened",  "D2OP");
  
    event ("lightOn",     "L1ON");
  
    event ("panelClosed", "PNCL");
  
  
    resetEvent ("doorOpened",  "D1OP");
  
  
    command("unlockPanel", "PNUL");
  
    command("lockPanel", "PNLK");
  
    command("lockDoor", "D1LK");
  
    command("unlockDoor", "D1UL");
  
  
    state("idle")
  
        .actions("unlockDoor","lockPanel")
  
        .transition("doorClosed").to("active")
  
        ;
  
  
    state("active")
  
        .transition("drawOpened").to("waitingForLight")
  
        .transition("lightOn").   to("waitingForDraw")
  
        ;
  
  
    state("waitingForLight")
  
        .transition("lightOn").to("unlockedPanel");
  
  
    state("waitingForDraw")
  
        .transition("drawOpened").to("unlockedPanel");
  
  
    state("unlockedPanel")
  
        .actions("unlockPanel", "lockDoor")
  
        .transition("panelClosed").to("idle");
  
  
"It's formatted oddly, and uses some unusual programming conventions, but it is valid Java. It's java written in what is these days called a Fluent Interface style. A Fluent Interface is an API that's designed to read like an internal DSL. This I would call a DSL - although it's more messy than the ruby DSL it still has that declarative flow that a DSL needs."
  
  
Regards,
  
Sendhil
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment3</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment3</guid><pubDate>Sun, 02 Dec 2007 06:12:46 GMT</pubDate></item><item><title>Tim Wilde commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>I do agree that the DSL example is much clearer than anything with a C-like syntax.
  
  
DSLs aren't something I've really been able to fully grok, to be honest. I would be interested to find out how you would implement a DSL like the second example. Would you consider a post (or series) showing a basic example?
  
  
I've been using fluent interfaces quite a bit recently, and I fealt that the C# example didn't really get a good representation, so, taking a leaf out of your book Oren, I spent about 30 minutes playing with the idea and got a basic implementation working like this:
  
  
ITask SiteCheckTask =
  
	Schedule.Task( "Report website down-time" ).
  
		Repeat.Every( 3 ).Minutes.
  
		Starting( DateTime.Now ).
  
		If( Web.Site( "http://www.example.com" ).IsNotResponding() ).
  
		Notify( "admin@example.com", "Site down!" );
  
  
I cleaned it up with a convenience class for expressing the site check, which basically just builds the same delegate, and I moved the periods to the end of the lines to make things a little more readable. True, it has still got the noise of C# syntax, but it makes it a little more readable, I think.
  
  
All in, it's about 250 lines of code, in 8 classes, 6 interfaces, and a delegate.
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment2</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment2</guid><pubDate>Sun, 02 Dec 2007 05:21:27 GMT</pubDate></item><item><title>John &amp;quot;Z-Bo&amp;quot; Zabroski commented on DSL vs. Fluent interface: Compare &amp; Contrast</title><description>I want code that is correct, explicit, fast, and in that order.
  
  
Please do talk more about imperative vs. declarative DSL.  For what it is worth, I have never programmed in C#, but am interested in your comments on imperative vs. declarative DSLs.
  
  
Also, it is not clear to me that the second version has far less noise.  Can you justify how it "allows [you] to grow [your] DSL as [you] get more information, without hitting the language limits"?  The only thing clear to me is that the DSL code is not comparable to the Fluent Interface code, because they're testing handling different situations.  The  Fluent Interface incorrectly checks to see if the Web Site is up, whereas the DSL correctly checks to see if the Web Site is down.  At least, that is how I interpret "return WebSite("http://example.org").IsAlive;": when the web site is alive is true, then notify.  In that case, you will get a notification every three minutes!
  
  
Now that I've addressed that, could you provide an example where you actually hit these so-called language limits and what those limits are precisely?
  
  
Although I am not a C# programmer, your feedback can still be instructive.  Please share.  Thank you.
</description><link>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment1</link><guid>http://ayende.com/2984/dsl-vs-fluent-interface-compare-contrast#comment1</guid><pubDate>Sun, 02 Dec 2007 00:47:06 GMT</pubDate></item></channel></rss>