Typesafe DSLs in Java: Part 1 — Typesafe Bytecode

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

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.
原创粉丝点击