Skip to content

Scoping

Nick Pope edited this page Dec 5, 2015 · 6 revisions

In many languages, or extensions to those languages, there is some notion of object. An object is a grouping of state along with associated actions to modify or access that state. This can be done in a class-based way, where the structure and contents of an object are defined by blueprint. Or it can be done in a prototype-based way where each object is based upon some exemplar but is not restricted by it. So why do we need objects? And how can this be done in JS-Eden?

Problems with Objects

Underneath JS-Eden is JavaScript which provides a prototype-based object mechanism, and it is possible to leverage this within JS-Eden to some degree. However, whilst prototype-based objects are relatively flexible, they are still not entirely suited to Empirical Modelling activities because of the following:

  1. A classification needs to be made by the modeller, most likely at an early stage prior to fully understanding the problem.
  2. Cross-cutting concerns. It may prove difficult or impossible to neatly split definitions as belonging to one object or another. Forcing such organisation may be inappropriate.
  3. Complex hierarchies make observation more difficult not less.

The last point requires more explanation because it goes against the very reason for having objects in the first place, which is to reduce the incomprehensibility of a vast single flat view of state.

Organising state and action into a vast hierarchy of objects means that observation of that state is also restricted to observing objects and needing to know the path through the hierarchy to find what you are looking for. The arguments here are the same as those found in support of relational databases. It would be better if any view of the state could be supported rather than a single fixed view, as is possible using relational queries.

Benefits of Objects

Despite the disadvantages given above, objects still have advantages and solve problems which (prior to scoping) the js-eden environment suffered from. Specifically:

  1. Rapid creation of similar entities.
  2. Shared and reusable code.
  3. Conflicting names in a vast flat namespace of symbols.

These issues must be resolved to scale up, but the question is are there ways of doing so without backing ourselves into a corner with fixed ontologies?

Existing Solutions

JS-Eden and its predecessor EDEN have had a variety of solutions to the object problem. A recent approach has been to use constructor functions and function generators which generate observables from a pattern described by that function. The function potentially being generated from an existing piece of script. However, this means a solidification of a pattern into a class that cannot easily be altered and is in a totally different form requiring an understanding of functions and requiring an understanding of the object being constructed.

Another solution was the use of virtual agency. In simple terms this was namespacing where observables were specified in some context and then instantiated by automatically prepending all the observable names with some given string. You could shift the interpreter in and out of these different virtual agents, which meant you didn't always need to deal manually with this prepended part of an observable name. In essence, identical to something like C++ namespaces.

A more recent approach is the use of JavaScript objects directly in JS-Eden. However, it was not (until very recently and with limitations) possible to give properties of the objects is definitions. It also, obviously, suffers from the "Problems with Object" identified previously.

Scoping Scripts

A proposal, as implemented in the latest versions of JS-Eden, is to allow any existing script of definitions in the flat namespace to be scoped so that the context for the evaluation of those definitions is changed. This scoping is achieved by providing, temporarily, different definitions for some of the observables in the system and seeing what the consequences of that are on other observables that depend upon those changed.

In this way you can ask questions such as: what would the value of a be if I changed b to X?

There is no need for the modeller to know what dependencies are involved in asking the above question, so in effect the system automatically generates an object of sorts which contains all the required re-evaluations to answer the question. The object is generated by dependency, things are grouped and organised purely by their dependencies which are extraordinarily fine-grained, local, automatic, atomic and easily changed.

The same observables may appear in many entirely different scopes depending upon their network of dependencies, so this resolves the cross-cutting concerns issue above. No explicit definition of what is and is not in an object is required, the content of a scope is entirely fluid. The namespace is still flat and yet arbitrary groupings can be pulled out of it to generate multiple instances by overriding an observable with multiple different values.

Limitations

The key concern with scoping is that it is still insufficiently observable. All of the intermediate observable values involved in asking the what if? question are hidden away from view.

Clone this wiki locally