Search code examples
rascal

Representing a class table in Rascal


I would like to represent a kind of class table (CT) as a singleton in Rascal, so that some transformations might refer to the same CT. Since not all transformations need to refer to the CT (and I prefer not to change the signature of the existing transformations), I was wondering if it is possible to implement a kind of singleton object in Rascal.

Is there any recommendation for representing this kind of situation?

Edited: found a solution, though still not sure if this is the idiomatic Rascal approach.

module lang::java::analysis::ClassTable

import Map;

import lang::java::m3::M3Util;

// the class table considered in the source 
// code analysis and transformations. 
map[str, str] classTable = ();


/**
 * Load a class table from a list of JAR files. 
 * It uses a simple cache mechanism to avoid loading the 
 * class table each time it is necessary. 
 */ 
 map[str, str] loadClassTable(list[loc] jars) {
   if(size(classTable) == 0) {
     classTable = classesHierarchy(jars);
   }
   return classTable;
 }

Solution

  • Two answers to the question: "what to do if you want to share data acros functions and modules, but not pass the data around as an additional parameter, or as an additional return value?":

    • a public global variable can hold a reference to a shared data-object like so: public int myGlobalInt = 666; This works for all kinds of (complex) data, including class tables. Use this only if you need shared state of the public variable.
    • a @memo function is a way to provide fast access to shared data in case you need to share data which will not be modified (i.e. you do not need shared state): @memo int mySharedDataProvider(MyType myArgs) = hardToGetData();. The function's behavior must not have side-effects, i.e. be "functional", and then it will never recompute the return value for earlier provided arguments (instead it will use an internal table to cache previous results).