10

囲まれた関数に拡張されないような方法でスコープが定義されている言語はありますか? 言い換えれば、次のようなコード (Python のような構文) を持つ言語があります。

>>> x = 3
>>> def fact(n):
...     print x
...     return reduce(lambda u, v: u*v, xrange(1, n+1), 1)
...     

関数内で x が定義されていないため、エラーが発生しますfactか?

一般に、関数のスコープに定義された関数が含まれない言語はありますか?

編集:有益なコメントをありがとう。私がこれについて考えた理由は、含まれる関数によって提供されるすべての環境にアクセスできる内部関数の状況が、 OOP に対する彼の議論で Joe Armstrong によって説明された状況に疑わしいほど近いように聞こえるからです。

オブジェクト指向言語の問題は、オブジェクト指向言語が持ち歩く暗黙の環境をすべて持っていることです。あなたはバナナが欲しかったのですが、手に入れたのはバナナとジャングル全体を持ったゴリラでした.

また関連するのは、 Newspeakという言語にはグローバルな名前空間がないと聞いたことですが、それがどのように機能するのかはわかりません。

以下のブライアンのコメントで提起された、組み込み関数 ( __builtins__Pythonspeak または他の多くの言語のシステムからインポートされた関数) の問題は、すべての関数でインタープリター/コンパイラーによって人為的に導入されることを想像できます。結局のところ、彼らはほとんどの場合、そもそもその言語で特別に扱われています。もう 1 つのオプションは、オブジェクトのメソッドとしてそれらを関数にパラメーターとして渡すか、内部からモジュールとしてインポートすることです。

4

3 に答える 3

8

Newspeak でどのように機能するかを大まかに説明しようと思います。

作成するコードはすべてモジュール内にある必要があります。Module は一種のクラスです。Newspeak ではクラスに他のクラスを含めることができるため、Module は本質的にトップレベルのクラスであり、別のクラスに含まれていません。Newspeak の特別な点は、モジュール外のものを参照できないことです

では、Newspeak でコンソールに出力するにはどうすればよいでしょうか。印刷は、Platform モジュールの一部である Console クラス (別名 Smalltalk の Transcript) に属します。コンソールに出力できるようにするには、モジュールで Platform コンストラクター パラメーターを受け取り、プラットフォームからコンソールを取得し、コンソールをスロットに格納してから、それを使用して出力します。

基本的には、言語レベルで強制される依存性注入のようなものです。言語 IDE とランタイムは、プログラムのパッケージ化とブートストラップに役立ちますが、詳細を知りたい場合は、Gilad Bracha のブログにアクセスするか、たとえばこの投稿を参照するか、 Newspeak Modules paperを参照してください。

記録として、PS Newspeak は非実用的でも使用不能でもありません。これは産業環境で使用されており、現在は小規模な (しかし成長している) オープンソース コミュニティがあります。確かに、Newspeak は非常に新しく進化していますが、個人的な経験から言えば、プログラムを書くのは非常に簡単で楽しいものです。

于 2010-12-24T23:09:24.673 に答える
0

たとえば、関数とオブジェクトを含む連想配列によってグローバル スコープが置き換えられ、呼び出されるすべての関数に作業環境として渡されるプログラミング言語を作成できると思います。

次の例を考えてみましょう。通常の Python プログラムでは、次のように記述します。

import foo

def square(x):
    return x*x

print(square(int(raw_input("give a number: "))))

グローバルのないプログラムでは、次のように記述します。

def main(environment):
    environment['import']('foo')
    environment['square'] = lambda x: x*x
    environment['print'](environment['square'](int(environment['raw_input']("give a number:"))))

このコードは、次のようなコンテキスト内で実行されます。

def import_foo(modulename):
    # dummy example
    if modulename == 'foo':
        import foo

environment = {
    'import': import_foo,
    'print': print,
    'raw_input': raw_input
}

main(environment)

この種のアプローチを使用し、グローバルを使用しないプログラムでは、プログラム内の関数は、取得する引数を介してアクセスできるものを除いて、すべてからほぼ完全に分離できます。次に、関数の代替環境を作成し、それらを「jails」で実行することもできます。ライブラリと関数は、必要な回路内の電子部品のようなものですが、部品を必要なものに接続することもできます。このパターンを念頭に置いて設計されたプログラミング言語は、便宜上、暗黙的な「デフォルト」環境を関数呼び出しに自動的に渡す構文糖衣を備えている可能性がありますが、必要な代替環境を使用するように常に明示的に強制することができます。

たとえば、グローバルレス言語で、オペレーティング システムのファイル システムまたはネットワーク内のデータにアクセスするように設計されたライブラリがある場合、代替環境を提供して I/O を監視するか、ライブラリに独自の仮想を使用させることができます。通常のファイル システムとネットワークの代わりに、ファイル システムまたは VPN 接続を使用します。

于 2015-03-01T16:54:05.853 に答える
-5

現実的には、そのようなものは決して存在し得ません。考えてみてください-コンソールに印刷するとき、そのコンソールハンドルはどこから来ていますか?関数を参照するとき、その関数はどこから来たのですか?呼び出し元の関数のスタックに物理的に存在しないことは確かです。そうです-それはグローバルです。現実には、グローバルがなければ、スタックまたはヒープに直接存在しないものを参照することはできません。つまり、DEPのおかげで、マシン命令はありません。そして、ヒープの場合、どこからヒープを取得しますか?OS関数を呼び出して、実際の新しいメモリを割り当てることはできません。これはグローバルです。

理論的には、そのような言語やプログラムを作成することもできますが、実際に使用できるものよりも、Brainfuckに似ているのが現実です。

于 2010-11-21T21:42:26.590 に答える