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

欢迎!请参阅关于页面获取更多有关如何使用本网站的信息。

+2投票
Clojure

我是Clojure的忠实粉丝,因为它的简洁性、多线程模型、语言稳定性和优秀的Java互操作性。但我对静态类型更加着迷,它对于多开发者的项目非常有帮助。

TypeScript为JavaScript增加了一层出色的类型检查功能,有助于在编译时消除许多编程错误。它还开启了大量的编辑器/IDE工具的可能性。我认为TypeScript是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),它是基于spec的静态类型检查。据我所知,这两个都不被广泛使用,也不是特别活跃的开发项目。

by
edited by
感谢您的解答。

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

我们是一家小型初创公司,有几位程序员。当我们开始时,我们认真考虑了Clojure,但最终我们决定采用Scala来解决其强大的类型系统。在需要JavaScript时,我们也使用TypeScript。

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

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

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

在我工作的地方,我们尝试引入Scala,但类型系统对每个人都非常不具吸引力,所以我们转而使用Clojure。那是近九年前的事了,现在我们运营着几十个在线约会网站,拥有数百万客户,完全采用Clojure后端,我们发现它提供的强大和灵活性使我们能够非常快速地改变和改进系统。我们在生产中大量使用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。所以我会认为这是一个保险的选择。

话虽如此,我相信支持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。我们在一个高度依赖SocketIO功能的应用程序中直接使用Netty(通过Java互操作)。

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

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

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

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

我认为这将对社区非常有帮助。
我不会将其固定,但在https://ask.clojure.org/index.php/8280/what-is-your-clojure-and-clojurescript-stack》有一个技术栈问题。
非常有帮助。谢谢

编辑
我想这里可能存在误解
"静态类型,这对于有多个开发者的项目非常有帮助"
"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。TS 最大的好处是它可以帮助你更快地理解他人的代码(并提供一些避免误用的帮助,但这居次要地位)。
by
我看不出您的评论与原始问题有什么关联,但如果您是在询问与函数定义集成的规范,那么这正是我们在规范2中考虑的事情。
by
那么,以下是如何解释的呢?

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

TypeScript ... 也为编辑器/IDE工具提供了很多可能性。我想说,TypeScript是JS发展史上最好的事情。”

 从我理解来看,这意味着必须不断地处理大量既不是你、也不是你的团队以前编写或审查过的代码。对于企业应用来说,拥有数十个具有30多个键且命名非常不一致的DTO是典型的。典型的思考过程是这样的:“好吧,我们的函数将得到一个“sales-deal”的DTO,我需要将其转换为“financing-deal”并发送给分析,我们在“sales-deal”上称利润率为‘margin’、‘markup’还是单纯‘rate’?并且它是十进制还是作为逐项明细率的子DTO?" 然后同样的问题应用于“financing-deal”...

我完全同意“TypeScript是JS发展史上最好的事情”这一部分。遗憾的是,尝试使用ClojureScript就像回到JS一样——这并不好。我赞赏spec的力量,以及它如何在运行时和测试中帮助我。我现在想做的事情是,将所有的力量都嵌入到我的IDE中,以帮助我编写代码。如果你还没有编写代码,就没有东西可以运行或测试。
by
顺便说一句,为了更好地说明我在找什么,请查看这个库: https://github.com/vriad/zod
它允许你在设计/编译时间定义规范似的模式,这些模式也能被TS编译器在设计和编译时理解和使用。

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

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

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

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