Redian新闻
>
What is the difference between Haskell and Clojure
avatar
l*n
2
which one is more suitable for industry application
avatar
f*o
3
能寄到美国吗?运费多少?
avatar
d*r
4
Clojure 吧
avatar
i*a
5
according to fatwallet post, yes. $24 shipped to US

【在 f**********o 的大作中提到】
: 能寄到美国吗?运费多少?
avatar
c*o
6
they have different strength.
here is some fun example of beautiful clojure code for quick sort:
(defn qsort [L]
(if (empty? L)
'()
(let [[pivot & L2] L]
(lazy-cat (qsort (for [y L2 :when (< y pivot)] y))
(list pivot)
(qsort (for [y L2 :when (>= y pivot)] y))))))
Another short version (using quasiquote):
(defn qsort [[pvt & rs]]
(if pvt
`([email protected](qsort (filter #(< % pvt) rs))
~pvt
[email protected](qsort (filter #(>= % pvt) rs)))))
Another, more readable version (no macros):
(defn qsort [[pivot & xs]]
(when pivot
(let [smaller #(< % pivot)]
(lazy-cat (qsort (filter smaller xs))
[pivot]
(qsort (remove smaller xs))))))
A 3-group quicksort (fast when many values are equal):
(defn qsort3 [[pvt :as coll]]
(when pvt
(let [{left -1 mid 0 right 1} (group-by #(compare % pvt) coll)]
(lazy-cat (qsort3 left) mid (qsort3 right)))))
A lazier version of above (unlike group-by, filter returns (and reads) a
lazy sequence)
(defn qsort3 [[pivot :as coll]]
(when pivot
(lazy-cat (qsort (filter #(< % pivot) coll))
(filter #{pivot} coll)
(qsort (filter #(> % pivot) coll)))))
avatar
c*o
7
some beautiful example for haskell:
Java:
public int[] seriesUp(int n) {
int[] result = new int[n * (n + 1) / 2];
int pos = 0;
int i = 1;
while (i <= n + 1) {
for (int j = 1; j < i; j++) result[pos++] = j;
i++;
}
return result;
}
Haskell:
seriesUp :: Int -> [Int]
seriesUp n = concatMap (\x -> [1..x]) [1..n]
avatar
c*o
8
I am more familar with scala, which have deep haskell root:
example: a list monad implemented by myself:
sealed trait List[+A] {
def head: A
def tail: List[A]
def isEmpty: Boolean
override def toString = "[ " + asString_internal(this) + "]"
private def asString_internal[B >: A](l: List[B]): String =
l match {
case Cons(head,tail) => head.toString + " " + asString_internal(tail)
case _ => ""
}
def append[B](a1: List[B], a2: List[B]): List[B] =
a1 match {
case Nil => a2
case Cons(h,t) => Cons(h, append(t, a2))
}
def foldleft[That](z: That)(f: (That, A) => That): That =
foldLeft_internal(this, z)(f)
@annotation.tailrec
private def foldLeft_internal[B, That](l: List[B], z: That)(f: (That, B) =
> That): That =
l match {
case Nil => z
case Cons(h,t) => foldLeft_internal(t, f(z,h))(f)
}
def reverse: List[A] = reverse_internal(this)
private def reverse_internal[B](l: List[B]) = foldLeft_internal(l, List[B]
())((acc,h) => Cons(h,acc))
def foldRight[That](z: That)(f: (A,That) => That): That =
foldRight_internal(this, z)(f)
private def foldRight_internal[B, That](l: List[B], z: That)(f: (B,That) =
> That): That =
foldLeft_internal(reverse_internal(l), z)((b,a) => f(a,b))
def concat[B](l: List[List[B]]): List[B] =
foldRight_internal(l, Nil:List[B])(append)
def unit[B >: A](a: B): List[B] =
Cons(a, Nil)

private def unit_internal[B](a:B): List[B] =
Cons(a, Nil)
def flatMap[That](f: A => List[That]): List[That] =
concat(foldRight(Nil:List[List[That]])((h,t) => Cons(f(h),t)))
private def flatMap_internal[B, That](la: List[B])(f: B => List[That]):
List[That] =
concat(foldRight_internal(la, Nil:List[List[That]])((h,t) => Cons(f(h),t
)))
def apply[That](f: List[A => That]): List[That] =
flatMap_internal(f)(t1 => flatMap((t2) => unit_internal(t1(t2))))
def map[That](f: A => That): List[That] =
apply(unit_internal(f))
def fold[B >: A](z: B)(op: (B, B) ⇒ B): B=
foldRight(z)(op)
def filter(f: A => Boolean): List[A] =
foldRight(Nil:List[A])((h,t) => if (f(h)) Cons(h,t) else t)
}
case object Nil extends List[Nothing] {
override def isEmpty = true
override def head: Nothing =
throw new NoSuchElementException("head of empty list")
override def tail: List[Nothing] =
throw new UnsupportedOperationException("tail of empty list")
}
case class Cons[+A] (hd: A, tl: List[A]) extends List[A] {
override def isEmpty = false
override def head : A = hd
override def tail : List[A] = tl
}
avatar
h*i
9
我不懂Haskell, 只会Clojure。 以下是一些对比,完全基于我知道的事实:
1. Haskell是搞计算机语言研究的学术界人士组织了一个委员会来发明的语言,发明于
1990年。目前是计算机语言实验研究的一个通用语言,而且是很多大学计算机系的正式
课程。
Clojure是工业界的一个人发明的语言,发明于2007年,发明人Rich Hickey没拿过计算
机学位,而是学音乐出身的,其职业是程序员。据我所知,目前没有什么大学计算机系
把Clojure放入正式课程。
2. Haskell是直接编译成机器码的原生语言。
Clojure是寄生语言,编译成宿主语言或者代码,目前在JVM上编译成Java byte code,
在Javascript上编译成Google Closure javascript code, 在.net上编译成CLR byte
code, 其他宿主包括Flash, python, ruby, 甚至还有perl。作为寄生语言,Clojure追
求和宿主共生,尽量利用宿主的生态环境,和宿主语言相互调用一般很方便。
3. Haskell是ML系的FP 语言, Clojure是LISP系的FP语言。
4. Haskell是static typed语言,Clojure是dynamic typed语言。

【在 l**********n 的大作中提到】
: which one is more suitable for industry application
avatar
c*o
10
ML 和 Lisp的最主要对比是:
1. common Lisp and most Lisps (Clojure) are all dynamic language
ML/Haskell/Scala are "strong" static typed
2. lisp all have "minimum" syntaxes. Really minimum. and program in it feels
"freedom".
ML line in theory have simple syntax, but because of the advanced FP/type
feature, program is like work in maths, compose a symphony, drawing a
architecture design. Grand and precise and all fit together in harmony.
3. lisp are free form, and consistence in style.
ML are delicate and precise, very ordered (restrictive and statically
checking a lot of things), also consistence in style.
avatar
e*o
11
如果工作就是秀算法,那选haskell不错。
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
import Yesod
data HelloWorld = HelloWorld
mkYesod "HelloWorld" [parseRoutes|
/ HomeR GET
|]
instance Yesod HelloWorld
getHomeR :: Handler Html
getHomeR = defaultLayout [whamlet|Hello World!|]
main :: IO ()
main = warp 3000 HelloWorld
http://www.yesodweb.com/book/basics
看你从学编程到能成功写个hello world 得多长时间?
avatar
e*o
12
https://www.linkedin.com/in/richhickey
看看教育经历一栏。

,

【在 h*i 的大作中提到】
: 我不懂Haskell, 只会Clojure。 以下是一些对比,完全基于我知道的事实:
: 1. Haskell是搞计算机语言研究的学术界人士组织了一个委员会来发明的语言,发明于
: 1990年。目前是计算机语言实验研究的一个通用语言,而且是很多大学计算机系的正式
: 课程。
: Clojure是工业界的一个人发明的语言,发明于2007年,发明人Rich Hickey没拿过计算
: 机学位,而是学音乐出身的,其职业是程序员。据我所知,目前没有什么大学计算机系
: 把Clojure放入正式课程。
: 2. Haskell是直接编译成机器码的原生语言。
: Clojure是寄生语言,编译成宿主语言或者代码,目前在JVM上编译成Java byte code,
: 在Javascript上编译成Google Closure javascript code, 在.net上编译成CLR byte

avatar
h*i
13
喔,还不知道他在State University of New York Empire State College念过
computer science, 有学位么?

【在 e*******o 的大作中提到】
: https://www.linkedin.com/in/richhickey
: 看看教育经历一栏。
:
: ,

avatar
z*e
14
就是一个map嘛
你凹凸了
rxjava已经搞掂了

【在 c******o 的大作中提到】
: some beautiful example for haskell:
: Java:
: public int[] seriesUp(int n) {
: int[] result = new int[n * (n + 1) / 2];
: int pos = 0;
: int i = 1;
: while (i <= n + 1) {
: for (int j = 1; j < i; j++) result[pos++] = j;
: i++;
: }

avatar
l*n
15
seriesUp :: Int -> [Int]
seriesUp n = concatMap (x -> [1..x]) [1..n]
这个你用rxJava怎么搞?
第一行是说function accepts a int, returns a int array
第二行是implementation。

【在 z****e 的大作中提到】
: 就是一个map嘛
: 你凹凸了
: rxjava已经搞掂了

avatar
z*e
16
一样的嘛
http://reactivex.io/RxJava/javadoc/rx/Observable.html#concatMap

【在 l**********n 的大作中提到】
: seriesUp :: Int -> [Int]
: seriesUp n = concatMap (x -> [1..x]) [1..n]
: 这个你用rxJava怎么搞?
: 第一行是说function accepts a int, returns a int array
: 第二行是implementation。

avatar
l*n
17
function seriesUp(n){
var source = Rx.Observable.range(0, n);
source
.concatMap(function(x, i){
return Rx.Observable.range(0, x);
})
}
avatar
z*e
18
用上lambda后再看

【在 l**********n 的大作中提到】
: function seriesUp(n){
: var source = Rx.Observable.range(0, n);
: source
: .concatMap(function(x, i){
: return Rx.Observable.range(0, x);
: })
: }

avatar
z*e
19
var source = Rx.Observable.range(0, n);
source.concatMap(x->Rx.Observable.range(0, x));
大概是这么个意思,其实一些鸟蛋api而已了
装得很牛逼的样子,你自己用反射实现一个也没啥难度
avatar
l*n
20
不错,这个简洁。用上了ES6 lambda

【在 z****e 的大作中提到】
: var source = Rx.Observable.range(0, n);
: source.concatMap(x->Rx.Observable.range(0, x));
: 大概是这么个意思,其实一些鸟蛋api而已了
: 装得很牛逼的样子,你自己用反射实现一个也没啥难度

avatar
l*n
21
haskell牛逼应该不在这些,而在乎IO Monad, clojure应该牛在concurrency。这个
Java没法搞,js更不行。
avatar
c*o
23
重点在clojure的一致和简单,所有的程序在clojure的眼中都是类似这几个程序的结构
,没有例外。
只以简单的几种基本数据为重点,通过各种函数转化,再加上无所不能的macro(因为
clojure/lisp的哲学,数据和程序是一模一样的结构,所以macro用一致的数据方法处
理已有的程序,动态改变,重写,几乎是无所不能的,真正强的dsl在这儿)。
习惯以后是极简一致后的一种奇怪的感觉,好像一切cs都在那几个秘籍中的感觉。
哦,我是抛砖引玉,clojure不是我的主要语言,其他大牛们再说说。

【在 z****e 的大作中提到】
: 就是一个map嘛
: 你凹凸了
: rxjava已经搞掂了

avatar
c*o
24
再说说scala,上面我那个monad的精髓就在于它的通用性,和强大的模式(读作“限制
”)
,你可以用它来解决很多很多不一样的复杂问题,同时又能帮你在编程/编译/构思的时
候剔除很多不必要的错误和弯路。
avatar
z*e
25
我强烈反对只用这些基础的数据结构
我认为object一样自由的数据结构才是王道
真正的框架作者应该明白怎样用reflection来窥视object的内部结构
就像外科医生一样,而非强迫所有人用那么几种数据结构
我相信不同学科应该有自己的数据结构
而非被cs所绑架,只用那么几种数据结构
这是错误的,dsl应该配合这种趋势
这就是为啥应该用非pure fp,比如scala来写框架,而非pure fp来搞
pure fp能成功的话,今天已经成了

【在 c******o 的大作中提到】
: 重点在clojure的一致和简单,所有的程序在clojure的眼中都是类似这几个程序的结构
: ,没有例外。
: 只以简单的几种基本数据为重点,通过各种函数转化,再加上无所不能的macro(因为
: clojure/lisp的哲学,数据和程序是一模一样的结构,所以macro用一致的数据方法处
: 理已有的程序,动态改变,重写,几乎是无所不能的,真正强的dsl在这儿)。
: 习惯以后是极简一致后的一种奇怪的感觉,好像一切cs都在那几个秘籍中的感觉。
: 哦,我是抛砖引玉,clojure不是我的主要语言,其他大牛们再说说。

avatar
l*n
26
这个说得好。

【在 c******o 的大作中提到】
: 重点在clojure的一致和简单,所有的程序在clojure的眼中都是类似这几个程序的结构
: ,没有例外。
: 只以简单的几种基本数据为重点,通过各种函数转化,再加上无所不能的macro(因为
: clojure/lisp的哲学,数据和程序是一模一样的结构,所以macro用一致的数据方法处
: 理已有的程序,动态改变,重写,几乎是无所不能的,真正强的dsl在这儿)。
: 习惯以后是极简一致后的一种奇怪的感觉,好像一切cs都在那几个秘籍中的感觉。
: 哦,我是抛砖引玉,clojure不是我的主要语言,其他大牛们再说说。

avatar
z*e
27
你看,当你为了不用oop的pattern而使用fp了之后
很快你又进入了另外一大圈模式之中
这就是问题,我们之所以选择一些东西的目的是为了简化开发
而不是简化了这部分同时复杂化了另外一部分
这其实就是一弯路,最后回头看,还在原地打转转
最后就变成回字的不同写法,自我娱乐一下而已了

【在 c******o 的大作中提到】
: 再说说scala,上面我那个monad的精髓就在于它的通用性,和强大的模式(读作“限制
: ”)
: ,你可以用它来解决很多很多不一样的复杂问题,同时又能帮你在编程/编译/构思的时
: 候剔除很多不必要的错误和弯路。

avatar
e*o
28
哈哈。说的不错

【在 z****e 的大作中提到】
: 你看,当你为了不用oop的pattern而使用fp了之后
: 很快你又进入了另外一大圈模式之中
: 这就是问题,我们之所以选择一些东西的目的是为了简化开发
: 而不是简化了这部分同时复杂化了另外一部分
: 这其实就是一弯路,最后回头看,还在原地打转转
: 最后就变成回字的不同写法,自我娱乐一下而已了

avatar
c*o
29
你写一些就知道了,很清晰,明了。
你觉得java复杂的结构内部是怎么实现的?
只要能拆分的干净(FP),你就能一次只考虑一个部分,然后一切的一切都是那么简单
的东西的组合而已。
觉得复杂是因为无法拆分的强耦合,fp正是对此的解决方案之一。
你非要选的scala/clojure的话,可能更喜欢scala(ML/Haskell系), scala就是宏大
,强力,复杂而专业的美妙,对什么都有解决方案。
其实我觉得两个都很牛,但是思维太不一样,有时候觉得精神分裂了。。。

【在 z****e 的大作中提到】
: 我强烈反对只用这些基础的数据结构
: 我认为object一样自由的数据结构才是王道
: 真正的框架作者应该明白怎样用reflection来窥视object的内部结构
: 就像外科医生一样,而非强迫所有人用那么几种数据结构
: 我相信不同学科应该有自己的数据结构
: 而非被cs所绑架,只用那么几种数据结构
: 这是错误的,dsl应该配合这种趋势
: 这就是为啥应该用非pure fp,比如scala来写框架,而非pure fp来搞
: pure fp能成功的话,今天已经成了

avatar
l*n
30
fp让我脑子里的那部分数学的思维激活了。不然写程序就是调用个库而己。

【在 z****e 的大作中提到】
: 你看,当你为了不用oop的pattern而使用fp了之后
: 很快你又进入了另外一大圈模式之中
: 这就是问题,我们之所以选择一些东西的目的是为了简化开发
: 而不是简化了这部分同时复杂化了另外一部分
: 这其实就是一弯路,最后回头看,还在原地打转转
: 最后就变成回字的不同写法,自我娱乐一下而已了

avatar
c*o
31
这个也是写一些就明白了,真的是会发现很多原来看起来不相关的居然都是一类问题,
一种解决方法。
然后找到这个对应的写法能让你发觉基本啥都被考虑到了,什么都为你准备好了。

【在 z****e 的大作中提到】
: 你看,当你为了不用oop的pattern而使用fp了之后
: 很快你又进入了另外一大圈模式之中
: 这就是问题,我们之所以选择一些东西的目的是为了简化开发
: 而不是简化了这部分同时复杂化了另外一部分
: 这其实就是一弯路,最后回头看,还在原地打转转
: 最后就变成回字的不同写法,自我娱乐一下而已了

avatar
z*e
32
我不否认只用那几种简单啊
但是问题是,现实具有一定的复杂度
我不认为现实的复杂可以被这么简单的结构所取代
这就是为啥我们还在研究物理和生物,因为人和宇宙本身不简单
我们尝试着将它们变简单,问题是,到目前为止,都失败了
所以不可能把这么复杂的东西简单化
你当然可以用简单的方式予以描述,但是这只是它们的一小部分
当你需要其他部分的时候,这些简单的结构马上就会呈现出不适应性来
那这个时候你就很痛苦了,这就是代价
scala自身也处于一种混乱的状态,总是啥都想搞,结果在语言level上应该enforce的
东西
都被放到一般程序员手中去搞,最后搞不定的大有人在
初衷是美好的,现实是残酷的

【在 c******o 的大作中提到】
: 你写一些就知道了,很清晰,明了。
: 你觉得java复杂的结构内部是怎么实现的?
: 只要能拆分的干净(FP),你就能一次只考虑一个部分,然后一切的一切都是那么简单
: 的东西的组合而已。
: 觉得复杂是因为无法拆分的强耦合,fp正是对此的解决方案之一。
: 你非要选的scala/clojure的话,可能更喜欢scala(ML/Haskell系), scala就是宏大
: ,强力,复杂而专业的美妙,对什么都有解决方案。
: 其实我觉得两个都很牛,但是思维太不一样,有时候觉得精神分裂了。。。

avatar
z*e
33
扯蛋,让你几何思维彻底挂了
我几何学得也不好,但是几何就喜欢整各种乱七八糟的结构
cs里面的结构比起人家几何的结构来说,小巫见大巫
如果连object都搞不定,几何就更没戏
你激活的部分只是算术,也就是简单的代数学
甚至都无法深入到抽象代数中去,严格说来只是cs的数学部分
那这个小儿科了,对于真正的数学来说
本来数学也不在乎cs

【在 l**********n 的大作中提到】
: fp让我脑子里的那部分数学的思维激活了。不然写程序就是调用个库而己。
avatar
z*e
34
no
我写了一些之后越发地觉得immutable是扯蛋
那个lilip说得很对
lambda什么还有点用
immutable和monad不用纠结

【在 c******o 的大作中提到】
: 这个也是写一些就明白了,真的是会发现很多原来看起来不相关的居然都是一类问题,
: 一种解决方法。
: 然后找到这个对应的写法能让你发觉基本啥都被考虑到了,什么都为你准备好了。

avatar
z*e
35
顺便我告诉你
java里面的fp在以前其实就是reflection
古德霸那次说shape其实就是用最简单的reflection搞定的

【在 l**********n 的大作中提到】
: fp让我脑子里的那部分数学的思维激活了。不然写程序就是调用个库而己。
avatar
l*n
36
你说的是指proxy吗?

【在 z****e 的大作中提到】
: 顺便我告诉你
: java里面的fp在以前其实就是reflection
: 古德霸那次说shape其实就是用最简单的reflection搞定的

avatar
z*e
37
也算吧,不过感觉只是一小部分

【在 l**********n 的大作中提到】
: 你说的是指proxy吗?
avatar
c*o
38
我只是描写一下我知道的两者的编程哲学,当然不是大家都喜欢。
我现在写的最多的其实是ruby... 工作需要。

【在 z****e 的大作中提到】
: no
: 我写了一些之后越发地觉得immutable是扯蛋
: 那个lilip说得很对
: lambda什么还有点用
: immutable和monad不用纠结

avatar
z*e
39
顺便问一个问题
你上次说了adt的例子
你觉得好吗?
把exception和正常的return value强行捆绑成一类type
这种做法比起object来说简直就是有过之而无所不及啊
太恶劣了,我觉得不可接受
当然fp的教徒会尝试着说服别人这是reasonable的
我反正到目前为止还没觉得有多对哈

【在 c******o 的大作中提到】
: 这个也是写一些就明白了,真的是会发现很多原来看起来不相关的居然都是一类问题,
: 一种解决方法。
: 然后找到这个对应的写法能让你发觉基本啥都被考虑到了,什么都为你准备好了。

avatar
z*e
40
我知道呀,你说得就是问题所在,很精确
我现在在写python,tmd

【在 c******o 的大作中提到】
: 我只是描写一下我知道的两者的编程哲学,当然不是大家都喜欢。
: 我现在写的最多的其实是ruby... 工作需要。

avatar
c*o
41
就举一个例子,自动化测试。
统一一致的输入输出,和纯函数,可是容易测试多了。
很容易对这个exception做一个专门的test case, 和一般的test case一样的形式.
当然,这只是好处的冰山一角。

【在 z****e 的大作中提到】
: 顺便问一个问题
: 你上次说了adt的例子
: 你觉得好吗?
: 把exception和正常的return value强行捆绑成一类type
: 这种做法比起object来说简直就是有过之而无所不及啊
: 太恶劣了,我觉得不可接受
: 当然fp的教徒会尝试着说服别人这是reasonable的
: 我反正到目前为止还没觉得有多对哈

avatar
z*e
42
是啊,问题是如果程序员能预测到的话
那还需要exception做啥?

【在 c******o 的大作中提到】
: 就举一个例子,自动化测试。
: 统一一致的输入输出,和纯函数,可是容易测试多了。
: 很容易对这个exception做一个专门的test case, 和一般的test case一样的形式.
: 当然,这只是好处的冰山一角。

avatar
l*n
43
这个如果滥用了,很不好。程序就不知所以了。fp的exception还是在pattern
matching里用到,不是一种改变程序流程的方法,而是正常的return,因为不能return
null

【在 z****e 的大作中提到】
: 顺便问一个问题
: 你上次说了adt的例子
: 你觉得好吗?
: 把exception和正常的return value强行捆绑成一类type
: 这种做法比起object来说简直就是有过之而无所不及啊
: 太恶劣了,我觉得不可接受
: 当然fp的教徒会尝试着说服别人这是reasonable的
: 我反正到目前为止还没觉得有多对哈

avatar
z*e
44


【在 l**********n 的大作中提到】
: 这个如果滥用了,很不好。程序就不知所以了。fp的exception还是在pattern
: matching里用到,不是一种改变程序流程的方法,而是正常的return,因为不能return
: null

avatar
z*e
45
return null如果你能够预见到
你自然懂得怎么处理,所有的exception之所以存在
都是因为你事先没有预测到

return

【在 l**********n 的大作中提到】
: 这个如果滥用了,很不好。程序就不知所以了。fp的exception还是在pattern
: matching里用到,不是一种改变程序流程的方法,而是正常的return,因为不能return
: null

avatar
l*t
46
老赵你基本不知道自己在说什么。你要不能塌下心来用fp做几个东西永远不知道别人在
说什么。
avatar
z*e
47
你再琢磨一下这个回帖
发信人: coltzhao (coltzhao), 信区: Programming
标 题: Re: What is the difference between Haskell and Clojure
发信站: BBS 未名空间站 (Tue Feb 24 23:40:10 2015, 美东)
我只是描写一下我知道的两者的编程哲学,当然不是大家都喜欢。

【在 l******t 的大作中提到】
: 老赵你基本不知道自己在说什么。你要不能塌下心来用fp做几个东西永远不知道别人在
: 说什么。

avatar
z*e
48
我很清楚滴知道他们在说什么,但是我怀疑你知道不知道我在说什么
我用另外的方式解决,但是我也有些怀疑我的方式是不是正确
log肯定可以,但是exception,可能未必,他们说的这种方式笨拙而且不实用
代码灰常messy,其本质跟try catch木有太大区别
我在琢磨用其他方式来搞定,不过不知道可行不可行哈
算了,这个太复杂了,还是扯蛋吧

【在 l******t 的大作中提到】
: 老赵你基本不知道自己在说什么。你要不能塌下心来用fp做几个东西永远不知道别人在
: 说什么。

avatar
z*e
49
小手我们来扯蛋一下monad吧
coltzhao的例子你想说就是monad对吧?
嘿嘿,哈哈,我觉得很扯蛋,真的很扯蛋
adt整个都是扯蛋

【在 l******t 的大作中提到】
: 老赵你基本不知道自己在说什么。你要不能塌下心来用fp做几个东西永远不知道别人在
: 说什么。

avatar
z*e
50
另外楼主说monad是chain pattern
那还是不是一回事
monad是一个structure
而chain pattern是一个行为模式
这两个倒是经常凑一起出现
avatar
z*e
51
monad倒是很像aop里面的aspect
这就是为啥我前面说的那些东西
aop和fp还有oop到这里凑一块了
小手呢?快来扯蛋
avatar
z*e
52
妈蛋,小手个鸟人又灌废水
好容易说点有趣的
avatar
l*t
53
麻蛋你要讨论那块?

【在 z****e 的大作中提到】
: 妈蛋,小手个鸟人又灌废水
: 好容易说点有趣的

avatar
z*e
54
monad

【在 l******t 的大作中提到】
: 麻蛋你要讨论那块?
avatar
n*p
55
you got it

【在 c******o 的大作中提到】
: 重点在clojure的一致和简单,所有的程序在clojure的眼中都是类似这几个程序的结构
: ,没有例外。
: 只以简单的几种基本数据为重点,通过各种函数转化,再加上无所不能的macro(因为
: clojure/lisp的哲学,数据和程序是一模一样的结构,所以macro用一致的数据方法处
: 理已有的程序,动态改变,重写,几乎是无所不能的,真正强的dsl在这儿)。
: 习惯以后是极简一致后的一种奇怪的感觉,好像一切cs都在那几个秘籍中的感觉。
: 哦,我是抛砖引玉,clojure不是我的主要语言,其他大牛们再说说。

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。