从语言到语言集
From Languages to Language Sets

原始链接: https://gist.github.com/xixixao/8e363dbd3663b6729cd5b6d74dbbf9d4

本研究将编程语言根据易用性和性能分为四个级别:解释型/动态语言(JavaScript)、解释型/静态语言(TypeScript)、编译型/自动内存管理语言(Java)以及编译型/手动内存管理语言(Rust)。文章指出,企业通常使用多种编程语言,这会导致维护和专业技能方面的挑战。为了解决这个问题,文章提出了一种以 Rust 为中心的语言组合方案,利用其坚实的基础和现代化的工具。该方案包括:Rust(用于性能关键型任务)、RustGC(一个介于 2/3 级别的混合语言,具有垃圾回收机制,可加快开发周期并提供不错的性能)以及 RustScript(一种 4 级语言,用于快速原型设计,尤其适用于 UI 开发)。这三种语言都具有相似的语法,便于轻松转换,并允许更高级别的语言利用 Rust 生态系统。这种方法旨在通过为不同的任务提供合适的语言来简化开发流程,同时最大限度地减少管理不同工具集和程序员技能集的开销。

这个Hacker News讨论围绕着一个提案展开,该提案建议将编程语言分组为“语言集”,并实现自动化的外部函数接口(FFI)和序列化/反序列化。核心思想是不同的语言用于不同的任务(前端、后端、系统),导致胶水代码方面的挑战。一种统一的方法将允许同一语言集内的语言之间无缝通信,例如Rust、RustScript和RustGC。 评论者指出,当前添加类型系统(如TypeScript到JavaScript,为Python添加类型)的趋势是一种变通方法。他们建议设计更易于编译的语言,以克服解释器(如CPython的FFI)带来的限制。一位用户分享了他们使用C结构体和`cffi`来提高Python性能的经验,这反映了为SQL访问定义良好数据模型的概念。另一位用户表示支持为Rust添加自动垃圾回收(GC)。
相关文章
  • (评论) 2023-12-10
  • Rust 值得吗? 2023-10-27
  • (评论) 2024-01-17
  • (评论) 2025-03-14
  • (评论) 2024-02-08

  • 原文

    After working with a lot of languages, writing my own, this is currently what I consider the most useful classification of programming languages, into 4 levels:

    • 4: Interpreted, dynamically typed: JavaScript, Python, PHP
    • 3: Interpreted, statically typed: Hack, Flow, TypeScript, mypy
    • 2: Compiled with automatic memory management (statically typed): Go, Java (Kotlin), C#, Haskell, Objective-C, Swift
    • 1: Compiled with manual memory management (statically typed): Rust, C, C++

    There is a 0th level, assembly, but it’s not a practical choice for most programmers today.

    Now every language trades off “ease of use” with “performance”. On this hierarchy the higher numbered, “higher level”, languages are easier to use, while the lower numbered, “lower level”, languages are more performant.

    I postulate that for most programming, the “business logic” kind of programming, we want to use a language that sits right in the middle of that hierarchy. Looking at the languages listed that’s no revelation. One language could combine the 2nd and 3rd level though. A language that can be interpreted during development for fast iteration cycle, but compiled for better performance for deployment. There isn’t such a language popular today though.

    Now let’s address level 4. Big players sit at this level, perhaps the most popular languages by headcount of their programmers. The problem with a lack of static typing is that it’s hard to work on such code in groups and at scale. Every successful business started with those languages eventually rewrites their codebase to use one of the “lower level” languages because big codebases written by many people are hard to maintain and modify without the support of a static type-checker. They are still great languages for solo, small projects, especially if the code can be easily automatically tested.

    Now for level 1, Rust has done an amazing job bringing level 1 to a wider audience of programmers. By both being modern, and safe, it allows many more people to write code that requires best possible performance and resource utilization. In such scenarios Rust should be a clear choice. But coding in Rust is not easy, not in the way coding in JavaScript or Python is. The same solution, much more performant, might require many more lines of code.

    And so we come to the levels 2 and 3, where most professional programmers today spend their time. The tradeoff between them is clear: The interpreted languages have a faster development cycle because they don’t require the programmer to wait for a compilation step. But this comes at the cost of performance, as the interpreter in general cannot be as good at optimizing and executing the code as the compiler.

    The interesting thing is that these languages are almost identical in their expressive power. The only gap between them is that interpreted languages can include “eval” and dynamic meta-programming (modification of program structure at runtime). These features are usually shied away from in production code though, and are more helpful during development, especially for testing.

    The discussion here implies that companies need to use at least 3, often 4 different languages in their codebases. This means 4 different toolsets to maintain. Trainings to provide. Experts to hire. And usually disjoint sets of employee programmers who cannot easily jump from one language to the other.

    Clearly there will never be a single language that all programmers use. We need to take advantage of the tradeoffs laid out in this hierarchy. But what we could do is to build a language set, which would smooth out the transition between these levels.

    As the basis of this set I propose to use Rust. It is a solid low level foundation to build our language set on. It has modern, well thought out language tooling (including things like its syntax).

    There will be 3 languages in this set, besides Rust we want a level 2/3 hybrid and level 4 language.

    Let’s look at an example to make this concrete. First a program in Rust:

    fn main() {
        let rect1 = Rectangle {width: 30, height: 50};
        println!(The area is {}., area(&rect1));
    }
    
    struct Rectangle {
        width: u32,
        height: u32,
    }
    
    fn area(rectangle: &Rectangle) -> u32 {
        rectangle.width * rectangle.height
    }

    Now a program in RustGC, our level 2/3 hybrid:

    fn main() {
        let rect1 = Rectangle { width: 30, height: 50 };
        println!(The area is {}., area(rect1));
    }
    
    struct Rectangle {
        width: int,
        height: int,
    }
    
    fn area(rectangle: Rectangle) {
        rectangle.width * rectangle.height
    }

    And now a program in RustScript, our level 4 language:

    fn main() {
        let rect1 = { width: 30, height: 50 };
        println!(The area is {}., area(rect1));
    }
    
    fn area(rectangle) {
        rectangle.width * rectangle.height
    }

    RustScript can be used for heavy prototyping, especially for complicated stateful programming (interactive UIs). RustGC is our workhorse, with great async support, decent performance thanks to a modern garbage collector, but without the mental overhead of fighting the borrow checker. Finally we reach for Rust any time we need maximum performance and 0-cost abstractions.

    RustGC comes with a VM that allows instantenous save -> execute dev cycle, but is compiled for deployment to a binary similar to the one that Rust would compile to, but with an accompanying GC runtime.

    The best part is that all three languages share pretty much the same syntax, and they are built so that calling from higher level to lower level variant is effortless. This gives us the ability to use the rich Rust ecosystem from a level 2/3 or even level 4 language.

    More examples. UI component in RustScript:

    fn app() {
      let (state, setState) = useState({
        total: None,
        next: None,
        operation: None,
      });
    
      let handleClick = |buttonName| => {
        setState(|state| => calculate(state, buttonName));
      };
      
      let value = state.next.or(state.total).unwrap_or("0");
      <div className="component-app">
        <Display value={value} />
        <ButtonPanel clickHandler={handleClick} />
      </div>
    }

    Async example in RustGC:

    async fn main() {
      let user_ids = vec![1, 2, 3];
      let user_names = user_ids.iter().map_async(
        async |id| => fetch_user_name(id).await,
      ).await;
      println!(user_names.join(", "));
    }
    
    async fn fetch_user_name(_: int) -> Future<string> {
      // This could be a database request.
      ""
    }
    联系我们 contact @ memedata.com