{"action":"opened","issue":{"url":"https://api.github.com/repos/ramda/ramda/issues/1582","labels_url":"https://api.github.com/repos/ramda/ramda/issues/1582/labels{/name}","comments_url":"https://api.github.com/repos/ramda/ramda/issues/1582/comments","events_url":"https://api.github.com/repos/ramda/ramda/issues/1582/events","html_url":"https://github.com/ramda/ramda/issues/1582","id":125153258,"number":1582,"title":"Inconsistency between assoc and merge","user":{"login":"ivan-kleshnin","id":2128182,"avatar_url":"https://avatars.githubusercontent.com/u/2128182?v=3","gravatar_id":"","url":"https://api.github.com/users/ivan-kleshnin","html_url":"https://github.com/ivan-kleshnin","followers_url":"https://api.github.com/users/ivan-kleshnin/followers","following_url":"https://api.github.com/users/ivan-kleshnin/following{/other_user}","gists_url":"https://api.github.com/users/ivan-kleshnin/gists{/gist_id}","starred_url":"https://api.github.com/users/ivan-kleshnin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ivan-kleshnin/subscriptions","organizations_url":"https://api.github.com/users/ivan-kleshnin/orgs","repos_url":"https://api.github.com/users/ivan-kleshnin/repos","events_url":"https://api.github.com/users/ivan-kleshnin/events{/privacy}","received_events_url":"https://api.github.com/users/ivan-kleshnin/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2016-01-06T10:43:04Z","updated_at":"2016-01-06T10:43:04Z","closed_at":null,"body":"Starting with usecase... I need to normalize URL for scraping, i.e. remove hash from URL and convert relative URL to absolute. Node `url` module is able to parse and format URL but gives no way to immutably reset hash. Let's try Ramda's `assoc`.\r\n\r\n```js\r\nimport Url from \"url\";\r\n\r\nlet rootUrl = \"http://github.com/\";\r\nlet url = \"github.com/somepage#something\";\r\n\r\nlet absUrl = Url.resolve(rootUrl, url);\r\nassoc(\"url\", null, Url.parse(absUrl)).format();\r\n// => https://github.com\r\n```\r\n\r\nIt works because `assoc` copies all the keys including functions.\r\n`.format` method was copied to new object.\r\n\r\n```js\r\n// === assoc source code ===\r\nfor (var p in obj) {\r\n  result[p] = obj[p];\r\n}\r\n// === === === === === ===\r\n```\r\n\r\nNow try Ramda's `merge`.\r\n\r\n```js\r\nimport Url from \"url\";\r\n\r\nlet rootUrl = \"http://github.com/\";\r\nlet url = \"github.com/somepage#something\";\r\n\r\nlet absUrl = Url.resolve(rootUrl, url);\r\nmerge(Url.parse(absUrl), {url: null}).format();\r\n// => **format is not a function**\r\n```\r\n\r\nIt does not work because `merge` copies only `enumerable` keys omitting functions.\r\n`.format` method was not copied to new object.\r\n\r\n```js\r\n// === merge source code ===\r\nvar result = {};\r\nvar ks = keys(a); // a is original obj\r\n// === === === === === ===\r\n```\r\n\r\nI think we should apply same politics to both functions and they should give equal result in this case.\r\nOf course, other Ramda functions are subject to this.\r\n\r\nBut I'm not sure which behavior is \"correct\" and which one should be \"fixed\". \r\nIn this case `assoc` turned out to be more useful as `merge` failed to patch OOP code. \r\nBut we surely need to account more use cases."}}