Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Here's an implementation of "deep equality" -- a relatively common operation on composite values -- in JS. It has millions of downloads in just the last week: https://github.com/substack/node-deep-equal/blob/master/inde...

It includes special cases for dates, takes O(n log n) time in the number of keys, and has suspicious comments like, "I've managed to break Object.keys through screwy arguments passing. Converting to array solves the problem." There are 15 open issues and 15 open pull requests. A sane language would have this operation built-in.



I would otherwise agree that JS's standard library is too small, but I don't think your example showcases it. Which languages offer this in their standard library? It's not in any of the languages I have used: C, C++, C#, Java, PHP, Python..

A better example would be the extremely poor Date object, which has only a couple format functions and can't even be created from a specified format. There's also a bunch of holes when manipulating data, filled by libraries like lodash(although the standard lib has improved significantly in this regard).


Python does:

>>> {"foo": [1, 2, set([True])]} == {"foo": [1, 2, set([False])]}

False

>>> {"foo": [1, 2, set([True])]} == {"foo": [int('1'), 2, set([bool(1)])]}

True


You're right, I forgot about those and overstated my case.


I don't blame you. I think the only reason I ever do deep comparison is in unit tests, and every test/assertion library has a `deepEquals` assertion, so it's not something I regularly miss.

There are better examples of deficiencies in Javascript's standard library, especially when targeting browsers, but Javascript has made massive strides lately like its native Set and Map datastructures.

For example, Set doesn't come with the classic methods `.intersection()` / `.difference()` / `.union()` / etc. but it's just not a defining moment of my overall experience with Javascript.

We're long past the days where you had to bring your own `Array#map`, but I don't know if all of these commenters are.


Ruby too:

  irb(main):002:0> {'foo' => [1, 2, [true].to_set]} == {'foo' 
  => [1, 2, [false].to_set]}
  => false

  irb(main):003:0> {'foo' => [1, 2, [true].to_set]} == {'foo' 
  => ['1'.to_i, 2, [true].to_set]}
  => true


C++ has this kind of equality for STL containers. Create nested maps, vectors, lists, sets, strings, etc, and you can just compare them with "==". It will do a deep compare.


Which languages offer this in their standard library? It's not in any of the languages I have used: C, C++, C#, Java, PHP, Python..

Off the top of my head, Haskell has "deriving Eq", and Scheme has "equal?". I'm pretty sure Python uses deep equality for tuples as well. Anyway, it's just one example of something I wanted to do in JS recently and ended up disappointed in the quality of the code I saw to do it.


In Clojure = is the deep equality op. (= 1 1) is true.


I'm all for bashing the insane world of Javascript, and think that the argument grandparent is is making is quite weak, but not many languages have deep-equality baked in.

Sure, you can perhaps override some methods on an object, but given two arbitrary objects (like two dicts in Python), knowing if two are 'equal' is not easy and certainly not built in.

That being said, JS doesn't make implementing this easy or simple at all.


This works in Ruby:

  irb(main):001:0> require 'set'
  => true

  irb(main):002:0> {'foo' => [1, 2, [true].to_set]} == {'foo' 
  => [1, 2, [false].to_set]}
  => false

  irb(main):003:0> {'foo' => [1, 2, [true].to_set]} == {'foo' 
  => ['1'.to_i, 2, [true].to_set]}
  => true


Actually it works in Python. And it's VERY handy, especially in unit tests.

See my other comment.


And yet, this is a perfect example of "this does not matter."

Pick a project. Think of a website you want to make. At no point during that are you going to be stonewalled by "Man, if only I wasn't forced to spend the last 4 hours debugging this weird deep equality issue. I could've gotten so much more done!"

You can take that information and use it however you want. It's the truth. It's up to you to either reject the notion or integrate it into your mindset and abandon the tendency to cling to idealisms. Ivory tower development simply does not happen in reality, and I say this as someone who spent a couple years trying to build an ivory tower Lisp.

I know it's not coming across at all, but I really identify with your mindset and acutely feel your pain. This was a major mental hurdle that I had to force myself to overcome. I'm saying, it's possible, and the only thing you have to do is to choose to do it.

Let go. Realize that it doesn't matter. It's worth the benefits. You can do so much more.

I was afraid that "letting go" would translate into "now I'm part of the problem too." But it turns out the opposite is true. It's very powerful that you have a background that most JS devs lack. Because they often rabbithole themselves into complexity, and you can come along and do something simple that no one else thought to stop and do.

But you can do all of that while still embracing the wider ecosystem. It's not an either-or. You can help bring sanity to what would otherwise be a ball of hair. But the way to be in that position is to jump in and churn churn churn until you've used Vue and React+Redux and understand the concepts and tradeoffs.


> Pick a project. Think of a website you want to make. At no point during that are you going to be stonewalled by "Man, if only I wasn't forced to spend the last 4 hours debugging this weird deep equality issue. I could've gotten so much more done!"

I have faced this on the job. About three abstraction layers deep in a Backbone app. It took me two days to trace the exact cause and find a way to implement a better check, that wouldn't make things respond in unexpected ways.

> It's up to you to either reject the notion or integrate it into your mindset and abandon the tendency to cling to idealisms.

JavaScript is terrible. It is not the product of academic research like Smalltalk or Haskell. I can accept it is the only tool available for the job, and continually look at all the solutions for that particular issue, and I will keep doing that.

I can use JavaScript, and I can write it. Usually my code is simpler and faster, because it takes me much longer to write anything, because of how aware I am of the side-effects. My employers in the past have liked the results that has produced.

But I will never enjoy writing it.

It is a language that is difficult in ways that reveal it's sloppy roots, and spill it's implementation details. Much of the time JS feels like working with UB in C, except it is actually detailed to act that strangely, in the spec.

Just an example that has always stuck with me, this is valid JS:

    [][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()
Pretending it's puss-filled core is wonderful is going to lead to nothing but burn out, but so is hating every procedure you write in it.

It's a tool. It's sharp on both sides, which can lead to a lot of blood-letting if you aren't careful. But it is still the best carving tool we have on hand.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: