免费注册 查看新帖 |

Chinaunix

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

[其他] tcsh,shebang和clojure [复制链接]

论坛徽章:
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
11 [报告]
发表于 2012-10-09 21:36 |显示全部楼层
回复 35# OwnWaterloo


    对shell来说,命令名和参数没区别,都一样处理的,假设有个目录里面有a.exe, b.exe, c.exe,你写:

$ *.exe

最终的结果就是执行: a.exe b.exe c.exe了。

只有到了最后一步,shell才会把一个string-array的第一项当做命令名,后续的当做命令的参数,到这一步命令名和参数才有区别……

论坛徽章:
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
12 [报告]
发表于 2012-10-09 22:12 |显示全部楼层
回复 39# OwnWaterloo


    其实要达到这样的效果,还是会有问题。

主要原因是天杀的所谓“stateless iterator”,即实际上ipairs返回的是iter, state, first_key,这玩意儿不能放到中间:

map(f, ipairs(t1), ipairs(t2)) -- 完蛋了,ipairs(t1)的state和first_key被吞了…

这时**只能**传递table或者closure。

但是closure代价太大,很慢的。

最终只剩下table了。

那啥,小数据量下,map的参数是table似乎没有问题吧?table本身做成惰性的也不难啊……

t = lazy_table(function()...end)

这种……t是标准的table,只是里面的key/value是惰性产生的……

论坛徽章:
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
13 [报告]
发表于 2012-10-09 23:00 |显示全部楼层
本帖最后由 starwing83 于 2012-10-09 23:04 编辑

回复 44# OwnWaterloo


    range的“stateless iterator”写法(效率最高,应用最狭窄):

  1. local function range_helper(n, i)
  2.    if i <= n then return i + 1 end
  3. end

  4. function range(n)
  5.    return range_helper, n, 0
  6. end
复制代码
注意,这里一个闭包都没有的。

如果数据量大,使用方式可以不变。也就是一个抽象层而已了。而table和closure都是很好的抽象层。

假设我需要这个stateless iterator变成闭包,就需要一个函数:

  1. function iter(f, s, init)
  2.    local t = {init}
  3.    return function()
  4.        t = {f(s, table.unpack(t))}
  5.        return table.unpack(t)
  6.    end
  7. end
复制代码
注意这个写法很浪费,因为每次调用都会产生一个表。更高效的写法是在C API里面写。可以做到每次调用都不产生内存。

有了iter函数,那么就可以这样:

map(f, iter(ipairs(t1)), iter(range(10)))

iter不一定要在这里出现,甚至可以让iter函数是一个处理stateless iterator generator的函数,即抽一个地方:

  1. if data_is_too_big then
  2.     map = iter(map)
  3. end
复制代码
iter负责把表驱动的改为用闭包驱动的。这是很简单的。

好了,这是用闭包/stateless iterator作为接口。如果用表作为接口:

  1. function range(n)
  2.    return setmetatable({}, {__index = function(t, k)
  3.        if k < n then return k end
  4.    end})
  5. end
复制代码
这个写法照样是示例性的,metatable和__index函数都是可以stateless的。这没有问题。

我们可以通过lazy_table函数,做到closure/stateless到table的转换。

  1. if data_is_too_large then
  2.     map = lazy_table(map)
  3. end
复制代码
之前map接受table,返回table之前的map接受闭包,返回闭包,我们可以让现在map接受table(这需要所有的工具都被lazy_table包裹),但是返回的是个lazy_table。即惰性的table。

我们还可以设计接口,让接受表返回表的map变成接受闭包返回闭包的。方案也是上面的lazy_table,它可以让map本身接受的表实际上以前是个闭包,而返回的表实际上依然是个闭包。

这就是Lua中的序列操作和惰性操作的基本方式。有两套接口:函数和表,两套接口都是可以互相转换的,不存在兼容性问题。
      

论坛徽章:
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
14 [报告]
发表于 2012-10-09 23:42 |显示全部楼层
回复 46# OwnWaterloo


    是否存在比丰富表操作更好写的循环方式呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP