Is it possible to implement the Yin-Yang puzzle in

2019-07-25 11:12发布

问题:

The puzzle, implemented in Scheme, is as follows:

(let* ((yin
     ((lambda (cc) (display #\@) cc) (call-with-current-continuation (lambda (c) c))))
   (yang
     ((lambda (cc) (display #\*) cc) (call-with-current-continuation (lambda (c) c)))))
(yin yang))

The goal of the puzzle is to work out and understand the output of this code.

I'm wondering if it's possible to implement code with the same semantics using C# 5.0's new async CPS features.

The part that I'm having trouble grasping, is that the puzzle relies on the semantics of let* as much as call/cc. I'm not sure how to correctly express this interplay in C#.

回答1:

CPS can get rid of call/cc entirely, so you can definitely implement this in C# by hand-CPS-ing it. Knowing nothing about C#'s automatic CPS-ing, I can't say whether that feature will do this automatically. However, the "async" in the name gives me pause. The question you give is explicitly related to the synchronous evaluation of this expression.

My opinion: I think that translating this to C# is not the fastest way to understand this.

Finally: let* is shorthand for nested bindings. So you can rewrite this as:

(let ([yin ...])
  (let ([yang ...])
     ...))

... to get rid of the let*. In your case, since 'yang' doesn't depend on 'yin', the effect is that of sequencing. That is, the continuation captured in the right-hand-side of the 'yin' binding is one that hasn't yet evaluated the 'yang' binding.