Re: Factor

Factor: the language, the theory, and the practice.

JavaScript Arrays

Wednesday, November 22, 2023

JSON or “JavaScript Object Notation” is widely used as a data format for storing, transmitting, and retrieving data objects. It is language-independent and has parsers in most modern programming languages. Factor is no exception, containing the json vocabulary.

I wanted to go over some wtfjs that relates to JavaScript Arrays and JavaScript Objects, and then see how something similar might work in Factor!

In JavaScript

You can define an array:

const person = ["John", "Doe", 46];

Or you can define an object:

const person = {firstName: "John", lastName: "Doe", age: 46};

You can start with an array and set it’s values by index:

const person = [];
person[0] = "John";
person[1] = "Doe";
person[2] = 46;

You can start with an object and set it’s values by key:

const person = {};
person["firstName"] = "John";
person["lastName"] = "Doe";
person["age"] = 46;

Or, using “dot notation” on an object:

const person = {};
person.firstName = "John";
person.lastName = "Doe";
person.age = 46;

In JavaScript, arrays are indexed by number, and objects are indexed by name. But, you can mix these and create association arrays that can be… both?

> const list = ["A", "B", "C"];
> list.length
3

> list[0]
"A"

> list["0"]
"A"

> list.key = "value";
> list.length
3

> list.key
"value"

> Object.assign({}, list);
{0: "A", 1: "B", 2: "C", key: "value"}

That’s kinda weird.

In Factor

Maybe Factor needs something like that? What if we define a type that has both a sequence and an assoc, and supports both the sequence protocol and the assoc protocol. How might that look?

TUPLE: js-array seq assoc ;

: <js-array> ( -- js-array )
    V{ } clone H{ } clone js-array boa ;

INSTANCE: js-array sequence

CONSULT: sequence-protocol js-array seq>> ;

INSTANCE: js-array assoc

CONSULT: assoc-protocol js-array assoc>> ;

And now we can do something kinda similar:

IN: scratchpad <js-array>
               { "A" "B" "C" } [ suffix! ] each
               "value" "key" pick set-at

IN: scratchpad dup first .
"A"

IN: scratchpad dup length .
3

IN: scratchpad dup members .
V{ "A" "B" "C" }

IN: scratchpad dup >alist .
{ { "key" "value" } }

IN: scratchpad "key" of .
"value"

Well, it doesn’t handle converting string keys so that "0" of would return the same value as first. And it doesn’t handle combining all the number indexed keys and name indexed keys to an alist output like the Object.assign({}, ...) call above. And probably a few other idiosyncrasies of the JavaScript association array that I’m not familiar with…

But do we like this? I dunno yet.