Feels like something had gone very wrong if a function like this is useful.
Would only be useful for unstructured data since if you had structure data you could write a more specific function.
This can easily match the wrong value and cause problems. And why would it match the wrong value? Because you have unstructured data and it might not be knowable if you might have false positives
This is often useful if you're rewriting something that looks like an abstract syntax tree.
> And why would it match the wrong value?
Because you may be searching the tree for something that looks like `(op(const)(const))` to replace it with `(const)`. But that may live many levels deep inside the structure.
I disagree. For example, It's useful if you have a bunch of cached network requests that each list some resources and you want to update all of the instances of a specific resource (matching by uuid).
Function-ified visitor pattern I guess? Python's NodeTransformer[0] is a good example of a thing like this though only across AST nodes.
Going along some previous discussions about jq, and stuff like specter (for Clojure), I do think it would be cool if there were more syntactic niceties for path expressions, extracting data from nested data structures/lists/etc, and applying transformations on them.
Specter can have a "nice DSL" (for certain definitions of nice!) thanks to Clojure's macro functionality. Haskell lenses get somewhere thanks to custom infix operator syntax being a thing. I have yet to see a library that tackles this nicely without those two tools though.
This is a simple function that I find quite useful. Crawl through an object to update some specific nested value. Useful for things like optimistic updates in a cache (eg. Find every instance of an object with some guid in any random data structure and update a field in it).
Disliking the generality of this function (as a sibling commenter said.. I mean with the wrong predicate you won't even get to test for list or dict.. but ok for those nested list/dict structures; but why not test first for them?) it is just a map and an if, or a map/list comprehension?
I mean, the paradigm would be a iterable-based dispatch. There's no name (that I know of) for such a specific (and yet, weirdly general) implementation.
I agree with many others in this thread when it comes to this being too specific to be useful and too generic to keep you from shooting yourself in the foot. I would, instead, add this to Array/Object's prototypes and call it on the specific types instead. At least, in that case, you aren't handling multiple fields of concern.
basically fmap in haskell. A more complete implementation would have the iterating logic distributed and owned by the prototypes of any arbitrary data container, dynamic dispatch ftw.
As a senior engineer, you see things like this all the time from more junior engineers: way too generic code, done in an overly clever way, incompressible to most. I've spent countless hours telling junior engineers to "dumb it down" and "make it less generic". Not all features that exist must be used. And no, you don't have to combine them all either. That's why I dislike Scala, and like Go. Go has like 3 features, and Scala has 100. It's very hard to make something overly complicated with 3 features (this is hyperbole obviously;I like Scala as a language, but not how many humans use it).
Code is written once, and read 100x, so it must be easy to parse by humans, and easy to understand in a split second. Junior engineers will have to understand it. New team members will have to understand it. If you have the occasional function like this, that's fine. If your entire code looks like this, or you are proud to have written a "clever function", that's not so good.
I try to write dumb code wherever possible. Do the expected, do the boring.
Very much so, it’s a functor instance on some sort of tree, except the `map` includes a conditional dispatch.
It’s essentially
fmap $ ap fromMaybe
Except this doesn’t quite work, I’m sure there’s a pointfree version, best I can achieve is
\p -> fmap $ ap fromMaybe p
Which takes an `a -> Maybe a` and an `[a]`, and replaces all the values for which the callback returns `Some`, and leaves as-is all the values for which it returns `None`.
(I collapsed the `whereFn` and `updateFn` into a single one because there’s no reason not to)
This seems like ramda’s evolve function because it updates with a function instead of a value, and it’s conditional because you’re giving a predicate.
One idea to make this more versatile would be to use a mapping instead of a callable for the whereFn and updateFn in order to simultaneously alter multiple columns of your objects. Also, you could add a path field in order to focus on particular nested paths in your data.
Ultimately, others might be right; this function is intended for use on collections, make sure to avoid using this to enable yourself to have a messy junk drawer of json blobs!
Would only be useful for unstructured data since if you had structure data you could write a more specific function.
This can easily match the wrong value and cause problems. And why would it match the wrong value? Because you have unstructured data and it might not be knowable if you might have false positives