Typesafe DSLs in Java: Part 1 — Typesafe Bytecode

来源:互联网 发布:linux 管道符什么作用 编辑:程序博客网 时间:2024/05/16 01:36


Posted by: Joseph Ottinger on ?? 18, 2008 DIGG<script type="text/javascript">function _parseDiggURL() { var _diggURL = "http://digg.com/submit?phase=2&topic=Programming&url=" _diggURL += encodeURIComponent(location.href); _diggURL += "&title="; _diggURL += escape ( "Typesafe DSLs in Java: Part 1 — Typesafe Bytecode") ; _diggURL += "&bodytext="; _diggURL += escape ( "&#034;&lt;a href=&#034;http://dow.ngra.de/2008/03/24/typesafe-dsls-in-java-part-1-typesafe-bytecode/&#034;&gt;Typesafe DSLs in Java: Part 1 — Typesafe Bytecode&lt;/a&gt;,&#034; by Jevgeni Kabanov (M. Sc., in case you&#039;re interested), offers a way to use ASM to build a typesafe engineering DSL as a case study. There&#039;s also a followup (&#034;&lt;a href=&#034;http://dow.ngra.de/2008/03/26/typesafe-asm-problems-solved/&#034;&gt;Typesafe ASM — problems solved?&lt;/a&gt;&#034;) that addresses some of the problems the first post left unaddressed. Jevgeni is scheduled to be speaking at &lt;a href=&#034;http://javasymposium.techtarget.com/europe/index.html&#034;&gt;TSSJS in Prague&lt;/a&gt;, although he&#039;s not on the schedule yet - it looks like a cool session based on the abstract.&lt;br&gt;&lt;br&gt;It&#039;s an interesting concept - one of the things that Jevgeni is addressing in his post is the following sort of process, which is an example of a normal fluent interface:&lt;pre&gt;Person p=new Person().setFirstName(&#034;Jean-Claude&#034;).setHair(Hair.BROWN).setHair(Hair.GREY);&lt;/pre&gt;In this case, you can see where setting the hair color is done twice, which Jevgeni addresses by saying:&lt;blockquote&gt;The type you return from your DSL method should allow exactly those operations that are possible with the current state.&lt;/blockquote&gt;In other words, the &lt;code&gt;setHair&lt;/code&gt; method shouldn&#039;t return a Person, but a Person implementation for which setHair() isn&#039;t valid - which means the above code wouldn&#039;t compile.&lt;br&gt;&lt;br&gt;The cool thing here is that Jevgeni&#039;s actually producing something to address this sort of problem - in that fluent interfaces are a result of not having good DSLs in the first place. &lt;br&gt;&lt;br&gt;There&#039;s a lot of potential here. The idea is that with typesafe fluent interfaces, you can build a domain-specific type of language for Java that are just as powerful as you might find in Scala or Haskell. &lt;br&gt;&lt;br&gt;There&#039;s even a project in the works to show all of this in action: &lt;a href=&#034;http://code.google.com/p/flu/&#034;&gt;flu&lt;/a&gt;, hosted on Google Code. It&#039;s important: &lt;b&gt;this project is not production-ready&lt;/b&gt;, although Jevgeni says that it will be eventually.&lt;br&gt;&lt;br&gt;Some example code using this concept:&lt;pre&gt;Person p = new Person();&lt;br&gt;&lt;br&gt;List&amp;lt;Tuple3&amp;gt;&amp;lt;String, Integer, Date&amp;gt;&amp;gt; persons =&lt;br&gt; new QueryBuilder(datasource)&lt;br&gt; .from(p)&lt;br&gt; .select(p.name, p.height, p.birthday)&lt;br&gt; .where(gt(p.height, 170))&lt;br&gt; .find();&lt;br&gt;for (Tuple3&amp;lt;String, Integer, Date&amp;gt; person : persons) {&lt;br&gt; String name = person.v1();&lt;br&gt; Integer height = person.v2();&lt;br&gt; Date birthday = person.v3();&lt;br&gt; System.out.println(&lt;br&gt; name + &#034; &#034; + height + &#034; &#034; + birthday); &lt;br&gt;}&lt;/pre&gt;This is cool stuff - even if the SQL parsing isn&#039;t directly useful to you, the potential for enforcing type safety and valid operations on fluent interfaces can be a powerful addition to the toolbelt.").substring(0,300); return _diggURL ;}</script>
"Typesafe DSLs in Java: Part 1 — Typesafe Bytecode," by Jevgeni Kabanov (M. Sc., in case you're interested), offers a way to use ASM to build a typesafe engineering DSL as a case study. There's also a followup ("Typesafe ASM — problems solved?") that addresses some of the problems the first post left unaddressed. Jevgeni is scheduled to be speaking at TSSJS in Prague, although he's not on the schedule yet - it looks like a cool session based on the abstract.

It's an interesting concept - one of the things that Jevgeni is addressing in his post is the following sort of process, which is an example of a normal fluent interface:
Person p=new Person().setFirstName("Jean-Claude").setHair(Hair.BROWN).setHair(Hair.GREY);
In this case, you can see where setting the hair color is done twice, which Jevgeni addresses by saying:
The type you return from your DSL method should allow exactly those operations that are possible with the current state.
In other words, the setHair method shouldn't return a Person, but a Person implementation for which setHair() isn't valid - which means the above code wouldn't compile.

The cool thing here is that Jevgeni's actually producing something to address this sort of problem - in that fluent interfaces are a result of not having good DSLs in the first place.

There's a lot of potential here. The idea is that with typesafe fluent interfaces, you can build a domain-specific type of language for Java that are just as powerful as you might find in Scala or Haskell.

There's even a project in the works to show all of this in action: flu, hosted on Google Code. It's important: this project is not production-ready, although Jevgeni says that it will be eventually.

Some example code using this concept:
Person p = new Person();

List<Tuple3><String, Integer, Date>> persons =
new QueryBuilder(datasource)
.from(p)
.select(p.name, p.height, p.birthday)
.where(gt(p.height, 170))
.find();
for (Tuple3<String, Integer, Date> person : persons) {
String name = person.v1();
Integer height = person.v2();
Date birthday = person.v3();
System.out.println(
name + " " + height + " " + birthday);
}
This is cool stuff - even if the SQL parsing isn't directly useful to you, the potential for enforcing type safety and valid operations on fluent interfaces can be a powerful addition to the toolbelt.
  Message #250797 Post reply Post reply Post reply Go to top Go to top Go to top

Re: Typesafe DSLs in Java: Part 1 — Typesafe Bytecode

Posted by: Jevgeni Kabanov on ?? 18, 2008 in response to Message #250787
To give credit where credit is due -- the typesafe SQL stuff is joint work with Juhan Aasaru and Rein Raudjärv.

  Message #250804 Post reply Post reply Post reply Go to top Go to top Go to top

Re: Typesafe DSLs in Java: Part 1 — Typesafe Bytecode

Posted by: Cedric Beust on ?? 18, 2008 in response to Message #250787
p=new Person().setFirstName("Jean-Claude").setHair(Hair.BROWN).setHair(Hair.GREY);In this case, you can see where setting the hair color is done twice, which Jevgeni addresses by saying:
The type you return from your DSL method should allow exactly those operations that are possible with the current state.
In other words, the setHair method shouldn't return a Person, but a Person implementation for which setHair() isn't valid - which means the above code wouldn't compile.

Really? Is this possible? (I haven't read the article yet. The formatting is painful and I don't like to read code that forces me to scroll back and forth horizontally all the time...)

It seems to me that the only way to know that setHair() is no longer valid is to run code inside that object, which therefore needs to be compiled.

I can't really see how you could discover this kind of error at compile time...

--
Cedric