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

$ instead of %? #17

Closed
glaebhoerl opened this issue Aug 12, 2012 · 16 comments
Closed

$ instead of %? #17

glaebhoerl opened this issue Aug 12, 2012 · 16 comments

Comments

@glaebhoerl
Copy link

I think it would make sense to use $ instead of % where the mnemonic is for applying a function, given that ($) is the function application operator, e.g. ($=) instead of (%=), ($) instead of (%), and so on (Control.Lens.Setter, Type, IndexedLens, and IndexedSetter seem to be affected). Is there a rationale for % besides it being an otherwise unused symbol?

If you agree I can prepare a patch.

(I'm guessing operators with more than one % like (%%=) and (%%) should also become ($$=) and ($$) in that case, rather than keeping one of the %s?)

@ekmett
Copy link
Owner

ekmett commented Aug 12, 2012

The mnemonic for % is 'mod'ify. ;)

We actually explicitly rejected using $ back for this in data-lens, and now it is a compatibility point between this, lens-family and data-lens, so i'm somewhat loath to break expectation on it.

@ekmett
Copy link
Owner

ekmett commented Aug 12, 2012

One issue with $= is the intuition that it is applying a function here is slightly off.

l +~ a uses lens_value + a
l <>~ a uses: lens_value <> a
...
l $~ a would use a $ lens_value

@glaebhoerl
Copy link
Author

Yeah, I noticed that too. If we had an operator for flip ($) that's what we would want, but we don't. (($.) is a name I remember being suggested, and I think F# and/or OCaml have (|>)?) Anyway, I think a slightly imperfect analogy is better than no analogy at all. You could say "($=) isn't intended to be in the mould of (+=) and (*=), it's just meant to remind you of ($)". Is this the reason it was rejected for data-lens, or was there something else?

I was also expecting the compability argument. ;) If it's a change worth making, compability will only be more of a deterrent in the future than it is now. (Although there are ways to preserve it, like export-without-documenting or simply providing both.) If it's not worth changing then obviously that's that.

@ekmett
Copy link
Owner

ekmett commented Aug 12, 2012

Pretty much the same consistency argument came up whe we originally picked % for data lens over $.Of course switching to $.~ is an even harder sell. ;)

If I were to pursue it it'd probably be best done as ~$ to indicate the side being edited or something, but that explanation is even worse.

I'm going to close out the issue, but I definitely appreciate the feedback.

@ekmett ekmett closed this as completed Aug 12, 2012
@orenbenkiki
Copy link

@glehel said "If we had an operator for flip ($)..." - well, now we do: |>. So, there is something to be said for using |>= instead of %=. The equivalent of %%= would be ||>=, or something like that. This actually doesn't look too bad; however, there's still the compatibility issue...

Having |> opens up other interesting options. For example, one could argue for writing foo . to bar . baz as foo .|> bar . baz (this is especially nice if the function has arguments: foo . to (bar a b) . baz vs. foo .|> bar a b . baz). I even tried setting this up, just to see how it would work, but it seems the associativity of . gets in the way :-(

@mgsloan
Copy link
Collaborator

mgsloan commented Sep 11, 2012

For comparison purposes, here's (#) = flip ($) from diagrams

http://hackage.haskell.org/packages/archive/diagrams-lib/0.4.0.1/doc/html/Diagrams-Util.html#v:-35-

On Tue, Sep 11, 2012 at 1:10 AM, Oren Ben-Kiki notifications@github.comwrote:

@glehel https://github.com/glehel said "If we had an operator for flip
($)..." - well, now we do: |>. So, there is something to be said for
using |>= instead of %=. The equivalent of %%= would be - ||>=, or
something like that. This actually doesn't look too bad; however, there's
still the compatibility issue...

Having |> opens up other interesting options. For example, one could
argue for writing foo . to bar . baz as foo .|> bar . baz (this is
especially nice if the function has arguments: foo . to (bar a b) . bazvs. foo
.|> bar a b . baz). I even tried setting this up, just to see how it
would work, but it seems the associativity of . gets in the way :-(


Reply to this email directly or view it on GitHubhttps://github.com//issues/17#issuecomment-8450338.

@ekmett
Copy link
Owner

ekmett commented Sep 11, 2012

Hrmm, one downside to |>= is that <|>= isn't what you'd expect.

@ekmett
Copy link
Owner

ekmett commented Sep 11, 2012

Re compatibility, I'd rather break it now before I get too many users, but at least at the moment, I think the |>= version introduces more confusion and is longer than %=, which is a glaring fault in such a commonly used operator.

@ekmett
Copy link
Owner

ekmett commented Sep 11, 2012

I wonder if a ? operator would work for .|>. That is annoyingly unrelated to ^? though.

Maybe ... that way ^... could be used for to? But we already have ^.. for a very different purpose.

foo.to bar is already pretty unobtrusive, and i'm leery of stealing another good operator name for a redundant purpose. The main design goal of the names in Control.Lens was to make it so users wouldn't be tempted or forced to import it qualified and where all the combinators clearly involve lenses, traversals, etc. in some fashion.

With (|>) we've already compromised on that vision. Because users of Data.Sequence get a (|>) that collides with it and it doesn't strictly deal with lenses.

@orenbenkiki
Copy link

I would make the case that |> really belongs in prelude...

BTW, if it were called # (as in Diagrams.Util), then #=, ##= and .# would make reasonable operators. It would also be less of a conflict concern, since I assume that Data.Sequence is used much more often than Diagrams.Utils; and anyway it would be trivial to import one of the modules with hiding ((#)) since the definition is the same "everywhere". The down side would be that it won't be compatible with F# (there is some irony in that :-)

@ekmett
Copy link
Owner

ekmett commented Sep 11, 2012

Alternately the same logic could be used in reverse to just rename ('|>') to ('%'), without renaming dozens of combinators.

ekmett added a commit that referenced this issue Sep 11, 2012
@orenbenkiki
Copy link

That is a good point. I personally don't mind using % for flip ($). According to hoogle, % is used by Data.Ratio; this is probably less of a conflict than the conflict with Data.Sequence. And as you point out it would be consistent with all the existing operators. Even .% doesn't look too bad (. to is pretty cumbersome when the function has parameters).

@ekmett
Copy link
Owner

ekmett commented Sep 11, 2012

Annoyingly, the precedence issue is pretty brutal for defining something like .%. -- The only . like operator that has the correct precedence to allow it is >>>, which would lead to a %>> combinator, but visually it composes backwards from what you're looking for.

@orenbenkiki
Copy link

Yes, I noticed that.. I couldn't find a way around it and gave up short of trying to reverse the associativity of .. I was hoping you have some magic up your sleeve to overcome the problem ;-) I guess .% is out. A pity, there's a whole class of useful operators of that form. Oh well, . to isn't that bad after all...

@ekmett
Copy link
Owner

ekmett commented Sep 11, 2012

Magic found

@orenbenkiki
Copy link

So the key insight is that once one "drops out of lens" using ^%, one needs ^. again to apply another lens. Makes perfect sense, in retrospect...

Well done magic indeed!

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

4 participants