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

favour identifiers a, b, c, and x #90

Closed
wants to merge 1 commit into from

Conversation

davidchambers
Copy link
Member

Closes #86

@joneshf
Copy link
Member

joneshf commented Feb 13, 2015

Any changes to Monad, Extend and Comonad?

@davidchambers
Copy link
Member Author

I'm happy to go further. I don't know whether people are attached to m and w. If not, I'll update the pull request to replace them with a and b as well. :)

@5outh
Copy link
Member

5outh commented Feb 13, 2015

I definitely prefer m for monad and w for comonad, since that's almost universal in Haskell docs. If others are opposed to that I'd love to hear an argument against it.

This looks great to me, thanks for your PR! 👍

@puffnfresh
Copy link
Member

One of Fantasy Land's goals was to remove a lot of the focus and faith put into names. I think we should not care about these names and so it's a little disappointing to see a focus here.

But sticking to the principle, I don't care about these names. Feel free to merge 🌵

@davidchambers
Copy link
Member Author

How far would you like us to go, @puffnfresh? For example,

a.map(function(x) { return f(g(x)); }) is equivalent to a.map(g).map(f) (composition)

could become:

a.map(function(d) { return c(b(d)); }) is equivalent to a.map(b).map(c) (composition)

I see value in using f to mean "some function", g to mean "some other function", and x to mean "some value". I realize I'm putting "a lot of […] focus and faith […] into names"; it's quite possible I should abandon this crutch.

Since no one has objected to the changes made in this pull request, I suggest we merge it as is. I'll then open a separate pull request to remove the beloved m and w. :)

@puffnfresh
Copy link
Member

I don't mean "I don't care, so enumerate them alphabetically" - I mean "I don't care, let them be arbitrary to the reader"

@davidchambers
Copy link
Member Author

I don't mean "I don't care, so enumerate them alphabetically" - I mean "I don't care, let them be arbitrary to the reader"

I'm not sure I grasp your point. Are you saying that the choice of identifiers in f(x) is okay because the user will see f as "some function" and x as "some value"?

Making identifiers arbitrary to the reader is challenging. Arbitrarily chosen values may not appear arbitrary to the reader. The motivation for the pull request was my confusion surrounding u and v. They were arbitrary to the author, but I assumed there must have been a reason to choose u and v rather than a and b used elsewhere in the document.

There are several ways to encourage readers to see identifiers as arbitrary:

  • use single-letter identifiers;
  • use (and reuse) a small number of identifiers; and
  • use sequential identifiers when several are needed (e.g. x, y, and z).

@bergus
Copy link
Contributor

bergus commented Feb 14, 2015

u and v probably were chosen here because they were used in the Haskell Applicative docs (and also the paper there). There, they were probably chosen over a, b, c… because those are usually used in type signatures, so values typically go by x, y, z, u, v, w …. I don't know why u was used instead of x, but maybe that had a different meaning in the unpublished thoughts.

u and v don't seem to have any deeper meaning like m and w do.

@joneshf
Copy link
Member

joneshf commented Feb 14, 2015

I'm not sure I grasp your point. Are you saying that the choice of identifiers in f(x) is okay because the user will see f as "some function" and x as "some value"?

I think @puffnfresh 's point is the name of an identifier like this doesn't change the semantics.

It doesn't matter if the Functor specification states

u.map(function(x) { return f(g(x)); }) is equivalent to u.map(g).map(f)

or

f.map(function(a) { return x(c(a)); }) is equivalent to `f.map(x).map(c)``

It doesn't change the meaning.

@joneshf
Copy link
Member

joneshf commented Feb 14, 2015

Maybe what might be better is to give more depth to the explanations.

Like for the Functor spec give a legend of the identifiers used.

@davidchambers
Copy link
Member Author

I think @puffnfresh 's point is the name of an identifier like this doesn't change the semantics.

Understood. In this respect this pull request is a no-op. But given two equivalent ways to express a given law we should choose the one less likely to confuse the reader. That's the motivation for this change.

@puffnfresh
Copy link
Member

The reader should not be confused because the reader should not rely on identifier names to understand the laws. I'd rather make that clear than spend effort giving into the pitfall of relying on identifier names for understanding.

@davidchambers
Copy link
Member Author

I'd rather make that clear than spend effort giving into the pitfall of relying on identifier names for understanding.

I believe using a, b, and c makes it clear that the identifiers are arbitrary, but we could make this clear in prose without changing the identifiers if you prefer.

Presumably Haskell's type signatures use a, b, and c for their inherent arbitrariness:

(b -> c) -> (a -> b) -> a -> c

This is equivalent, but not clearly arbitrary:

(o -> r) -> (l -> o) -> l -> r

I've found this discussion enlightening. I've learnt that the identifiers usually have no inherent meaning (f, m, and w are exceptions), and that I should feel free to use different identifiers in my library's assertions if it helps me to sleep at night. :)

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.

why these identifiers?
5 participants