The Forum for Discussion about The Third Manifesto and Related Matters

Please or Register to create posts and topics.

Javascript records/tuples proposal

It seems Javascript is only very hesitantly thinking about records/tuples -- here's the current form of a language proposal.

Then how are Js programmers handling record-alike data structures currently?

My reason for asking is there's a couple of Haskell-derived languages that compile to Js; and which already have (very similar) record-alike data structuring: Elm, PureScript. That is to say, those two languages' approaches are similar to each other, but notably different from Haskell. Have they rolled their own record-alikes, not used anything already in Js?

I'm thinking about how to combine Algebraic Data Types (aka Tagged Unions), with data structures having components, with record access. Consider this example from that Elm page:

type Msg
  = PressedEnter
  | ChangedDraft String
  | ReceivedMessage { user : User, message : String }
  | ClickedExit

PressedEnter etc are tags (starting upper case); PressedEnter, ClickedExit carry no components; ChangedDraft carries a single component type String; ReceivedMessage carries two components, so to support position-independent expressions, there's a record-alike thing inside { ... } giving attribute names (-ish).

But the semantics is awkward: ReceivedMessage actually has a single component (the tuple), which has two sub-components. And that needs double-nesting syntax every time you want to extract or build/update a sub-component. (Also it means the implementation has a corresponding extra layer of indirection.)

Artefacturally (if that's a word) what's also annoying is there's doubling-up of names: both ReceivedMessage and message are in the namespace. It's particularly irking both contain (sub)label message.

I'm wondering if a language could mash together tags and fields like ... | { ReceivedMessage : String, user : User } ...

Then the rule is that in a (data)type declaration, each branch of the union must contain a globally unique field label that acts as the tag, and can contain other components with not-necessarily-unique field labels. IOW the declaration above is shorthand for

type Msg
  = { PressedEnter : Void }
  | { ChangedDraft : String }
  | { ReceivedMessage : String, user : User }
  | { ClickedExit : Void }
  | { SentMessage : String, user : User }          -- added, see below

(Type Void is a dummy not-really component.) Different branches might contain the same-labelled component, providing there is a unique tag to identify the branch. (In the example, field labelled user appears against two branches.)

Is this giving a coherent sum-of-products data structuring?

 

Quote from AntC on November 30, 2021, 7:58 am

It seems Javascript is only very hesitantly thinking about records/tuples -- here's the current form of a language proposal.

Then how are Js programmers handling record-alike data structures currently?

I use JavaScript arrays.

There is an inbuilt array sort()method that accepts an optional compareFunction and which can be used to sort arrays that contain both primitive and object values. Once sorted, other array methods can be used to "de-duplicate" the arrays to provide set-alike structures such a tuples and relations.

The JS record/tuple proposal is OK I guess, but for me, limitations such as records only allowing String keys and primitive values would probably lead me to stick with using arrays.

I note that the "silent dedup" of record literals is somewhat interesting (or maybe an artefact of the pollyfill?)

import { Record, Tuple } from "@bloomberg/record-tuple-polyfill";
const log = console.log;
const rec = #{a:1,b:1,a:2};
for(const[key, value]ofObject.entries(rec)){
   console.log(key); console.log(value)
}

which returns

"a"
2
"b"
1

 

Quote from Paul Vernon on December 2, 2021, 1:00 pm
Quote from AntC on November 30, 2021, 7:58 am

Then how are Js programmers handling record-alike data structures currently?

I use JavaScript arrays.

Hmm? Usually 'array' means homogenous: all cells are the same type; you access elements by some sort of offset or enumeration. Tuples are heterogenous: the value labelled name is a String, the value labelled height is a number, the value labelled frequent-flyer is a Boolean.

There is an inbuilt array sort()method that accepts an optional compareFunction and which can be used to sort arrays ...

Hmm? Sorting usually applies to collections of homogenous values/structures -- a collection of tuples, for example. You wouldn't "sort" a single tuple, because changing relative position changes meaning.

that contain both primitive and object values. Once sorted, other array methods can be used to "de-duplicate" the arrays to provide set-alike structures such a tuples and relations.

The JS record/tuple proposal is OK I guess, but for me, limitations such as records only allowing String keys and primitive values would probably lead me to stick with using arrays.

I note that the "silent dedup" of record literals is somewhat interesting (or maybe an artefact of the pollyfill?)

const rec = #{a:1,b:1,a:2};
...
which returns
"a"
2
"b"
1

 

So could I have the b:-value being of different type (say a String) vs the a:-value(s)? Allowing a repeated label a: makes that not a record IMO.

Quote from AntC on December 2, 2021, 9:36 pm

Hmm? Usually 'array' means homogenous: all cells are the same type

I'm not sure that JavaScript is a very "usual" kind of language.

> Arrays are list-like objects whose prototype has methods to perform traversal and mutation operations. Neither the length of a JavaScript array nor the types of its elements are fixed

Still, that is all handy if you are looking to implement relations and/or sets of (relational model, named perspective) tuples

Hmm? Sorting usually applies to collections of homogenous values/structures

Maybe so, but you are not stopped from sorting heterogeneous values. Well, you need to build your own compareFunction as native JS compare is not antisymmetric . E.g. in JavaScript both 1 > '1' and '1' > 1 return false. JS sort is stable nowadays however, so at least things are deterministic, but still the native sort is not really up-to the job of giving a total sort;

[2,'1',1].sort() returns ['1', 1, 2] while

[1,2,'1'].sort()  returns [1, '1', 2]

 

 You wouldn't "sort" a single tuple, because changing relative position changes meaning.

Maths tuples yes, relational tuples no. Not that it means anything logically to sort a relational model tuple, but if implementing relational operators using JS arrays, then sorting is one way to go about removing duplicate attributes after a join, cross product etc.

BTW one reason I posted my Which Tuple? thread was to ask about the multiple meanings the word tuple has. I certainly think it unfortunate. If we add in programming language use of the word, then (maybe?) we end up with yet another meaning. Although to be fair, I think the proposed JS tuple is pretty much exactly a maths tuple - i.e. it can be empty, can't have "gaps", can hold a value of any type (well primitive types anyway). I'm not so sure about other programming languages tuples.

There is something to be said for database folks to stop using the word tuple, and use the word record, (or even row), instead.

Quote from Paul Vernon on December 3, 2021, 9:56 am
Quote from AntC on December 2, 2021, 9:36 pm

Hmm? Usually 'array' means homogenous: all cells are the same type

I'm not sure that JavaScript is a very "usual" kind of language.

So I'm discovering. The word that comes to mind so far is 'icky'. As in, the more I find out, the more I need go wash my hands afterwards.

Arrays are list-like objects whose prototype has methods to perform traversal and mutation operations. Neither the length of a JavaScript array nor the types of its elements are fixed

So it's somewhere between a ALGOL-style 'Array', and a LISP List. Ick!

Still, that is all handy if you are looking to implement relations and/or sets of (relational model, named perspective) tuples

"Handy" as in 'hackable', not a disciplined a structure that will make sure what you are implementing is a set or a named-perspective tuple. Ick!

Hmm? Sorting usually applies to collections of homogenous values/structures

Maybe so, but you are not stopped from sorting heterogeneous values. Well, you need to build your own compareFunction as native JS compare is not antisymmetric . E.g. in JavaScript both 1 > '1' and '1' > 1 return false. JS sort is stable nowadays however, so at least things are deterministic, but still the native sort is not really up-to the job of giving a total sort;

[2,'1',1].sort() returns ['1', 1, 2] while

[1,2,'1'].sort()  returns [1, '1', 2]

Ick! Ick!

 You wouldn't "sort" a single tuple, because changing relative position changes meaning.

Maths tuples yes, relational tuples no.

Let's be careful here. There are many relational models. We can contrast TTM 'tuple' with for example the Alice book 'named vs unnamed perspective' -- for the latter relative position changes meaning.

Not that it means anything logically to sort a relational model tuple, but if implementing relational operators using JS arrays, then sorting is one way to go about removing duplicate attributes after a join, cross product etc.

You don't get "duplicate attributes" from a valid (Natural) Join; nor a valid cross-product (indeed avoiding gibberish like "duplicate attributes" is the purpose for the definition of a valid operation) -- unless you're talking about SQL which can produce either/both "duplicate column names" and "anonymous columns" but never "attributes" -- and which is neither "logical" nor "relational".

BTW one reason I posted my Which Tuple? thread was to ask about the multiple meanings the word tuple has. I certainly think it unfortunate. If we add in programming language use of the word, then (maybe?) we end up with yet another meaning. Although to be fair, I think the proposed JS tuple is pretty much exactly a maths tuple - i.e. it can be empty, can't have "gaps", can hold a value of any type (well primitive types anyway). I'm not so sure about other programming languages tuples.

maths tuples don't have anything identifiable as a attribute label. Therefore no notion of "duplicate attributes".

There is something to be said for database folks to stop using the word tuple, and use the word record, (or even row), instead.

Well, there's something to be said for D&D choosing a different word than tuple. They have given entirely sensible reasons for why they don't use record (positional) nor row (goes with column, therefore positional) -- essentially because they wish to distinguish TTM from SQL. On a quick googling, there's plenty of hits for "labelled tuple" nothing to do with TTM; and the Alice book doesn't call them anything other than 'named tuples'. So seems nobody else has found an adequate replacement term for tuple.

Furthermore for those of us who have a more sophisticated view of programming-language typing. (So the following doesn't apply for you.) ... Alice section 3.2

In the named perspective, it is natural to view tuples as functions. More precisely, a
tuple over a (possibly empty) finite set U of attributes (or over a relation schema R[U])
is a total mapping u from U to dom.

... (In general, the order used in the linear syntax will correspond to ≤att, although that is not necessary.)

Then we say (using Alice's notation) < A:5, B:3, C:"Widget" > is not comparable to < A:5, BB:3, C:"Widget" > (not comparable because different type) -- even though they have the same field values of the same type in the same position. Our language design might say < B:3, A:5, C:"Widget" > is comparable/is equivalent/is isomorphic under a morphism induced by ≤att.

A sophisticated-enough type system with first-class phantom types and type-erasure might even physically implement those comparable/isomorphic tuples with the same in-memory content, mapped from ≤att; and such that an equality-check runs the same code as an equality check of positional tuples. (But labelled tuples remain type-incomparable with positional.)

Quote from AntC on December 4, 2021, 4:26 am

"Handy" as in 'hackable', not a disciplined a structure that will make sure what you are implementing is a set or a named-perspective tuple. Ick!

Agreed. Yes it up to you to ensure you end up with a set coming out of each operator and not a bag. JS does not help, but then again it does not really get too much in the way either - which is well, handy.

 You wouldn't "sort" a single tuple, because changing relative position changes meaning.

Maths tuples yes, relational tuples no.

Let's be careful here. There are many relational models. We can contrast TTM 'tuple' with for example the Alice book 'named vs unnamed perspective' -- for the latter relative position changes meaning.

Agreed. Maybe it is a pity that the forum does not have some inbuilt glossary functionality. Then we might be able to have "tuple₁", "tuple₂", "tuple₃" etc to disambiguate the word "tuple" (or whatever words that are at risk of misinterpretation and mis-use). An on-line version of Date's New Relational Database Dictionary would be a great start for such a thing (if Chris/his publisher was willing) ...

You don't get "duplicate attributes" from a valid (Natural) Join; nor a valid cross-product (indeed avoiding gibberish like "duplicate attributes" is the purpose for the definition of a valid operation) -- unless you're talking about SQL which can produce either/both "duplicate column names" and "anonymous columns" but never "attributes" -- and which is neither "logical" nor "relational".

Agreed. At least in (all of) the relational model(s) anyway.  I was talking more about implementation matters where a JS concat() method will leave you with an array that will need "deduplicating".

Still, tuples with two or more attributes of the same name (but not the same value - I'm not interested in bags) are an interesting concept (to me anyway) ...   but that is a another topic entirely :-)

There is something to be said for database folks to stop using the word tuple, and use the word record, (or even row), instead.

Well, there's something to be said for D&D choosing a different word than tuple. They have given entirely sensible reasons for why they don't use record (positional) nor row (goes with column, therefore positional) -- essentially because they wish to distinguish TTM from SQL. On a quick googling, there's plenty of hits for "labelled tuple" nothing to do with TTM; and the Alice book doesn't call them anything other than 'named tuples'. So seems nobody else has found an adequate replacement term for tuple.

Thank you. That is useful. Another term would be good if there were an adequate alternative one. I was liking row but yes, when it goes with column we then get coorrdinate, matrix, array and other positional connotations. Humm. I can't find any adequate terms out of this lot...   fact, line, run, sentencestrand , object (!), whole, entity, ensemble, conglomeration, whatchamacallit, doodah , thingo  :-(

Furthermore for those of us who have a more sophisticated view of programming-language typing. (So the following doesn't apply for you.) ... Alice section 3.2

Ha! Still, very true.

For the record. For simple me. EQUAL < A:5, B:3, C:"Widget" >< A:5, BB:3, C:"Widget" > would return false rather than be "undefined" or be a "compile/runtime time error". (although your IDE might underline in red such a statement and let you know it is redundant and that it could be replaced by the literal false )