Firacode: Ligature request: %>% pipe operator in R

Created on 10 Aug 2017  ·  68Comments  ·  Source: tonsky/FiraCode

We use the pipe operator %>% a lot in the Tidyverse set of packages in the R programming language. It's a way of stringing together many functions, converting them from prefix to infix. It would be really nice to have a pipe ligature.

screen shot 2017-08-10 at 12 24 36 pm

Most helpful comment

In R, %% is used to create custom infix operators, and technically any sequence of characters can come in between the two % (even whitespace, although that's obviously a bad idea) . Given that, I'd recommend either:

  • Provide ligatures for a small set of the most popular infix functions (i.e. %*%, %in%, %%, %/%, %>%)

  • Provide a general ligature (if possible) for any sequence of alphabetic characters that come in between % and %. However, even if OpenType supports this, it may have too high a risk of interfering with syntax from other languages.

Personally, of the options presented so far, I like @kelleyvanevert's suggestion to use smaller percent signs the best. I think using °▷° is too risky as it looks very different to %>% and it's is likely to confuse people.

All 68 comments

There was a couple of request for getting better coverage for R. I’m not against it, but can’t think of a way to improve the rendering of those

I'll give a design a shot in a day or so.

@jtth Want to share your design idea? Would be awesome to have this in R.

I would second this, and third this for colleagues who have commented on how ugly the pipe symbol is. Has anyone made progress on this?

Maybe something like this?
image
It's a horizontal invert of the arrow that is shown for <-, with the zeroes of the percent mark.

Better question is: does R (or RStudio that is) provide ligatures for more than 2 characters?
When typing ===, I get: image. I don't know if it will understand something in place for %>%.

I don’t think R authors had anything in mind when they chose %>%. Probably it’s just a random sequence of characters. I also think it’s unfixable, visually I mean

You could rotate the two % and connect them to form a line with a > through it. That way you would still have three-character width too.

I would propose to just use F# pipe ligature for %>%. In R, custom operators are defined between percent signs, so anyone can define an operator like so %whatever% <- function(){ ...}. R's pipe operator was actually inspired by F#'s pipe and is supposed to have similar behavior. However, since arbitrary-character operators have to be wrapped in %...%, the pipe ended up looking like %>%

There are several other popular R operators mentioned in https://github.com/tonsky/FiraCode/issues/39. Not sure what can be done with them though.

I would second the proposal to use the F# ligature for the R pipe %>% . With respect to the #39 issue, it would be nice to have some of the other symbols changed, but I think most R developers would tell you they use the %>% in maybe 1/4 of their lines of code, it is everywhere. I think it should have the highest priority.

There was an earlier comment that RStudio does not support three-character ligatures. I am not sure about RStudio 1.0, but in RStudio 1.1 the double headed arrow <<- correctly changes to the ligature for that symbol with Fira Code.

The % characters should be preserved — one of the rules of Fira Code AFAIK is that all of the characters stay. What about rendering %>% like %|>%?

There was an earlier comment that RStudio does not support three-character ligatures. I am not sure about RStudio 1.0, but in RStudio 1.1 the double headed arrow <<- correctly changes to the ligature for that symbol with Fira Code.

True!

I think most R developers would tell you they use the %>% in maybe 1/4 of their lines of code, it is everywhere

True!!!!

j-f1, could you elaborate on rule about all of the characters staying?

Would like this as well. How about removing the slashes and extra dots in the percent symbols, something like:

𐩑<𐩑

(Except maybe the dots being on the same level as the bracket, and also nicer etc)

I want the ligatures to resemble original characters combination

@bcollier

j-f1, could you elaborate on rule about all of the characters staying?

See above ⬆️ 🙂

I agree with the suggestion of something like the F# pipe ligature (right-pointing triangle). The percent signs (which are really just there because of R's requirements for custom binary operators) could be reduced to individual small circles.

Something like this:
∘▷∘
except I would stretch the triangle so it touches the circles.

Yeah, that’s beautiful! And I agree about the percentages :+1:

@timgoodman that's a lot better than what I had in mind. As long as the midline of the ∘ aligns with the centerline of the ▷ that's great!

Kind of like
screen shot 2017-12-10 at 12 17 29 pm

(Fun design note: this induces a size illusion such that the left circle appears smaller than the right. Dunno whether it'd be better to increase the size of the leftmost circle, or just leave it.)

  1. Pilcrow
  2. Manicule

@holstius You want a paragraph marker and a hand? What?

Either seemed appropriate to me.

%>% is read “and then”; it does the same thing pseudo-linguistically as a
paragraph break (that is, it separates “sentences”).

The “hand” is more of a visual analogy. There’s a rightward momentum.

On first read, I missed the point about preserving the elements of the
original characters. In that case, both my suggestions are way off the
mark.

On Mon, Dec 11, 2017 at 9:14 AM Jordan T. Thevenow-Harrison <
[email protected]> wrote:

@holstius https://github.com/holstius You want a paragraph marker and a
hand? What?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/tonsky/FiraCode/issues/473#issuecomment-350791628,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAyaakESgjaXanj4yI5LiNmllWKtSyb8ks5s_WLjgaJpZM4OzrQB
.

One idea for all of these would be to drop the second o on the first % and the first o on the second %, then elongate the center operator character.

@tonsky Any good arguments against
image
??

Else I think most of us would say: please implement 😉

@tonsky and others:
Any interest in some variants inspired by the ligature for $>?
screenshot 2

I thought that a compromise between no resemblance to the original characters (as in the o |> o) and a full representation of the two % signs might be to turn the / in the percent sign into an arrow. That sort of nests the arrow "within" a percent.
pipe2
pipe3

Even the compound pipe could be represented with uneven <>

@epspi I like yours better than mine. Very nice! That's more clear and visually unpacks a lot better.

Thanks @jtth
Adding better compound pipe
file-1d

Alternative based on arrows instead of > <
dd


    1. Consistency with other languages is a good principle, so following F# is a sound choice


    1. Not to stray too far off-topic, but that would suggest that %in% follows the ancient lead of LaTeX \in which inserts the ∈ (isin) symbol, consistent with math in general.


    1. FWIW, I believe this represents some specialized type of op-amp in the EE world:

      image

While some resemblance to the original characters is good (and we should follow the rule that each character in the original corresponds to some part of the ligature), I think it's more important that the meaning is conveyed (in the semantic sense, not the "what characters does it stand for" sense). For instance, != produces a ligature which doesn't bear much resemblance to an exclamation point, but that's OK because the ligature clearly represents the meaning "not equal". (Put another way, the ligature looks like the symbol that probably would have been used, if only that symbol existed as a key on the standard keyboard.)


For this reason, I still think the percentages should be de-emphasized, since they don't convey much meaning. They are just required for defining any custom binary operator in R. If not for this requirement of the R language, the author of magrittr might well have chosen |>, given that the magrittr pipe was actually inspired by F#'s pipe, |> (see here: https://www.r-statistics.com/2014/08/simpler-r-coding-with-pipes-the-present-and-future-of-the-magrittr-package/ ).


So, the magrittr pipe is not a random character sequence as suggested above; it's just an approximation of F#'s pipe that meets the rules of R. And F#'s pipe, it seems clear to me, is meant to have some resemblance to an arrow pointing in the direction of piping (and this is consistent with the fact that the reverse pipe resembles an arrow pointing the other way).

With all that said, I don't particularly care for the suggestion using diagonal arrows, because instead of using an arrow from x to f to represent "x piped into f", they use an arrow pointed off at an oblique angle, which seems less connected to the meaning. Moreover, while they increase the resemblance to the percent sign (the semantically-irrelevant part), they actually decrease the resemblance to the greater-than symbol (the semantically-important part). Even the suggestion before that, which is closer to resembling the greater-than sign, seems like it's favoring a resemblance to the percent sign a bit too much in my opinion.


So, I would still prefer the closed triangle with dots on either end, which:

  1. Resembles the greater-than sign, and more importantly resembles the meaning of the symbol: an arrow in the direction of piping

  2. Includes but deemphasizes the semantically-irrelevant percent signs

  3. Resembles the equivalent F# operator, which actually inspired the magrittr pipeline operator
  1. While I favor consistency, @timgoodman makes good points, and I think most people would agree that the "op amp" just _looks better_. I certainly don't think it's a good idea to preserve the % signs that bracket the operators - they are escape characters and an accident of history.
  2. I do think we want to be consistent with the conventions of mathematics. And %in% has a well-defined mathematical meaning. However if we respect the constraint that the ligature must span the same number of characters I'd be OK with
    %in% maps to something like: o∈o
    assuming that the membership sign spans two character widths - is that possible? (note that in addition to being ignorant, I'm too lazy above to make real circles and just used lower-case 'o')
  3. Where the real soul searching starts is in the _undoing_ of unfortunate accidents of history. Specifically,%%, which is actually called the _remainder_ and the floor of integer division is called the _modulus_. As in:
    A = modulus * divisor + remainder
    And yes, probably Backus' fault, as I believe it first showed up in Fortran, but for some reason, computer languages use the term 'mod' to designate the remainder.
    In the long run, one reason ligatures are a great thing is that they can be used to close this gap, so it's probably a good idea not to use them to widen it.

I would very much love to see ligatures for these R operators, but I think it is imperative to keep (each) ligature's shape within close proximity of the original shape of the operator, in line with what the rest of the Fira Code ligatures do. (They all just slightly move around, enlarge and reduce, and extend/warp the sub-shapes. The most drastic changes appear in >>= and |>, and still here you can see the original shapes.)

Because the choice of the percentage sign is awkward and unfortunate (as @BStudent notes) and has no semantic relation to the operator (as opposed to say >= and !=), we cannot and should indeed refrain from trying to "semanticize" them. Moreover, because entire words can be used between the percentage signs, as in %between% and %in%, such an attempt would only lead to weird solutions.

I would propose just a minor de-emphasization or subtle change of presentation of the percentage signs, for example:

screenshot from 2018-05-07 14-02-46

fira_r

This obviously makes the operator more legible, while retaining the visual characteristic of the original operator (beit awkwardly chosen or not).

How about changing the > in %>% into the |> ligature?

@j-f1 : that replacement would not generalize well to %in% and %between%.

I'm convinced that Fira Code (or any other symbols-ligaturing font) should stay well away from the programming language's motivation & stylistic reasons for choosing certain operators. We're not here to redefine the syntax of R, but just to make it slightly more pleasing (read: legible) to the eye. Replacing != with is not about replacing an arbitrary "is not equal" syntax to , but about working with the idea that is already captured in !=, namely that it visually looks somewhat similar to , and then trying to preserve the original shape somewhat.

There is no logic to the percentage-operator-syntax of R, that is a given; but Fira Code shouldn't try to 'create' this logic out of thin air (and probably upset some R-coders along the way), but rather try to make the syntax R-coders already work this on a day-to-day basis a bit more legible / pleasing to the eye.

There is no logic to the percentage-operator-syntax of R, that is a given; but Fira Code shouldn't try to 'create' this logic out of thin air (and probably upset some R-coders along the way), but rather try to make the syntax R-coders already work this on a day-to-day basis a bit more legible / pleasing to the eye.

Absolutely agree. Your proposal to simply reduce the size of the % signs to de-emphasize them is perfect.

Other ways of de-emphasizing could be proposed of course. The following is a bit whacky (and probably too much), but just as an example of a different presentation that doesn't semanticize, but just re-arranges slightly to create a eye-catching but recognizable version of the original thing.

fira_r_2

I like the suggestion of reducing the size of the percentages -- I would suggest though that the circles in the percentages could become individual solid dots (so each percent symbol looks like dot slash dot). To me that seems clearer and less visually noisy, compared to having tiny circles with just a wee bit of white space in the middle.



I also like the suggestion of still turning the > into the ligature for |>, for the reasons I gave above. But if folks prefer to leave it more closely resembling the original >, my suggestion would be to at least stretch it horizontally a bit to suggest the shape of an arrow a bit more, which I think is more suggestive of the symbol's meaning. In fact, we could preserve the original width of the full three-character combination, just shrink the percentages and stretch the greater-than to make up the difference.

Yes, @timgoodman, that's an excellent suggestion, I think it looks good because it's very clean :) And widening the > does seem like the Fira Code think to do, and it looks good:

fira_r_3

I do believe the whole point of Fira Code is to have the ligatures take the same space as the original characters, even though that often means adding more space around a shrunk figure, so yes, that is necessary.

Thanks for illustrating that, @kelleyvanevert. I think I've come around to liking that better than my earlier suggestion based on F#'s ligature. It looks nice and clean, with the emphasis on the meaningful part, but still clearly recognizable to anyone who's seen the magrittr/dplyr pipe.

(Nice. I do think I've shrunk the percentages a bit too much though, displaying the text so big is different than displaying it regular size, where legibility is more of an issue.)

=> What do other people think?

By the way, this would make existing code look something like this:

fira_r_4

Where the original would be:

fira_r_4o

... which makes me think it's not legible enough, and is a bit unclear still. Really, those percentage signs are ugly, man :| Crazy R people.

The @timgoodman suggestion (with the wider > character for the pipe) looks great! I think perhaps with the mini-% signs aligned with the bottom line, rather than centered would be less jarring regarding legibility.

From a quick review of packages, it looks like the following operators are in at least somewhat common use. I don't know how flexible the ligature system is if it could detect a pair of % % separated by an arbitrary number of characters and ligature in all such cases.

From base
%*%
%o%
%in%
%x%
%%
%/%

From tidyverse and others
%>%
%+%
%@%
%|%
%||%
%T>%
%$%
%<>%
%within%
%m+%
%--%
%+replace%
%??%
%,%

From igraph
%u%
%--%
%->%
%<-%
%c%
%du%
%m%
%s%

From foreach
%:%
%do%
%dopar%

From stringi
%s<%
%s+%

From data.table
%chin%
%inrange%
%like%
%between%

From assertthat
%has_name%
%has_attr%
%has_args%

Others
%over%
%nin%

Although I really like these ideas of the last few days, do we know if this is technically possible for the creator of this font?

I do think so. I'm not versed in typography and all the crazy opentype features, but it seems that the technique that Fira Code uses is generalizable, and it already includes a 4-character ligature (####). As far as I can tell, it has to do with not just using the normal liga substitution table, but some kind of quircky method that can generalize.

See gen_calt.clj.

I think out of all the possible options, I prefer the deemphasis of the % and emphasis of the operator that is contained that @kelleyvanevert introduced. It is also extensible, which is important as new packages begin to create their own binomial operators. I wouldn't want to get in the business of having to custom do ligatures for each iteration of %(╯°□°)╯︵ ┻━┻% that involves too much deep thinking. Using a ligature that can't be comprehended by a programmer of the language who is unfamiliar with FiraCode doesn't seem like a good 💡

@robertmitchellv Agreed, the fact that the same approach works for any custom binary operator is definitely a plus.

But now I'm really wanting to think of a good use for the "flip the table over" operator. :)

This preserves the % and the directionality, but also the concept of "pipe" in that it has an opening for the data to flow through.

image

@jzadra That doesn’t really look like the % at all to me, and there is no indication that a second % is there. Also isn’t extensible to any other % operator.

@bwiernik Pretty sure it was a joke....

I know I haven’t had enough sleep when I miss a phallus in my environment.

In R, %% is used to create custom infix operators, and technically any sequence of characters can come in between the two % (even whitespace, although that's obviously a bad idea) . Given that, I'd recommend either:

  • Provide ligatures for a small set of the most popular infix functions (i.e. %*%, %in%, %%, %/%, %>%)

  • Provide a general ligature (if possible) for any sequence of alphabetic characters that come in between % and %. However, even if OpenType supports this, it may have too high a risk of interfering with syntax from other languages.

Personally, of the options presented so far, I like @kelleyvanevert's suggestion to use smaller percent signs the best. I think using °▷° is too risky as it looks very different to %>% and it's is likely to confuse people.

Wow, the great Hadley jumped in himself 😄 Thanks!

@hadley, this touches on an issue concerning (what I'll dub) "mathematician" and "designer" viewpoints to reconcile, some things seem obvious while others seem hard (and adherents don't always agree which is which). The examples I'd offer as a math camper are

  1. %in% - look no further than LaTeX (actually the semantics speak for themselves to a math person)

  2. %% - I righteously proclaim that wrongs can be righted by translating this to remainder or some variant, with attendant aesthetic challenges

  3. %>% is a special challenge ... One can almost justify changing pipe semantics: really, this is function composition in reverse, to wit:
    y <- x %>% h() %>% g() %>% f()

Is in most cases effectively function composition:
f(g(h(x)))

In many other branches of math this is written with the circle operator:

f o g o h(x)

(Forgive me, I am doing this from a phone so I have to use lowercase o as a kind of circle operator purchased on sale at Walmart)

Other than Maybe for %in% I do not claim to have all the answers much less good ones, and there are perhaps counter-examples to my interpretation of the pipe as function composition.
But I do think that with existing sins - such as referring to remainder as modulus with casual abandon - destroying the very fabric of society, we have some obligation to maintain a consistency between Computer Science and the other branches of Mathematics, or at least not make the situation worse.

@bwiernik @traversc Pretty sure it was intended to be extensible ...

The fundamental concern of a typeface is making text easier to read and, for programming typefaces, making it easier to identify errors. Things that obscure the actual underlying characters, like °▷° or run counter to this purpose.

@bwiernik I agree with your statement of purpose ... and pipe is a different animal from %in% and %% ... what would be nice from both a ligature standpoint and to your concern is if all languages with a pipe-like operator could agree on a single ligature for the representation, independent of the horrifying assortment of ascii characters they have settled upon for the individual compilers/interpreters.

Considering that %...% frames every type of custom operator, I wonder if they could be rendered as standard bookends to any such customer operator... something more akin to [>], except as a complete box (or something) framing the actual operator symbol. The left and right % would always render into the same framing characters, and the internal operator symbols would include both a _ floor and ceiling.

So in the case of %>% this could render to something like [ ▷ ] (though within a full rectangle).
image

image

image

image

image

image

image

image

image

Alternatively, the standard framing characters could resemble something like an ellipses ⋯▷⋯
image

My two cents:

  1. A ligature that won't confuse programmers who know the language will be good. It should feel natural. That is why the arrow ligature works so well and why the de-emphasized percent symbol option works so well.
  2. Someone said that the centered de-emphasized percent symbols are "jarring" and suggested percent symbols be placed on bottom line. I disagree. This will make the symbol harder to distinguish from other symbols. The triad of shapes of different sizes and the symmetry of the centered percent symbols makes those ligatures pop out in the test that I saw. Making the symbol easier to read and distinguish from other symbols is a plus.

as Fira already has ligatures for those symbols inside % such as %->% it seems to be a wasting of time trying to come up with new symbols every time. Following the deemphasise ideas, replacing the % sign with that of Courier New font look pretty readable for me, even for those cases without ligature like the modulo
Screenshot 2019-06-13 at 13 54 06
I guess changing this to Fira Code is out of question? if so is there a way to customise this for personal usage?

@kklot you can open ttf/otf files in any font editor and change them to your liking. To rebuild from sources there is https://github.com/tonsky/FiraCode/blob/master/script/build

@kklot you can open ttf/otf files in any font editor and change them to your liking. To rebuild from sources there is https://github.com/tonsky/FiraCode/blob/master/script/build

Is there any documentation about how to do this for contributors? I looked around the files in this repo but didn't see anything like that.

@jzadra I’m afraid not. You’re on your own

as Fira already has ligatures for those symbols inside % such as %->% it seems to be a wasting of time trying to come up with new symbols every time.

Ever since tidyverse, the %>% is really something else, that could use a lot more dedication than what you’re suggesting. I think that’s clear from this (way too long) thread and the ones of #41 and #195.

I want the ligatures to resemble original characters combination (@tonsky)

Then maybe it’s time for an R specific fork...

The relevance of this discussion will perish, since we now know base R will come up with a pipe in their next version as a drop-in replacement for the magrittr/dplyr pipe.

The pipe will probably be |>.

The pipe is only one of many inline operators in R. Anything between two % would be better with a ligature.

(Last I read, the base R pipe was not planned to have the same behavior as the magrittr pipe unfortunately)

Edit: see here for the major incompatibility https://twitter.com/bmwiernik/status/1334853345966780421?s=21

Whatever you like. This is the actual implementation and it looks like perfect drop-in to me: https://github.com/wch/r-source/commit/a1425adea54bcc98eef86081522b5dbb3e149cdc

(off-topic mode off)

@bwiernik It looks like instead of writing y %>% f(x, .), you'll be able to write y |> \(.) f(x, .) (or choose a different argument name instead of .)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

aolko picture aolko  ·  3Comments

hatched picture hatched  ·  3Comments

ghivert picture ghivert  ·  4Comments

blucell picture blucell  ·  4Comments

pamu picture pamu  ·  3Comments