地址: https://github.com/albertlee/clj-tips
主要收集自己写的一些Clojure代码段,留做备忘。
地址: https://github.com/albertlee/clj-tips
主要收集自己写的一些Clojure代码段,留做备忘。
一个小需求:一个SQL语句的字符串,需要替换其中几个变量,可以用模板模块来实现,不过我不想为了这点小功能劳师动众,因此自己造了个轮子,用一句reduce 搞定,代码如下:
- (ns clj_sample.core
- (:gen-class)
- (:require [clojure.string :as string]))
-
- (def sql "AND add_time>=unix_timestamp('$startTm')
- AND add_time<unix_timestamp('$endTm')
- AND add_time>=unix_timestamp('$startTm')
- AND add_time<unix_timestamp('$endTm')")
- (def params [["$startTm" "2010-1-1"]
- ["$endTm" "2012-2-17"]])
-
- (defn -main [& args]
- (println (reduce #(clojure.string/replace %1 (first %2) (second %2))
- (cons sql params))))
废话不多说,直接上代码:
(Update: 下面这段代码太丑了,后来又优化的比较优雅了,现在懒的贴了)
- (ns sample.core
- (:gen-class)
- (:import (
- (org.quartz CronTrigger JobDetail Scheduler SchedulerException Trigger)
- (org.quartz.impl StdSchedulerFactory)
- (org.quartz TriggerBuilder)
- (org.quartz JobBuilder)
-
- (org.quartz SimpleScheduleBuilder)
- (org.quartz CronScheduleBuilder)
- )
- )
-
- ;; 实际执行的任务
- (defn run-import-process
- []
- (println "running import process..."))
-
- (def scheduler* (atom nil))
-
- (deftype ImportJob []
- org.quartz.Job
- (execute [this context] (run-import-process)))
-
- (defn start-import-manager
- []
- (let [scheduler (StdSchedulerFactory/getDefaultScheduler)
- trigger (TriggerBuilder/newTrigger)
- job (JobBuilder/newJob ImportJob)]
-
- (reset! scheduler* scheduler)
- (.scheduleJob scheduler
- (.build (.withIdentity job "job1" "import"))
- (.build (.withSchedule (.startNow (.withIdentity trigger "trigger 1" "import")) (CronScheduleBuilder/cronSchedule "*/3 * * * * ?"))))
-
- (.start scheduler)))
-
- (defn stop-import-manager
- [& [wait?]]
- (if wait?
- (.shutdown @scheduler* true)
- (.shutdown @scheduler*)))
-
- (defn -main [& args]
- (start-import-manager))
一直以为SBCL在MacOSX上不支持多线程,导致自己痛苦了很久,这都是不读书惹得祸阿!
昨天在上海LispMeetup上,经黄涧石同学一语点醒梦中人,才发现原来SBCL是支持多线程的,而且还有很多其他的编译选项!
具体说来就是在SBCL源代码目录下,写一个 customize-target-features.lisp 文件,在其中将需要打开或关闭的特性写入,具体的特性列表在 base-target-features.lisp-expr 这个文件中有介绍。
(lambda (features)
(flet ((enable (x)
(pushnew x features))
(disable (x)
(setf features (remove x features))))
;; Threading support.
(enable :sb-thread)
(enable :SB-XREF-FOR-INTERNALS)
(enable :sb-doc)
(enable :sb-test)
(enable :sb-unicode)
(enable :sb-eval)
(enable :sb-source-locations)
(enable :sb-xref-for-internals)
(enable :sb-core-compression)))Condition System 是Common Lisp中很独特的东西,不单单用来做异常处理,还可以用来实现一些函数控制传递。
Condition Sys 与通常的 try-catch 结构相比,更加的通用更加灵活。
Condition sys的组织与开发过程很相关,通常在开发时,首先写出一段工作代码,然后再考虑如何处理异常情况。
首先写出工作代码,在这段工作代码中可能会遇到各种各样的异常(condition)情况,我们只要抛出它们即可。先不去考虑如何处理它们。
之后,我们可以提供多种处理方式,既 restart ,它们可以让出现状况的代码原地满血复活。
有了多种处理方式后,应该选择哪一个呢?这就是恢复策略问题,可以在更靠后(更外层)代码中进行处理。
PyClips 简单说就是把Clips的源代码包装了一层,方便在Python中进行交互调用,这里是文档:
PyClips手册
使用非常简单,Clips独立于Python进程之外,在Python中通过clips库来交互:
>>> import clips
>>> clips.Reset()
>>> clips.Assert("(duck)")
>>> clips.BuildRule("duck-rule", "(duck)", "(assert (quack))", "the Duck Rule")
>>> clips.PrintRules()
MAIN:
duck-rule
>>> clips.PrintAgenda()
MAIN:
0 duck-rule: f-1
For a total of 1 activation.
>>> clips.PrintFacts()
f-0 (initial-fact)
f-1 (duck)
For a total of 2 facts.
>>> clips.Run()
>>> clips.PrintFacts()
f-0 (initial-fact)
f-1 (duck)
f-2 (quack)
For a total of 3 facts.
也可以用 clips.Load 来调用一个外部Clips文件执行。
如果你发现自己的代码中IF-ELSE 嵌套超过5层,就可以考虑结合Python和Clips了。
通宵似乎开发效率不太高。不知不觉天亮了,无聊中。
刚刚搜erlang,结果在erlang-china上看到 Arduino 暗示的另一种可能 。想想自己手头上已经积累了四五块Arduino芯片,还有一堆的乱七八糟的元件。但一直没时间深入的去开始个项目。毕竟,最近小米手机实在是太火了⋯⋯
这些电子元件都是小时候的梦想阿⋯⋯唉,少先队员的时代。
那么如果无聊起来,该搞些什么无聊的东西出来呢?
1. 把家里那台电子体重秤接上网,自动发微博上~还要能生成曲线图,还要能自动@给那谁 (这种减肥方式不靠谱)
2. 对于整天见不到太阳的程序员来说,在电脑旁边接个三自由度机械手云台,实时指向太阳。
3. 搞一堆导线缠到管子上,做个倒计时的定时期,几个鲜红的数字跳阿跳
4. 把小车改造改造,到楼后面的公园里去追那些野猫
5. 拿那块三轴加速芯片绑头上,用摇头和点头来输入Yes/No
6. 接温度感应,自动控制usb风扇
由于我一向乐于助人并总是可以解决些稀奇古怪的问题,因此在非技术人员眼中我就是神秘的攻城师。
刚才市场帅哥又带来了一个古怪的需求:他们要生成一堆“靓号”。
要说咱中国人似乎对号码有特别的偏好,啥8888、1688之类的。我们的一个产品,每个用户都有一个号码,我们的市场帅哥想看看有哪些“靓号”,而如何定义靓号呢?市场的同志们自有一套私企古怪的规则,我用程序员的眼光真的无法理解其中的道理。
他们给出了一个数字范围,并列出了多条规则,比如:有四个连续的相同数字、四个连续的递增或递减的数字等等。
需要根据每一种规则生成出所有的“靓号”。
收到这个需求后,我心中一动,Prolog兄,终于有你的用武之地了,我等这天很久了……
这里拿其中一条规则举个例子:
长度为7位,首位为4,含2组3位连续顺数的号,例如:4123123
直接上源代码:
dig(0).
dig(1).
dig(2).
dig(3).
dig(4).
dig(5).
dig(6).
dig(7).
dig(8).
dig(9).
num_array(A, B, C, D, E, F, G):-
A = 4, dig(B), dig(C), dig(D), dig(E), dig(F), dig(G).
pretty(A, B, C, D, E, F, G):-
num_array(A, B, C, D, E, F, G),
B is A + 1,
C is B + 1,
A = D,
B = E,
C = F.
pretty(A, B, C, D, E, F, G):-
num_array(A, B, C, D, E, F, G),
C is B + 1,
D is C + 1,
B = E,
C = F,
D = G.
pretty(A, B, C, D, E, F, G):-
num_array(A, B, C, D, E, F, G),
B is A - 1,
C is B - 1,
A = D,
B = E,
C = F.
pretty(A, B, C, D, E, F, G):-
num_array(A, B, C, D, E, F, G),
C is B - 1,
D is C - 1,
B = E,
C = F,
D = G.
main:-
pretty(A, B, C, D, E, F, G),
writef("%t%t%t%t%t%t%t\n", [A, B, C, D, E, F, G]),fail.
生成结果部分:
4012012
4123123
4210210
4234234
4321321
。。。。
其他各条变态的规则都是直觉的翻译,虽然看上去有点长,但实际上都是复制粘贴,对于这种一次性的需求,就没那么讲究了,几乎没动啥脑子,这个需求如果用其他的方式写还真有点头大的。我的原则就是合适的工具解决合适的问题,绝对不用锤子干锯子的活。
ILC2012 预定在日本的京都(应该是京都大学)举办,组委会的黄先生发邮件给我交流议题。真是令我受宠若惊啊。感谢田春的介绍哈。
把博客迁移到自己的主机上,冷清了很多:)
检讨下原因:
1. Lisp (包括进来的R方面的内容)本身就是冷话题,虽然有近期的《黑客与画家》的催生,但是该冷还是会冷的。如果那些人聪明到读了几篇文章就能认准Lisp的话,那他们早在5年前就该认识到了。
2. 文章内容在外行眼里看着古怪,在行家眼里看着肤浅。
3. 没有了CSDN博客上“专家”的戳。
4. 我本来就想搞个冷博客。