2010-11-21 22 views
9

Có các ngôn ngữ mà phạm vi được xác định theo cách không mở rộng đến các chức năng được đính kèm không? Nói cách khác là có một ngôn ngữ mà một mã như sau (cú pháp Python-like):Có ngôn ngữ lập trình không có biến toàn cầu không?

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

sẽ đưa ra một lỗi vì x không được định nghĩa bên trong hàm fact?

Nói chung, có các ngôn ngữ có phạm vi bất kỳ chức năng nào sẽ không bao gồm các hàm được xác định trong đó không?

Chỉnh sửa: Cảm ơn các nhận xét thông tin. Lý do tôi nghĩ về việc này là tình hình của một chức năng nội bộ có quyền truy cập vào tất cả các môi trường được cung cấp bởi các chức năng chứa của nó nghe có vẻ đáng ngờ gần gũi với tôi với tình hình được mô tả bởi Joe Armstrong trong mình argument against OOP:

Bởi vì vấn đề với ngôn ngữ hướng đối tượng là họ đã có tất cả môi trường tiềm ẩn này mà họ mang theo bên mình. Bạn muốn một quả chuối nhưng những gì bạn nhận được là một con khỉ đột giữ chuối và toàn bộ khu rừng.

Cũng có liên quan là tôi nghe rằng ngôn ngữ Newspeak không có không gian tên chung, mặc dù tôi không biết nó hoạt động như thế nào.

Tôi có thể tưởng tượng vấn đề, được nêu trong nhận xét của Brian dưới đây, các chức năng tích hợp (chức năng được nhập từ __builtins__ trong Pythonspeak hoặc Hệ thống bằng nhiều ngôn ngữ khác) được trình biên dịch/trình biên dịch giới thiệu trong mọi chức năng. Sau khi tất cả họ hầu như luôn luôn được đối xử đặc biệt trong ngôn ngữ ở nơi đầu tiên. Một tùy chọn khác là đặt chúng dưới dạng các phương thức của một đối tượng được truyền như một tham số cho hàm hoặc được nhập dưới dạng một mô-đun từ bên trong.

+1

Điều gì sẽ thực hiện được? – Blindy

+4

Lưu ý rằng 'in',' reduce' và 'xrange' cũng xuất hiện là số nhận dạng được giải quyết từ một số phạm vi bên ngoài. Điều này cho thấy lý do tại sao điều này hiếm khi hữu ích. – Brian

Trả lời

8

Tôi sẽ cố gắng phác họa chi tiết cách hoạt động của nó trong Báo.

Bất kỳ mã nào bạn viết phải nằm trong mô-đun . Mô-đun là một loại lớp, vì trong các lớp học của tạp chí có thể chứa các lớp khác, một Module về cơ bản là một lớp cấp cao nhất - một lớp không có trong lớp khác. Điều đặc biệt về Báo chí là bạn không thể tham chiếu đến bất kỳ điều gì bên ngoài mô-đun.

Vậy làm thế nào để bạn in ra bàn điều khiển trong Báo? In ấn thuộc về lớp Console (a.k.a. Bảng điểm của Smalltalk) là một phần của mô-đun Nền tảng.Để có thể in ra bàn điều khiển, mô-đun của bạn sẽ nhận tham số của hàm tạo dựng nền tảng, nhận bảng điều khiển từ nền tảng, lưu trữ bảng điều khiển trong một vị trí và sau đó sử dụng nó để in.

Về cơ bản giống như việc tiêm phụ thuộc được thực thi ở cấp độ ngôn ngữ. IDE ngôn ngữ và thời gian chạy giúp bạn gói và khởi động chương trình của bạn, nhưng nếu bạn đang tìm kiếm thêm chi tiết - hãy truy cập Gilad Bracha's blog, xem this post ví dụ hoặc xem Newspeak Modules paper.

P.S. Báo chí không thực tế hoặc không sử dụng được, vì hồ sơ - nó được sử dụng trong môi trường công nghiệp, và bây giờ có một cộng đồng nguồn mở nhỏ (nhưng đang phát triển) xung quanh nó. Báo chí rất mới mẻ và phát triển, chắc chắn, nhưng từ kinh nghiệm cá nhân - nó khá dễ dàng và thú vị để viết chương trình.

+0

Đó là không thiếu nhà nước toàn cầu - rằng lớp Console là trạng thái toàn cầu, nó chỉ được quản lý bởi trình biên dịch chứ không phải người dùng. – Puppy

+0

Không hoàn toàn. Lớp Console là một phần của mô-đun nền tảng, không có cách nào để lấy nó mà không có một cá thể Platform. Bản thân lớp này là thuộc tính của mô-đun, chuỗi bài đăng này của Vassili Bykov đưa ra một lời giải thích khá tốt: http://blog.3plus4.org/2008/12/04/a-taste-of-nested-classes-part -1/ – Yardena

+0

Tôi nghĩ rằng đối số sẽ tóm tắt định nghĩa "không tồn tại trong một ngôn ngữ". IMHO nếu trình biên dịch và thời gian chạy của ngôn ngữ lập trình không đưa ra khái niệm nhất định cho lập trình viên, thì "khái niệm không tồn tại trong ngôn ngữ", ví dụ: Java là một ngôn ngữ không có phân bổ bộ nhớ và các goto, mặc dù chúng rõ ràng xảy ra dưới mui xe. – Yardena

-5

Thực tế, một thứ như vậy không bao giờ tồn tại. Hãy xem xét - khi bạn in ra bàn điều khiển, bộ điều khiển đó đến từ đâu? Khi bạn đề cập đến một hàm, hàm đó đến từ đâu? Nó chắc chắn không tồn tại trên thực tế trên chồng của hàm mà bạn gọi nó từ đó. Đúng vậy - đó là toàn cầu. Thực tế là không có globals, bạn không bao giờ có thể tham khảo bất cứ thứ gì không trực tiếp trong stack hoặc heap của bạn - điều đó có nghĩa là không có hướng dẫn máy, nhờ DEP. Và đối với heap, nơi bạn sẽ nhận được một đống từ? Bạn không thể gọi một hàm hệ điều hành để cấp phát cho bạn một số bộ nhớ mới thực sự - đó là toàn cầu.

Về lý thuyết, bạn có thể tạo một ngôn ngữ hoặc chương trình như vậy, nhưng thực tế là nó sẽ giống Brainfuck hơn bất kỳ thứ gì thực sự có thể sử dụng được.

+3

Như tôi đã nói trong câu hỏi, tờ báo tuyên bố sẽ làm chính xác điều đó (công việc không có không gian tên chung). –

+0

@Muhammad: Tôi đọc bài viết wikipedia, và nó không có vẻ rất phi toàn cầu đối với tôi. Nó cũng nghe có vẻ không thực tế và không sử dụng được. – Puppy

+4

@DeadMG: không thực tế và không thể sử dụng được trong mắt của người xem. Nó là một dẫn xuất Smalltalk mới và tạo ra sự quan tâm. Bất kể, khái niệm thường phụ thuộc vào thông điệp đi qua vì vậy tôi sẽ cung cấp cho bạn một ví dụ khác: Giả sử một chương trình đồng thời Erlang bao gồm một số quy trình song song giao tiếp là tin nhắn. Trên các bộ vi xử lý khác nhau. Bạn có thể cho tôi biết môi trường chung/toàn cầu là gì? Thực hiện bất kỳ hệ thống nhắn tin chia sẻ không có gì cho vấn đề đó. –

0

Tôi tin rằng bạn có thể tạo ra một ngôn ngữ lập trình mà phạm vi toàn cầu được thay thế bằng, ví dụ, một mảng kết hợp chứa các hàm và đối tượng, sau đó nó sẽ được chuyển thành môi trường làm việc cho mọi hàm được gọi.

xem xét ví dụ sau đây. Khi trong một chương trình Python thường xuyên bạn sẽ viết một cái gì đó như thế này:

import foo 

def square(x): 
    return x*x 

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

trong một chương trình không có globals bạn thà viết một cái gì đó như thế này:

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

và mã này sẽ được thực hiện trong một bối cảnh một cái gì đó như thế này:

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

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

main(environment) 

Trong một chương trình có cách tiếp cận này và không có globals, các chức năng trong chương trình có thể gần như hoàn toàn bị cô lập khỏi mọi thứ thu thập những gì họ có thể truy cập thông qua các đối số họ nhận được. Sau đó bạn có thể tạo môi trường thay thế cho các chức năng và sau đó chạy chúng trong "jails". Thư viện và chức năng sẽ giống như các thành phần điện tử trong một mạch, nơi bạn cần, nhưng cũng có thể kết nối các mảnh với bất kỳ thứ gì bạn muốn. Một ngôn ngữ lập trình được thiết kế theo kiểu này có thể có một số đường cú pháp để thuận tiện tự động chuyển một môi trường ngầm định để thực hiện các cuộc gọi, nhưng bạn luôn có thể buộc chúng sử dụng bất kỳ môi trường thay thế nào bạn muốn. Ví dụ, trong một ngôn ngữ toàn cầu, nếu bạn có thư viện được thiết kế để truy cập dữ liệu trong hệ thống tệp hoặc mạng của hệ điều hành, bạn có thể cung cấp một môi trường thay thế và giám sát I/O hoặc tạo thư viện sử dụng hệ thống tệp ảo của riêng bạn hoặc kết nối VPN thay vì hệ thống tệp và mạng thông thường.

Các vấn đề liên quan