请分享您的想法到2024 Clojure状态调查!

欢迎!请查看关于页面以了解更多关于如何使用的详细信息。

+2

我是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) 感兴趣,它基于规格的静态类型检查。据我所知,这两个都并未广泛使用,也没有特别活跃的开发。


编辑了
感谢您的回答。

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

我们是家小型的初创公司,有几名程序员。当我们开始时,我们认真考虑了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的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。我们对一个依赖于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开发者生产经验分享技术栈和见解的线程置顶吗?

我想这对社区会很有帮助。
 avatar
 avatar
非常有帮助。谢谢
 avatar
编辑了
我认为这里可能有误解
"静态类型,对于拥有几名以上开发者的项目非常有帮助"
“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 spec",并基于其键及其相应子spec提供提示。也就是说,帮助我按其作者意图使用::dog,而无需查看其文件。

TypeScript在编译后不存在,其输出为JavaScript。TS最大的好处是它可以帮助你更快地理解他人的代码(并且提供一些避免误用的帮助,但这只是次要的)。
我对你的评论是否与原始问题相符并不清楚,但如果你在询问与函数定义集成的规范,那正是我们在规范2中考虑的内容。
那么,以下内容还有什么其他解释方式呢?

"我是一名静态类型的狂热分子,这对拥有超过几个开发者的项目非常有帮助。

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

在我看来,这意味着你将不得不不断与大量代码打交道,这些代码既不是你写的,也不是你的团队之前写的或审查过的。对于企业应用来说,拥有数十个具有30多个键的 DTO 程序是非常常见的,并且命名非常不统一。典型的思维过程是这样的:"好吧,我们的函数将获得一个 'sales-deal' DTO,我需要将其转换为 'financing-deal' 并发送到分析系统,'sales-deal' 中的利润率属性叫什么?是 'margin'、'markup' 还是单纯的 'rate'?它是十进制数吗?或者销售 DTO 仍然有它作为一个细分的项目的子 DTO 的比率组件?" 然后,对 'financing-deal' 也要问同样的问题...

我完全赞同 "JS 发生过的最好的事情" 这部分。遗憾的是,尝试 ClojureScript 的感觉就像回到了 JS - 这并不是好事。我欣赏 spec 的强大功能,以及它在运行时和测试中帮助我的方式。我现在想做的事情是把所有这些功能都集成到我的 IDE 中,以帮助我编写代码。如果我没有写代码,就没有可以运行或测试的东西。
顺便说一句,为了更好地说明我想要的东西,请查看这个库: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

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

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