8

I am working on a set implementation in JavaScript currently. This should kind of simulate generics as known from Java or C#. I need a mutable version of that (allows for adding/removing set values) and an immutable one.

My constructor signature looks like this:

new GenericSet( 'number', [ 10, 20, 30 ] );

,

 // mutable set of mixed values (allows to add further values via "add")
 new MutableGenericSet( '*', [ 'foo', 42, {}, /./ ] );

or

// DataValues.prototype.equals will be used by the set for determining equality.
new GenericSet( { type: DataValue, valueComparison: 'equals' }, [ dv1, dv2, dv3 ] );

Just GenericSet or one set implementation per type?

Initially, my main purpose for this was to have sets of values of one type. E.g. a DataValuesSet which would only accept data Values. I could then define interfaces with functions that require a DataValuesSet instance. I could not use inheritance (and guess that would be bad anyhow), so I would use composition and have a GenericSet / MutableGenericSet instance internally.

An alternative approach would be to always take GenericSet and implement and use GenericSet.requireSetOfType( type ) which would throw an error if the set's type was not the required one. My concern with doing it this way is that my interface definitions would look less explicit.

Take

/**
 * @param DataValuesSet dataValues
 */
function printDataValues( dataValues ) {
 if( !( dataValues instanceof DataValuesSet ) ) {
 throw Error( '...' );
 }
 // ...
}

vs.

/**
 * @param GenericSet<DataValue>
 */
function printDataValues( dataValues ) {
 // Throws error if dataValues is not a set or it it is a set with values of wrong type.
 GenericSet.requireSetOfType( dataValues, DataValue );
 // ...
}

perhaps using @param GenericSet(DataValues) dataValues for documenting the second choice would be alright? Does anyone see any further implications with the second approach or are there any alternative suggestions? To me the, second one looks more intuitive and my concern with the first one is that I would just create more overhead with constructors while I can not see any clear advantage right now.

asked Jul 12, 2013 at 21:37
2
  • 6
    Why would generics matter in a language like JS which is weakly typed? Commented Apr 23, 2015 at 23:28
  • 1
    This isn't possible in a language like JavaScript, which is both weakly and dynamically typed. Just use a typed JS variant like TypeScript. Commented Mar 4, 2017 at 2:10

3 Answers 3

3

I used to try solving these sorts of problems with JavaScript, which only served to complicate implementations of... Well... Anything. If you don't want to use something like Typescript, document what you expect. If people ignore your documentation they enter uncharted territory.

Don't try to force a round peg into a square hole that anyone can mold into a round hole. That's JavaScript. Embrace it. Don't fight it, baby. Document it, and just get back to writing code.

answered Oct 1, 2017 at 0:33
0

I would say that the first example is more readable. It does not imply that an error is thrown for the incorrectly typed set. It says that this function takes a DataValueSet. Being explicit in your code adds clarity.

GenericSet.requireSetOfType obfuscates the intent of the type check in the print function. It looks like it is checking for items with type DataValue.

answered Jan 8, 2016 at 10:19
1
  • Readability doesn't seem to be a strong enough argument for me here. You could make the documentation perfectly clear in either case by using DataValuesSet vs. GenericSet<DataValue>. Perhaps instead of GenericSet.requireSetOfType naming the function GenericSet.assertSetOfType or similar would be clearer indeed. Commented Mar 4, 2017 at 16:56
0

Given on the options, you present, I would prefer the first solution, because it is more readable than the second one. But, if you really want to do a JS-style solution, make a builder-function, whether the objects are from the same type or should be of mixed type (MakeStrictCollectionvs MakeMixedCollection). In the builder function, you could test, whether the type of every member of your given collection is from the same type or not and throw an error or return an object from each constructor, which has an additional type attribute "type":"strict" vs "type":"mixed".


Besides that:

You should take a look at Typescript, which may be, what you are looking for. And there is a package, which seem to suit your needs having generic collections.

answered May 7, 2016 at 19:29
1
  • -1 For MakeStrictCollection vs MakeMixedCollection. In regard to the code examples above, the printDataValues function would change to verify that the given object was instanceof StrictCollection and that its type was DataValues. GenericSet.requireSetOfType could be exactly that - hence, your suggestion seems to be merely an implementation detail to the GenericSet approach. Commented Mar 4, 2017 at 17:15

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.