2010-11-21 104 views
9

是否有語言的範圍被定義爲不擴展到封閉函數的方式?換句話說就是在那裏有像以下的(類Python語法)的代碼的語言:因爲X不是功能fact內部定義有沒有全局變量的編程語言?

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

將給出錯誤?

一般來說,任何函數的作用域的範圍是否會包含其中定義的函數?

編輯:感謝您提供的信息。我想過這樣做的原因是,有機會獲得由它包含的功能所提供的所有環境中的內部函數的情況聽起來耳熟我附近由喬·阿姆斯特朗在他的argument against OOP描述的情況:

因爲問題與 面向對象的語言是他們有 得到所有這些隱含的環境,他們隨身攜帶。你 想要一個香蕉,但你得到的是一個 大猩猩拿着香蕉和 整個叢林。

同樣相關的是,我聽說語言Newspeak沒有全局命名空間,但我不知道它是如何工作的。

我可以想象,在各種函數中,解釋器/編譯器會人爲地引入內置函數(Pythonspeak中的__builtins__或其他語言中導入的函數)引發的問題。畢竟,他們幾乎總是首先在語言中特別對待。另一種選擇是將它們作爲對象的方法作爲參數傳遞給函數,或從內部作爲模塊導入。

+1

這會完成什麼? – Blindy 2010-11-21 21:20:29

+4

請注意,'print','reduce'和'xrange'也顯示爲從某個外部作用域解析出的標識符。這顯示了爲什麼這很少有用。 – Brian 2010-11-21 21:22:45

回答

8

我會盡量粗略地概述它在Newspeak中的工作原理。

你寫的任何代碼必須在模塊。模塊是一種類,因爲在Newspeak類中可以包含其他類,模塊本質上是一個頂級類 - 它不包含在另一個類中。 Newspeak的特別之處在於你不能在你的模塊之外引用任何東西。

那麼如何在Newspeak中打印控制檯?打印屬於平臺模塊的一部分的控制檯類(a.k.a. Smalltalk的腳本)。爲了能夠打印到控制檯,您的模塊需要一個Platform構造函數參數,從平臺獲取控制檯,將控制檯存儲在一個插槽中,然後使用它進行打印。

基本上它就像在語言級別執行的依賴注入一樣。語言IDE和運行時可幫助您打包並引導程序,但如果您正在查找更多詳細信息,請轉至Gilad Bracha's blog,例如參見this post或查看Newspeak Modules paper

P.S.爲了紀錄,新聞報道既不實用也不可用 - 它在工業環境中使用,現在已經有一個小型(但正在增長)的開源社區。 Newspeak是非常新的,不斷髮展的,但從個人經驗來看,編寫程序非常簡單有趣。

+0

這並不缺乏全局狀態 - Console類是全局狀態,它只是由編譯器管理,而不是用戶。 – Puppy 2010-12-26 20:58:54

+0

不完全。控制檯類是平臺模塊的一部分,沒有首先獲取平臺實例就無法獲得它。這個類本身就是模塊的一個屬性,Vassili Bykov的這些系列文章給出了一個很好的解釋:http://blog.3plus4.org/2008/12/04/a-taste-of-nested-classes-part -1/ – Yardena 2010-12-26 21:19:39

+0

我認爲這個論點歸結爲「不存在於一種語言中」的定義。恕我直言,如果編程語言的編譯器和運行時不向程序員公開某個概念,那麼「該概念在語言中不存在」,例如, Java是一種沒有內存分配和轉到的語言,儘管它們顯然是在引擎蓋下發生的。 – Yardena 2010-12-26 21:37:28

-5

實際上,這樣的事情永遠不會存在。考慮 - 當您打印到控制檯時,該控制檯手柄從哪裏來?當你提到某個功能時,該功能從哪裏來?它肯定不存在於你調用它的函數的堆棧中。沒錯 - 這是全球性的。實際情況是,如果沒有全局變量,你永遠不能引用任何不是直接在堆棧或堆中的東西 - 這意味着沒有機器指令,這要歸功於DEP。對於堆,你會從哪裏得到堆?你不能調用OS函數來爲你分配一些實際的新內存 - 這是全局的。

從理論上講,您可以創建這樣一種語言或程序,但事實上它更像Brainfuck,而不是任何實際可用的東西。

+3

正如我在問題中所說的,Newspeak聲稱完全是這樣做的(沒有全局命名空間的工作)。 – 2010-11-21 21:46:02

+0

@穆罕默德:我讀過維基百科的文章,對我來說聽起來並不是非全球性的。這聽起來也很不切實際且不可用。 – Puppy 2010-11-21 23:04:24

+4

@DeadMG:在觀察者眼中,不切實際且無法使用。這是一個Smalltalk衍生品,它是新的並引起了一些興趣。無論如何,這個概念通常依賴於消息傳遞,所以我會給你另一個例子:假設一個由許多並行進程組成的Erlang併發程序是消息通信。跨越不同的處理器。你能告訴我什麼是全球/共享環境?就這件事採取任何不共享消息系統。 – 2010-11-21 23:34:55

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) 

與這種做法並沒有全局的程序時,程序中的功能幾乎可以完全從一切前隔離通過他們得到的論點來理解他們可以訪問的內容。然後你可以爲函數創建替代的環境,然後在「監獄」中運行它們。庫和函數就像電路中的電子元件一樣,在你需要的地方,而且能夠將這些元件連接到你想要的任何地方。設計這種模式的編程語言可能會有一些語法糖,以方便自動將隱式「默認」環境傳遞給函數調用,但是您總是可以明確強制他們使用任何您想要的替代環境。例如,在全球語言中,如果您有一個旨在訪問操作系統文件系統或網絡中數據的庫,則可以提供備用環境並監視I/O或創建庫使用您自己的虛擬文件系統或VPN連接,而不是常規的文件系統和網絡。