Meta-Interpretation

Code, better explained.

Java与groovy混编 —— 一种兼顾接口清晰和实现敏捷的开发方式

| Comments

  1. 有大量平均水平左右的“工人”可被选择、参与进来 —— 这意味着好招人
  2. 有成熟的、大量的程序库可供选择 —— 这意味着大多数项目都是既有程序库的拼装,标准化程度高而定制化场景少
  3. 开发工具、测试工具、问题排查工具完善,成熟 —— 基本上没有团队愿意在时间紧、任务重的项目情况下去做没有把握的、基础开发工具类的技术试探
  4. 有面向对象特性, 适合大型项目开发 —— 无数大型项目已向世人述说,“面向对象”是开发大型软件的优秀代码组织结构
  5. 能适应大型团队、多人协作开发 —— 代码需要简单易懂,起码在接口、api层面是这样

—— 这是我所理解的“工业化开发编程语言”的概念

很显然, java就是种典型的“工业语言”, 非常流行,很多企业靠它赚钱,很实际;
但java也是常年被人黑,光是对其开发效率的诟病就已经足够多,不过java始终屹立不倒;

这样的局面其实无所谓高兴还是担忧,理性的程序员有很多种,其中一种是向“钱”看的 —— 我写java代码,就是因为工作需要而已,能帮助我的组织搞定业务,做出项目,这很好;
当有人说java语言不好的时候,理性的程序员不会陷入宗教式的语言战争之中,他会思考这些人说的是否有道理;如果真的发现整个java平台大势已去,他会毫不犹豫地扭头就走,不过直到目前为止,还没有这种迹象出现;

那么,从这些无数次的口水之争中,我们能否从别人的“战场”上发现一些有用的东西, 来改进我们的开发方式,从而使得java这种已经成为一个“平台”的东西走得更远,赚更多的钱呢?
答案是“有的”,感谢那些参与口水战争的、各种阵营的年轻程序员们,有了你们,java speaker们才有了更多的思考;

安全的免登方案

| Comments

免登

  • 也就是用户在网站A已经登录,希望不必再重复登录过程,即可以登录状态访问网站B
  • 这其实是一种“信任交换”,即用户已经取得了网站A的信任,希望以一种安全的方式也取得网站B的信任
  • 从网站A免登到网站B的信任交换其实就是交换“登录cookie”, 很显然“交换登录cookie”只是“信任交换”的一种情形;从普遍意义上讲,用户在系统A和系统B之间做“信任交换”,其实可以交换任意“信任凭证”,他们的原理都是大同小异的

动态的Java - 无废话JavaCompilerAPI中文指南

| Comments

JavaCompiler API

1.6之后JDK提供了一套compiler API,定义在JSR199中, 提供在运行期动态编译java代码为字节码的功能
简单说来,这一套API就好比是在java程序中模拟javac程序,将java源文件编译为class文件;其提供的默认实现也正是在文件系统上进行查找、编译工作的,用起来感觉与javac基本一致;
不过,我们可以通过一些关键类的继承、方法重写和扩展,来达到一些特殊的目的,常见的就是“与文件系统解耦”(就是在内存或别的地方完成源文件的查找、读取和class编译)
需要强调的是,compiler API的相关实现被放在tools.jar中,JDK默认会将tools.jar放入classpath而jre没有,因此如果发现compiler API相关类找不到,那么请检查一下tools.jar是否已经在classpath中;
当然我指的是jdk1.6以上的版本提供的tools.jar包

使用’Tsukuba Help’观看国外免费在线网络课程(android篇)

| Comments

目前在Coursera.org, udacity.com, edx.org等网站都提供有丰富的、高质量的在线视频课程可学习;
虽然国内也有网易公开课等视频课程项目(其课程来源仍是上述国外网站),但数量相对较少且翻译也跟不上,而且,更重要的是,这些在线课程往往随堂提供有课后作业,如果你想同一时间与来自世界各地的同学一起交作业、一起讨论的话,用网易公开课平台是无法达到的;
(当然我没有说网易公开课不好,在这里我要向网易致敬!)
但由于网速、网络等各种原因,直接观看上述国外网站的在线课程有些困难,为此我推荐一种快速有效的办法,在android手机上,直接观看国外在线课程视频。

用于代码生成的模板引擎应该是什么样子?

| Comments

以前在做一个涉及代码生成的项目的时候,使用了velocity模板引擎来做这个代码生成;
而事后发现,velocity有大部分的语法是我在代码生成过程中没有用到的;
且velocity的引入,也导致引入了一些看起来很多余的jar包;
后来我看了看StringTemplate这个东西,发现它不仅包含velocity几乎全部的语法,还有模板继承机制!这岂不是更复杂?虽然标榜为“为了代码生成”的模板引擎…但鉴于velocity的复杂印象,我并没有使用它.
再后来,我为了包管理上的简洁(对于某些项目我承认我有洁癖),我直接使用了java标准库里的java.text.MessageFormat来做代码生成;这也确实可行!不过,缺点也是很快就能遇到的:

  1. 大括号{}MessageFormat中是关键字!所以输出时必须转义;这两个东西在目标代码中(比如java)很常见,遇到一个就要转义一个是很不爽的事情;
  2. 除了字符串替换之外,没有任何分支逻辑判断、循环结构支持,这使得所有的分支逻辑和循环结构都要写在调用这些MessageFormat的java代码里;虽然很多时候确实可以这么做并且很合适,但是还是有一些情况,如果能写在模板里会明显比写在java代码里好;
  3. MessageFormat的placeholder是数字,渲染时是根据传入参数的位置来做值替换,这很不直观,更好的用户体验应该是依据名字来替换,就像所有的、普遍意义上人们所见过的模板引擎那样;

总结性地思考一下:我在做代码生成的时候,需要的模板引擎大概应该是:

  • 简单,这意味着只需要拥有简单的语法以及简单的jar包依赖(或者不需要jar包依赖)
  • 高效,最好直接编译成字节码执行,而非像velocity那样每次渲染都遍历AST

而重点就在于第一点:简单,这需要我好好总结一份“用作代码生成的模板引擎所必须的语法特性”列表, 并且除此以外,不能有更多其它的东西;
至于高效,只要确保最终被反复执行的逻辑是一个编译好的java类就行了,而非遍历AST,这很容易办到;
而且..正好之前开发的dropincc.java需要为用户提供一个模板引擎,因为语法解析与代码生成在很多任务中是一对好基友,常常是伴随着出现;那么在dropincc.java中内建一个针对代码生成的模板引擎也就是非常有必要的了;它之于dropincc.java,就好比StringTemplate之于antlr,都是为了方便用户做代码生成创造的;
并且,这个模板引擎应该随着dropincc.java一起发布,不需要引入新的jar包依赖;
计划中,这个模板引擎的基本特性:

Prime Numbers Less Than N

| Comments

  • Sieve方法: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
  • 优化1:初始化list时,预先排除2,3,5,7的倍数, 得到一个初始化list
  • 优化2:在筛除合数时,不必一个一个挨着筛,只需在列表中剔除: p * x 即可(x是从p开始,初始list中的数字), 直到p*p > 初始化list中的最大数

资料: 用作测试,素数个数对照表: http://primes.utm.edu/howmany.shtml

扩展: 也许下一篇文章介绍一下“素数测试”? http://en.wikipedia.org/wiki/Primality_tests

TODO 后面再完成本文,反正有版本管理~

Growing a Full-Featured Calculator in 15 Minutes Using Dropincc.java

| Comments

First, let’s create a empty java project in eclipse IDE, download newest playable dropincc.java jar file from here. Adding it to the build path of the project, like this(note: jdk1.6 or above required):
emptyProjWithJar
And then, create a new java source file to build our grammar, for example, Calculator.java.
We start by specifying the EBNF form of our expected calculator language. The calculator expression would do addition and subtraction operations and also multiplication and division operations which have a greater priority.
Also, we expect the calculator could handle parentheses to do priority adjustment.
We could write the EBNF grammar rules in a top-down pattern:

calc ::= expr $
expr ::= addend (('+'|'-') addend)*

We specified that the overall expression consists one or more addend sub-expressions with '+' or '-' symbol delimited.
And for every single addend expression:

addend ::= factor (('\*'|'/') factor)*

consists one or more factor separated by '*' or '/'.
And finally, for any single factor, is either a single digit or a quoted expression:

factor ::= '\d+(\.\d+)?'
         | '(' expr ')'

Ok, we’ve done defining the EBNF of our calculator. This is what it look like all over:

calc ::= expr $
expr ::= addend (('+'|'-') addend)*
addend ::= factor (('\*'|'/') factor)*
factor ::= '\d+(\.\d+)?'
         | '(' expr ')'

Ideas and Concepts Behind Dropincc.java

| Comments

DSLs in java is hard.

DSLs are rarely discussed in java community. Or, at least comparing to other dynamic languages’ world, DSLs in java is much harder to create.

Why does this happen?

According to Martin Fowler’s comments on DSLs, they are separated mainly to two kinds: internal and external DSLs.

I believe that, the ability of how a specific general purposed programming language could be customized to an internal DSL relies on the language’s meta-programming features.

Some languages, especially dynamic typed ones, have ability to customize its syntactical appearance at runtime. By intercepting their class defining life-cycles, executing fail-over strategies when method or field missings, or doing presentation substitutions via sophisticated macro systems or even, directly change their parse tree at runtime. All those incredible features are the magic behind internal DSLs.

But, we sadly found that java has none of those magic stuff to help building internal DSLs. There’s little meta-programming features in java. Annotations? Perhaps one rare creature, but its not enough.
Maybe the only way to create internal DSLs in java is to design a set of Fluent Interface API. It’s great, but you won’t have much space on customizing the syntax of your DSL.

Then, seems that the possible ways to create real-world, sophisticated DSLs in java are always turns out to be external-DSLs. But, this won’t be easy, always, since the creation of computer world.

Dropincc.java, the Ultimate Tool to Create DSLs in Java

| Comments

Initial version released.

Dropincc.java is a dynamic parser generator which allows you crafting your DSLs in pure java, using your favorite editor.
Now it reached its initial release version 0.1.0. You can download it from the project page and play around with it.
There’s a detailed Quick Start guide on the project page, it could guide you through to have a overall feeling on using dropincc.java.

Main attributes of Dropincc.java.

  • It’s not just ‘yet another compiler compiler’. It aims to help you building DSLs in java Dynamically.
  • Dynamic means you can use your newly defined DSL immediately after you have just finished its definition. No other steps required, no additional command-line instructions needed to type.
  • Very close to EBNF grammar syntactically when defining grammar rules using dropincc.java. With the fluent interface API, you can feel as if you are writing EBNF directly. Syntactically close to EBNF is very nice for a parser generator.
  • It generates LL(*) parser for your language, dynamically, using java 1.6’s compiler API. And it provide powerful semantic predicate mechanics to handle even context-sensitive situations.
  • It won’t generate a parser source file to you and telling you to place the file into some where of your project directory. Instead, it handles all those generation & compiling staff in the background and only provides you a executable object which you can invoke.
  • No other dependencies except for the built-in java library. Requires JDK 1.6 or above.

A dummy language example.