方案中的方法和属性:方案中是否可以进行OOP?

Cam*_*Cam 4 oop scheme racket

我将用一个简单的例子来说明我的问题.在Java,C或任何其他OOP语言中,我可以pie用类似于此的方式创建一个类:

class Apple{
    public String flavor;
    public int pieces;
    private int tastiness;
    public goodness(){
        return tastiness*pieces;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用Scheme的最佳方法是什么?我想我可以做这样的事情:

(define make-pie
  (lambda (flavor pieces tastiness)
    (list flavor pieces tastiness)))

(define pie-goodness
  (lambda (pie)
    (* (list-ref pie 1) (list-ref pie 2))))

(pie-goodness (make-pie 'cherry 2 5))

;output: 10
Run Code Online (Sandbox Code Playgroud)

...樱桃是味道,2是碎片,5是味道.然而,没有类型安全或可见性,所有东西都只是在一个未标记的列表中.我怎样才能改善这一点?

旁注:make-pie程序需要3个参数.如果我想让它们中的一些是可选的(就像我能够使用像Java或C这样的大括号语言),那么将参数作为一个列表(将参数视为列表)是一种好习惯-并不需要一个参数,它一个列表)和处理他们的方式?


更新:

我收到了几个答案,链接到各种扩展/库,可以满足我对计划中OOP的渴望.这很有帮助,谢谢.

然而,虽然我可能没有很好地传达它,但我也想知道在pie没有这些类或库的情况下实现上述对象的最佳方法是什么,因此我可以更好地理解方案最佳实践.

Jef*_*tin 8

在某种意义上,闭包和对象是等价的,所以它当然是可能的.对于Scheme来说,不同的OO系统有很多帮助 - 一个更好的问题可能是使用哪一个!

另一方面,如果这是一个教育练习,你甚至可以使用闭包对象等效来自己动手.(请原谅任何错误,我的计划相当生疏.)

(define (make-pie flavor pieces tastiness)
        (lambda (selector)
                (cond ((eqv? selector 'flavor) flavor)
                      ((eqv? selector 'pieces) pieces)
                      ((eqv? selector 'tastiness) tastiness)
                      ((eqv? selector 'goodness) (* pieces tastiness))
                      (else '()))))
Run Code Online (Sandbox Code Playgroud)

这是一个pie对象的简单构造函数.参数变量flavor,piecestastiness由λ表达式关闭了,成为对象的字段,并且所述第一(和这里简单起见,只)参数来封闭是方法选择器.

完成后,你可以实例化并捅一些:

> (define pie1 (make-pie "rhubarb" 8 4))
> (define pie2 (make-pie "pumpkin" 6 7))
> (pie1 'flavor)
"rhubarb"
> (pie1 'goodness)
32
> (pie2 'flavor)
"pumpkin"
Run Code Online (Sandbox Code Playgroud)