Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Could set accept a function? #49

Open
tomek-he-him opened this issue Feb 9, 2015 · 17 comments
Open

Could set accept a function? #49

tomek-he-him opened this issue Feb 9, 2015 · 17 comments

Comments

@tomek-he-him
Copy link
Contributor

Is it possible to bend set to set properties through a function? I mean like:

var markdown = require("marked");

[{string: "..."}, {string: "..."}].map(compose
  ( set("html", markdown)
  , pluck("string")
  ));
@tomek-he-him
Copy link
Contributor Author

Maybe

set(markdown, "html")

or

set({property: "html", function: markdown})

– these should be backwards compatible.

@tomek-he-him
Copy link
Contributor Author

I'll be happy to code it if you give the green light @tjmehta.

@tjmehta
Copy link
Owner

tjmehta commented Feb 9, 2015

IMO overloading this function makes it harder to understand and less elegant.

It's easy to get carried away with overloading functions with functional behavior,
but sometimes the literal implementation is easier to follow::

var markdown = require("marked");

[{string: "..."}, {string: "..."}].map(function (obj) {
  obj.html = markdown(obj.string)
  return obj;
});

What do you think?

@tomek-he-him
Copy link
Contributor Author

Well yeah, that's what I did in the end.

Or rather, loving the immutability of set:

... .map(function (obj) {
  return set(obj, "html", markdown(obj.string));
  });

I've just had the impression that set could be more useful when mapping. At the moment its only use seems to be setting some property to the same value in all items. Just what you've shown in the example.

@tomek-he-him
Copy link
Contributor Author

But I must admit it seems less elegant, the way I proposed.

How about making it an optional options argument at the beginning? Like

set({through: markdown, keypaths: false}, "html")

@tjmehta
Copy link
Owner

tjmehta commented Feb 9, 2015

I definitely like the idea. I even considered just assuming a a function as a value in set is a transform function. What about a separate method all-together, like setMap or something?

@tomek-he-him
Copy link
Contributor Author

Well, as you wish :)

I guess I'd like the options more as it's more concise – but it does bring its own problems along as well.

@tjmehta
Copy link
Owner

tjmehta commented Feb 9, 2015

Yeah, I am not a fan of options objects, unless it's a last resort for a powerful function. I think rigidity of arguments leads to less usage confusion, and a simpler implementation.

@tomek-he-him
Copy link
Contributor Author

I'll do it just as you wish :)

Now for the name, I'd go for something more generic. Because .map may not be the only use. Like setThrough or setVia.

What do you think?

@tjmehta
Copy link
Owner

tjmehta commented Feb 9, 2015

How about key-map or keypath-map?

[....].map(keypathMap({
'foo.bar': compose(markdown, pluck('string'))
});

@tomek-he-him
Copy link
Contributor Author

I've just had another idea for that – in reference to #53.

[{string: "..."}, {string: "..."}].map(compose
  ( set("html")
  , [ noop
    , compose(markdown, pluck("string"))
    ]
  ));

That would pipe every item through

(item) =>
  set("html")(item, pluck("string")(item))

noop would need to be changed a little to (argument) => argument, which should also be backwards compatible. Another way would be to use null as an idiom for that.

Maybe we could avoid stuffing another function to 101 and an options object altogether.

@tomek-he-him
Copy link
Contributor Author

I like the idea of keyMap as well :)

@tjmehta tjmehta mentioned this issue Feb 10, 2015
@tomek-he-him
Copy link
Contributor Author

Well then @tjmehta , now #53 is almost ready – do we want this?

[{string: "..."}, {string: "..."}].map(compose
  ( set("html")
  , [ noop
    , compose(markdown, pluck("string"))
    ]
  ));

If so, we need to decide if we change noop or use null as an idiom.

Changing noop wouldn't be bad – after all, a function should always return something. But then again there can be people who rely on noop returning undefined. We could make it another function pass then.

@tjmehta
Copy link
Owner

tjmehta commented Feb 11, 2015

After thinking through keyMap I think it is a bit convoluted.

I really like the literal form here

var markdown = require("marked");

[{string: "..."}, {string: "..."}].map(function (obj) {
  obj.html = markdown(obj.string)
  return obj;
});

Versus

[{string: "..."}, {string: "..."}].map(compose
  ( set("html")
  , [ noop
    , compose(markdown, pluck("string"))
    ]
  ));

I think the latter is much harder to read.

@stoeffel
Copy link
Contributor

I think the latter is much harder to read.

I think so too.

@tomek-he-him
Copy link
Contributor Author

Cool @tjmehta @stoeffel .

How about

[{string: "..."}, {string: "..."}].map
  ( setEach("html", compose(markdown, pluck("string"))
  );

Just an idea

@stoeffel
Copy link
Contributor

I would prefer setThrough or setVia over setEach as you suggested before.

Repository owner deleted a comment from Pappyskull1 Feb 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants