请在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的一个特性。但TypeScript证明了,一个健全的类型系统可以为灵活且强大的类型无语言生态系统增添巨大价值。

附言,前几天我在2017年Clojure大会上看到了Zach Tellman关于抽象技术的演讲。我记得他分享了一个观点,在一般的Lisp语言家族中,包括Clojure在内的相当灵活,这在某种程度上阻碍了它更成功。
TypeScript并不能“证明”类型系统“能增添巨大价值”,但我认为您评论中的关键点在于“对于某些团队...类型系统是一个重要因素”。而对于更看重灵活性的团队来说,像Clojure这样的语言将比Scala更适合。

在我工作的公司,我们尝试引入Scala,但类型系统让每个人都感到不适应,所以我们转向了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 提供的,它可以与Servlet兼容,用于和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。我们针对一个依赖于 SocketIO 的大量应用程序直接使用 Netty(通过 Java 交互)。

我们在大约十二个服务中使用了大量其他库。其中一些在服务器端渲染 HTML -- 我们几乎所有 HTML 渲染都使用 Selmer,一个地方使用 Hiccup 从 Clojure 数据渲染 HTML 片段。

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

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

顺便问一下,我可以建议这个论坛的版主将一个帖子固定到顶,供具备生产经验的 clojure 开发者分享技术堆栈和见解吗?

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

编辑
我认为这里存在误解
“静态类型,这对于有几位以上开发者的项目来说非常有益”
“Clojure 核心团队没有计划为 Clojure 开发静态类型,因为我们认为这不是必要的。我们的努力集中在规范(《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 规范并提供基于其键及其对应子规范的建议。即帮助我使用 ::dog 如其作者所打算的那样,而无需查阅其文件。

TypeScript 在编译后不存在,其输出是 JavaScript。TS 的最大好处是它可以帮助你更快地理解他人的代码(并提供一些避免误用的帮助,但这只是次要的)。
我完全看不出您的评论与原始问题有什么关联,但如果您是询问集成函数定义的规范,那这正是我们在规范2中一直在研究的内容。
by
对于您下面的评论,还有其他解释方式吗?
“我是一位静态类型的粉丝,这对有多个开发人员的项目来说非常有帮助。”

TypeScript也开启了大量的编辑器和IDE工具功能。我认为TypeScript是发生在JavaScript上的最好的事情。

按照我的理解,这意味着你将不得不不断地与之前既没有编写也没有审查过的大量代码一起工作。对于企业级应用来说,通常有成打的DTO具有30多个键,命名非常不一致。典型的思考过程是:“好吧,我们的函数将得到一个‘sales-deal’ DTO,我需要将其转换成‘financing-deal’并发送给分析,‘sales-deal’上的利润边际属性叫什么?是‘margin’、‘markup’还是只是一个 plain ‘rate’?而且它已经是十进制了吗?还是有销售交易的组合费率分项DTO?”然后对于‘financing-deal’也是同样的问题...

我完全同意“对JavaScript最好的事情”的部分。遗憾的是,尝试ClojureScript感觉就像是回到了JS - 这不是一件好事。我欣赏spec的力量,以及它在运行时和测试中所起到的作用。我现在想要做的是将所有这些力量集成到我的IDE中,以帮助我编写代码。如果你还没有写出来,那就没有什么可以运行或测试的。

by
正如我在之前的评论中所说的,我非常欣赏spec,以及它在运行时和测试中所起到的作用。我现在想要做的是将所有这些力量集成到我的IDE中,以帮助我编写代码。如果你还没有写出来,那就没有什么可以运行或测试的。
by
附言。为了更好地说明我要找的内容,请查看这个库: https://github.com/vriad/zod

它让你可以在设计/编译时定义类似spec的schema,同时也能被TS编译器理解和使用。
// spec 定义 - 在TS编译后存在,可以用来验证schema
const dogSchema = z.object({
  name: z.string(),
});

  neutered: z.boolean(),
// 实时验证schema
const cujo = dogSchema.parse({
  name: 'Cujo',
  neutered: true,

}); // 通过,返回 Dog
// TypeScript 类型定义 - 在TS编译后不存在
/*
等价于
类型 Dog = {
  name: string;
  neutered: boolean;
}
*/

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