schema 中的方法和属性:Scheme 中是否可以实现 OOP?

2024-03-08

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

class Apple{
    public String flavor;
    public int pieces;
    private int tastiness;
    public goodness(){
        return tastiness*pieces;
    }
}

使用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

...其中樱桃是味道,2 是切片,5 是美味。然而,这样就没有类型安全性或可见性,所有内容都被推入未标记的列表中。我该如何改进?

旁注:make-pie 过程需要 3 个参数。如果我想让其中一些参数成为可选的(就像我可以在 Java 或 C 等大括号语言中那样),将参数作为列表(即将参数视为列表)是一种很好的做法吗? - 不需要一个参数is一个清单)并以这种方式处理它们?


Update:

我收到了一些答案,其中包含各种扩展/库的链接,这些扩展/库可以满足我对方案中 OOP 的渴望。这很有帮助,所以谢谢你。

然而,虽然我可能没有很好地传达它,但我也想知道实施该方法的最佳方法是什么pie上面的对象没有这样的类或库,所以我可以更好地理解方案最佳实践。


在某种意义上,闭包和对象是等价的 http://c2.com/cgi/wiki?ClosuresAndObjectsAreEquivalent,所以这当然是可能的。有不同面向对象系统对Scheme的大量帮助 http://www.faqs.org/faqs/scheme-faq/part1/section-6.html——更好的问题可能是使用哪一个!

另一方面,如果这是一个教育练习,您甚至可以使用闭包对象等效性来开展自己的练习。 (请原谅任何错误,我的方案相当生疏。)

(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 '()))))

这是一个简单的构造函数pie目的。参数变量flavor, pieces and tastiness被 lambda 表达式封闭,成为对象的字段,并且闭包的第一个(也是为了简单起见,仅在此)参数是方法选择器。

完成后,您可以实例化并查看一些:

> (define pie1 (make-pie "rhubarb" 8 4))
> (define pie2 (make-pie "pumpkin" 6 7))
> (pie1 'flavor)
"rhubarb"
> (pie1 'goodness)
32
> (pie2 'flavor)
"pumpkin"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

schema 中的方法和属性:Scheme 中是否可以实现 OOP? 的相关文章

随机推荐