ramda: `toString` is not idempotent for strings?

Somewhat surprisingly:

R.toString('abc'); //=> "\"abc\""
'abc'.toString(); //=> "abc"

Is it intended?

http://ramdajs.com/repl/?v=0.23.0#?toString('abc')%3B %2F%2F%3D> '"abc"'

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 19 (17 by maintainers)

Most upvoted comments

I agree with @dmitriz that the name R.toString() is surprising and I would expect it to be idempotent for Strings.

For a beginner the similarities between JavaScript’s functional torso in Array’s map, filter, reduce , etc. and Ramda’s R.map, R.filter, R.reduce are obvious. Then there are functions like R.test and R.match which just dispatch to JS. Fine. However, except for Numbers, R.toString has nothing to do with JavaScript’s toString().

I still have not encountered a situation there R.toString() could come in handy:

  • for dictionary Objects and Arrays it’s JSON.stringify(),
  • for Strings it’s something like String.quote() (or JSON.stringify()),
  • for Numbers it’s Number.toString(10) (or JSON.stringify()),
  • for Date it produces the JS code of a date constructor call in a string

Idempotence: The JS toString() method is often used to ensure that a variable is of type String if one is in doubt whether it is a Number or already a String. Applying R.toString() a number of times results in multiply quoted strings.

Oh I see, I’ve thought that kind of method is also called inspect.

toString reads like the JS traditional type conversion to String, which is also identical with Lodash:

https://lodash.com/docs/4.17.4#toString

I understand that Ramda is different from Lodash, but still find it unfortunate that methods with the same name produce different results.

We could deprecate R.toString and suggest that users migrate to show.

@skirankumar7: No. Among other differences:

> JSON.stringify  ({a: 1, b: () => {}})
'{"a":1}'            // Note, edited in response to comment from dmitriz 

> R.toString      ({a: 1, b: () => {}})
'{"a": 1, "b": () => {}}'

In this case, @dmitriz, we have R.toString(R.toString({a: {a: 1}, b: [1]})).

R.toString could choose between single and double quotes in order to minimize escaping, but I don’t like this option because:

  • it’s less consistent; and
  • it only helps in some cases (any string containing both ' and " will still require escaping).

@semmel, it sounds as though String is the function you’re after. 😉

R.toString is very helpful when writing a REPL or generating documentation. In these contexts it is not acceptable for 0 and "0", /x/ and "/x/", etc. to have colliding string representations.