大家都用scheme做些什么

没有重载

只有一堆 list->string string->vector list->vector vector->list … 而不是 coerce 或者自动 type promotion

想想一下,不能写 (+ 1.5 12) 而是要写

(define three (suc (suc one)))
…
(define five (suc (suc three)))
…
(define fifteen (integer-multiply three five))
(flonum-add (flonum fifiteen (negative one)) (integer->flonum twelve))

更糟的是 list, immutable list, reference list, 各自有命名不同的相似操作

vector 同理

显然意思是方便输入的纯文本的表示, scheme 没 reader macro,自带的 vector list string 是有的专门语法,SRFI 的就不见得了,只能通过 constructor 等函数构造

1 个赞

啊!

对于「重载」的那个,我的意思是 lisp 没有 C++ 式静态分派的重载 (或别的什么动态分派),或许是因为动态语言文化上倾向于使用 predicate。但另一方面,我同意使用 list-ref 和 vector-ref 很麻烦,有一个 aref 或 elt 会很舒服。所以我想说的是,即使没有那样的「重载」,我也赞同标准库应该提供一个统一(而且常见应用要精短)的方式操作这些类型。

当然,我不觉得再提供一些专门的函数如 list-ref 和 vector-ref 以供需要时使用有什么问题。

1 个赞

lua或者其他胶水语言当然也可以。我用guile纯粹是个人偏好。也许其中的函数式范式在编写生成受约束的随机测试向量的代码时会显得简洁一些吧。

我这几天写 Clojure, 我觉得 Clojure 的重载挺好的,这样比强制覆盖同名函数有好多了。 ;)

clojure 那个更像是模式匹配,也就是一个超级 case 的语法糖。这个模式 clojure 其实不是最早的,起码 erlang 比 clojure 早。haskell、ml 也有类似的,但 haskell、ml 是静态类型语言。

太惨了,要不来玩 Scala 3 吧,scala-cli 超爽的!

我在Goldfish Scheme上面实现了一堆SRFI,并没有全部实现。

然后我发现SRFI的设计并不好,因为作者太多了,并不统一。

最近一周,我在Scheme里面实现了define-case-class。

有了类似Scala的case-class之后,我发现我可以借鉴Scala实现Option, Char, Integer, List, Array, HashMap。于是一发不可收拾,今天刚刚新增了一个R7RS库:(liii lang)示例如下。

这套设计我自己现在相当满意!然后可以用于我自己的商业产品: https://liiistem.cn 的研发!

Boxed Integer

(check (((box 1) :to 3) :collect) => (list 1 2 3))

Boxed String

(check ((case-string "abc") :map char-upcase :unbox) => "ABC")

(let1 str (case-string "Hello, World!")
  (check (str :forall char-alphabetic?) => #f)
  (check (str :exists char-alphabetic?) => #t)
  (check (str :count char-alphabetic?) => 10)
)

Boxed List

(let ((lst (case-list '(1 2 3 4 5))))
  (check (lst :take-right -1 :collect) => '())
  (check (lst :take-right 0 :collect) => '())
  (check (lst :take-right 3 :collect) => '(3 4 5))
  (check (lst :take-right 5 :collect) => '(1 2 3 4 5))
  (check (lst :take-right 10 :collect) => '(1 2 3 4 5))
)

Boxed Vector


(let ((vec (case-vector #(1 2 3 4 5))))
  (check (vec :fold 0 +) => 15)
  (check (vec :fold '() (lambda (x acc) (cons x acc))) => '(5 4 3 2 1))

  (check (vec :fold-right 0 +) => 15)
  (check (vec :fold-right '() (lambda (x acc) (cons x acc))) => '(1 2 3 4 5))
)

我是从Scala走向Scheme的(翻译过《Scala实用指南》),现在打算把Scheme打造成没有OOP的Scala。

感兴趣看一下我的Goldfish Scheme :sunglasses:

这个问题我现在已经解决了:

你可以看一下A Love Letter to S7 Scheme,其实S7 Scheme也很好的解决了这个问题

示例代码:

> (define h (hash-table* 'a 1 'b 2))
> (display (h 'a))
1
> (set! (h 'b) 3)
> (display (h 'b))
3

示例代码2:

> ; lists
> (display ('(1 2 3) 1))
2
> ; vectors (with constant time)
> (display (#(1 2 3) 1))
2
> ; strings
> (display ("abc" 1))
#\b
> ; environments (!?!)
> (display ((let ((a 2)) (curlet)) 'a))
2
> ; dilambdas (more on this later)
> (define dil (let ((a 0))
    (dilambda
        (lambda () a)
        (lambda (v) (set! a v)))))
> (display (dil))
0
> (set! (dil) 10)
> (display (dil))
10
1 个赞

那个scheme-to-llvm的东西, 我猜你可能说的是Andy Keep为了演示Nanopass随手写的玩意儿. 实际上, 之前那个东西还有个scheme-to-c的版本, 没啥特别本质上的不同. 这个其实基本上是参照着以前的IUB P423/523的作业来的. 至于你说native code compiler, 我倒是觉得已经有很多了, 而且如果你要连Chez Scheme或者Gambit或者Racket之类的实现性能都不够用的话, 我想不出来你在写什么东西. (至于你说实验性编译器以Scheme为目标语言, 这方面我真是孤陋寡闻了, 我似乎随便一想只能想到Idris?)

1 个赞

那是什么原因没有继续用scala?

现在自己创业(https://liiistem.cn),主要用Scheme,Scala等以后会用上

1 个赞

是的。考虑llvm是因为我知道这个方案可以回避一些跨平台的问题,写一个前端可以多个平台使用,如果我打算独自做一个家用的scheme编译器,这很有吸引力不是吗?不选择编译到C主要是觉得带一个完整C后端太笨重了,还不如先开发一个C--。

并没有写什么东西,只是想想而已。chez的后端实现之前看过,做的也没有很细致。看起来scheme的一些后端优化问题需要侵入前端,只靠后端优化的那些算法不够的。我对native code多少是有点儿执念,希望可以编出像几百行C代码那样足够小的编译产物。

好吧,记名字我一时也想不起来。考虑到我并不是编译器研究人员,请把这句划掉吧。

完整的 llvm 就不笨重了是吧( 显然 tcc 比 llvm 要小得多,还不用 C++

另一个问题,lllvm ir 不是一个稳定标准,你也不想自己写的项目像 Haskell 那样放置个 3 年就编译不了吧

我觉得像現在的真正主流实验性语言那样 targeting WASM,就很实在,个人项目没必要好高騖遠。