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

欢迎!请查阅 关于 页面了解有关这个网站的更多信息。

+2
Clojure

我是 Clojure 的忠实粉丝,因为它的简单性、多线程模型、语言稳定性和优秀的 Java 交互。但我也是静态类型的超级粉丝,这对拥有多于几个开发者的项目非常有帮助。

TypeScript 为 JS 增加了一层出色的类型检查,这有助于在编译时消除许多编程错误。它还开辟了许多编辑器/ ide 工具的可能性。我会说这是 JavaScript 发展史上最伟大的事情之一。

我想知道 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),这是一个基于 specs 的静态类型检查工具。据我所知,这两个工具都未被广泛使用,并且在开发上不是特别活跃。


修改
感谢回答。

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

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

我相信许多Clojure粉丝和我有相同的经历。他们喜欢Clojure,并希望将其用于严肃的工作,但由于缺乏类型检查,不得不选择其他语言。为了澄清,我并不是说Clojure不是一个用于严肃工作的语言。我的意思是,对于某些团队或公司来说,类型系统在选择语言或技术栈为严肃项目时是一个重要的因素。

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

顺便说一下,前几日我在2017年的Clojure会议上,听到了扎克·特林曼(Zach Tellman)关于抽象的科技演讲。我记得他分享了一个观点,在教育Lisp语言家族,包括Clojure在内,过于灵活可能会成为一种阻碍它更成功发展的因素。
TypeScript并没有“证明”类型系统“增加了巨大的价值”,但我觉得你评论中的关键点在于“对于某些团队...类型系统是一个重要因素”。而对于重视灵活性的团队来说,像Clojure这样的语言将比Scala更适合。

在我工作的公司,我们尝试引入Scala,但类型系统使每个人都感到很不舒服,所以我们改用了Clojure。那是在近九年前,现在我们在Clojure后端运行了四十多个在线约会网站,拥有数百万客户,我们发现它提供的强大和灵活性使我们能够非常快速地改变和增强系统。我们在生产中大量使用Spec进行输入验证,以及在测试所有那些一些依赖类型系统的事情上,Spec更加强大,因为它可以描述形状和行为的组合,这在类型系统中是不能做到的。
by
谢谢您分享您的见解。

我能问问您在用的Clojure Web框架是哪个吗?

REST API服务是我们服务的关键部分。我们曾是Netty的忠实粉丝,之前在我们开始自己的业务之前,我们曾在Netty上运行自定义构建的REST API框架。因此,当我们开始时,我们希望采用基于Netty的Web/REST框架。我们评估了Clojure的框架,发现大部分Clojure Web框架都不是积极维护的或者没有生产案例。我们最感兴趣的一个,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服务器接口也不是太差的选择。
by
谢谢。

正如你所说,如果我们决定从Clojure开始做一些事情,我们可能会直接使用Netty。我们在Netty之上进行了Java互操作实验,一切都很顺利。裸机方法将给我们带来更大的灵活性。
by
我们不使用任何“框架”来构建Clojure。我们使用库的组合。Ring是几乎所有事物的核心。我们在几乎所有应用中都使用Compojure进行路由(我们在一个应用中使用Bidi)。我们主要使用内嵌的Jetty web服务器(通过“标准”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年里发生了巨大的变化。我不确定在那个时刻我们会选择JS还是cljs。
by
谢谢,这非常有帮助。我们也许会考虑使用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))))

让智能提示抓取 :happy-puppy-co.api/dog spec并根据其键及其相应子spec提供提示。例如,帮助我按照作者的本意使用 ::dog,而无需查看其文件。

TypeScript编译后不存在,其输出是JavaScript。TS的最大优点是它可以帮助你更快地理解他人的代码(并提供了避免误用的帮助,但这只是次要的)。
by
对我来说,你的评论与原始问题是否一致并不完全清楚,但如果你在询问与函数定义集成的规范,那正是我们在规范2中正在考虑的事情。
by
那么,以下内容还有其他什么含义吗?

我非常喜欢静态类型,这对于有多个开发者的项目来说非常有帮助。

TypeScript也开辟了许多编辑器/IDE工具的可能性。我认为TypeScript是JS发生过的最好的事情。

在我看来,这意味着你必须一直与大量你或你的团队之前没有编写或审核过的代码一起工作。企业应用通常有几十个具有30个以上键的dtos,且命名非常不一致。典型的思维过程是:“好,我们的函数将获取一个‘sales-deal’ dto,我需要将其转换为‘financing-deal’并发送给分析,‘sales-deal’上的利润率属性叫什么?是‘margin’、‘markup’还是简单的‘rate’?它已经是小数还是sales-deals仍然有作为订单列表组件子dto的详细费率?”然后对于‘financing-deal’……

我完全同意“对JS来过最好的事”的部分。遗憾的是,尝试ClojureScript感觉像是回到了JS - 这不好。我欣赏spec的强大之处,以及它如何帮助我在运行时和测试中。我现在想做的事是将所有这些功能都集成到IDE中,以帮助我编写代码。如果没有写出来,根本就没有什么可以运行或测试的。
by
顺便说一下,为了更好地说明我所寻找的东西,请查看这个库: https://github.com/vriad/zod
它允许你在设计/编译时定义类spec模式的架构,同时TypeScript编译器也能理解和使用。

//规范定义 - 在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: string;
  neutered: boolean;
}
*/

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