免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: asuka2001
打印 上一主题 下一主题

命名难,难于上青天 [复制链接]

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
151 [报告]
发表于 2012-02-16 03:23 |只看该作者
本帖最后由 OwnWaterloo 于 2012-02-16 03:24 编辑

又出现了帖子只发出一半的情况,编辑一下……
回复 145# walleeee

>> 很赞成,但是加4个字“好用,一致”
小众语言有库就不错了……  还挑……


>> 为什么不用haskell,这个库很多啊?
那个作者好像说了原因,貌似他原来学过SML。


>> 不是,而是中缀更符合数学的思维
>> 你看那个更好看?更易懂?当然,我是指对从没接触过c也没有接触过Lisp的人,即新手。
对,我承认 (= x (* 2 y)) 不如 x = 2 * y, 后者更像数学老师教过的东西。

我的意思是,编程新手要接受的东西很多,这只是其中很小的一部分。
会有"怎么是这样写算术表达式的?"问题,但有其他更多的问题比这更重要,更感兴趣。
当那些问题解决后,可能就已经习惯而且能理解为什么要使用前缀了。

而对于非新手,已经建立了许多编程思维,就会更注重并讨厌前缀与他们习惯的语法不同这点。
许多人都喜欢用翻译法学语言:我知道在X语言里应该怎么做,我想知道在Y里面应该怎么做?
但另一个问题是:如果Y能像X那样,或者说要将Y用得像X那样,那为什么要去学Y?

至少我自己就是因为lisp太不同,当时还仅仅是注意到语法上的不同,才选择emacs而非vim的……
而且也是出于很实践性的目的: 即使这语言真不怎么样,至少可以很好的操控emacs了。
结果中奖了…… 即使emacs lisp本身很渣……


>> 你不解决这里存在一个记忆栈?尽管x=2*y也存在一个记忆栈,但是我只需要时刻关注当前的,看到x后面的=,知道是对x的赋值操作,那么赋什么值,后面就是。这是顺向的思维,更接近于人的思考习惯。lisp注重的是当前做的事,而c等则关注的是当前被操作的物。

这么说,bignum_mul至少在C里面是不是就必须bignum_mul(a,b)了?这与lisp的(bignum-mul a b)就没区别了。
C++支持*,+等重载, 但也存在许多不适合用操作符记法而适合使用命名函数记法的, f(x) 与 (f x)也没什么区别了。

这问题前天与sw也讨论过: lisp对算术运算都一视同仁,使用前缀(我们讨论的是连算术运算都可以被重定义的问题)。
那么你说的记忆栈问题是不是仅仅是针对arithmetic expression?这在上面已经说过了。
对非算术表达式呢?


>> 唯一不同,就是现在的东西视乎用起来稍微方便一些而已。
方便还不足够重要吗?
那么可读性呢?比如 0x5d,能很快反应出这是0b101010吗?
还有"没本"前段时间的crc32问题, 许多C实现有一个预计算的表:unsigned table[] = { ... };
这已经丢失了这个表是如何计算得来的信息。
而el/cl可以 (setq table (eval-when-compile (计算那个表的代码)))。


>> 至少写《黑客与画家》那个作者就是用lisp发家的,还有一些人也喜欢用lisp来标榜自己,因为用lisp的人实在是太少了,而且视乎在语言领域的地位很高,是鼻祖级别的,会这个是一个荣耀。
我是在认识到lisp如何如何后,在校内上吐槽了一句:软件学院居然不教lisp而教什么Java,C#,这与技校有什么区别?
然后被人推荐这本书的,前面那个《百年后语言》也是这个作者写的。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
152 [报告]
发表于 2012-02-16 03:32 |只看该作者
回复 148# walleeee

我想list:: size()这种问题可能不会列到feature列表里……
而不仅仅那些drafts,最终版本我其实也有…… 显然是盗版的……

标准委员会运作需要资金,能理解,但400美刀实在是太贵了啊…… cl的标准也是这样……要钱,但网上其实有……
出于研究性学习目的,悄悄地盗一下版…… 不声张不张扬……

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
153 [报告]
发表于 2012-02-16 03:37 |只看该作者
回复 147# walleeee

html应该就是你说的那种…… A语言里面可以混入B,甚至可以混入C、D……

我又要开始传教了……

  1. (html
  2.   (php "php code")
  3.   (javascript "js code")
  4.   ...
  5. )
复制代码

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
154 [报告]
发表于 2012-02-16 05:47 |只看该作者
回复 149# OwnWaterloo

想了一下,似乎遗漏了一些关键点。

  1. (defmacro 0b (s) (string-to-number s 2))
  2. (setq x (0b "111"))
复制代码
这代码只能够演示通过macro,编译时计算与运行时计算是同一套系统
其实el/cl的macro本身实现方式也是用的同一套系统
(sw不要吐槽scheme的问题了…… r5rs是用的另外的系统,r6rs,r7rs不知道,但实践中各种语言实现是有提供与el/cl一样的macro的)

这套系统与计算运行时的东西完全没有区别。只是操作的对象通常是编译时可知的list与symbol。
比如el里,可以定义一个运行时使用 —— 但可能没什么用,只是为了突出这确实是运行时计算的机制 —— 的函数:

  1. (defun unless-transform(condition &rest body)
  2.   `(if (not ,condition) (progn ,@body)))
复制代码
可以传递一些symbol与list给该函数:

  1. (unless-transform 'condition0)
  2. ;=> (if (not condition0) (progn))

  3. (unless-transform 'condition1 '(f0))
  4. ;=> (if (not condition1) (progn (f0)))

  5. (unless-transform 'condition2 '(f0) '(f1 x))
  6. ;=> (if (not condition2) (progn (f0) (f1 x)))
复制代码
其实输出很明显地是一些程序了。

可以使用与运行时相同的机制去实现macro:

  1. (defmacro my-unless(condition &rest body)
  2.   (apply 'unless-transform condition body))

  3. ; 如果在代码中写
  4. ; (my-unless condition0)
  5. ; condition0 这个符号会被传递给my-unless并继续传递给unless-transform
  6. ; 如同这样:
  7. (macroexpand
  8. '(my-unless condition0) )
  9. ;=> (if (not condition0) (progn))
  10. ; 然后 (if (not condition0) (progn)) 继续被求值


  11. ; (my-unless condition1 (f0))
  12. (macroexpand
  13. '(my-unless condition1
  14.     (f0) ) )
  15. ;=> (if (not condition1) (progn (f0)))


  16. ; (my-unless condition2
  17. ;   (f0)
  18. ;   (f1 x) )
  19. (macroexpand
  20. '(my-unless condition2
  21.     (f0)
  22.     (f1 x) ) )
  23. ;=> (if (not condition2) (progn (f0) (f1 x)))
复制代码
所以lisp叫做LISt Processing。



>> program-text -(read)-> lisp-object -(eval)-> result
这个图还不完善, 应该是这个样子:

  1. lisp code, in source code <---
  2.       |                      |
  3.       | read -> read-macro ---
  4.       v
  5. lisp object, in memory <--
  6.       |                  |
  7.       | eval -> macro ----
  8.       v
  9. result
复制代码
支持read-macro的lisp我只知道有cl。
但lisp都至少支持macro,或者说支持macro才算得上lisp。

那么至少在object -(eval)-> result这个层面,可以通过与运行时操作表相同的机制,构造任意合法的object送给evaluator。
这种构造通常是通过macro,并且操作的输入是read从text转换到的tree,操作的输出是另一个tree。
而lisp独特的code notation,使得源代码中写的样子,基本上就是读入到内存中的样子,这个层面不需要心算。
相对于那些直接eval("structured souce code")的语言,lisp的(eval (read "(tree notation code)"))会使得代码转换更容易。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
155 [报告]
发表于 2012-02-16 05:57 |只看该作者
OwnWaterloo 发表于 2012-02-16 05:47
相对于那些直接eval("structured souce code")的语言,lisp的(eval (read "(tree notation code)"))会使得代码转换更容易。


嗯,我帮sw吐槽好了……
lisp的这种易用性确实是通过程序员人肉parse换来的,代码写的就是tree,需要构造的也是tree。
但习惯了之后其实还不坏……  infix真心要解决其实都是小case。

如果直接在text level做transformation,对简单的例子可能有效,对稍微复杂点的情况就不合适了。
可能就需要 text -(parse)-> tree -> transform -> tree -(generate)-> text -> eval。
复杂到一定程度,再折中一下,可能就放弃了……

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
156 [报告]
发表于 2012-02-16 08:00 |只看该作者
本帖最后由 starwing83 于 2012-02-16 08:05 编辑
OwnWaterloo 发表于 2012-02-16 05:57
嗯,我帮sw吐槽好了……
lisp的这种易用性确实是通过程序员人肉parse换来的,代码写的就是tree,需要构 ...


可怜的孩子,这两个都不是我想吐槽的部分……

我先整理一下:

你一直在强调,一致性,不同的部分采用相同的机制来实现。是的,这就是抽象,可是你想过没有,如果不同的部分是真的非常不同呢?

从冯·诺依曼角度和现代计算机的角度,真正执行的东西,应该是个流状物,里面可能有些跳转,bc和natie都很适合这种模型,这种模型也适合优化,然而lisp不适合这种模型——lisp是个递归的模型,而不是流状的。——事实上,所有的编程语言都是递归的模型。

因此,在语言层次上来说,都一定会有一个“将递归模型转换成流式模型”的过程。lisp逃避了这个问题,宣称“递归模型是能直接执行的”(lambda演算),这可以,但是彻底断绝了优化的可能性。

关键点来了:如果一个lisp实现希望自己足够快,至少跟lua一样快,那么它就只能做一件事了:在底层,用特别不同的方法,去支持高层“看上去相同”的东西。换句话说,这种一致性是有代价的。

想象一下,本来就是完全不同的东西,现在你有选择:
  1. 既然底层是不同的机制,我也采用不同的方式(问题是C++0x选择的方式并不好——以后再说)
  2. 虽然底层不太相同,但是有相同的部分,所以可以抽象相同。

lisp选择了第二点,而大多数语言选择了第一点。其实也就是特化(专业化)和泛化(一般化)的区别了。

回到lisp,其实元编程和实际编程有一个相同的地方:都是计算。而lisp仅有一种计算:apply,因此自然可以结合在一起。而其他的语言,比如C,至少就有算术计算啦,指针计算啊,神马乱七八糟的各种计算,这就很不好办了。比如编译时肯定是没有指针的——有指针也是肯定不会让你改的,不然你写个C代码,编译的时候就能hack你的系统= =

lisp的问题在于太灵活(OW意义的:容易产生糟糕的代码;和我的意义的:把明明不该放到一起的东西放到了一起),它的问题就在于太宽泛,掩盖了不该掩盖的不一致性,凸显出实际上是虚假的“抽象”“一致性”。这就是问题。


修改一下:我想到了第二个吐槽点,本来我是打算一起吐的,结果吐了第一个忘了第二个。

你说的很对,f(x)和(f x)差不多。
问题是,C++里,
{
   ....
   int i;
   ...
}

似乎和lisp里的:

(begin
    ....
    (let ((i 0))
        ....
    )
)

差很多吧?(后者有一半代码被多缩进了一层)。

lisp的算术运算那个样子,我忍了,可是控制结构包括变量声明反正所有结构话的东西不管是啥全部需要添加一层括号我受不了哇。

如果C语言不再有if语句,while语句,for语句,而是if函数while函数for函数,这世界上估计没多少人受得了。这就是“表现形式”,不同的语法语义采用不同的表现形式恰恰是尊重程序员时间的表现。lisp只有一种表现形式(调用),最终的结果就是,苦逼的程序员们被迷失在一堆括号里了……

论坛徽章:
0
157 [报告]
发表于 2012-02-16 11:05 |只看该作者
walleeee 发表于 2012-02-14 23:15
回复 119# OwnWaterloo

 编程其实就是写一个个的数学计算式,lisp也好,c也好,还是python也好,只是写法上的出入,看你是喜欢写x = 2 * y还是= x * 2 y这种,显然前者更符合常人的理解。
   

一直认为infix notation的流行是人类数学史上最nasty的部分,没有之一。反正我不属于这里的常人之列。
除了节约纸张以外好像没什么特别突出的贡献。

论坛徽章:
0
158 [报告]
发表于 2012-02-16 11:17 |只看该作者
本帖最后由 幻の上帝 于 2012-02-16 11:18 编辑
walleeee 发表于 2012-02-16 00:49
回复 140# OwnWaterloo

(= x (* 2 y))是略有点不爽。
考虑一下((= x)((* 2) y))如何。
(想了想括号还是先全加上吧,其实只是伪代码了。)

论坛徽章:
0
159 [报告]
发表于 2012-02-16 11:21 |只看该作者
starwing83 发表于 2012-02-16 08:00
可怜的孩子,这两个都不是我想吐槽的部分……

我先整理一下:

收拾“把明明不该放到一起的东西放到了一起”和“把明明该放到一起的东西却没放到了一起”哪个更麻烦点呢。
lisp的括号……好吧,这点确实挺反人类的。。= =
不知道这个问题是不是可以换一种词法上的处理解决。

论坛徽章:
0
160 [报告]
发表于 2012-02-16 18:18 |只看该作者
回复 151# OwnWaterloo

bignum_mul(a,b)了?这与lisp的(bignum-mul a b), f(x) 与 (f x)。(省略中间)。对非算术表达式呢?

这种我觉得应该是a bignum_mul b,至于怎么实现这样,在c中可以封装,在c++中更是可以重载。但是这里你的确说中了lisp的一个好处,一致性。就是你后面说的“lisp对算术运算都一视同仁”,所谓一切都是函数。

方便还不足够重要吗?

冤枉啊,我从来没觉得方便不重要,甚至认为方便是设计软件和编写程序最重要的考虑之一。我只是说现在的语言和以前的语言的计算能力是等价的。

(setq table (eval-when-compile (计算那个表的代码)))。

包括你前面说的元编程是否就是宏能完成的?在c++中还可以用模版来完成。如果仅仅是这样,那我并不觉得你所谓的元编程有什么让人耳目一新的地方。比如前面那个bignum_mul(a, b),我也可以用:

  1. #define BIGNUM_OP(a, op, b) ((bignum_##op)((a), (b)))
  2. BIGNUM_OP(a, mul, b)
复制代码
来稿嘛,尽管看起来没你那个好看,但是你那个到处是括号也不见得比我好到哪里去,五十步笑一百步,半径八两。

首先,鉴于lisp的表达能力,10万行已经是很大很大的项目了。(省略)《XXX C++编码规范》

很久以前lisp的确有很多大型项目是lisp写的,不过那都差不都是几十年前的事情了。至于说规范,我觉得不管是什么规范,一致才是核心,但是别人不是你,你也不是别人,所以一个团队里面多少有些不一致,这个就很麻烦。

鉴于lisp的表达能力,10万行已经是很大很大的项目了。如果退一步,万行左右的lisp项目

不觉得lisp表达能力有c的10倍强,尽管有些地方Lisp表达是占优,但是别忘了,还有些地方c等也比lisp占优。

我是在认识到lisp如何如何后,在校内上吐槽了一句:软件学院居然不教lisp而教什么Java,C#,这与技校有什么区别?然后被人推荐这本书的,前面那个《百年后语言》也是这个作者写的。

《百年后。。。》这个我看过,这个人现在据说成了天使投资人。以前lisp写了个web系统,卖给雅虎赚了钱就洗手了5000万$。至于天朝的大学,我已经心灰意冷了。倒不是教不教lisp这些事情,而是其他很多很多事情,我觉得高中读完,懂事的孩子(知道该干什么,不是那种只知道玩,什么也不知道的那种)就该自己想想想做什么,然后一门子心思去做,专注才能成大事,现在互联网方便了,要什么资料,都是那么方便而廉价。反观去中国的大学,费用浪费倒是小事,还浪费你很多事情去搞些莫名其妙的东西。唉,不说了,心灰意冷。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP