锁定老帖子 主题:ajoo的jaskell和jparsec
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2005-02-03
ajoo 写道 monk 写道 引用 我现在最希望的就是社群里的讨论和批评了。
哪。你那个东西啊,我估计没几个开发者能看得懂,批评就更谈不上了。不过我来斗胆批评一下吧: 做啥不好,一定要给haskel这种比Scheme还难懂、语法比BASH shell还难看的语言做Java实现啊!脱离文化大众!Kick ass! 是我的介绍没有做好。目前还缺乏文档。我现在正一步一步做起来。 我本来是想开始做做优化,但是目前看来,当务之急还是多花点时间写文档。 不过,haskell就我的理解,不大好懂的是它的类型系统,什么type class之类的,确实让人晕。 不过jaskell里面已经扔掉了这个强类型的包袱了。应该比haskell好懂许多。 比如,要写一个阶乘函数,就是如此: fact i = if i==0 then 1 else i*fact (i-1);; 不好懂吗? 你说它语法难看,是指什么呀?是函数调用吗? 我倒觉得f a b c比f(a,b,c)要好看简洁。 我做这个东西的初衷是要非程序员的业务用户也能用,所以采用函数式就比较合适。毕竟不是所有business analyst都懂得“赋值”是什么意思。 我记得我小时候开始学计算机的时候,最最让我发疯的就是为什么i=i+1。这东西无论如何不相等啊!要是当时学的是个函数式语言,我想我的计算机起步会早很多。 对于函数调用,f(a,b,c) 显然要比 f a b c 来得清楚,也符合一般数学记号(不仅仅是写程序)的习惯。又及,你最初学计算机的时候用的是 basic 么?貌似赋值还是用 PASCAL 的 := 来得更好,可惜从 C 语言开始就走岔了路 …… |
|
返回顶楼 | |
发表时间:2005-02-03
引用 对于函数调用,f(a,b,c) 显然要比 f a b c 来得清楚,也符合一般数学记号(不仅仅是写程序)的习惯。又及,你最初学计算机的时候用的是 basic 么?貌似赋值还是用 PASCAL 的 := 来得更好,可惜从 C 语言开始就走岔了路 …
你这个说法也有道理。虽然我自己更喜欢f a b c,因为可以省着写括号。但是习惯上也许还是有括号比较好。 刚刚改了parser,现在既可以写f a b c,也可以写f(a,b,c)。 在括号嵌套较多的时候,用f a b c可以避免太乱, 在简单的时候则用f(a,b,c)。 现在好了吧? 函数定义的时候还是不用括号,比如: f a b c = a+b+c; 这是因为一则函数定义用空格应该还是很清楚的。 二则,括号和逗号给pattern match占用了,要是强行支持括号的风格,parser可能会需要太多的lookahead,而且也对以后语法扩展造成障碍。 就是还有一点不爽。 下标存取不能用a[i],而只能用a@i。 这是因为a[i]会被认为是用列表[i]做参数来调用函数a。 好处是(@)可以被直接当作一个函数,而[]明显智能是一个空表。 我原来学的就是basic。当时看着有的同学都能把计算机弄出音乐来了,而我还搞不清楚怎么做从1加到100,心里这个挫折感啊! |
|
返回顶楼 | |
发表时间:2005-02-03
ajoo 写道 就是还有一点不爽。
下标存取不能用a[i],而只能用a@i。 这是因为a[i]会被认为是用列表[i]做参数来调用函数a。 好处是(@)可以被直接当作一个函数,而[]明显智能是一个空表。 这个奇怪,规定函数应用的时候函数名与参数之间要有空格就可以了吧? |
|
返回顶楼 | |
发表时间:2005-02-03
即使那样也不爽啊。
c/java里面, a[1], a [1], a [1] 都可以。现在忽然说有空格没空格有那么大差别,不也很怪异? 而且,必须要有空格?那么注释呢? a/*comment*/[1] 算什么呢? |
|
返回顶楼 | |
发表时间:2005-02-03
楼主的思路很好,但是没必要使用高阶函数的方式,不是每个人都有深厚的数学和计算机语言功底,能让别人易懂易学才是王道。
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"); 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("折扣"); |
|
返回顶楼 | |
发表时间:2005-02-03
ajoo 写道 即使那样也不爽啊。
c/java里面, a[1], a [1], a [1] 都可以。现在忽然说有空格没空格有那么大差别,不也很怪异? 而且,必须要有空格?那么注释呢? a/*comment*/[1] 算什么呢? 对haskell基本上一无所知。仅有的“语法难看”的印象还是从《程序员》里几篇文章里得来的(一篇是gigix讲规则引擎的,一篇是讲FP的),怪异的语法我横竖看不懂。 给个外行的建议。java, C++, C的句法分析不是基于空格的,所以格式比较自由。另一种风格是python那样,句法分析是由着行和空格来判断的,所以空格不能乱打。你应该选定一种句法分析风格,不要什么都可以,容易歧义。我个人还是喜欢用括号来界定边界;不用括号的话,用换行和缩进也可以。光用空格的话,会让我有很混乱的感觉。比如f a b c,我就很难分清楚函数调用和参数本身。 |
|
返回顶楼 | |
发表时间:2005-02-04
age0 写道 楼主的思路很好,但是没必要使用高阶函数的方式,不是每个人都有深厚的数学和计算机语言功底,能让别人易懂易学才是王道。
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"); 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("折扣"); 我用jaskell的语法写一个对应版本你看看: let facts = new_facts .new ("价格", "100"); .new("价格", "100"); .new("数量", "2"); .new("货物名称", "猪");; acts = new_acts .New("折扣1 = 5%", "数量 > 100 or 货物名称='猪' "); .New("折扣2 = 3%", "数量 > 10 and 数量 < 100"); .New("折扣3 = 0%", "数量 <= 10"); .New("折扣 = Max(折扣1, 折扣2, 折扣3);"); .New("总额 = 价格 * 数量 * (100% - 折扣);");; result = acts.onAction(facts);; total = result.Get("总额");; discount = result.Get("折扣");; in "total is $total, discount is $discount" |
|
返回顶楼 | |
发表时间:2005-02-04
monk 写道 ajoo 写道 即使那样也不爽啊。
c/java里面, a[1], a [1], a [1] 都可以。现在忽然说有空格没空格有那么大差别,不也很怪异? 而且,必须要有空格?那么注释呢? a/*comment*/[1] 算什么呢? 对haskell基本上一无所知。仅有的“语法难看”的印象还是从《程序员》里几篇文章里得来的(一篇是gigix讲规则引擎的,一篇是讲FP的),怪异的语法我横竖看不懂。 给个外行的建议。java, C++, C的句法分析不是基于空格的,所以格式比较自由。另一种风格是python那样,句法分析是由着行和空格来判断的,所以空格不能乱打。你应该选定一种句法分析风格,不要什么都可以,容易歧义。我个人还是喜欢用括号来界定边界;不用括号的话,用换行和缩进也可以。光用空格的话,会让我有很混乱的感觉。比如f a b c,我就很难分清楚函数调用和参数本身。 没看过这几篇东西。 不过,我之所以没有采用缩进表示的格式,是考虑到错误比较难找。万一人家用了tab键,编辑器里看着没问题,结果却就是不对。不同平台上的回车字符也不见得一样。 而且haskell的对于if-else的缩进格式我也始终没搞清楚,后来往往都是强制用格式更明确的case-of语句。 另外,这种jaskell script也许会被存进数据库,那时候,这些回行,空格什么的只怕反而捣乱。 而且,jaskell的语法尽量避免了太多的花括号,函数定义就直接在等号后面,用分号结束,已经很精简了。用缩进也产生不了多大好处。 至于函数调用是否用括号,还是空格,这就是两回事了。如果愿意,你也可以任意编排你的代码,不受格式限制的。这是函数调用的语法问题,不是代码编排问题了。 当然,我觉得elm说的习惯问题是存在的,所以,我同时也支持了f(a,b,c)的风格,大家自己按找自己的喜好选择就是。 |
|
返回顶楼 | |
发表时间:2005-02-04
ajoo 写道 我用jaskell的语法写一个对应版本你看看: let facts = new_facts .new ("价格", "100"); .new("价格", "100"); .new("数量", "2"); .new("货物名称", "猪");; acts = new_acts .New("折扣1 = 5%", "数量 > 100 or 货物名称='猪' "); .New("折扣2 = 3%", "数量 > 10 and 数量 < 100"); .New("折扣3 = 0%", "数量 <= 10"); .New("折扣 = Max(折扣1, 折扣2, 折扣3);"); .New("总额 = 价格 * 数量 * (100% - 折扣);");; result = acts.onAction(facts);; total = facts.Get("总额");; discount = facts.Get("折扣");; in "total is $total, discount is $discount" 语法问题解决了,还有一个扩展能力的问题。 class SpecialDiscount : Action { string m_item_name = ""; string m_result_name = ""; public SpecialDiscount(string item_name, string result_name); { m_item_name = item_name; m_result_name = result_name; } override bool OnAction(Facts facts); { // string goods_name = facts.Get(item_name);; // string sql = " select discount from special_goods where Name='" + goods_name + "'"; Result ret = DBAccess.Select(sql);; // if(ret.row_affected > 0); facts.Set(result_name, ret.Get(0, "discount");; return true; } } 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");; acs.New("折扣3 = 0%", "数量 <= 10");; acs.New(new SpecialDiscount("货物名称", "折扣4"););; acs.New("折扣 = Max(折扣1, 折扣2, 折扣3, 折扣4);");; acs.New("总额 = 价格 * 数量 * (100% - 折扣);");; acs.OnAction(facts);; string total = facts.Get("总额");; stirng discount = facts.Get("折扣");; |
|
返回顶楼 | |
发表时间:2005-02-04
好。我的facts是个immutable的tuple。它至少支持一个set成员。
let facts = new_facts .New("价格", "100"); .New("数量", "2"); .New("货物名称", "猪");; acs = new_actions .New("折扣1 = 5%", "数量 > 100 or 货物名称='猪' "); .New("折扣2 = 3%", "数量 > 10 and 数量 < 100"); .New("折扣3 = 0%", "数量 <= 10"); .new_action(specialDiscount "货物名称" "折扣4"); .New("折扣 = Max(折扣1, 折扣2, 折扣3, 折扣4);"); .New("总额 = 价格 * 数量 * (100% - 折扣);");; result = acs.OnAction(facts);; total = result.Get("总额");; discount = result.Get("折扣");; in "total is $total, discount is $discount" where new_action item_name result_name = {onAction = readFact item_name result_name}; readFact item_name result_name facts = let goods_name = facts.get item_name; sql = "select discount from special_goods where name='$goods_name'"; ret = DBAccess.Select sql; in if ret.row_affected>0 then facts.set(result_name, ret.get 0 "discount"); else facts; |
|
返回顶楼 | |