-
Notifications
You must be signed in to change notification settings - Fork 0
Home
强译! http://yuheng.randoms.us/blog/2010/10/solo-notes/
- 摧悲的是 宇桓的个站是 AGE 上的哪,是和谐的哪!!!!
- 嗯嗯嗯, 珠三角技术沙龙第7次~并CPyUG会课总第40期 认识的达人哪
- 从 http://twitter.com/#!/kyhpudding/status/52692690508316672 知道这一小神器的 ;-)
- 代码: http://github.com/kuangyh/solo
-
- 表达式 Expressive
-
- Python 是表达式的
- Python 但是不彻底的
- 相比 LISP
- 以及进行数据结构操纵时
-
- FP
-
- Python 不是函式语言,但是
我要!
- Python 有那么一点儿 FP 特性
- Python 不是函式语言,但是
-
- 目标
-
- 将FP 特性引入Python ,并 Pythonic 化
- 整得更加表达式化
- 写少作多 Write less, do more
-
- SOLO 库
-
- 为了数据
- 匹配: 模式的
- 操纵: 处理是管道化的,数据模板的
查询描述序列应用成对象
q = Query() # 获取键的 ``值``, 调用其超类方法 q = q['value'].upper() # ``编译`` 成一个调用 compiled = ~q compiled({'value' : 'hello'}) # => 'HELLO'
得到 Q = Query()
就可以认为,``Q`` 是个数据库输入的 魔法占位符
本质上,查询都是描述为一系列指令, 指令可以是方法调用和函式(接受一个参数)
查询使用常规语法来调用,如前述使用 +
和函式接合
同前设计
传统的 函式化 结合
, 查询使用 +
来整合入
q = P['value'] + (lambda x: x * 2) (~q)({'value' : 'hello'}) # => 'hellohello'
在 Python 我们可以:
value = { 'name' : foo(bar(value['x'])), 'ooxx' : [ 'example' : 123, 'ls' : map(lambda x: x * 2, value['values']) ] }
当我们查询时,想这么写:
Query() + (lambda value: { 'name' : foo(bar(value ... } )
很囧,特别是我们想在 查询内部使用 lambda
时,所以,我们想要
Q = Query() Q + { 'name' : Q['x'] + bar + foo 'ooxx' : [ 'example' : 123, 'ls' : Q + Map(lambda x: x * 2) ] }
如果实现这种形式,就称 数据模板
. 查询内置一个编译器,根据数据模板,编译成可执行的函式,最后输出整个数据结构体.
在这种强大的数据模板基础上,我们就可以这么写:
q = Q[Q['key']].join(Q['list']) (~q)({'key' : 'delim', 'delim', ':', 'list' : ['foo','bar']}) # => 'foo:bar'
因为 __getitem__
返回的键,
可视作数据模板方法调用时的参数列表,
能对输入进行评估,并``真正``应用到数据的方法调用上.
模式匹配 是一组处理器, 检验输入是否匹配特定的参数模式,如果有匹配,执行对应的并返回; 否则抛出异常.
Erlang
杀手特性
这就是著名的 Erlang 的内置特性哪,通过同名函式参数的不同来高效匹配同一接口的不同事务!
Q + Value(const_value) Q + Type(int) Q + Test(true_or_flase_function)
注意: 结构匹配 不返回输入本身,某种程度上这很难解释 ;-(
Q + Seq([first_pat, second_pat...]) Q + Tuple([first_pat, secon_pat..]) Q + Mapping({'key' : pat ...})
我们也能象数据模板那样进行模式的模板操作
# it matches a list/tuple that has 3 elements, # the first is 'send', the second is a string and the third is a # mapping that has a ``value'' element larger than 0 Q / ( 'send', str, { 'value' : Q/int/(lambda x: x > 0) } ) # 这里匹配 3元素的 list/tuple # 第一个元素得是 'send', 第二个是个字串 # 第三个须是 键``value`` 对应的值>0 的字典
模板编译器,将编译一系列组合进行匹配处理.
匹配复杂对象时,我们可以使用各种提取器,转换成简单的结构(列表,字典), 再进行模式匹配
# When match, Regex processor will return (groups, groupdict) # Then we can match the groups, bind values, convert value etc. q = (Q + extract.Regex(r'([^\s]+)\s+([^\s]+)') + Q[0]) / ( I.cmd, (Q + int) / I.value ) # 当完成正则匹配后,将返回 (groups, groupdict) # 然后我们就可以进一步匹配 groups, bind values, convert value etc. ctx = makectx() (~q)('send 1', ctx) ctx # => { 'cmd' : 'send', 'value' : 1 }
吐糟
形式化语言
创造出各种节省输入的形式化关键词,这是 Perl 的范儿哪...
在 Python 中我们能
name, value = ('key', 123)
这就是一种模式匹配(匹配到2元素元组) 以及名称约束.我们无法在查询本身这么作.
在这一背景中,上下文是个字典,
但是借助局部和全局线程,以及 with
语法,我们可以:
def foo(): currctx()['value'] = 10 ctx = makectx() with ctx: ... foo() ctx['value'] # => 10
注意: with ctx
是可堆叠的,我们在每个线程都要维持这一全局堆栈.
结合语法糖 (魔力的``I``),我们得到
# exchange 2 elements of the list q = Q / (I.x, I.y) + [I.y, I.x] ctx = makectx() with ctx: (~q)([1,2]) # => [2,1] ctx => {'x' : 1, 'y' : 2}
I.name
将输入的值丢到上下文中来匹配环境,
进而从正常指令和数据模板中获得返回值;
基于查询的函式设计,我们可以轻易的实现各种流程控制,例如选择.
这一灵感来自Scala语言的设计.
# a shortcut for Q + Choice([Q/in, Q/str + int]) Q | ( Q/int, Q/str + int) Implementation. class Choice(object): def __init__(self, *checks): self.checks = map(query.Q.__add__, checks) self.checks_call = map(lambda x: ~x, self.checks) def __call__(self, value): last_error = None for check in self.checks_call: try: return check(value) except BaseException, e: last_error = e if last_error is not None: raise last_error else: return value
批量处理系统的目标是 LINQ. 即:提供一个表达方式来描述内存中的数据结构和数据关系, 就象关系型数据库.
目前我们只实现地图和过滤,并提供对应的 语法糖
# Q + Filter(Q / int) Q // int # Q + Map(Q + { 'name ... Q >> { 'name' : Q[0], 'value' : Q[1] }
编译器将查询它编译成Python的代码. 我们努力使生成的Python代码尽可能高效.
事实上我们正在定义一种新的语言,使用Python语言构建组件,嵌入Python并保持 Pythonic!
数据源
[ { 'title' : '...' , 'username' : '...' } ]
要转换成 atom 聚合源(类似 JSON, GData JSON 定义)
atomfeed = Q + { 'title' : { '$t' : 'Atom feed'}, 'entry' : Q >> { 'title' : { '$t' : Q['title'] }, 'link' : { 'href' : I['http://mail.qq.com/mail/{0}.html'.format](Q['id']), 'rel' : 'alternative' }, 'author' : { 'name' : Q['username'].capitalize() 'email' : I['{0}@mail.qq.com'.format](Q['username']) } } }
- Request routing (matching, fetch input params, and route, with Choice)
- Form validation and processing
- Data source validation
- Various data model mapping