Struct Type Introspection

Introduction

Similar to C, Julia types can contain sub components (fields) and and in that case are considered struct types which can be mapped to Javascript objects. Thus, new to version 1.1 a mapping has been established where if a JRef is created which corresponds to a Julia struct type, it will have a Javascript Accessor defined for each field of the struct type. Currently these values are read only.

DataFrames example

Following the DataFrame Introduction, a DataFrame can be created and then introspected using the following:

var julia = require('node-julia');
var DataFrames = julia.import('DataFrames');

var dv = julia.eval('DataFrames.@data([NA, 3, 2, 5, 4, NA, NA, 6, 7])');

console.log(JSON.stringify(dv,null,2));
console.log('mean of dv with NA values dropped: ' + julia.exec('mean',DataFrames.dropna(dv)));

dv.data[1] = 1;
console.log('dv.data is readonly, so dv.data[1] remains set to ' + dv.data[1]);

for(var i = 0;i < dv.na.len;i++) {
   if(i % 64 == 0) chunk = dv.na.chunks[i/64];

   // Use DataFrames builtin isna; Julia indexing is 1 based not 0 like Javascript
   var na = DataFrames.isna(julia.exec('getindex',dv,i + 1));  

   // Compare
   if((chunk >> i%64) & 1) console.log('index ' + i + ' is NA (Julia = ' + na + ')');
   else console.log('index ' + i + ' is not NA (Julia = ' + na + ')');
}

Output

{
  "data": {
    "0": 3,
    "1": 3,
    "2": 2,
    "3": 5,
    "4": 4,
    "5": 3,
    "6": 3,
    "7": 6,
    "8": 7
  },
  "na": {
    "chunks": {
      "0": 97
    },
    "len": 9
  }
}
mean of dv with NA values dropped: 4.5
dv.data is readonly, so dv.data[1] remains set to 3
index 0 is NA (Julia = true)
index 1 is not NA (Julia = false)
index 2 is not NA (Julia = false)
index 3 is not NA (Julia = false)
index 4 is not NA (Julia = false)
index 5 is NA (Julia = true)
index 6 is NA (Julia = true)
index 7 is not NA (Julia = false)
index 8 is not NA (Julia = false)

Explanation

There are several things going on here. The DataFrame package is Imported, and a DataArray is created using the @data macro using julia.eval, the resulting JRef is printed, DataFrames.dropna is used to remove the NA values, and the mean is calculated on the result. The na component of a DataArray is a BitArray{1} and so to check the validity of each index, the correct bit of the correct chunk is examined. In this case na is of length 9, so there is only 1 chunk; all of this is hidden by the Julia type BitArray, but is exposed in Javascript.