论坛首页 Java企业应用论坛

ajoo的jaskell和jparsec

浏览 14931 次
精华帖 (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 语言开始就走岔了路 ……
0 请登录后投票
   发表时间: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,心里这个挫折感啊!
0 请登录后投票
   发表时间:2005-02-03  
ajoo 写道
就是还有一点不爽。
下标存取不能用a[i],而只能用a@i。
这是因为a[i]会被认为是用列表[i]做参数来调用函数a。
好处是(@)可以被直接当作一个函数,而[]明显智能是一个空表。


这个奇怪,规定函数应用的时候函数名与参数之间要有空格就可以了吧?
0 请登录后投票
   发表时间:2005-02-03  
即使那样也不爽啊。
c/java里面,

a[1], a [1],
a
[1]
都可以。现在忽然说有空格没空格有那么大差别,不也很怪异?
而且,必须要有空格?那么注释呢?
a/*comment*/[1]
算什么呢?
0 请登录后投票
   发表时间: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("折扣");
0 请登录后投票
   发表时间: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,我就很难分清楚函数调用和参数本身。
0 请登录后投票
   发表时间: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"
0 请登录后投票
   发表时间: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)的风格,大家自己按找自己的喜好选择就是。
0 请登录后投票
   发表时间: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("折扣");;
0 请登录后投票
   发表时间: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;
  
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics