作为当今最主流的运算平台JVM,把函数式编程语言引入JVM也是很多人尝试的方向,Clojure就是其中之一。Clojure是一个在JVM平台运行的动态函数式编程语言,其语法于类似LISP语言,在JVM平台运行的时候,会被编译为JVM的字节码进行运算。
诞生于2007年的Clojure是JVM平台上的Lisp实现,Lisp 以强大的功能和表达性而著称,但应用范围存在着固定的局限,于是发起人Rich Hickey设计Clojure的初衷便是希望得到一门能够服务于高并发应用场景,较Lisp更为先进的函数式编程语言。
Clojure保持了函数式语言的主要特点,例如immutable state,Full Lisp-style macro support,persistent data structures等等,并且还能够非常方便的调用Java类库的API,和Java类库进行良好的整合。
因为一些常用函数需要REPL中可用,所以定制了clojure的REPL.
#!/bin/sh
breakchars="(){}[],^%$#@\"\";:''|\\"
MY_LIB =/home/sw2wolf/lib #自己的CLJ文件放此处
CLOJURE_JAR=/usr/share/clojure/clojure.jar
CONTRIB_JAR=/usr/share/clojure/clojure-contrib.jar
CP="$CLOJURE_JAR:$CONTRIB_JAR:$ MY_LIB "
if [ $# -eq 0 ]; then
exec rlwrap --remember -c -b "$breakchars" \
-f "$HOME"/ .clj_completions \
java -cp $CP clojure.main -i ~/ .clojurerc -r
else
exec java -cp $CP clojure.main $1 -- "$@"
fi
在Clojure的REPL中,运行如下代码:
( def completions ( reduce concat ( map ( fn [ p ] ( keys ( ns-publics ( find-ns p ) ) ) ) ' ( clojure . core clojure . set clojure . xml clojure . zip ) ) ) )
( with-open [ f ( java . io . BufferedWriter . ( java . io . FileWriter . ( str ( System/getenv "HOME" ) "/.clj_completions" ) ) ) ] ( . write f ( apply str ( interleave completions ( repeat "\n" ) ) ) ) )
这会在你的主目录生成.clj_completions 文件, 用来自动补齐。
%head -10 .clj_completions
sorted-map
read-line
re-pattern
keyword?
val
chunked-seq?
find-protocol-impl
vector-of
object-array
*compile-path*
%cat .clojurerc
( set ! *warn-on-reflection* true)
( use 'money)
money中就有日常用的一些函数:
%head -30 ~/lib/money.clj
( ns money
(: import (java.util Date Timer Random)))
( def SXF 0.0015) ;手续费
( def YHS 0.001) ;印花费
( def GHF 1.0) ;过户费
( defn winG [qty pb ps]
"算股票盈利"
(- (* qty ps (- 1 SXF YHS)) (* 2 GHF) (* qty pb (+ 1 SXF))))
( defn winQ [qty pb ps]
"算权证盈利"
(- (* qty ps (- 1 SXF)) (* 2 GHF) (* qty pb (+ 1 SXF))))
( defn stopLoss [qty pb lossRate]
"止损价"
( let [t (* qty pb (+ 1 SXF))]
( println ( format "Stop Loss at:%.2f" (- pb (/ (* t lossRate) qty))))
( println ( format "Lost Money:%.2f" (* t lossRate)))))
(defn sys [cmd]
"执行SHELL命令"
(let [cmdList (clojure.string/split cmd #"\s")
{:keys [exit out err]} (apply clojure.java.shell/sh cmdList)]
(if (= 0 exit) (println out) (println err))))
%myclj
user=> (winG 1000 7.18 8.18)
966.7799999999997