clojure_解码Clojure代码,让您不知所措

clojure

最近,我写了一些有趣的功能Kotlin来解决FizzBu​​zz测试 。 我要求提供一些反馈,而我收到的答案之一是Clojure

左侧的代码如下:

(defn div-by? [n d]
  (zero? (mod n d)))

(defn fizz-buzz [n]
  (condp = [(div-by? n 3) (div-by? n 5)]
         [true true] "FizzBuzz"
         [true false] "Fizz"
         [false true] "Buzz"
         (str n)))

(->> (range 1 100)
     (map (comp println fizz-buzz)))

我对Clojure一无所知,但这只是一种功能性语言。 我认为尝试理解以上摘录是一个有趣的练习,尤其是因为它的大小非常有限。 在本文中,我将采用Java开发人员的观点。

括号,到处都有括号

如果您只熟悉C语言家族(例如我自己),那么此代码段看起来就很晦涩。 首先要知道Clojure属于Lisp语言家族。 后者在每个表达式,语句,调用等周围加上括号:

(str n) ; returns n.toString()

没有静态类型检查

Clojure没有静态类型检查。 没有。 零。 齐尔奇 您可以在上面的解决方案中检查是否缺少类型。

如果真的对此感到不舒服,可以使用一个子项目将类型引入Clojure。

没有返回关键字

Clojure是一种功能语言。 因此,它会尽最大努力来强制编写函数:

函数是将集合X的每个元素x(函数的域)与另一个集合Y的单个元素y相关联的过程或关系。
—维基百科
https://zh.wikipedia.org/wiki/功能_(数学)

这意味着每个函数都应该返回。 因此,如上述片段所示, return关键字是隐式的。

不应该返回值的函数-不纯函数, 例如 println无论如何都返回nil

前缀表示法

Clojure需要先编写方法名称,然后再编写参数(如果需要)。 这与Java非常相似,但是Clojure甚至在算术上将这种模式应用于所有地方

(mod n d) ; returns the reminder of n divided by d

编码约定

  • Clojure标识符使用连字符,而不是像Java中那样使用驼峰式大小写
    (div-by? n 3) ; calls the div-by? function with arguments n and 3
  • 返回boolean值的函数应以?结尾

定义功能

defn宏允许定义一个新函数。 宏的参数为:

  1. 函数名称
  2. 参数列表,指定为可选的空数组
  3. 功能体
(defn
  div-by?             (1)
  [n d]               (2)
  (zero? (mod n d)))  (3)
  1. 功能名称
  2. 函数参数,包装在数组中
  3. 功能体

链接功能

函数链接是通过comp宏实现的:

(def times-inc (comp inc *))  (1)
(times-inc 2 3)               (2)
  1. 组成乘和加一的函数
  2. 用参数23调用定义的函数,返回7

开关

condp宏代替了传统的switch语句,但功能更强大。 它更类似于Kotlin和Scala中的模式匹配功能。

(condp = [(div-by? n 3) (div-by? n 5)] ; a two-elements array of boolean
  [true true] "FizzBuzz"
  [true false] "Fizz"
  [false true] "Buzz"
  (str n)) ; if no other match, this is the default

摘要

总结一下,这是上述代码片段的Java等效项(或Java不够用时的Kotlin):

Clojure Java /科特琳
(str n)
returnn.toString();
(mod n d)
returnn%d;
(div-by? n 3)
returndivBy(n,3);
(defn div-by? [n d]
  (zero? (mod n d)))
booleandivBy(intn,intd){
  returnn%d==0;
}
(def times-inc
  (comp inc *))
(times-inc 2 3)
UnaryOperator<Integer>inc=i->i+1;
BinaryOperator<Integer>times=(i,j)->i*j;
BiFunction<Integer,Integer,Integer>timesInc=
  times.andThen(inc);
returntimesInc.apply(2,3);
(condp = [(div-by? n 3)
          (div-by? n 5)]
  [true true] "FizzBuzz"
  [true false] "Fizz"
  [false true] "Buzz"
  (str n))
returnwhen(divBy(i,3)todivBy(i,5)){
  truetotrue->"FizzBuzz"
  truetofalse->"Fizz"
  falsetotrue->"Buzz"
  else->i.toString()
}

去做

我仍然需要进一步深化一些细微之处:

  • 宏和函数之间的区别
  • →>
  • defdefn之间的区别

之后,可能的后续步骤包括:

  1. 解码原始推文右侧显示的代码
  2. 潜入收藏
  3. 了解Clojure / Java互操作性
  4. 尝试开发基本的Spring Boot应用程序
  5. 检查“经典”堆栈的Java框架的等效形式, 例如 Web开发,持久性,日志记录,构建等。

翻译自: https://blog.frankel.ch/decoding-clojure-code/

clojure

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值