Clojure学习笔记(一)——介绍、安装和语法

什么是Clojure

Clojure是一种动态的、强类型的、寄居在JVM上的语言。

Clojure的特性:

  • 函数式编程基础,包括一套性能可以和典型可变数据结构媲美的持久性数据结构
  • 由JVM提供的成熟的、高效的运行时环境:所以Clojure可以使用Java类库,反之Clojure库也可以被Java使用
  • 跟JVM/Java的互操作能力使得很多架构、运维方面的需求可以得到满足:Clojure代码可以像Java代码一样被打包,然后部署到任何Java应用可以部署的地方
  • 一套提供并发、并行语义的机制:Clojure的应用类型强制我们把对象的状态和对象的标识区分开(这是个天才的思想,参见[1][2]),对于多线程的支持使得我们不用手动加锁,解锁也能编写多线程代码
  • 是一种Lisp方言,因此提供了非常灵活、强大的元编程能力:Clojure保留了Lisp的最好的特性,去掉了Lisp方言的缺陷。

安装Clojure

因为Clojure需要运行在JVM上所以需要JRE。然后可以在http://clojure.org/community/downloads下载Clojure的代码。有了这些就可以运行Clojure的REPL了。

运行REPL

从命令行运行运行REPL的方式:1. 进入下载的Clojure目录;2.运行java -cp clojure-1.8.0.jar clojure.main,如果会看到如下,则成功:

为了以后运行方便可以创建一个shell脚本cljREPL.sh,内容如下:

#!/bin/sh
cd /home/namenode/Code/workspace/clojure-1.8.0
java -cp clojure-1.8.0.jar clojure.main 

然后,修改执行权限:

chmod +x cljREPL.sh

然后创建软链接:

sudo ln -s /home/namenode/Code/workspace/clojure-1.8.0/cljREPL.sh /bin/cljREPL

这样在终端直接输入cljREPL就可以直接运行Clojure的REPL了

安装Clojure命令工具

在Ubuntu下可以直接用apt-get安装Clojure。

sudo apt-get install clojure1.6

测试,创建文件balance.clj(例子来自《Java虚拟机并发编程》)

(def balance(ref 0))
(println "Balance is " @balance)

(dosync
(ref-set balance 100))

(println "Balance is now " @balance)

运行:clojure balance.clj则会打印下图的结果

语法

Clojure、Java、Python和Ruby中的函数调用语法比较

同像性

Clojure是由Clojure自身的数据结果:原子值(字符串、数字等)和集合的字面量来表示。这种特征就叫“同像性”,或者称为“代码即数据”。

Clojure没有定义一种将会别转换成AST(Abstract Sytax Tree,抽象语法树)的语法,Clojure代码是直接用表示抽象语法树的Clojure数据结构来写的。

Clojure使用数据来表示语言代码的特征使得Clojure代码可以很容易地用来编写和转换其他Clojure代码。这是宏(Macro)的基础,Clojure中的元程序编程工具要比C语言中提供的那种宏以及其他文本预处理器要强劲的多。

Clojure Reader

Clojure reader的功能是把程序员写的文本格式的代码转换成Clojure数据结构。Reader的所有操作是由一个叫read的函数定义的,这个函数从一个字符流里读入代码的文本形式,产生这个文本所对应的数据结构。Clojure的REPL就是使用Reader来读入文本代码的, reader的作用其实可以看做是反序列化的过程。与read和read-string对应的两个函数是pr和pr-str,这两个函数是序列化的过程。

所有Clojure的数据结构和值序列化之前都是既对人可读,又对机器可读

标量字面量

字符串

和Java等语言一样 “Hello World”

而且Clojure天然支持多行

布尔值

Clojure中用true和false表示布尔值

nil

Clojure中的nil和Java中的null是类似的,在判断中nil是逻辑的false

字符

字符字面量是通过反斜杠加字符表示的:

对于Unicode编码和octal编码,可以使用对用前缀:

同时对于一些特殊字符也有对应的常量:

\space
\newline
\formfeed
\return
\backspace
\tab

关键字

关键字始终是以冒号开头,它可以包含任意非空字符。如果关键字里面包含/,表示这个关键字是命名空间限定的。如果关键字是以两个冒号(::)开头的,那么表示是当前命名空间的关键字。如果关键字以两个冒号开头,同时又包含了/,如::alias/kw,那么表示某个特定命名空间里面的关键字。这个设计与XML里面的命名空间实体的用法和动机是一样的,也就是为了让同一个名字在不同的命名空间里有不同的值和语义。

符号

符号也是一种标识符,符号的值是它所代表的Clojure运行时里面的那个值,这个值可以使var所持有的值、Java类、本地引用等。

数字

十六进制:0xff  八进制:040(以0开头)   任意进制:BrN(N表示数字,B表示进制)  有理数:用比例数表示

正则表达式

以#开头,不需要对反斜杠转义

注释

  • 单行注释以分号开头
  • 形式级别的注释#_宏,告诉reader忽略下一个Clojure形式

空格和逗号

在Reader眼里,逗号就是空格

集合字面量

命名空间

所有的Clojure代码都是在一个命名空间中被定义和求值的。命名空间可以禅城Ruby和Python的module,Java的package。

Clojure中的一种引用类型var是一种可修改的内存地址,从而可以保存任何值,在var被定义的命名空间里,var和一个符号相关联,然后我们就可以通过这个符号来使用这个var,从而得到这个var的值。

在Clojure中var是用def来定义的。如:

在当前命名空间user中定义了一个名叫x的var

当前的命名空间始终绑定到*ns*上

符号求值

阻止求值:quote

阻止求值也可以用单引号表示

代码块:do

do会依次传入进来所有的表达式,并且把最后一个表达式的结果作为返回值

定义Var:def

本地绑定:let

所有本地绑定都是不可变的;let的绑定数组在编译期间在编译器间可以对通用集合进行解构,利用解构,可以大大简化从绑定数据中抽取想要的数据的操作。

解构:let

很多Clojure函数都接受顺序性数据结构和map作为参数或返回值,而且接受或返回抽象数据类型。这使函数在调用Clojure类库时,不需要额外的代码去对接具体数据结构的实现,也就不需要一些glue code来做类型转换之类的事情,可保持代码简单

定义函数:fn

函数是把参数值绑定到参数上,在执行

defn

defn基于fn,封装了def和fn的功能,定义一个具有名的函数

判断:if,when,cond

循环:loop和recur

与Java的互操作:.和new

异常处理:try和throw

状态修改:set!

锁的原语:monitor-enter和monitor-exit

参考

  1. http://ifeve.com/stm-1/
  2. Dr. Alan Kay, 《on the Meaning of “Object-Oriented Programming”》, http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en
  3. Chas Emerick, Brian Carper, Christophe Crand,《Clojure编程》
时间: 2024-08-11 01:19:13

Clojure学习笔记(一)——介绍、安装和语法的相关文章

python学习笔记一 介绍、基本语法、流程控制

1.用户输入 #!/usr/bin/env python #_*_coding:utf-8_*_ #name = raw_input("What is your name?") #only on python 2.x name = input("What is your name?") print("Hello " + name ) 2.输入密码时,如果想要不可见,需要利用getpass 模块中的 getpass方法,即: #!/usr/bin/

【改自lg2lh】EZ-USB 68013 学习笔记--设备信息安装文件CyUSB.inf详细说明

首先要明白一个INF文件的基本结构:INF由节组成,即一个个段组成.每个段的功能不一样.(大部分书上把这个段叫作"节") [Version]段:主要用说明版本信息的. [Strings]段:字符串信息,用于常量定义,用于显示.凡在其他段中出现的%XXXX%(就是两个百分号夹着一组字母),则对应的就会在Strings段里对应着它的一个字符串. [SourceDisksNames]段:定义安装源文件所在磁盘,一般为1,表示在第一个磁盘.此节可无. [SourceDiskFiles]段:驱动

树莓派学习笔记——apt方式安装opencv

0.前言 本文介绍如何在树莓派中通过apt方式安装opencv,并通过一个简单的例子说明如何使用opencv.相比于源代码方式安装opencv,通过apt方式安装过程步骤简单些,消耗的时间也少一些.通过apt方式安装没有自动生成opencv.pc文件,所以在编写makefile文件时不能直接使用pkg-config工具,而需要逐个指定opencv_core.opencv_imgproc等动态链接库. [相关博文] [树莓派学习笔记-- 源代码方式安装opencv] 更多内容请参考--[树莓派学习

Linux学习笔记——虚拟机中安装VMware Tools

0 前言 VMware Tools是VMware虚拟机中自带的一种增强工具,只有在VMware虚拟机中安装好了VMware Tools,才能实现主机与虚拟机之间的文件共享,实现文件在虚拟机之间的复制粘贴. 最近购买了周立功的一款EasyARM开发板,作为树莓派Linux学习的补充.在虚拟机中安装了周立功提供的ubuntu镜像,总觉得在主机和PC机之间直接复制粘贴才爽,所以又安装了Vmware Tools.     [相关博文] [ Linux学习笔记--vmware plarer中安装ubunt

Git 学习笔记<简介与安装> (一)

Git,开源中国以及GitHub所使用的系统, Is A 一个分布式版本控制系统 Be Used to 为团队合作写代码提供方便的管理系统.几乎满足你所有关于合作写代码的幻想. Has 本地端:工作区.版本库 (版本库还含有一个暂存区) 远程仓库:版本库(用来储存版本库的服务器) How To Install Linux: 首先,先输入git,看看是否安装Git: $ gitThe program 'git' is currently not installed. You can install

ExtJs学习笔记(1)---ExtJs安装及其使用

从官网下载了ExtJs的3.2版本的SDK,包含了代码依赖的详细说明.文档.范例和其他文件.其中,adapter和resources文件是Ext正常运行所必须的,其他的仅在开发过程中使用到. Adapter:支持把Ext和其他代码库一同使用的文件 build:用于自定义构建ext-all.js的文件 docs:文档中心(仅当运行在服务器上时能够正常访问) examples:大量令人印象深刻富有洞察力的范例 resources:Ext依赖的文件,例如CSS和图片 source:ext的所有代码 在

Maven学习笔记(1)之安装Maven

此笔记是学习Maven时自己摸索+各种百度而来,并非全部原创,望与各位一同学习,勿拍~勿拍~ 安装步骤: 1.下载Maven的最新版本,地址:http://maven.apache.org/download.cgi 2.将下载完成的压缩包放至D盘根目录(图方便,一会儿安装完再删就好) 3.在命令行上操作,进入到你想要安装的目录路径后敲:jar xvf 的命令来进行解压安装(请勿手动解压以省略此步) 4.配置环境变量 新建系统变量  MAVEN_HOME  变量值:D:\Java\apache-m

CoAP学习笔记——nodeJS node-coap安装和使用(Linux平台)

 0 前言 本文说明如果安装和使用node-coap.CoAP是专门为物联网系统开发的面向网络的应用层协议栈,CoAP建立在UDP协议之上尽可能减少网络开销,又具有HTTP Restful类型的特性.node-coap使用nodejs实现了coap的客户端和服务器端. [测试环境]--ubuntu/Linux [相关博文] [CoAP协议学习--CoAP基础] [CoAP学习笔记--CoAP资源发现] [CoAP学习笔记--服务器端繁忙时的处理请求流程] [树莓派学习笔记--webiopi安装与

CoAP学习笔记——nodeJS node-coap安装和使用(windows平台)

0 前言 本文尝试在windows平台中搭建基于nodeJS的CoAP Server. linux平台搭建和使用过程可参考--CoAP学习笔记--nodeJS node-coap安装和使用(Linux平台) [测试环境]--windows [相关博文] [CoAP协议学习--CoAP基础] [CoAP学习笔记--CoAP资源发现] [CoAP学习笔记--服务器端繁忙时的处理请求流程] [树莓派学习笔记--webiopi安装与入门]webiopi中集成了CoAP Server,可以方便地通过CoA