2024 Clojure现状调查中分享您的想法!

欢迎!请访问关于页面获取更多关于这个网站的信息。

+2
Clojure

我是 Clojure 的忠实粉丝,因为它的简单性、多线程模型、语言稳定性以及出色的 Java 互操作性。但我对静态类型更情有独钟,对于项目有多名开发者时,静态类型极有帮助。

TypeScript 为 JavaScript 添加了一个非常好的类型检查层,可以在编译时消除许多编程错误。它也打开了大量的编辑器和 IDE 工具的可能性。我可以说,TypeScript 是 JavaScript 最伟大的事情之一。

我想知道 Clojure 核心团队或任何具有强大能力和资源的机构是否正在考虑开发类似于 TypeScript 的 Clojure 工具?

如果不行,为什么?

谢谢

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》)感兴趣,它基于 specs 的静态类型检查。据我所知,这两个工具都不太广泛使用,也都没有特别活跃的开发活动。


编辑
感谢您的回答。

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

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

我相信很多Clojure粉丝都处于与我同样的境地。他们喜欢Clojure,并希望用它做严肃的工作,但因为缺乏类型检查,不得不选择其他语言。为了澄清,我的意思并不是Clojure不是用于严肃工作的语言。我的意思是,对于某些团队或公司来说,类型系统在选择语言或技术栈进行严肃项目时是一个重要的因素。

我明白类型无界是Clojure的一个特性。但TS证明了,一个健全的类型系统可以为灵活且强大的无类型语言生态系统带来巨大的价值。

附带说明,前几天我在2017年的一次Clojure会议上遇到了关于抽象的Technical Speech,作者是Zach Tellman。我记得他分享了一个观点,在Lisp语言家族中,包括Clojure在内,太过灵活,这可能在某种程度上是其难以更成功的一障碍。
TypeScript并没有“证明”类型系统“增加了巨大的价值”,但我觉得你评论中的关键点在于“对于一些团队来说,类型系统是一个重要的因素”。而对于那些重视灵活性的团队来说,像Clojure这样的语言会比Scala更适合。

在我工作的公司,我们尝试引入Scala,但类型系统让每个人都感到很沮丧,所以我们改用了Clojure。那是在将近九年之前,现在我们运行着四十多个在线约会网站,拥有数百万客户,完全使用Clojure后端,我们发现Clojure提供的强大和灵活性使我们能够非常迅速地改变和增强系统。我们在生产中使用Spec进行输入验证,以及在测试中用于各种事情,或许有些人会依赖于类型系统,但由于Spec可以以类型系统无法描述的方式同时描述形状和行为,因此它更加强大。
by
感谢分享您的见解。

我可以询问您正在使用哪个Clojure网络框架吗?

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

这也是我们选择了Scala并使用Akka http的部分原因。但我仍然非常希望将Clojure应用于其他项目,正如您提到的那些原因。

了解一些您的技术栈将对非常有益。谢谢。
by
我想补充一下,clj-kondo最近增加了一种简单类型检查的形式,这也值得一看: https://github.com/borkdude/clj-kondo/blob/master/doc/types.md
by
关于您的评论,很多人在成功地使用Aleph进行生产。所以我认为这是一个很安全的赌注。

尽管如此,我相信目前最积极维护的HTTP服务器是Pedestal,它支持Netty(以及其他): https://github.com/pedestal/pedestal

否则,Clojure中最受欢迎且积极维护的选择将是ring https://github.com/ring-clojure/ring,它附带ring-jetty-adapter,可与其Jetty服务器一起使用。

进一步阅读,我建议您阅读这篇指南: 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的应用程序。

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

我们最初在2015年考虑使用ClojureScript作为可能的前端,但当时生态系统很粗糙,工具似乎非常脆弱(那时候,Clojure和ClojureScript之间的差异比现在大得多)。因此,我们决定使用JS和React.js / Redux / Immutable.js等构建面向客户的应用程序。我们拥有一个负责JS的前端团队。

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

顺便问一下,我可以建议这个论坛的版主将有关有生产经验clojure开发者的帖子固定在首页吗?以分享技术栈和见解?

我认为这对社区非常有帮助。
作者:
作者:
非常有帮助,谢谢。
作者:
编辑了 作者:
我认为这里有一个误解。
"静态类型对于有多位开发者参与的项目来说非常有帮助"。
“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))))

并且让智能感知获取  :happy-puppy-co.api/dog 规范,并基于其键及其相应的子规范提供提示。换句话说,帮助我按作者意图使用 ::dog,而不必去查看其文件。

TypeScript 在编译后不存在,其输出是JavaScript。TS的最大好处是它可以帮助你更快地理解他人的代码(并且在避免误用方面也提供了一些帮助,但这 不是主要的)。
我觉得你的评论与原始问题并不相符,但如果你是在询问与函数定义集成的规范,那正是我们在规范2中寻求的东西。
那么,以下内容还能作何解释呢?

“我是静态类型的忠实粉丝,这在拥有多个开发者的项目中非常有帮助。

TypeScript...还开辟了许多编辑器/IDE工具的用途。我认为TypeScript是发生给JavaScript的最好的事情。”

据我所知,这意味着必须持续处理大量你或你的团队之前没写过也没审查过的代码。企业应用程序通常会有数十个具有30多个键的DTO,并且命名非常不一致。典型的思维过程是这样的:“好吧,我们的函数将获得一个‘sales-deal’ DTO,我需要将其转换为‘financing-deal’并发送到分析中,‘sales-deal’中的利润率属性被称为什么?是‘margin’、‘markup’还是‘rate’?以及它是否已经是小数形式,还是销售交易仍将其作为详细的项目化率组件子DTO?然后为‘financing-deal’提出相同的问题……”

我完全同意“发生给JavaScript的最好事情”这部分。遗憾的是,尝试ClojureScript感觉像回到了JavaScript——不好的体验。我非常欣赏spec的力量,以及它在运行时和测试中帮助我的能力。我现在想做的事情是,将这种力量全部整合到我的IDE中,帮助我编写代码。如果我没有写出来,就没有任何事情可以运行或测试。
顺便说一句,为了更好地说明我在寻找什么,请参阅这个库: https://github.com/vriad/zod
它允许你定义类似于spec的架构,这些架构在设计和编译时也由TS编译器理解和使用。

//spec定义 - 在TS编译之后存在,可用于验证架构
const dogSchema = z.object({
  name: z.string(),
  绝育:z.boolean()
});

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

// TypeScript 类型定义 - 在 TS 编译后不存在
type Dog = z.infer<typeof dogSchema>;
/*
等价于
type Dog = {
  name: string;
  neutered: boolean;
}
*/

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