These are chat archives for ramda/ramda

May 2018
Julien Bonnin
May 31 2018 09:56

Hello everyone. I had a small question before sumitting an issue. In many cases Ramda methods are trying to detect constructor/prototype implementation of a method and uses it if it exists. This is a huge problem for me as my JS is a javascript tag implemented on different websites.

Exemple :

The empty method.

module.exports = _curry1(function empty(x) {
  return (
    (x != null && typeof x['fantasy-land/empty'] === 'function') ?
      x['fantasy-land/empty']() :
    (x != null && x.constructor != null && typeof x.constructor['fantasy-land/empty'] === 'function') ?
      x.constructor['fantasy-land/empty']() :
    (x != null && typeof x.empty === 'function') ?
      x.empty() :
    (x != null && x.constructor != null && typeof x.constructor.empty === 'function') ?
      x.constructor.empty() :
    _isArray(x) ?
      [] :
    _isString(x) ?
      '' :
    _isObject(x) ?
      {} :
    _isArguments(x) ?
      (function() { return arguments; }()) :
    // else
      void 0

All those conditions are problematic. If the website is using old librairies such as Prototype.js or Mootools, Ramda will start using the x.empty method from those. In the case of Mootools for exemple, Array.prototype.empty is added, but their implementation is HORRIBLE (mutations are everywhere):

Array.prototype.empty = function() {
   this.length = 0;
   return this;

So whenever I use ramda's isEmpty (which uses empty and equals), here is what happens:

return equals(x, empty(x))
==> x is compared to an 'empty' version of x, but the call to empty empties the original x by reference because Ramda choses to use an external implementation. Thus, isEmpty will ALWAYS be true. This has horrible consequences.

Do you think I should file an issue ? Thanks

Zach Lysobey
May 31 2018 12:51
@Powerplex_gitlab I miss Mootools and Prototype.js!!!
Julien Bonnin
May 31 2018 13:02
You're the only one I think :trollface:
Mike Lambert
May 31 2018 14:29
this is interesting, but i don't really think it's a real issue
it's more of an issue of mootools/prototype.js modifying the prototypes of the built in Array, which we learned was a bad idea years ago
what could ramda do to fix this?
Stefano Vozza
May 31 2018 14:39
yeah, pandering to old libraries that did crazy stuff back in the day is why we can't have Array.prototype.flatten, which obviously makes sense at a language level because it will break lots of old sites but Ramda has no constraints like that
Julien Bonnin
May 31 2018 15:31
My question is more "Why is ramda looking into the constructor property in the first place ?"
To give a context, imagine a third-party script which is integrated on many websites, like a tag manager, or an analytics tracker. I do not have control over the libraries used by such websites, so I simply cannot use Ramda because of this.
My app is not a self-contained website, it is a script which send data from websites to machine-learning algorithms on the back-end. Ramda methods which are supposed to return a boolean are broken by outside libraries simply because it is trying to look into x.constructor
Julien Bonnin
May 31 2018 15:37
Of course if libraries are overriding native prototype methods, there is nothing that could be done. But in this case, Array.prototype.empty does not exists in ES specifications, so why does ramda is trying to look into it ?
But thanks for you answer :D
Rocky Madden
May 31 2018 15:42
For compatibility with Fantasy Land:
Stefano Vozza
May 31 2018 15:43
well this is down to a long running debate in the community amongst those of us who believe ramda's dispatching is too promiscuous and those who think it's not promiscuous enough. see #2347 and #2354 amongst many more...
Daniel Rodríguez Rivero
May 31 2018 15:48
I am on the side that things it is too promiscuous...
Julien Bonnin
May 31 2018 17:04
Thank you everyone, I will read all that :) In the meantime I have no choice but to get rid of some methods when I use ramda !