2024年Clojure状态调查!中分享您的想法。

欢迎!请参阅关于页面,了解更多有关其工作方式的信息。

+2
Clojure

我是Clojure的爱好者,因为它简洁、多线程模型、语言稳定性和优秀的Java交互。但我也对静态类型非常崇拜,这对于有多个开发者的项目来说非常有帮助。

TypeScript为JS添加了一个出色的类型检查层,这可以在编译时消除许多编程错误。它还开启了许多编辑器/IDE工具的可能性。我会说TypeScript是发生给JS的最佳事情。

我在想,Clojure核心团队或者任何具有严重能力和资源的团体是否正在考虑为Clojure开发类似TypeScript的工具?

如果不是,为什么?

谢谢

1个回答

+5

Clojure核心团队没有计划为Clojure开发静态类型,因为我们认为它不是必要的。我们的努力集中在spec(《https://clojure.org/about/spec》)上,它为描述Clojure数据函数的选填规格提供支持。

Typed Clojure项目(《https://typedclojure.org/》)是由Ambrose Bonnaire-Sergeant发起的,当时他正在攻读博士等学位。您也许也感兴趣Spectrum(《https://github.com/arohner/spectrum》)是一个基于spec的静态类型检查项目。据我所知,这两个项目都没有得到广泛使用,开发也很不活跃。


编辑了
感谢你的回答。

我们研究了规范,发现这主要是运行时的问题。这对文档和测试非常有帮助,但在我看来,它无法完成类型系统所能做到的事情。

我们是一家小型创业公司,有几个程序员。开始时,我们认真考虑了Clojure,但最后决定使用Scala,因为它的强大类型系统。当需要JavaScript时,我们也使用TypeScript。

我相信许多Clojure粉丝都和我处于同样的情况。他们喜欢Clojure,并希望用它来做一些实际的工作,但不得不因为缺乏类型检查而选择其他语言。为了阐明,我并不认为Clojure不是一款适合做实际工作的语言。我的意思是,对于一些团队或公司来说,类型系统在选择语言或技术栈进行重要项目时是一个重要因素。

我理解Clojure无类型是一个特性。但TS证明,一个良好的类型系统可以为灵活而强大的无类型语言生态系统增加巨大价值。

顺便说一下,有一天我在2017年Clojure会议上的一个关于抽象的演讲中遇到了Zach Tellman的技术演讲。我记得他分享了一个观点,即在Lisp语言家族中,包括Clojure在内,过于灵活,这在某种程度上阻碍了它的成功。
TypeScript并不“证明”类型系统“增加了巨大价值”,但我觉得你评论中的关键点是“对于某些团队...类型系统是一个重要因素”。而对于那些重视灵活性的团队,像Clojure这样的语言将会是一个更好的选择。

在我工作的公司,我们尝试引入Scala,但类型系统让大家都很抵触,所以我们转向了Clojure。那是在将近九年之前,现在我们用Clojure的后端运行了四十来个在线约会网站,拥有数百万客户,我们发现它的强大和灵活性使我们能够非常快速地改变和改进系统。我们在生产中使用Spec进行输入验证,以及在测试中针对各种可能依赖于类型系统的情况,但由于它能够以一种类型系统不能的方式描述形状和行为,所以它更加强大。
by
感谢您分享您的见解。

我可以问一下您正在使用哪个Clojure Web框架吗?

REST API服务是我们服务的关键部分。我们曾是Netty的大粉丝,在成立自己的店铺之前,我们在Netty上运行了一个自定义构建的REST API框架。因此,当我们开始时,我们想选择一个基于Netty的Web/REST框架。我们对Clojure的框架进行了评估,发现大多数Clojure网络框架都没有积极维护或者缺乏生产案例。我们最感兴趣的一个,aleph,似乎也被遗弃了。

这也是我们选择Scala的原因之一,因为Akka http。但我仍然非常希望根据自己的原因在其他项目中引入Clojure。

了解一下您的技术栈对我会非常有帮助。谢谢。
by
我还得加上,clj-kondo最近增加了一种简单的类型检查形式,这也值得一看:https://github.com/borkdude/clj-kondo/blob/master/doc/types.md
by
至于您的评论,许多人已经成功在产品中使用Aleph,所以我认为它是一个不错的选择。

换句话说,我认为支持netty(和其他)的最积极维护的HTTP服务器可能是Pedestal:https://github.com/pedestal/pedestal

否则,在Clojure中,维护最积极的流行选择将是ring https://github.com/ring-clojure/ring,包含用于与Jetty服务器一起使用的ring-jetty-adapter。

阅读以上指南,我建议您阅读此指南:https://purelyfunctional.tv/mini-guide/clojure-web-servers/

另外,请注意,您可以直接使用Netty,Clojure的Java交互相当好,比Scala好得多。因此,直接使用Java服务器接口也是一个不错的选择。
谢谢。

正如你所说的,如果我们决定用Clojure开始做些事情,我们可能会直接使用Netty。我们在Netty之上进行了Java互操作实验,一切都很顺利。裸机方法会给我们带来更多的灵活性。
我们没有在Clojure中使用任何“框架”。我们使用了一系列库的组合。Ring几乎是一切的核心。我们几乎在所有应用程序中使用Compojure进行路由(我们在一个中使用Bidi)。我们主要使用嵌入式Jetty网络服务器(通过“标准”Ring适配器),但所有我们的应用程序也可以根据命令行参数和环境变量启动http-kit。我们直接使用Netty为重用SocketIO的一个应用程序(通过Java互操作)。

我们在大约 dozen 个服务中使用了大量其他库的不同组合。其中一些是服务器端渲染的HTML -- 我们使用Selmer进行几乎所有HTML渲染,在一个地方使用Hiccup从Clojure数据渲染HTML片段。

我们最初在2015年把ClojureScript当作一个可能的前端,但是生态非常粗糙,工具感觉也不够健壮(并且当时Clojure和ClojureScript之间的差异比现在要大得多)。所以我们决定使用JS和React.js / Redux / Immutable.js等构建我们的客户应用。我们有一个专门的前端团队致力于JS。

如果我们今天再次进行相同的项目,我认为我们会再次将ClojureScript作为严肃的竞标者进行评估,因为过去 4-5 年生态系统发生了巨大的变化。我不知道到那时我们会选择JS还是cljs。
谢谢。非常有帮助。我们可能也会考虑Clojurescript。

顺便问一下,我可以建议这个论坛的版主将有关 clojure 开发者生产经验的线程置于顶部,以便他们分享技术堆栈和见解吗?

我认为这对社区非常有帮助。
非常 helpful。谢谢

编辑了
我认为这里可能存在一些误解
"静态类型,这对于拥有多个开发者的项目非常有用"
"Clojure 核心团队没有计划为 Clojure 开发静态类型,因为我们不认为它有必要。我们的努力集中在 spec (https://clojure.org/about/spec)"

AFAIU,如果我有误,请指正,发帖者请求的是“设计时类型”,而答案涉及的是 Java 所理解的静态类型。

我和,可能还有提问者都在寻找的是编写
 
(defn describe-dog [^:happy-puppy-co.api/dog dog]
      (println (str (:breed dog) (:age dog))))

让 intellisense 检索  :happy-puppy-co.api/dog spec 并根据其键及其相应的子规范提供提示。即帮助我像它的作者所期望的那样使用 ::dog,而无需查看其文件。

TypeScript 编译后不存在,其输出是 JavaScript。TS 的最大好处是它可以帮助你快速理解其他人的代码(并且还提供了一些避免误用的帮助,但这只是次要的)。
我不太清楚您的评论是否与原始问题一致,但如果您是在询问与函数定义集成的规格说明,那么这正是我们在规范2中关注的内容。
那么,以下内容还可以如何解释呢?

“我是静态类型的粉丝,这对于拥有多个开发人员的项目非常有帮助。

TypeScript……也开启了许多编辑器/IDE工具的可能性。我说 TypeScript 是JS发生的最好的事情。”

据我所知,这意味着您需要不断与大量代码打交道,这些代码既不是您写的,也不是您的团队之前编写或审核过的。企业应用程序通常有数十个具有30+键值的dto,命名非常不统一。典型的思维过程是“好吧,我们的函数将获得'sales-deal' dto,我需要将其转换为'financing-deal'并发送到分析,'sales-deal'上的利润边际属性叫什么?它是'margin'还是'markup',或者是简单的'rate'?它是十进制数吗,还是销售dto交易仍然将其作为详细的率组件子dto?”然后同样的问题适用于'financing-deal'...

我完全赞同“对于JS发生的最好的事情”这部分。遗憾的是,尝试ClojureScript感觉像是回到了JS——这并不好。我欣赏spec的强大功能,以及它在运行时和测试中的帮助。我现在想要做的是将所有的这些功能都集成到我的IDE中,以便在编写代码时也能提供帮助。如果我没有写过代码,那么就没有什么可以运行或测试的。
顺便说一句,为了更好地说明我要找的内容,请查看这个库:https://github.com/vriad/zod
它允许您在设计和编译时定义类似于spec的模式,这些模式也可以被TS编译器所理解和使用。

// 规范定义 - 在TS编译后存在,可用于验证模式
const dogSchema = z.object({
  name: z.string(),
  neutered: z.boolean(),
});

// 在运行时验证模式
const cujo = dogSchema.parse({
  name: 'Cujo',
  neutered: true,
}); // 通过,返回 Dog

// TypeScript 类型定义 - 在TS编译后不存在
购买 Dog = z.infer<typeof dogSchema>;
/*
相当于
类型 Dog = {
  name:字符串;
  sterilized:布尔值;
}
*/

// 使用推断的类型进行编译时类型检查和设计时智能感知
const fido:Dog = {
  name: 'Fido',
}; // TypeError: 缺少必填属性 'sterilized'
...