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

Single source of truth for everything #158

Closed
wants to merge 2 commits into from

Conversation

dead-claudia
Copy link
Contributor

This stemmed from this short discussion. I think it would be a good idea to have a single source of truth for everything: the object itself (instead of an optional constructor method as well).

Given other outstanding PRs and issues, I'd expect this would need to wait a bit even if accepted, because it messes with so much. Also, I refactored a few bits of code to not use classes unnecessarily.

impinball added 2 commits September 11, 2016 03:45
Basically, there is now one single source of truth, and `constructor` is not
it.
@dead-claudia
Copy link
Contributor Author

Also, note that this is based on #157, so it carries that commit. Here's that commit only.

@dead-claudia
Copy link
Contributor Author

(By the way, I'm not that attached to this. If it gets rejected, I'm not that concerned.)


3. `u.map(x => new Compose(x)).sequence(Compose.of)` is equivalent to
`new Compose(u.sequence(F.of).map(v => v.sequence(G.of)))` for `Compose` defined below and any Applicatives `F` and `G` (composition)
3. `u.map(compose.of).sequence(compose.of)` is equivalent to
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something wrong here. new Compose is intentionally not the same as Compose.of see #141

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll fix that when I get home to compose.create (the intended replacement method).

@rpominov
Copy link
Member

If we have of method only on values how do we create a value in the first place? :)

@rpominov
Copy link
Member

rpominov commented Sep 11, 2016

Another ways to improve things in this area:

  1. Replace "or" with "and" in "on itself or its constructor".
  2. Require only static of/empty/etc methods.

Maybe additionally to #1 or #2: state that in order to be compatible with FL one need to use JS "classes" (either via function or class) so it would be clear where to look for static of/empty/etc — on the class.

@dead-claudia
Copy link
Contributor Author

@rpominov

If we have of method only on values how do we create a value in the first place? :)

Note that the examples use plain objects for this reason. It's somewhat Lua-like.

Another ways to improve things in this area:

  1. Replace "or" with "and" in "on itself or its constructor ".

I was aiming to remove the latter. (Check out the green parts. grep . 'constructor' should bring absolutely nothing.)

  1. Require only static of/empty/etc methods.

Maybe additionally to #1 or #2: state that in order to be compatible with FL one need to use JS "classes" (either via function or class) so it would be clear where to look for static of/empty/etc — on the class.

See this comment by @davidchambers. That's why I removed references to constructor methods entirely.

@rpominov
Copy link
Member

Note that the examples use plain objects for this reason. It's somewhat Lua-like.

I still don't understand how one would use such API. Say someone gave me a type that compatible with FL; how do I create a value of that type? Or maybe FL don't have to support this use case (not sure).

Btw why do we switch to plain objects and __proto__? We can remove static methods but keep "classes", right?

See this comment by @davidchambers. That's why I removed references to constructor methods entirely.

That make sense. Seems like having it on prototype is essential.

Btw, this PR is related to #88 (seems like it wasn't mentioned before).

};
var compose = {
of: function(x) {
return {__proto__: compose, c};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you like a different method of setting the prototype? (Keep in mind, I'm not actually that deeply invested in this. I'm merely encouraging exploration.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not rely on the constructor property as we currently do? We could write:

//  Identity :: a -> Identity a
var Identity = function Identity(x) {
  return {
    constructor: {'fantasy-land/of': Identity},
    'fantasy-land/chain': function(f) { return f(x); },
    'fantasy-land/map': function(f) { return Identity(f(x)); },
    // ...
    value: x
  };
};

The nice thing about this approach is it allows a prototype-based implementation:

//  Identity :: a -> Identity a
var Identity = function Identity(x) {
  if (!(this instanceof Identity)) return new Identity(x);
  this.value = x;
};

//  Identity.of :: a -> Identity a
Identity['fantasy-land/of'] = Identity;

//  Identity#chain :: Identity a ~> (a -> Identity b) -> Identity b
Identity.prototype['fantasy-land/chain'] = function(f) { return f(this.value); };

//  Identity#map :: Identity a ~> (a -> b) -> Identity b
Identity.prototype['fantasy-land/map'] = function(f) { return Identity(f(this.value)); };

// ...

I don't see a reason to use __proto__.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

constructor: {'fantasy-land/of': Identity}
Identity['fantasy-land/of'] = Identity

But didn't we want to remove static method?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway if we want to remove static method, I think we should simply remove static method from current implementations, without switching to simple objects or anything.

@dead-claudia
Copy link
Contributor Author

@rpominov WRT #88, I think I saw that once, but that's not what drove me to write this. (It is related, though.)

@dead-claudia
Copy link
Contributor Author

Given the immediate negative feedback (and the admitted non-idiomatic nature of it), I'm going to close it now. I think this was fully explored.

@dead-claudia
Copy link
Contributor Author

dead-claudia commented Sep 12, 2016

#157 should still be looked at, though (it's just a series of bug fixes)

@dead-claudia dead-claudia deleted the no-constructor branch September 12, 2016 19:35

m.empty()
m.constructor.empty()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we all agree that this change is a good idea. I've opened #162 which makes this change only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants