Hacker News new | ask | show | jobs
by spion 4013 days ago
Here are some fun counter-examples

  let sqr = x => Math.pow(x, 2)

  let property = name => obj => obj[name]

  let distance = p1 => p2 => Math.sqrt(sqr(p2.x - p1.x) + sqr(p2.y - p1.y))

  let byComparing = f => (x, y) => {
    let fx = f(x), fy = f(y)
    fx < fy ? -1 : fx > fy ? 1 : 0
  }
  
  let points = [{x: 1, y: 2}, ...]
  
  let byX = points.slice().sort(byComparing(property('x'))
  
  let byStartDistance = points.slice().sort(byComparing(distance({x: 0, y: 0}))
1 comments

That's indeed pretty fun. In practice however this is much simpler:

    let sqr = x => Math.pow(x, 2)

    let distance = (p1, p2) => Math.sqrt(sqr(p2.x - p1.x) + sqr(p2.y - p1.y))

    const zero = Object.freeze({x: 0, y: 0})

    let byX = points.slice().sort((p1, p2) => p1.x - p2.x)

    let byStartDistance = points.slice
        .sort((p1, p2) => distance(p1, zero) - distance(p2, zero))
It's not nearly as composable, sure, but I think almost everyone would understand it much faster. The curried `distance` would also be a bit annoying to reuse in other contexts where you'd have to write `distance(p1)(p2)` instead of the idiomatic (at least now; idioms can change) `distance(p1, p2)`.

That said, the arrow function is a massive win in both examples. I've been using it for a while and never had any issue mistaking it with <= or >=. The linter would probably catch it anyway.