看过"黑客与画家"之后,你是不是对Lisp心动不已?然后翻了几页ACL(Ansi Common Lisp)又望而却步?叹息:如果有一天可以再.Net CLR 上写Lisp代码那就好了!这一天已经来了,这就是Clojure CLR.看语言转换矩阵, Clojure的寄生能力超强,这方面甚至超过javascript.在CLR上有一席之地不足为怪.

     
既然是入门,就必须回答下面几个问题:
  • 怎么安装?怎么运行REPL?
  • 使用什么IDE编写Clojure?
  • 如何编译clj文件?
  • Clojure CLR 与 Clojure JVM 有什么区别?
  • Clojure 如何调用 C#?
  • C# 如何调用Clojure?
  • Clojure如何调用.net WinForm ?
 

安装

这第一步就不是太顺利,如果你从Github上(  https://github.com/clojure/clojure-clr ) 下载了代码编译的时候,你可能遇到特别多的问题,比如一开始你会发现lib文件夹中并没有项目依赖的Microsoft.Dynamic.dll和Microsoft.Scripting.dll.这个问题不大,只要到  http://dlr.codeplex.com/ 下载一份就可以了(下载解压拷贝等若干步骤省略),通过这个问题其实也可以知道Clojure CLR是构建在Microsoft's Dynamic Language Runtime (DLR)之上的.
解决了引用的问题,紧接着就是编译项目,你可能会看到下面这个错误信息:
Error     16     The command "" D:\Code\clojure-clr-master\bin\4.0\Debug\Clojure.Compile.exe " clojure.core clojure.core.protocols clojure.main clojure.set clojure.zip  clojure.walk clojure.stacktrace clojure.template clojure.test clojure.test.tap clojure.test.junit clojure.pprint clojure.clr.io clojure.repl clojure.clr.shell clojure.string clojure.data clojure.reflect"  exited with code 1.     Clojure.Compile
与其这样,我的选择是:直接用编译好的二进制包,不要在Clojure的门口逡巡太久.下载地址:  https://github.com/clojure/clojure-clr/wiki/Getting-binaries  http://sourceforge.net/projects/clojureclr/files/

运行REPL

解压之后的目录里面只有一个带Clojure图标的Clojure.Main.exe,双击它,一个崭新的世界就来了:
Clojure 1.4.1
user=> (+ 1 2)
3
user=> (println "hello world")
hello world
nil
user=>

  

如果你真的按照我上面一步一步来操作了,走到这里你可能会问:你是怎么把上面的文字拷贝出来的?Clojure.Main.exe是一个.net的Console Application,在界面鼠标上选中操作是不能直接使用的,我们可以先单击应用左上角的图标,出来编辑菜单,可以选择"select all",然后回车即可完成复制.还是截图来看看这个略显扯淡的操作方式:

Clojure IDE

不必专门找Clojure CLR的IDE,只要是Clojure的IDE都可以拿来用.备选方案有:Eclipse插件,Light Table,Vim插件,Emac 等等,按照自己的口味自己选吧,下面Stackoverflow上的讨论基本上包含了呼声比较高的几个Clojure IDE:
http://stackoverflow.com/questions/463776/clojure-ide-on-windows

编译

编写下面的文件hello.clj
(ns hello)
(println "hello world" 2013)
命令行完成编译:
C:\Clojure-CLR 1.4>Clojure.Compile.exe hello
Compiling hello to .hello world 2013
-- 415 milliseconds.
编译完成之后就会生成hello.clj.dll文件,拖入Reflector里面看看生成的代码是什么样子,注意下面的0x7ddL就是常量2013:
public class __Init__
{// Fieldsprotected internal static Var const__0;protected internal static AFn const__1;protected internal static Var const__2;protected internal static object const__3;// Methodsstatic __Init__(){try{Compiler.PushNS();__static_ctor_helper_constants();}finally{Var.popThreadBindings();}}private static void __static_ctor_helper_constants(){const__0 = RT.var("clojure.core", "in-ns");const__1 = Symbol.intern(null, "hello");const__2 = RT.var("clojure.core", "println");const__3 = 0x7ddL;}public static void Initialize(){((IFn) const__0.getRawRoot()).invoke(const__1);((IFn) new hello$loading__16463__auto____5()).invoke();((IFn) const__2.getRawRoot()).invoke("hello world", const__3);}
}

  

Clojure CLR 与 Clojure JVM 有什么区别?

 
Clojure CLR项目的目标:

-- Implement a feature-complete Clojure on top of CLR/DLR.
-- Stay as close as possible to the JVM implementation.
-- Have some fun.

基础不同必然有差异,比如  https://github.com/richhickey/clojure-clr/wiki/Completing-CLR-interop

Clojure 调用 C#

 
CLR interop is essentially the same as JVM interop. However, we have to make a number of extensions to allow for parts of the CLR object model that are not in the JVM.
https://github.com/richhickey/clojure-clr/wiki/CLR-Interop
user=> (System.Console/WriteLine "Now we use Console Writeline")
Now we use Console Writeline
nil;;读写文件
user=> (def file (System.IO.StreamWriter. "test.txt"))
#'user/file
user=> (.WriteLine file "===Hello Clojure ===")
nil
user=> (.Close file)
nil
user=> (println (slurp "test.txt"))
WARNING: (slurp f enc) is deprecated, use (slurp f :encoding enc).
===Hello Clojure ===nil
user=>

  

我们把抓取Web页面的代码翻译成Clojure:
C#:
System.Net.WebClient webClient= new System.Net.WebClient();
byte[] bResponse = webClient.DownloadData("http://www.baidu.com");
Console.WriteLine(Encoding.UTF8.GetString(bResponse));

  

Clojure:
(import (System.Net WebClient))
(import (System.Text Encoding))(.GetString Encoding/UTF8 (.DownloadData (WebClient.) "http://www.baidu.com"))

 
我们继续在这个代码上做点文章,我们把它修改成一下放在hello.clj文件里面编译出来:

 

(ns hello)(import (System.Net WebClient))
(import (System.Text Encoding))(defn getbaidu [](.GetString Encoding/UTF8 (.DownloadData (WebClient.) "http://www.baidu.com"))
)

 

再一次把hello.clj.dll拖入Reflector,看生成的代码:
[Serializable]
public class hello$getbaidu__11 : AFunction
{// Methodspublic override bool HasArity(int num1){if (num1 != 0){return false;}return true;}public override object invoke(){return Encoding.UTF8.GetString(new WebClient().DownloadData("http://www.baidu.com"));}
}

  

是不是上面有一个问题已经在不知不觉之间解决了?(如何在C#中调用Clj代码) 
Clojure 调用.net Winform 当然也不是问题 
只要加载System.Windows.Forms程序集导入对应的类即可,示例代码如下:
user=> (System.Reflection.Assembly/Load "System.Windows.Forms,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
#<RuntimeAssembly System.Windows.Forms, Version=4.0.0.0, Culture=neutral, Public
KeyToken=b77a5c561934e089>
user=> (import (System.Windows.Forms MessageBox))
System.Windows.Forms.MessageBox
user=> (MessageBox/Show "Hello world from clojure-clr!" "Clojure-CLR DialogBox")OK
user=>

 

Clojure CLR 旅行愉快 !
   
[0]  http://www.myclojureadventure.com/2011/10/getting-started-with-clojure-clr.html
[1]  http://www.4clojure.com/ 
[2]  http://clojure-doc.org/   
[3]  http://try-clojure.org/
[4]  http://dev.clojure.org/display/doc/Getting+Started
[5]  https://github.com/rippinrobr/clojure-clr-intro
最后小图一张:

Clojure CLR 入门相关推荐

  1. Clojure 学习入门(1) - 学习资料

    转自:http://blog.csdn.net/ithomer/article/details/17225813 Clojure(发音类似"closure",['kləʊʒə(r) ...

  2. Clojure 学习入门(13)- binding

    Clojure里面是不支持变量的.Binding跟变量有点像,但是在被赋值之前是不允许改的,包括:全局binding, 线程本地(thread local)binding, 以及函数内的本地bindi ...

  3. Clojure 学习入门(17)- 异常处理

    异常处理  Clojure代码里面抛出来的异常都是运行时异常.当然从Clojure代码里面调用的Java代码还是可能抛出那种需要检查的异常的. try - catch - finally 以及thro ...

  4. Clojure 学习入门(16)- 正则表达式

    一.创建正则表达式  re-pattern函数:  函数 (re-pattern) 接受一个字符串参数,返回一个正则表达式样式(java.util.regex.Pattern类的实例).这个样式能用于 ...

  5. Clojure 学习入门(15)- 条件判断

    一.标准的流程控制  if:  将一个判断表达式作为它的第一个参数进行求值.如果求值为true,那么就返回它的第二个参数(相当于"then"子句)的求值结果.如果结果为false( ...

  6. Clojure 学习入门(14)- 循环控制

    Clojure 基于函数的流程控制  repeatedly 字面意思为重复函数.一般的用法如下: user=> (repeatedly 5 #(rand-int 11)) (6 8 2 6 6) ...

  7. Clojure 学习入门(12)- map/pmap

    clojure map数据结构的常用方法,小结一下 map 各种排序 [html] view plaincopy print? (println (sorted-map-by > 1 " ...

  8. Clojure 学习入门(11)- 宏 macro

    clojure macro宏在运行之前机械展开,定义宏相当于给语言增加新特性,写宏的*原则*:  能写成函数就不要用宏(因为写宏没有写函数简单直观,容易写错,需要先在 REPL 中测试一番) 只有不得 ...

  9. Clojure 学习入门(10)- httpkit

    Http-kit 是主要由Java 和 Clojure开发,为Clojure定制的零依赖的HTTP lib,仅用3000多行代码,实现了高性能 Server,Client,Timer.代码量少,实现简 ...

最新文章

  1. 你想见的大神都来AI ProCon 2019了,优惠票限时抢购开启!
  2. Pangolin在cmake时报“Could NOT find GLEW”错误
  3. jprofiler分析dump文件_内存溢出+CPU占用过高:问题排查+解决方案+复盘(超详细分析教程)...
  4. gp的分布、分区策略(概述)
  5. Java面试知识点:网络编程
  6. 有关链表的小技巧,我都给你总结好了
  7. SpringBoot自定义Filter
  8. 多玩家游戏设计注意思的地方(转)
  9. ImageMagick---import(截图)
  10. java语言精粹_java 成神之路 (一)
  11. android浮动按钮_Android浮动操作按钮示例教程
  12. 动画交互原型设计:Principle for Mac
  13. mall商城 -小程序,h5和pc vue前后端分离
  14. ant-design-vue 的颜色选择器
  15. 【附源码】计算机毕业设计java业俊宾馆客房管理系统设计与实现
  16. 我深夜用 Python 跑神经网络,只为关掉台灯!
  17. Vue 基础之常用内置指令
  18. 在国内使用iOS 6看苹果3D地图Flyover成功! 小教程
  19. 学生管理系统设计与实现(C++实现)
  20. Linux一:Linux启动及登陆

热门文章

  1. 检查内存泄露的利器--VLD使用指南
  2. python科学计数法的显示与转换
  3. 鸿蒙 华为watch gt3手表hello world
  4. 【基础知识】PCB布局设计入门步骤
  5. oracle数据库的安装及配置方法
  6. 【Python界面设计】Tkinter的Listbox控件
  7. 1M带宽服务器能够承载多少人
  8. python的py、pyc、pyo、pyd文件区别
  9. mysql联合索引如何创建
  10. 互联网快讯:粉笔科技双核驱动实现突围;猿辅导以科技助力教育提质增效;抖音升级谣言专项治理