10

Are there languages where the scope is defined in such a way that does not extend to the enclosed functions? In other words is there a language where a code like the following (Python-like syntax):

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

would give an error because x is not defined inside the function fact?

In general, are there languages where the scope of any function wouldn't include functions defined within it?

Edit: Thanks for the informative comments. The reason I thought about this is that the situation of an internal function having access to all the environment provided by its containing functions sounds suspiciously close to me to the situation described by Joe Armstrong in his argument against OOP:

Because the problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.

Also relevant is that I hear that the language Newspeak doesn't has no global namespace, though I have no idea how it works.

I can imagine the issue, raised in Brian's comment below, of built-in functions (functions imported from __builtins__ in Pythonspeak or System in many other languages) be introduced artificially by the interpreter/compiler in every function. After all they are almost always treated specially in the language in the first place. Another option is to have them as methods of an object passed as a parameter to the function or imported as a module from within.

Yardena
  • 2,837
  • 20
  • 17
Muhammad Alkarouri
  • 23,884
  • 19
  • 66
  • 101
  • 4
    Note that `print`, `reduce`, and `xrange` also appear to be identifiers being resolved from some outer scope. Which shows why this is rarely useful. – Brian Nov 21 '10 at 21:22

3 Answers3

8

I'll try to roughly outline how it works in Newspeak.

Any code you write has to be in a module. Module is a kind of class, since in Newspeak classes can contain other classes, a Module is essentially a top-level class - one which is not contained in another class. What is special about Newspeak is that you cannot refer to anything outside of your module.

So how do you print to console in Newspeak? Printing belongs to Console class (a.k.a. Smalltalk's Transcript) which is part of the Platform module. To be able to print to console, your module would take a Platform constructor parameter, get console from the platform, store the console in a slot, and then use it to print.

Basically it's like dependency injection enforced on the language level. The language IDE and runtime help you package and bootstrap your program, but if you are looking for more details - go to Gilad Bracha's blog, see this post for example, or check out Newspeak Modules paper.

P.S. Newspeak is neither impractical nor unusable, for the record - it was used in the industrial environment, and now has a small (but growing) open-source community around it. Newspeak is very new and evolving, sure, but from personal experience - it is quite easy and fun to write programs in.

Yardena
  • 2,837
  • 20
  • 17
  • That's not lacking global state- that Console class is global state, it's just managed by the compiler, not the user. – Puppy Dec 26 '10 at 20:58
  • Not quite. Console class is part of the platform module, there is no way to obtain it without first getting a Platform instance. The class itself is a property of the module, these series of posts by Vassili Bykov give a pretty good explanation: http://blog.3plus4.org/2008/12/04/a-taste-of-nested-classes-part-1/ – Yardena Dec 26 '10 at 21:19
  • I think the argument boils down to the definition of "not exist in a language". IMHO if the compiler and runtime of a programming language do not expose a certain concept to the programmer, then "the concept does not exist in a language", e.g. Java is a language without memory allocations and goto's, even though they obviously do happen under the hood. – Yardena Dec 26 '10 at 21:37
0

I believe you could make a programming language where global scope is substituted by, for example, an associative array containing functions and objects, which would then be passed as a working environment to every function that is called.

Consider the following example. When in a regular Python program you would write something like this:

import foo

def square(x):
    return x*x

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

in a program with no globals you would rather write something like this:

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

and this code would be executed within a context something like this:

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

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

main(environment)

In a program with this kind of approach and no globals, the functions within the program could be almost completely isolated from everything except what they can access through the arguments they get. You could then also create alternative environments for functions and then run them in "jails". Libraries and functions would be like electronic components in a circuit, where you need, but also are able to connect the pieces to whatever you want. A programming language designed this pattern in mind could maybe have some syntactic sugar for convenience to automatically pass an implicit "default" environment to function calls, but you could always explicitly force them to use whatever alternative environment you want.

For example, in a global-less language, if you have a library which is designed to access data in the operating system's file system or network, you could provide an alternative environment and monitor the I/O or make the library use your own virtual file system or a VPN connection instead of the regular file system and network.

trololo
  • 369
  • 1
  • 3
  • 4
-5

Realistically, such a thing could never exist. Consider - when you print to the console, where is that console handle coming from? When you refer to a function, where did that function come from? It sure doesn't exist physically on the stack of the function you called it from. That's right - it's a global. The reality is that without globals, you could never refer to anything that was not directly in your stack or heap - which means no machine instructions, thanks to DEP. And for the heap, where would you get a heap from? You can't call an OS function to allocate you some actual new memory - that's a global.

In theory, you could create such a language or program, but the reality is that it would be more like Brainfuck than anything actually usable.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • 3
    As I said in the question, Newspeak claims to do exactly that (work without a global namespace). – Muhammad Alkarouri Nov 21 '10 at 21:46
  • @Muhammad: I read the wikipedia article, and it doesn't sound very non-global to me. It also sounds hideously impractical and unusable. – Puppy Nov 21 '10 at 23:04
  • 4
    @DeadMG: impractical and unusable is in the eye of the beholder. It is a Smalltalk derivative that is new and generating some interest. Regardless, the concept usually depends on message passing so I will give you another example: Assume an Erlang concurrent program consisting of a number of parallel processes communicating be messages. Across different processors. Can you tell me what is the global/shared environment? Take any shared-nothing messaging system for that matter. – Muhammad Alkarouri Nov 21 '10 at 23:34
  • 3
    Linux would actually be usable if it wasn't based around global state and lack strongly typed data structures. You are thinking on much too low level anyways, obviously a high level language can be made without any globals, stdout is explicitly passed to any function that needs it (if you have tons of functions that are using stdout, you are doing something wrong). Global state is just plain wrong, look at the way programs get access to your file system and make all kinds of file name clashes for no good reason. That wouldn't happen without global state. – L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ Dec 26 '10 at 15:45
  • @Longpoke: So where did those function addresses to call with stdout come from? Oh wait- they're global state, and the instructions that compose them are also global state. – Puppy Dec 26 '10 at 16:11
  • 2
    Once again, you are thinking too low level. Anyways I'm not so sure there is merit for stdout's existence in these types of languages. – L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ Dec 26 '10 at 16:15
  • 2
    I consciously made the decision to pass the text output stream, "stdout" to the function I called; it is not necessarily the same one I passed to other functions. It could be outputting to a printer or a window. It could be a facade that only lets the .write function to be called and not any of the configuration methods. See Dependency Injection (AKA OOP). See Object Capability Model. The difference here is that 3rd party modules used by one object can't gratuitously access the output stream unless they are given it. File extensions... see NoApplication. – L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ Dec 26 '10 at 17:15