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

欢迎!请参阅关于页面,了解有关此处功能的更多信息。

+2
Clojure

我是Clojure的大粉丝,因为它的简洁性、多线程模型、语言稳定性以及与Java的出色互操作性。但我对静态类型更感兴趣,这对于多开发者的项目极有帮助。

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

我在想,Clojure核心团队或任何具备严肃能力和资源的团体是否考虑为Clojure开发类似TypeScript的东西?

如果不是,为什么?

谢谢

1 个答案

+5

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

类型化的Clojure项目(《https://typedclojure.org/》)是Ambrose Bonnaire-Sergeant在攻读博士学位期间进行的一项相当大的努力。您可能还会对Spectrum(《https://github.com/arohner/spectrum》)感兴趣,它基于spec进行静态类型检查。据我所知,这两个都不被广泛使用,而且发展并不活跃。


编辑了
感谢您的回答。

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

我们是一家小型初创公司,有几名程序员。刚开始时,我们认真考虑了Clojure,但最终我们决定使用Scala,因为它的类型系统很强大。我们也使用TypeScript来处理需要JavaScript的情况。

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

我明白Clojure的无类型是其一个特性。但TypeScript证明了良好的类型系统可以给灵活而强大的无类型语言生态系统带来巨大的价值。

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

在我工作的公司,我们尝试引入Scala,但类型系统让每个人都望而却步,所以我们转向了Clojure。那是在九年前,现在我们运行着四十多个在线约会网站,拥有数百万客户,全部使用Clojure作为后端。我们发现Clojure提供的强大功能和灵活性使我们能够非常快速地改变和增强系统。我们在生产中大量使用Spec进行输入验证,以及在测试中用于各种事情,这些事情有些人可能依赖于类型系统,但它更强大,因为它可以描述形状和行为的各个方面,这是类型系统所不能的。
感谢您分享您的见解。

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

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

这也是我们选择Scala(因为Akka http)的原因。但出于您提到的原因,我仍然非常希望在其他项目中引入Clojure。

了解您的技术栈会非常有帮助。谢谢。
我还想补充,clj-kondo最近增加了一种简单的类型检查形式,这也值得一看:[链接](https://github.com/borkdude/clj-kondo/blob/master/doc/types.md)
关于您的评论,很多人都成功地在生产中使用Aleph。所以我认为这是一个相对安全的赌注。

话虽如此,我相信目前最积极维护的、支持Netty(及其他)的HTTP服务器可能是Pedestal:[链接](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功能的应用(通过Java互操作)。

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

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

如果今天我们再次进行同样的项目,我认为我们会再次评估ClojureScript作为一个严肃的竞争者,因为在过去4-5年中,生态系统已经发生了巨大的变化。我不知道届时我们会选择JavaScript还是cljs。
谢谢。这非常有帮助。我们可能也会考虑Clojurescript。

顺便问一下,我能建议这个论坛的版主把一个关于 clojure 开发者有实际生产经验分享技术栈和见解的线程置顶吗?

我认为这对社区会有很大帮助。
非常有帮助。谢谢

编辑了
我认为这里有一种误解
"静态类型,对多人项目的帮助极大"
"Clojure 核心团队没有计划为Clojure实现静态类型,因为我们认为不是必要的。我们的努力集中在spec(《https://clojure.org/about/spec)》上")

按照我的理解,如果有错误请纠正,发帖者在询问“设计时类型”,而答案涉及到Java所理解的静态类型。

我要找的,可能是问题作者也在找的是写
 
(defn describe-dog [^:happy-puppy-co.api/dog dog]
      (println (str (:breed dog) (:age dog))))

并让intellisense获取并拾起  :happy-puppy-co.api/dog spec,并基于其键及其各自的子spec提供提示。也就是说,帮助我像其作者预料的那样使用 ::dog,而不必查看其文件。

TypeScript 编译后不存在,其输出是JavaScript。TypeScript的最大优点是它可以帮助你更快地理解他人的代码(并在某种程度上避免误用,但这只是次要的)。
by
我不认为你的评论与原始问题相符,但你如果是询问与函数定义集成的规范,这在规范2中是我们正在考虑的。
by
那么以下内容还有什么别的解释方式吗?

"我是一个……静态类型的粉丝,这对拥有多个开发人员的项目来说非常有帮助。

TypeScript 开发工具和IDE功能也打开了众多可能性。我可以说,TypeScript 是历史上对JS最好的事."

 根据我的理解,这意味着您必须始终面对大量的代码,这些代码 neither you, nor your entire team wrote or reviewed previously。企业级应用通常有数十个具有30+个key的dtos,并且命名非常不一致。典型的思维过程是这样的:"好吧,我们的函数将接收'sales-deal' dto,我需要将其转换为'financing-deal'并发送到数据分析,那么'ales-deal'上的利润率属性叫什么?它是'margin'还是'market'还是简单的'rate'?而且它是已十进制的吗,还是sales-deals作为详细列表的子dto仍然有它?" 然后,对于'financing-deal'也是同样的问...

我完全同意它是JS所发生过的最好的事情这一说法。不幸的是,尝试ClojureScript感觉就像回到了JS——并不好。我欣赏spec的力量,以及它在运行时和测试中的帮助。我现在想做的事情是,利用这些力量并将其集成到我的IDE中,这样也有助于我编写代码。如果我没有编写它,那么就没有什么可以运行或测试的。
by
顺便一提,为了更好地说明我正在寻找的内容,请查看这个库:https://github.com/vriad/zod
它允许您定义类似spec的模式,这些模式在设计和编译时间也被TS编译器理解和可用。

// spec定义存在在TS编译后可以用以验证模式
const dogSchema = z.object({
  ormap: z.string(),
  neutered: z.boolean(),
});

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

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

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