`
cookoo
  • 浏览: 648250 次
  • 性别: Icon_minigender_1
  • 来自: Shanghai
社区版块
存档分类
最新评论

First taste of rocaml

    博客分类:
  • FP
阅读更多
Rocaml lets you wrtie Ruby extension in Ocaml. It can be a relief to my project, I truely hope. We are using Ocaml with Rails by means of fork or socket and dealing with the format of communication between two sides is just boring.

Now let's have a look at how rocaml works. I'm gonna translate an example in rubyinline to rocaml. Since rubyinline supports basic type transaltion between Ruby and C, the orginal example is forced to declare a lot of complex data type defined in ruby.h by hand:
require 'rubygems'
require 'inline'

class Check
  class << self    
    inline do |builder|
      builder.c_raw "
        static VALUE check(int argc, VALUE *argv, VALUE self) {
          double x = NUM2DBL(RARRAY(argv[1])->ptr[0]);
          double y = NUM2DBL(RARRAY(argv[1])->ptr[1]);

          int len = RARRAY(argv[0])->len;
          double last_x = NUM2DBL(RARRAY(RARRAY(argv[0])->ptr[len-1])->ptr[0]);
          double last_y = NUM2DBL(RARRAY(RARRAY(argv[0])->ptr[len-1])->ptr[1]);
          double cur_x, cur_y = 0.0;

          int i, c = 0;
          for (i = 0; i < len; i++) {
            cur_x = NUM2DBL(RARRAY(RARRAY(argv[0])->ptr[i])->ptr[0]);
            cur_y = NUM2DBL(RARRAY(RARRAY(argv[0])->ptr[i])->ptr[1]);              
            if ((((cur_y <= y) && (y < last_y)) ||
                ((last_y <= y) && (y < cur_y))) &&
              (x < (last_x - cur_x) * (y - cur_y) / (last_y - cur_y) + cur_x)) {
              c = !c;
            }
            last_x = cur_x;
            last_y = cur_y;                  
         }
         if (c == 1) return Qtrue;
         return Qfalse;
       }
      "
    end        
  end
end


comparing to Ocaml code:

let check polygon point =
    let len = Array.length polygon in
    let last = polygon.(len - 1) in
    let result = ref false in
    for i = 0 to (len - 1) do
      let current = polygon.(i) in
      if ((current.(1) <= point.(1) && last.(1) > point.(1)) ||
          (last.(1) <= point.(1) && current.(1) > point.(1))) &&
         (point.(0) < ((last.(0) -. current.(0)) *.
                       (point.(1) -. current.(1)) /.
                       (last.(1) -. current.(1)) +. current.(0)))
      then
        begin
          result := not !result
        end;
      last.(0) <- current.(0); last.(1) <- current.(1)
    done;
    !result

open Callback
let _ =
  register "Check.check" check

and then we only have to declare a simple function interface in extconf.rb:

Interface.generate("check") do
  def_module("Check") do
    fun "check", [ARRAY(ARRAY(FLOAT)), ARRAY(FLOAT)] => BOOL
  end
end


Unfortunately though the ocaml code is more clear than the C one without being polluted by all kinds of type constants, the benchmark shows the rocaml extension is about 5 times slower than the C one. It seems the type conversion is still pricy considering Ocaml code generally should be on the same page with C in terms of speed.
分享到:
评论
6 楼 cookoo 2007-07-21  
恩,这个要看语言开发者的开发理由和本人习惯了。
5 楼 Lich_Ray 2007-07-21  
一个语言,到底是 user-friendly 是首要的呢,还是 powerful?如果要说“人性化设计”,这个就没准了;我自己还设计过一种自动把命名为主动动词的单参数方法转换为参数以被动方式调用的访问拦截器。但可能,这种东西做到语言中不太合适;如果能非常完美地整合到开发环境中,Smalltalk/Squeak 倒是个不错的想法,但怎么看怎么有点“超现实主义”。
Perl 不矛盾,只是语言学家对语言的抽象和我们“普通人”有点不同。
4 楼 cookoo 2007-07-21  
这是我自己使用Ruby快3年来的感觉。不仅仅指Ruby语法上的DSL能力(当然这个其实很简化,和真正能完全改变语法的meta programming不能比),更包括Ruby的API人性化设计风格,比如故意重复同一功能的不同名字减少记忆负担, 比如2.weeks.ago这种语法。任何语言对使用者来说都要求语法掌握和API掌握两方面,Ruby是唯一让我经常可以感受不翻文档直接猜中API这种奇妙感觉的语言。你如果只从语法规范上研究语言恐怕难以感受到使用语言的实际感觉。

Perl的设计哲学虽然以自然语言为蓝本,可惜太多设计不一致的符号把它污染了,这种内在矛盾性让我难以理解。
3 楼 Lich_Ray 2007-07-20  
引用
Ruby是最接近自然语言(英语)的程序语言

没听说过。你被一群 ruby 网站的菜鸟忽悠了。如果说要接近“自然语言”,Ruby 中没有任何有关自然语言语法的内容,Perl 才是“自然语言”;要说接近英语,Ruby 不就是允许函数调用少个括号+访问拦截器好用一点+一点不完善的标识符字符集扩展吗?别忘了还有 Smalltalk 那个变态……
世界不全是对象化的也不全是函数化的,这是真的…
2 楼 cookoo 2007-07-20  
呵呵,可以理解。

我觉得Haskell是最接近数学语言的程序语言,而Ruby是最接近自然语言(英语)的程序语言。各有各的用处,世界不全都是对象化的也不全都是函数化的。

可惜从以前的实验的情况看Haskell现在还不足以让我放心用到项目里,只好退而求其次了。

1 楼 Lich_Ray 2007-07-19  
被 Haskell 迷得神魂颠倒,遂对 ML 家族其他成员失去兴趣;又对 Ruby 之流没有兴趣,结果对 rocaml 没有兴趣...

相关推荐

Global site tag (gtag.js) - Google Analytics