1 个不稳定版本

0.9.2 2024年8月18日

#concepts 中排名第 7

MITLGPL-3.0-only

1MB
20K SLoC

Rust codecov Webpage VSCode Extension Crates.io Version

什么是 Ryna

Ryna 是一种具有强类型系统的命令式概念编程语言。许多想法来自我同时也是其作者的 ULAN 语言(仅限西班牙语),该语言的宗旨是挑战经典软件的可维护性观念,并将可扩展编程推向极致,以最大限度地减少语法和语义噪声。

请访问 官方页面 了解该语言及其特性!

我能使用 Ryna 吗?

当然可以! 该语言处于 实验 阶段,因此确实可以使用,但请预期一些事情可能会失败。您可以在此 查看安装解释器的说明。

特性

以下是可以使用 Ryna 做的一些事情:

  • 任意精度整数算术.

  • 完全参数化代数类型:

    Int | String;        // Either a number or a string
    (Int, String);       // A number followed by a string
    Array<Int | String>; // An array of elements that are either numbers of strings
    
  • 递归类型:

    class Nil {}
    type Tree<T> = Nil | ('T, Tree<'T>, Tree<'T>);
    
    let t: Tree<Int> = (
        3, 
        (
            1, 
            Nil(), 
            (
                3, 
                (1, Nil(), Nil()), 
                (2, Nil(), Nil())
            )
        ), 
        (2, Nil(), Nil())
    );
    
  • 强大的函数重载语义:您将能够使用这种丰富的类型系统定义函数,并利用调用多态语义

    fn this_is_a_test(a: Int) -> Bool {
        return true;
    }
    
    fn this_is_a_test(a: String) -> Bool {
        return false;
    }
    
    // Both valid
    this_is_a_test(5);      // Returns true
    this_is_a_test("Test"); // Returns false
    
  • 基于模板的泛型编程:参数化类型也通过类似于 C++ 的模板方式支持

    fn<T> is_number(a: 'T) -> Bool {
        return a.is<Int>();
    }
    
    // Template arguments are automatically inferred from the parameters if possible
    5.is_number();        // This is true
    "Test".is_number();   // This is false
    5.is_number<Int>();   // You can also explicitly instantiate the template
    
  • 自定义字面量:您可以使用内部语言 RDLRyna 定义语言)创建新的字面量

    class Dice {
        // Syntax definition
        syntax from Arg(1{d}, rolls) 'D' Arg(1{d}, faces)
    
        faces: Int
        rolls: Int
    }
    
    //Usage
    dice = 4D20; // Four dice of twenty sides
    
  • 编译时语法扩展:您可以使用 RDL 通过高级模式扩展语言的语法

    syntax array_initialization from "<" Arg(<type>, type) ">[" [{Arg(<expr>, elems) "," [s]} Arg(<expr>, elems)] "]" {
        let res = arr<$type>();
    
        @elems.i {
            res.push($elems.i);
        }
        
        return move(res);
    }
    
    let array = <Int>[1, 2, 3, 4];
    
  • 操作符和操作定义:该语言允许使用简单的语法定义新的操作符和操作

    // Operator definition
    unary postfix op "++" (500);
    binary op "<=>" (1000);
    nary op from "`" to "´" (1500);
    
    // Operation definition for each operator
    // These can be overloaded and templated just the same as functions
    op (a: &Int) ++ -> Int {
        return a + 1;
    }
    
    op (a: &Int) <=> (b: &Int) -> Int {
        if a < b {
            return -1;
        }
        
        if a > b {
            return 1;
        }
      
        return 0;
    }
    
    op (a: &Int) `(b: &Int, c: &Int)´ -> Int {
        return a + b * c;
    }
    
  • 内置测试框架:您可以使用 @test 注解构建单元测试,无需外部库

    @test
    fn fill_test() -> Bool {
        let res = arr_with_capacity<Int>(3);
        res.fill(100);
    
        for i in res {
            if i != 100 {
                return false;
            }
        }
    
        return true;
    }
    
  • 内置文档生成器:您可以使用 @doc 注解对项目进行文档化,并使用 ryna docs 命令生成具有项目文档的人类可读的 markdown 文件

    @doc(
        "Fills every available position in an array with a given value. The filling starts in the current `len`.",
        array: "the array to fill.",
        value: "the value to fill the available positions with.",
        "An array where every position starting from the previous `len` is `value`"
    )
    fn<T> fill(array: @Array<'T>, value: 'T) -> @Array<'T> {
        while array.capacity() > array.len() {
            array.push(*value);
        }
    
        return array;
    }
    

Ryna 编写的项目

如果您想在此展示一个项目,您可以提交一个 pull request 或打开一个 issue :)

RyChess 引擎

RyChess 是用 Ryna 编写的一个简单的棋类引擎,旨在展示该语言在中型项目中的应用。此外,它还作为优化测量的内部基准。

RyGenes

RyGenes 是一个用 Ryna 编写的遗传算法库。它允许创建自定义的交叉和突变函数,并包括如 N-Queens 问题等示例。

贡献

您可以通过在解释器中发现错误或在如何改进语言或文档方面有建议时打开问题来为项目做出贡献。所有贡献,无论大小,都受欢迎 :)

依赖

~38–52MB
~873K SLoC