设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

JVM 平台上的各种语言的开发指南2

2013-7-9 14:16| 发布者: 红黑魂| 查看: 3088| 评论: 0|来自: 51CTO

摘要: Groovy“Groovy有超过Java将能够提供的甜点,例如它具有轻易地在宿主程序中嵌入并编译,以提供定制业务规则的能力,还有它如何为领域特定语言(Domain-Specific Language)提供优雅,简洁并且可读性好的语法的能力.” ...

仅仅为了好玩,我们也看了看Clooj,它是用Clojure本身开发的一个轻量级的Clojure IDE.下载和运行它都很容易,不过我们发现它同Eclipse相比,就有点黯然失色了.

最后我们用了用最难的方式开发Clojure程序——只在命令行中使用Lein,还有可靠的GVIM作为文本编辑器——主要是想看看Lein是如何详细工作的.

交互式解释器(REPL)

像众多的函数式语言, Clojure提供的命令行shell可以直接执行Clojure语句。这个shell对开发者非常方便,因为它在开发中不仅允许你测试一小端代码,而且允许你运行程序的一部分。

这或许对用Python,Perl开发的码农没什么新鲜的,但对Java开发者来说,这无疑带来更新鲜、更交互的方式来写代码。

jvm languages code example

函数式编程——另外一种思考方式

Clojure是一种非常类似于Lisp和Scheme的函数式编程语言.函数式范式同那些习惯于Java的面向对象方式并且习惯于其副作用的方式非常不同.

函数式编程推崇:

  • 很少或者完全没有副作用
  • 如果使用相同的参数区调用,函数就永远返回同一个结果(而不是依赖于对象状态的方法)
  • 没有全局变量
  • 函数是第一位的对象
  • 表达式懒计算(Lazy evaluation of expression)

这些特性并不是Clojure独有的,而是总体上对函数式编程都要求的:

(defn send-html-response
 "Html response"
 [client-socket status title body]
 (let [html (str "" body "")]
  (send-http-response client-socket status "text/html"
  (.getBytes html "UTF-8"))

))

同Java的互操作性

Clojure提供了优秀的同Java库的互操作功能.事实上,对于一些基本的类,Clojure并没有提供它自己的抽象,而是超乎你预期的直接使用了Java类来代替.在这个HTTP服务器的示例中,我们从Java中获取了像Reader和Writer这样的类:

(ns clojure-http-server.core
(:require [clojure.string])
(:import (java.net ServerSocket SocketException)
(java.util Date)
(java.io PrintWriter BufferedReader InputStreamReader BufferedOutputStream)))

创建和调用Java对象是非常直截了当的.而实际上有两种形式(在这个优秀的Clojure介绍中描述到了):

(def calendar (new GregorianCalendar 2008 Calendar/APRIL 16)) ;
April 16, 2008
(def calendar (GregorianCalendar. 2008 Calendar/APRIL 16))
Calling methods:
(. calendar add Calendar/MONTH 2)
(. calendar get Calendar/MONTH) ; -> 5
(.add calendar Calendar/MONTH 2)
(.get calendar Calendar/MONTH) ; -> 7

下面是一个实际的样例:

(defn get-reader
"Create a Java reader from the input stream of the client socket"
[client-socket]
(new BufferedReader (new InputStreamReader (.getInputStream client-
socket))))

然而,对于一些结构,我们决定要使用到Clojure的方式.原生的Java代码使用StringTokenizer,这样做违背了不可变对象的纯函数式 原则,还有无副作用的原则.调用nextToken()方法不仅有副作用(因为它修改了Tonkenize对象)并且使用同一个(或许是不存在的)参数也 会有不同的返回结果.

由于这个原因,我们使用Clojure的更加"函数式"的Split函数:

(defn process-request
"Parse the HTTP request and decide what to do"
[client-socket]
(let [reader (get-reader client-socket) first-line
 (.readLine reader) tokens (clojure.string/split first-line #"\s+")]
(let [http-method (clojure.string/upper-case
 (get tokens 0 "unknown"))]
(if (or (= http-method "GET") (= http-method "HEAD"))
(let [file-requested-name (get tokens 1 "not-existing")
[...]

并发(Concurrency)

Clojure从一开始设计对并发很上心,而不是事后诸葛亮.使用Clojure编写多线程应用程序非常简单,因为所有的函数默认都实现了来自Java的Runnable和Callable接口,自身得以允许其任何方法在一个不同的线程中运行。

Clojure也提供了其它特别为并发而准备的结构,比如原子(atom)和代理(agent),但是我们在这个HTTP服务器示例中并没有使用它们,而是选择熟悉的Java的Thread.

(defn new-worker
"Spawn a new thread"
[client-socket]
(.start (new Thread (fn [] (respond-to-client client-socket)))))

有关方法使用顺序的问题

我们认识到的一件事情是在源代码文件中,方法的顺序是严格的。函数必须在它们第一次被使用之前被定义。另外一种选择是,你可以在一个函数被实际定义之前利用一种特殊的声明格式,来使用函数。这让我们想起了C/C++的运作方式,它们使用头文件和函数声明。

原文链接:http://zeroturnaround.com/rebellabs/the-adventurous-developers-guide-to-jvm-languages/

译文链接:http://www.oschina.net/translate/the-adventurous-developers-guide-to-jvm-languages





酷毙
2

雷人

鲜花

鸡蛋
1

漂亮

刚表态过的朋友 (3 人)

  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部