Существуют ли языки программирования без глобальных переменных?
есть языки, где объем определяется таким образом, что не распространяется на вложенные функции? Другими словами, есть язык, где код выглядит следующим образом (синтаксис, подобный Python):
>>> x = 3
>>> def fact(n):
... print x
... return reduce(lambda u, v: u*v, xrange(1, n+1), 1)
...
даст ошибку, потому что x не определен внутри функции fact
?
В общем, есть ли языки, где область любой функция не будет включать функции, определенные в ней?
редактировать: Спасибо за информативные комментарии. Причина, по которой я думал об этом, заключается в том, что ситуация внутренней функции, имеющей доступ ко всей среде, обеспечиваемой ее содержащими функциями, подозрительно близка мне к ситуации, описанной Джо Армстронгом в его аргумент против ООП:
- за проблемы с объектно-ориентированные языки все эти неявные среды они носят с собой. Вы хотел банан. а что у тебя было горилла держит банан и целые джунгли.
также актуально то, что я слышу, что язык новояз не имеет глобального пространства имен, хотя я понятия не имею, как это работает.
Я могу себе представить проблему, поднятую в комментарии Брайана ниже, встроенных функций (функций, импортированных из __builtins__
в Pythonspeak или системе на многих других языках) вводится искусственно интерпретатором / компилятором в каждом функция. Ведь к ним почти всегда относятся специально на языке в первую очередь. Другой вариант-иметь их как методы объекта, переданного в качестве параметра функции или импортированного как модуль изнутри.
3 ответов
Я постараюсь примерно описать, как это работает на новоязе.
любой код, который вы пишете, должен быть в модуль. Module-это своего рода класс, так как в классах Newspeak могут содержаться другие классы, модуль по существу является классом верхнего уровня, который не содержится в другом классе. Что особенного в новоязе, так это то, что вы не можете ссылаться ни на что за пределами вашего модуля.
Итак, как вы печатаете на консоли на новоязе? Печать принадлежит Класс консоли (a.к. a. Транскрипт Smalltalk), который является частью модуля платформы. Чтобы иметь возможность печатать на консоли, ваш модуль возьмет параметр конструктора платформы, получит консоль с платформы, сохранит консоль в слоте, а затем использует ее для печати.
в основном это похоже на инъекцию зависимостей, применяемую на уровне языка. Языковая среда IDE и среда выполнения помогут вам упаковать и загрузить вашу программу, но если вы ищете более подробную информацию-перейдите в Гилад Брача по блог см. этот пост например, или проверить бумага модулей новояза.
П. С. "новояз" - это не непрактично, ни непригодным для использования, для записи - он используется в промышленной среде, и сейчас имеет небольшой (но растет) с открытым исходным кодом сообщества вокруг него. Новояз очень новый и развивающийся, конечно, но из личного опыта-в нем довольно легко и весело писать программы.
Я считаю, что вы можете сделать язык программирования, где глобальная область заменяется, например, ассоциативным массивом, содержащим функции и объекты, которые затем будут переданы в качестве рабочей среды для каждой вызываемой функции.
рассмотрим следующий пример. Когда в обычной программе 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)
в программе с таким подходом и без глобалов функции внутри программы могут быть почти полностью изолированы от всего, кроме того, что они могут получить доступ через аргументы, которые они получают. Затем вы также можете создать альтернативные среды для функций, а затем запустить их в "тюрьмах". Библиотеки и функции были бы подобны электронным компонентам цепь, где вам нужно, но также может соединить части к все, что угодно вы хотите. Язык программирования, разработанный для этого шаблона, может иметь некоторый синтаксический сахар для удобства автоматической передачи неявной среды "по умолчанию" для вызовов функций, но вы всегда можете явно заставить их использовать любую альтернативную среду, которую вы хотите.
например, на глобальном языке, если у вас есть библиотека, предназначенная для доступа к данным в операционной системе файловая система или сеть системы, вы можете предоставить альтернативную среду и контролировать ввод-вывод или заставить библиотеку использовать вашу собственную виртуальную файловую систему или VPN-соединение вместо обычной файловой системы и сети.
реально, такая вещь никогда не могла бы существовать. Подумайте - когда вы печатаете на консоли, откуда берется этот дескриптор консоли? Когда вы ссылаетесь на функцию, откуда взялась эта функция? Он уверен, что физически не существует в стеке функции, из которой вы его вызвали. Правильно-это глобальный. Реальность такова, что без глобалов вы никогда не могли бы ссылаться на что - либо, что не было непосредственно в вашем стеке или куче-что означает отсутствие инструкций машины, благодаря DEP. И для куча, откуда у тебя куча? Вы не можете вызвать функцию ОС, чтобы выделить вам фактическую новую память - это глобальная.
теоретически, вы могли бы создать такой язык или программу, но реальность такова, что это было бы больше похоже на Brainfuck, чем что-либо реально используемое.