#lisp #language #functional #interpreter

bin+lib turtle-lang

谦逊、有趣且友好的 Lisp

2 个版本

0.1.1 2020 年 8 月 20 日
0.1.0 2020 年 8 月 20 日

#825编程语言

MIT 许可证

100KB
2.5K SLoC

Rust 2K SLoC // 0.0% comments Common Lisp 525 SLoC // 0.1% comments Pest 24 SLoC // 0.1% comments

龟式编程语言

龟式编程语言是一种谦逊、有趣且友好的 Lisp。您可以使用 Cargo 安装它,浏览一些 示例代码,或遵循(目前尚未编写的)教程

;; Print "Hello, world!" to the terminal:
(disp "Hello, world!")

;; Let's print the squares of the numbers 1 through 10 using Turtle.
(func square (n) (exp n 2))
(disp (map square (range 10)))

;; We can also do this using anonymous functions (lambdas):
(disp (map (lambda '(n) '(exp n 2)) (range 10)))

动机

现在有太多编程语言,其中大多数并不适合任何实际应用——它们是 玩具编程语言。龟式编程语言也不例外:它存在是因为我想在不需要处理最受欢迎的实现(Common Lisp、Clojure、Scheme 等)的细微差别的情况下实验 Lisp。

龟式编程语言没有 I/O 功能,而且速度并不快。然而,它极其简单,内存高效,线程安全(至少在我实现创建线程的方法后将是这样),非常适合自包含编程和数学挑战(如 Project Euler)。龟式编程语言适用于函数式和命令式编程,并且——就像任何好的 Lisp 一样——具有强大的宏和元编程支持。

龟式编程语言受到 Haskell、Rust、Scheme、Common Lisp、Python 和 Ruby 的启发。解释器是用 Rust 编写的,但该语言的大多数功能都是用 Turtle 自身编写的。

安装

您可以使用 Cargo 通过运行以下命令来安装 Turtle:cargo install turtle-lang

示例

你好,世界
(disp "Hello, world!")
错误

对于龟式编程语言来说,拥有有用的错误消息是一个重点。这里有一个示例类型不匹配的错误堆栈跟踪

An example Turtle stacktrace
Fizz Buzz (Crackle Pop)

FizzBuzz 是一个简单的程序,它从 1 数到 100,但如果数字能被 3 整除则打印 "Fizz",如果数字能被 5 整除则打印 "Buzz",如果数字能被 3 和 5 同时整除则打印 "FizzBuzz"。

首先,让我们定义一个处理单个数字的函数

(func handle (n)
    (cond ((eq (modulo n 15) 0) (disp "FizzBuzz"))
          ((eq (modulo n 3) 0) (disp "Fizz"))
          ((eq (modulo n 5) 0) (disp "Buzz"))
          ('t (disp n))))

现在,这里有一个命令式的计数方法

(let 'i 0)
(while
    (decreasing 100 i)
    (do
        (handle i)
        (++ i)))

这里有一个更函数式的方法

(map handle (range 100))
质因数分解

标准库中有一个内置函数可以找到任何整数的质因数分解。以下是其命令式定义

(func prime-factorization 
    (n) 
    (do 
        (letq factors ()) 
        (letq curr n) 
        (while 
            (not (eq ,(append '(prod) factors) n))
            (do
                (let 'trying 2)
                (while
                    (not (eq (modulo curr trying) 0))
                    (++ trying))
                (push! factors trying)
                (let 'curr (/ curr trying))))
     factors))

以下是如何在您的代码中使用此定义(在这个例子中,用于解决 Project Euler 问题 3

;; From https://projecteuler.net/problem=3
;;
;; The prime factors of 13195 are 5, 7, 13 and 29.
;;
;; What is the largest prime factor of the number 600851475143 ?

(import "@math" :math)

(let 'n 600851475143)

(assert (eq (last (math::prime-factorization n)) 6857))

文件类型

我通常使用 .lisp 文件扩展名来表示海龟源代码,以便更好地支持编辑器,但从长远来看,我也希望看到 .tl 也被使用。

依赖项

约10MB
~186K SLoC