锁定老帖子 主题:ajoo的jaskell和jparsec
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2005-02-04
ajoo 写道 好。我的facts是个immutable的tuple。它至少支持一个set成员。
不错,但是我们还有一个跟踪调试的问题,因为有些处理流程可能会很复杂,所以我们应该提供流程跟踪和类似设置断点的能力,我们不要求做到策略库内部函数实现过程的跟踪,但是至少要能够得到每一行语句执行前和执行后的数据,以判定所写的策略语句是否复合预期的要求。 比如说要跟踪“折扣2”执行前后的数据变化,OO架构可以轻易完成的工作,高阶函数要怎么玩呢? Facts facts = new Facts; facts.New("价格", "100");; facts.New("数量", "2");; facts.New("货物名称", "猪");; Actions acs = new Actions; acs.New("折扣1 = 5%", "数量 > 100 or 货物名称='猪' ");; acs.New("折扣2 = 3%", "数量 > 10 and 数量 < 100");; // register event acs.current_ac.before += new Action.OnBefore(ac_trace_action);; acs.current_ac.after += new Action.OnAfter(ac_trace_action);; acs.New("折扣3 = 0%", "数量 <= 10");; acs.New("折扣 = Max(折扣1, 折扣2, 折扣3);");; acs.New("总额 = 价格 * 数量 * (100% - 折扣);");; acs.OnAction(facts);; string total = facts.Get("总额");; stirng discount = facts.Get("折扣");; // handle event private void ac_trace_action(bool is_before, string expression, string error, Facts facts); { string discount = facts.Get("折扣2");; string count = facts.Get("数量");; } |
|
返回顶楼 | |
发表时间:2005-02-04
首先,对这类event handling的东西,我并不推荐用jaskell这种脚本,至少是看不出太多好处。
函数式的优势在于对一些业务逻辑的声明性编成,或者灵活组合不同的模块,起一个胶水的作用。 而对event handler这种OO的传统强项,函数式恐怕看不出太多优势。 不过,也不是不能做。 只是,你的这个例子我没有看得太懂。 你的这个trace似乎还是硬编码近来的。如果如此,你为什么不这样? final Action act = new SimpleAction("折扣2 = 3%", "数量 > 10 and 数量 < 100");. .setBefore(ac_trace_action); .setAfter(ac_trace_action);; acs.New(act);; 我自己觉得这比用current_ac更好。 而这种设计也更加functional,是immutable的。用函数式也很容易做到。 而如果你需要的是更加动态,类似aop风格的trace织入,比如: Actions new_acts = acts.setBefore("折扣2 = 3%", ac_trace_action); .setAfter("折扣2 = 3%", ac_trace_action);; 这用jaskell这种动态语言也很容易: let key = "折扣2 = 3%"; old_act = acts@key; weave_trace a x = let _ = ac_trace_action; r = a x; _ = ac_trace_action; in r; new_acts = extend acts key (weave_trace old_act);; in new_acts 这应该就算aop了吧? |
|
返回顶楼 | |
发表时间:2005-02-04
看了2天的jaskell, 偶的小脑袋已经接近发疯的边缘
ajoo 写道 我做这个东西的初衷是要非程序员的业务用户也能用,所以采用函数式就比较合适。毕竟不是所有business analyst都懂得“赋值”是什么意思。 偶觉得好像脱离了你的设计初衷, 对于这些业务用户来说重要是lib, 他们只用知道fact 10 或者 fact (10) 是计算10的阶乘, 用discount(customer, product)能够获得打折的数值, 不能指望他能够用jaskell写出多复杂函数式来, 他也不关心具体的实现是尾递归,lamda之类的. 对于这些业务用户来说, 越简单越好, 比如获得当前时间,并进行格式化, 最简单的就是提供now和format 2个函数: format(now(), "yyyy-MM-dd") 如果让他们写成: $SimpleDateFormat.new"yyyy-MM-dd".format $Date.new 之类的, 就太繁琐了. ajoo 写道 此时,可以让一个不懂java的维护人员花一个小时熟悉一下jaskell的基本语法,就可以写各种不同的逻辑规则了。 如: if north_america_sales + asian_sales > central_sales then north_america_sales - 100 else central_sales where north_america_sales = canada_sales+mexico_sales+united_states_sales .. 他需要了解if, else, where 还有 .. 这些keyword 偶认为简单的做法就是提供if(boolean expression, true return value, false return value)这样一个if函数 if(north_america_sales + asian_sales > central_sales, north_america_sales - 100, central_sales); where north_america_sales = canada_sales+mexico_sales+united_states_sales 总之, 各种应用, 用户只要会查函数手册以及学一个定义变量的关键字就够了 而jaskell其他的高级特性, 不是语法太怪异, 就是需要用户有良好的数学背景, 用户群太小 |
|
返回顶楼 | |
发表时间:2005-02-04
语法怪,是你impretive 语言用多了。
|
|
返回顶楼 | |
发表时间:2005-02-04
Readonly 写道 偶觉得好像脱离了你的设计初衷, 对于这些业务用户来说重要是lib, 他们只用知道fact 10 或者 fact (10) 是计算10的阶乘, 用discount(customer, product)能够获得打折的数值, 不能指望他能够用jaskell写出多复杂函数式来, 他也不关心具体的实现是尾递归,lamda之类的. 对于这些业务用户来说, 越简单越好, 比如获得当前时间,并进行格式化, 最简单的就是提供now和format 2个函数: format(now(), "yyyy-MM-dd") 如果让他们写成: $SimpleDateFormat.new"yyyy-MM-dd".format $Date.new 之类的, 就太繁琐了. 可以这样啊。写个外围函数库就是了。就是一个now函数和一个format函数而已。或者可以写成 now.format "yyyy-MM-dd" 可能更好看些吧? 本来就不指望他们能写递归。只要能写公式,定义简单的函数就行了。 Readonly 写道 ajoo 写道 此时,可以让一个不懂java的维护人员花一个小时熟悉一下jaskell的基本语法,就可以写各种不同的逻辑规则了。 如: if north_america_sales + asian_sales > central_sales then north_america_sales - 100 else central_sales where north_america_sales = canada_sales+mexico_sales+united_states_sales .. 他需要了解if, else, where 还有 .. 这些keyword 偶认为简单的做法就是提供if(boolean expression, true return value, false return value)这样一个if函数 if(north_america_sales + asian_sales > central_sales, north_america_sales - 100, central_sales); where north_america_sales = canada_sales+mexico_sales+united_states_sales 我已经删掉".."了。直接用分号就是了。最后的那个函数甚至不需要分号。 我是觉得if-then-else比你提的函数要清楚,更接近自然语言。也许更为业务用户所接受。 不过如果if是个函数的话,倒是有一个好处:currying。我可以写 if true, if x a等等partial application的东西。 而且语言也更简练,连if-then-else这三个关键字都没了,有的只是一个库定义的if函数。true和false也可以由库定义。这样关键字就剩下 where, let, in, and, or了。 坏处是,因为if是函数,而函数调用的优先级最高,如果你用haskell式的空格分隔法写函数调用,碰巧你比较懒,省括号过了头,写成这样 if 1>2 "a" "b"却被解释成: (if 1); > 2 "a" "b"。然后报错。 你必须或者写成: if(1>2); "a" "b" 或者写成 if(1>2, "a", "b"); 总而言之,是给程序员留下了一处陷阱。 而if-then-else却没有这个问题。 何去何从,倒是有点费脑筋呢。 我其实是很希望能说服自己用函数,这样语言更加简单,而我喜欢简单。 trustno1意见如何? if-then-else是函数好还是关键字好? 是内建于语言还是外建于库? 当然,也可以自己定义一个函数 ifelse cond yes no = if cond then yes else no; 然后让用户用ifelse函数好了。 对了,看来你已经深谙jaskell的lazy之道了呀。 在strict的语言里,比如java/c++,你是不可能用函数来模拟if-else,、因为if(true, 1, throw new Exception()); 会出错,而不是象 if (true); return 1; else throw new Exception();; 那样返回1。 其实,jaskell的keyword已经尽量精简了。只有: if, then, else, where, let, in, true, false, and , or。 再有,就是一个定义在顶级名字空间的not函数。 就这些了,再没有了。 而且一个业务员可能还不需要了解let和in。就是8个关键字和定义函数,调用函数的语法。 Readonly 写道 总之, 各种应用, 用户只要会查函数手册以及学一个定义变量的关键字就够了 我不认为让业务用户查函数手册是个可以让人满意的解决方法。如果需要定义一些函数给业务用户用,这个函数库一定要精简,最好就那么三五个意义不言自明的函数。 Readonly 写道 而jaskell其他的高级特性, 不是语法太怪异, 就是需要用户有良好的数学背景, 用户群太小 举个例子?语法怪异的我看看能不能改进。需要良好数学背景的你是指高阶函数? 可是你不见得需要用它呀。 : |
|
返回顶楼 | |
发表时间:2005-02-05
用函数,还是关键字对用户来说没有什么根本差别。
如果用函数的话,还不如用三目算符呢。如果用函数的话,我估计会演变成lisp的风格。这就会很好看。 |
|
返回顶楼 | |
发表时间:2005-02-06
ajoo 写道 首先,对这类event handling的东西,我并不推荐用jaskell这种脚本,至少是看不出太多好处。
函数式的优势在于对一些业务逻辑的声明性编成,或者灵活组合不同的模块,起一个胶水的作用。 而对event handler这种OO的传统强项,函数式恐怕看不出太多优势。 不过,也不是不能做。 只是,你的这个例子我没有看得太懂。 你的这个trace似乎还是硬编码近来的。如果如此,你为什么不这样? final Action act = new SimpleAction("折扣2 = 3%", "数量 > 10 and 数量 < 100");. .setBefore(ac_trace_action); .setAfter(ac_trace_action);; acs.New(act);; 我自己觉得这比用current_ac更好。 而这种设计也更加functional,是immutable的。用函数式也很容易做到。 而如果你需要的是更加动态,类似aop风格的trace织入,比如: Actions new_acts = acts.setBefore("折扣2 = 3%", ac_trace_action); .setAfter("折扣2 = 3%", ac_trace_action);; 这用jaskell这种动态语言也很容易: let key = "折扣2 = 3%"; old_act = acts@key; weave_trace a x = let _ = ac_trace_action; r = a x; _ = ac_trace_action; in r; new_acts = extend acts key (weave_trace old_act);; in new_acts 这应该就算aop了吧? 事实上所有的代码都是硬编的,因为我提供的是类库而不是脚本解释器,主要是用于模拟脚本语言,这样做的好处是直观易懂、灵活、易于扩展。 引用 我自己觉得这比用current_ac更好。 而这种设计也更加functional,是immutable的。用函数式也很容易做到。 final Action act = new SimpleAction("折扣2 = 3%", "数量 > 10 and 数量 < 100");. .setBefore(ac_trace_action); .setAfter(ac_trace_action);; acs.New(act);; 这样写有一个坏处,就是会破坏脚本语言的直观性,因为我们并不是任何时候都需要setBefore和setAfter,这些非必要的代码必须能够随意加入和删除,同时不能对原有代码造成任何影响,要做到这一点就需要使用acts.current_ac。 引用 而如果你需要的是更加动态,类似aop风格的trace织入,比如: Actions new_acts = acts.setBefore("折扣2 = 3%", ac_trace_action); .setAfter("折扣2 = 3%", ac_trace_action);; 这种方法本来不错,但是有一个缺点,就是必须为每一行语句命名,并且必须保证命名的唯一性,不过如果真要为每行代码去命名的话相信大部分人都会受不了。 引用 这用jaskell这种动态语言也很容易: let key = "折扣2 = 3%"; old_act = acts@key; weave_trace a x = let _ = ac_trace_action; r = a x; _ = ac_trace_action; in r; new_acts = extend acts key (weave_trace old_act); in new_acts |
|
返回顶楼 | |
发表时间:2005-02-06
我觉得设计面向大众的程序设计语言基本上是mission impossible.不过图形化的语言,比如以前的authorware那种东西,还有那个十么易语言。倒是可能成功的方向。
把脚本语言定在Business logic 的方向,我觉得应用也不会太大。一个系统真的要用script来做business logic的地步的话,估计已经是大的不成样子了。 Jaskell目前能有十么应用,我至少没有看出来。不过我建议设计语言应该小步快走,边用边改. 所以我想,ajoo首先应该在实际的项目中用用看。如果设计者都无法在项目中使用它,只能当个Toy了。 |
|
返回顶楼 | |
发表时间:2005-02-06
引用 这样写有一个坏处,就是会破坏脚本语言的直观性,因为我们并不是任何时候都需要setBefore和setAfter,这些非必要的代码必须能够随意加入和删除,同时不能对原有代码造成任何影响,要做到这一点就需要使用acts.current_ac。 可是你那个current_ac的代码仍然是对原有代码造成影响了呀。你还要改变原有代码(通过插入这两行trace代码)。 引用 这种方法本来不错,但是有一个缺点,就是必须为每一行语句命名,并且必须保证命名的唯一性,不过如果真要为每行代码去命名的话相信大部分人都会受不了。 这倒是。但是,至少你可以允许为某一行命名吧? 给一行命名总比在这行前后插入trace代码好吧? 引用 这用jaskell这种动态语言也很容易: let key = "折扣2 = 3%"; old_act = acts@key; weave_trace a x = let _ = ac_trace_action; r = a x; _ = ac_trace_action; in r; new_acts = extend acts key (weave_trace old_act); in new_acts 引用 这段就不评论了,我已经看傻眼了。 jaskell的语法怎么看都不象是面向大众设计的,业务专家要使用这个东西恐怕得先修炼成为jaskell专家才行。 我想主要是因为很多语法都没有解释,我的tutorial也很不详细。 先解释一下: let - in中间的是一些变量定义, 后面的是使用这些变量的表达式。 操作符@就是下标操作,acts@key就等价于c++中的acts[key]。这个语法确实不太符合习惯,这也是不得已。如果要批评这个语法,我只好听着,暂时没有办法。唉。 _ = ...; 的意思是我不在乎返回值,只在乎这个表达式的副作用。 extend函数是动态改变一个tuple的内容。 weave_trace函数把trace动作编织进某一个方法中去。 我相信,你即使用java或者aspectJ也不会有更简洁的语法的。因为上面的代码几乎没有任何废话。你可以试试·用java来描述这种动态织入,看看是否更简单。 至于说这段代码,本来就不是面向非程序员的。这我前面已经说过了。业务用户要做的就是简单的公式定义和函数定义。他们不可能去搞什么高阶函数,什么OO,什么AOP。 你要是能找出一个语言来让非程序员用户可搞这种aop(除了通过wizard, GUI什么的),我可真要佩服了。 jaskell有目标有两个,一方面让非程序员用户可以简单的使用;另一方面让熟悉高阶函数的程序员可以获得强大的能力。就象数学一样,小学生也可以学1+1,但是研究生,博士生也仍然不会认为数学是个容易的东西。我们不能拿一个微分方程然后批评数学不大众化吧? |
|
返回顶楼 | |
发表时间:2005-02-06
Trustno1 写道 我觉得设计面向大众的程序设计语言基本上是mission impossible.不过图形化的语言,比如以前的authorware那种东西,还有那个十么易语言。倒是可能成功的方向。
把脚本语言定在Business logic 的方向,我觉得应用也不会太大。一个系统真的要用script来做business logic的地步的话,估计已经是大的不成样子了。 Jaskell目前能有十么应用,我至少没有看出来。不过我建议设计语言应该小步快走,边用边改. 所以我想,ajoo首先应该在实际的项目中用用看。如果设计者都无法在项目中使用它,只能当个Toy了。 我是在工作过程中,发现确实存在这种用户要灵活定义公式的需求。 这些公式可能被用在data-entry和report中。 这种东西如果每次改变都要开发员介入,效率不高。 jaskell面对业务客户的东西很少,就是一个公式定义和简单的函数定义,if-else, 加减乘除,大于小于。这些对业务用户已经够了。 而如果先提出一个需要程序员来解决的需求,然后批评代码业务员看不懂,我觉得好像有点那个吧? |
|
返回顶楼 | |