6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PythonのyieldをJavaScriptやJavaで表現する

Last updated at Posted at 2014-02-09

PythonのyieldをJavaやJavaScriptで表現するにはどうすればいいのかを考えてみました。

今回は実用的に何か作ってみたというのではなく、コードジェネレーターをなどを作るとすればどう置き換えればいいのかを考えてみたというレベルなのであしからずです。

とりあえず、これを題材にしてみました。

# your code goes here
def Generator(n):
	yield 1;
	
	idx = 0
	while idx < n:
		yield 2
		idx += 1

	yield 3
	
g = Generator(5)
for x in g:
	print x

ちょっと考えた方針

  • ループはgoto文のようなもので置き換え可能
  • while文とswitch文を組み合わせればgoto文を表現可能
  • yieldした位置をstateとして保存しておく

この方針でJavaScriptで書いてみました。

// your code goes here
function Generator(n) {
	var ctx = { state:0, idx:0 };

	return function() {
		while (1) {
			switch (ctx.state) {
				case 0:
					ctx.state = 1;
					return 1;
				
				case 1:
					if (ctx.idx < n) {
						ctx.idx++;
						return 2;
					}

					ctx.state = 2;
					break;
					
				case 2:
					ctx.state = -1;
					return 3;
				
				default:
					return undefined;
			}
		}
	};
}

(function() {
	var g = Generator(5);
	while (1) {
		var x = g();
		if (x === undefined)
			break;
		print(x);
	}
})();

同様にJavaで書いてみました。

/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
	private static class Generator {
		final int n_;
		int state_ = 0, idx_ = 0;
		boolean completed_ = false;
		
		Generator(int n) {
			n_ = n;
		}
		
		int generate() {
			while (true) switch (state_) {
				case 0:
					state_ = 1; return 1;
					
				case 1:
					if (idx_ < n_) {
						idx_++;
						return 2;
					}
					else {
						state_ = 2;
					}
					break;
					
				case 2:
					completed_ = true;
					return 3;
			}
		}
		
		boolean isCompleted() { return completed_; }
	}

	public static void main (String[] args) throws java.lang.Exception
	{
		Generator g = new Generator(5);
		while (! g.isCompleted()) {
			int x = g.generate();
			System.out.println(x + "");
		}
	}
}

どちらも一応目的の動きはしています。

こんなコードジェネレーターはすでにあるんでしょうか。

世の中でブラウザでyield文が普通に使える時代になればこんなことは考えなくてすみますね。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?