metarhia / common

Metarhia Common Library 🗜️
https://metarhia.com
MIT License
63 stars 34 forks source link

Implement Either type #31

Closed DzyubSpirit closed 7 years ago

DzyubSpirit commented 7 years ago

safeRequire function in metarhia/jstp can be implemented using Either type which will be used commonly in projects I think.

DzyubSpirit commented 7 years ago

@nechaido Could you describe please why you prefer array?

nechaido commented 7 years ago

It is more consistent this way, IMHO. And also seems like overkill in that case.

DzyubSpirit commented 7 years ago

@nechaido Could you please give an example of implementation with tuples for that case for comparison?

nechaido commented 7 years ago

@DzyubSpirit here it is:

const getTuple = () => [null, 5];

const [error, data] = getTuple();

if (error) {
  console.log('Error');
} else {
  console.log(data);
}
DzyubSpirit commented 7 years ago

@nechaido

const getEither = () => ({ isLeft: false, val: 5 });
// can be eitherRight(5), but it's not fair because tupleData can be implemented

const { isLeft, val } = getEither();

if (isLeft) {
 console.log('Error');
} else {
  console.log(val);
}

Seems pretty same, but what I really ask to implement is that case

DzyubSpirit commented 7 years ago

Comparing object/hash and tuple/array implementations

Conclusion

Tuples are compatible with errback contract for callbacks unlike hash. Hash is better checking for left type value as primitive type (but isn't common use case). Other differences aren't important in my opinion. Therefore I propose tuples.

Initialization

const eitherValTuple = [err, val]; // for tuple
const eitherValObject = { isLeft, val }; // for object
const eitherValBoth = makeEither(err, val); // for both

Syntax for initializing tuples is better because it don't need err and val names against object needing isLeft and val variable names or worse syntax { isLeft: false, val: 'data' }.

Checking whether either left or right type

const [err, val] = eitherValTuple;
if (err !== null && err !== undefined) {
  // if it's left type
} else {
  // if it's right type
}
const { isLeft, val } = eitherValObject;
if (isLeft) {
  // if it's left type
} else {
  // if it's right type
}

Syntax for object is better.

Implementing methods

// for tuples
const makeEither = (...) => {
  ...
  res[methodName] = method;
  return res;
}
// for objects
Either.prototype.methodName = method;

Syntax for objects is more common but isn't better as I think.

Using with callbacks

// for tuples
callback(...eitherValTuple);
// for objects
const { isLeft, val } = eitherValObject;
if (isLeft) {
  callback(val);
} else {
  callback(null, val);
}

Syntax for tuple is better obviously. Also it allows save not only left and right type values but all arguments for callback as array.

DzyubSpirit commented 7 years ago

@tshemsedinov, what do you think?

DzyubSpirit commented 7 years ago

Can be implemented as proposed there