[REBOL][HelloWorld] http://www.rebol.com/
REBOL [ Title: "Hello, world" File: %hello.r Date: 2004/12/20 Author: "Tea" ] print "Hello, world"
REBOLの決まりで、REBOL の記述は最低限必要。実行時にチェックされます。
一行目に REBOL と書いておくと、vimでREBOLのスクリプトだと判断してくれます。
REBOL は、特殊なおまじない構文ではなく、
これ自身もオブジェクトで、実行環境の様々な情報をもっているオブジェクト。
help REBOL と打ち込むとREBOLについてのヘルプが表示されます。
オブジェクトは木構造を持ち、それぞれの子要素も参照できます。
例えば、help REBOL/schemes でサポートされているプロトコルの一覧表示。
Stackframe
Pythonは、inspectionが優れていて
関数,コード,スタックフレームのオブジェクトにまで
Pythonスクリプト上からアクセスできたりする。
import inspect def show_var(varname): """ 呼出元のローカル変数を表示 """ try: frame = inspect.currentframe() print "%s : %s" % (varname, frame.f_back.f_locals[varname]) finally: del frame if __name__ == "__main__": foo = "HiNa" show_var("foo") # foo : HiNa
エラーや例外時にでるメッセージは、このframeオブジェクトの情報を参照している。
これを使うと、Perlの caller みたいな関数も定義できる。
def caller(num=1): """ 引数は、幾つ前のスタックを辿るかを整数で指定。初期値は1。 [ 呼出元の名前, 呼出元のファイル, 呼出元の行番号 ] """ assert num > 0, "Stack depth number must be greater than zero." try: frame = inspect.currentframe() for _ in xrange(num-1): frame = frame.f_back code = frame.f_code return [ code.co_name, code.co_filename, frame.f_lineno ] finally: del frame
Python in parrotで心配になったのは、先にも書いたけど
この code や frame オブジェクトの互換性をどう解決するのか。
いずれも C で実装されていて、Pythonプログラムの実行に深く関わっている。
例えば、関数の引数のフォーマット情報を表示するinspectの関数などは、
関数オブジェクト内のコード・オブジェクトが持つバイトコードの情報を参照している。
当然ながら python bytecode -> parrot bytecodeになると、バイトコードが代わるので、
この部分の変更は避けられない。
また、parrot用に書き直されるとした場合でも、
branchになるので、CPythonとParrotPython版両方の保守が発生する。
開発者でもないのに余計な心配かなとは思うが、実装依存部分を取り除くには手間がかかりそうだ。
[Parrot][Python]
Python/Parrotの実装は現在3つ。
- pie-thon (parrot ./languagesディレクトリ以下に収録)
- pirate (http://pirate.tangentcode.com/)
- pyrate (http://www.intertwingly.net/blog/2004/10/02/Pyrate)
disやinspectモジュールのCPythonとの互換はどうなるのか気になる所。
内部のobjectで言うと、codeやframeオブジェクト・レベルでの互換性。
parrotだとbytecodeが代わるので、co_codeとかそのままでは無理なはず。
frameは、アーキテクチャを考えるとparrotの内側に隠蔽差れそうな気がする。
parrotではframeオブジェクトに対してのアクセスを提供しているのだろうか。
-
-
- -
-
組み込み向けを除いた主なPythonの実装。
- CPython (http://python.org/) [C]
- Jython (http://jython.sf.net/) [Java]
- IronPython (http://ironpython.com/) [C#]
- PyPy (http://codespeak.net/pypy/) [Python]
- Vyper (http://vyper.sourceforge.net ... not found) [OCaml]
- StacklessPython (http://www.stackless.com/) [C]
# vyperは、サイトが亡くなっていて現在入手不可能。
-
-
- -
-
組み込み型 set, frozenset
ちょっと変な使い方かも知れないけど、応用で。
def uniq(args): return list(set(args))
sorted, reversed
式のなかで、リストの並べ変えが出来るようになり、
method chain や 副作用のないFPスタイルでのコードが書き易くなった。
sortがcmd, key, reverseの引数を取るようになっので、
sortedでも第二引数以降にこれらのオプションを設定できる。
None constant.
と言う事で、Noneへの代入がSyntaxErrorになった。
でも、True, Flase への代入は相変わらず ...
True, False = "A", "B"
[Python] 2.4
Releaseされたので早速インストール。新しい機能のテスト。
Generator Expression
# 使い方: # リスト内包表現 [ ... ] の代わりに ( ... ) # リスト内包表現では新しいリストを作成して返す為、 # 巨大なリストをfor文で処理したい場合に、 # - 一時リストを作成するので非効率、 # - 又、無限リストを扱えないなどの問題があった。 # ジェネレータ表現ではジェネレータを返す為、 # foo in ステートメント内でも遅延評価,リスト内包の両方の利点を活かせる。 foo = (funcA(x) for x in alist if funcB(x)) # 上のgenerator expressionで作成されたgenerator fooは、 # 以下の generator と同じ振舞をする。 def _foo(): for x in alist: if funcB(x): yield funcA(x) foo = _foo()
Decorator
- 関数を定義する際に、Wrapper関数を適用できる。
classmethod, staticmethodを簡単に定義する際に使える。
(というより主にそっちの目的で付けられた構文が汎用化されて、
デコレーターとして提供されたような気がする。)
class C: @classmethod def meth(self): print "C::meth"
複数のデコレーターを組み合わせる事も出来、
デコレーターを使って AOP での before, after の様なフックも掛ける事が出来る。
def require_int(func): def wrapper(arg): assert isinstance(arg, int) return func(arg) return wrapper def provide_int(func): def wrapper(arg): result = func(arg) assert isinstance(result, int) return result return wrapper @require_int @provide_int def test(num): return num * 2 # 従来のコードに展開すると、test定義後に、 # test = require_int(provide_int(test)) print test(10) print test("1") # AssertionError, in wrapper in require_int
デコレーターに引数を渡す事も出来るらしい。(書き方がわからなかったのでTODO)