Skip to content
DevMeme
525 of 7435
F# custom operators: peak flexibility or unreadable chaos?
FunctionalProgramming Post #604, on Aug 23, 2019 in TG

F# custom operators: peak flexibility or unreadable chaos?

Why is this FunctionalProgramming meme funny?

Level 1: Secret Code Math

Imagine you have two numbers, like 5 and 6, and you want to add them. Normally, you’d write 5 + 6 and everyone knows that means 5 plus 6, which equals 11. Easy, right? Now picture your clever friend decides to make up a secret code for the plus sign. Instead of writing +, they draw a little squiggly arrow, say something like -+->, between the numbers. So on the paper it looks like 5 -+-> 6. You look at that and go, “Huh? What is that supposed to mean?” Your friend says, “Oh, that’s my special symbol for add, it does the same thing as +.”

You’d probably laugh and maybe roll your eyes, because why not just use the regular plus sign that everyone understands? Your friend basically turned a simple addition problem into a puzzle! You’d have to be told that -+-> means the same as plus. Until then, it’s just gibberish to you, like ancient hieroglyphics. In ancient Egypt, they used symbols to represent words and ideas, and if you don’t know what the symbols mean, you can’t read it. This is the same idea but with ASCII symbols (those are the characters on a standard keyboard).

In the meme, a programmer did exactly that in code. They had the computer learn a new made-up operator symbol (the -+->) which, in the end, just adds two numbers. The computer doesn’t care — as long as we define -+-> to mean add, it will happily do it. But any person reading the code is going to be puzzled at first. It’s as if the programmer wrote part of the code in a secret language that only they know. In a code review, which is when other programmers look at your code, this would be pretty funny and a bit annoying. The reviewers might say, “Umm, it took me a minute to realize your fancy arrow thingy is just adding these numbers. Next time, can we please stick to +?!”

The humor here is like someone needlessly complicating something very simple. It’s kind of like if you asked a friend for directions to a place you both know, and instead of saying “Go straight for two blocks and turn left,” they gave you directions in Tolkien’s Elvish for no reason. You’d be like, “Okay… I guess that works, but why tho?” In the end, everybody understands 5 + 6 = 11. Replacing + with some bizarre -+-> symbol is totally unnecessary — and that’s why it’s funny. It’s poking fun at programmers who do overly clever things that make others say, “You’re not writing a secret message, just tell me plainly!”

So the meme is a joke about making simple things look complicated. The image shows the code version of a secret handshake or a private joke. If you’re in on it (you know F# can do that), you nod and chuckle. If you’re not, you just see weird text and go “What does that even mean?” The bottom line: sometimes programmers invent crazy ways to do basic stuff, and while the computer doesn’t mind, it can leave other people scratching their heads. This meme finds the fun in that situation — turning a straightforward 5 + 6 into a mysterious riddle 5 -+-> 6 and laughing at the confused reactions it gets!

Level 2: Readability vs Expressiveness

Let’s break down what’s happening in this meme in simpler, more educational terms. The meme is about F#, which is a functional programming language. One quirky feature of F# (and some other functional languages) is that you can define your own operators. An operator is typically something like +, -, *, or > that you place between values (infix) to do an operation. In most languages, you’re stuck with the predefined ones (you can’t just make a new symbol and have it do something). But F# says, “Go ahead, invent one if you want!”

In the image, the text explains: “In F# I can define a function like this” and shows:

let (-+->) x y = x + y

This line is F# code that defines a function named (-+->). In F#, the let keyword is used to define values or functions. If the name of the function is made up of special characters (like -+->), you put it in parentheses in the definition. So here, (-+->) is the name. It takes two parameters, x and y, and the body of the function is x + y (meaning it returns the sum of x and y). Effectively, we created a new infix operator -+-> that does exactly what + (plus) does.

The next part says: “and call it like this” with:

let z = 5 -+-> 6

This is using our shiny new operator. Because we defined -+-> as an infix operator (by giving it a symbolic name), we can write 5 -+-> 6 just like we would write 5 + 6. The result, of course, is 11, so z gets the value 11. In other words, -+-> is a fancy (needless) alias for +. If you’re thinking “Why not just use +?” — that’s exactly the joke! The developer literally reinvented + with a more complicated symbol. 😄

Now, the meme doesn’t stop there. It says: “I can even do something like this” and shows a more complex example:

let (-++->) x y z = x y z
let p = ((fun x -> fun y -> x + y) -++-> 5) 6

This looks intimidating, but let’s unpack it step by step. The operator name here is -++-> (they added an extra plus in the middle). It’s defined with three parameters: x, y, z, and the function body is x y z. What does that mean? It means: take x (which we expect to be a function), call it with argument y, then call that result with argument z. In plainer terms, (-++->) is an operator that takes a function and two values, and applies the function to those two values. It’s like a custom way to call a function.

To see it in action, they wrote: ((fun x -> fun y -> x + y) -++-> 5) 6. Here, (fun x -> fun y -> x + y) is an anonymous function (a lambda) that takes an x and a y and returns x + y. Essentially, it’s a function that adds two numbers (just like a regular add function). When they write (fun x -> fun y -> x + y) -++-> 5, they are using our operator -++->. According to its definition, that will call the lambda with 5. The lambda (fun x -> fun y -> x + y) expects two arguments, but if you give it one (x = 5), it returns another function (this is due to currying in functional languages: you can call a multi-parameter function with fewer params and get back a function waiting for the rest). So (fun x -> fun y -> x + y) -++-> 5 results in a new function that will take the second argument y and add it to 5. Then they immediately call that resulting function with 6 by putting ( ... ) 6 at the end. The outcome is again 11 (because 5 + 6). So all that convoluted expression did was add 5 and 6, again! They proved that even something as unnecessarily complex as this still works in F#. It’s like saying, “Look, Mom, I made adding two numbers ridiculously indirect but it still gives the right answer!”

Why does F# allow this craziness? The serious reason: to let developers create domain-specific languages (DSLs) or intuitive APIs. A DSL means writing code that feels like it’s its own little language for a specific problem. For example, if you’re doing math, you might want an operator for matrix multiplication or vector dot product that isn’t a standard operator. If you’re making a parser, you might use <!> or <|> as custom operators to combine parsing rules (F#’s famous parser library uses <|> to mean “OR” between two parsing alternatives, which is neat once you know it). The idea is these symbols, once learned, make the code look like the equations or grammar you’re implementing, which can be very expressive and concise. Expressiveness here means how easily you can express complex ideas in code without writing a lot of boilerplate. Custom operators can help with that by reducing a complex function call into a clean infix notation.

However, there’s a big but: expressiveness can hurt readability if overused or used without care. Readability means how easily others (or you in the future) can read and understand the code. If you come back to a piece of code and see a bunch of -+-> or -->! or <<>> operators that aren’t standard, you’ll have to stop and figure out what each one does. It’s doable (you can search where they’re defined), but it slows you down. If the benefit of the custom operator isn’t obvious, it might not be worth the confusion it causes. That’s why this meme is funny: the benefit of -+-> is zero (it’s just adding, which + already did perfectly), and the cost is making the reader do a double-take. It’s syntax sugar that actually makes things less clear — more like syntax salt in the wound for the code reviewer 😊.

Let’s touch on a couple of the tags and concepts mentioned:

  • OperatorOverloading vs Custom Operators: In many languages (C#, Java, etc.), you cannot define new operator symbols; you can only overload existing ones for new types. For instance, you can make + work for your custom class. F# allows that too (you could implement the + operator for, say, a complex number type). But on top of that, F# lets you invent brand-new operators like our -+->. That’s relatively rare in programming languages, and it’s a fun feature when used moderately.
  • FunctionalProgrammingConcepts: F# is a functional-first language. Concepts like currying (the thing where a function with multiple parameters can be partially applied one argument at a time) and higher-order functions (treating functions as values you can pass around) are built-in. The second example with -++-> leverages these concepts: it passes a function as x and uses partial application. It’s showing off that in F#, functions are flexible entities; you can even stick them between custom operators if it makes sense to you!
  • SyntaxAbuse / LanguageQuirks: Every powerful feature can be abused. This meme highlights a mild case of syntax abuse: using an ultra-flexible syntax feature in a goofy way. It’s a quirk of F# that (-+->) is a valid function name. In fact, F# has some rules (like operator names must consist of certain allowed characters, and you can’t start an identifier with a number, etc.), but within those rules, you have a lot of freedom. The result is you can make some code that looks truly alien. (There’s a joke among F# users: “With great power comes great responsibility – and sometimes great ridicule from your teammates.”)
  • Readability vs Expressiveness: This is a common tug-of-war in software development. More expressive code (in the sense of being concise or using domain-specific notation) isn’t always more readable to everyone. There’s a sweet spot. In a team setting, you typically want to err on the side of clear, straightforward code unless there’s a compelling reason to get fancy. Code is a communication tool, after all. Everyone immediately knows what + does, but -+-> would require a comment or a lookup. The meme is basically laughing at an case where expressiveness (or cleverness) was pushed to the point of reducing clarity.

So, what’s the takeaway for a newer developer? It’s that F# and languages like it give you some awesome capabilities to make your code feel like a custom language. You can define operators, you can make your code very mathematical or very DSL-like, which can be super powerful in the right context. But if you misuse that power for trivial things (like redefining addition with symbols), you might confuse your fellow developers more than you help. It’s funny to see in a meme context, but it’s also a gentle lesson: use fancy language features judiciously. Otherwise, you might get called out in a code review for writing code that looks like ASCII art or “hieroglyphics.” And that’s exactly what happened here, humorously. The meme exaggerates it for comedic effect, but it’s rooted in real developer experiences. We laugh, and maybe we also think, "Okay, maybe I'll think twice before I unleash my own ~~**>>> operator on my codebase." 😜

Level 3: Operators Gone Wild

For experienced developers, this meme elicits a knowing grin (or groan) because it highlights a classic case of “just because you can, doesn’t mean you should.” In F#, you can concoct new operators out of thin air. That’s cool… until you’re the one reviewing code and stumble upon something like 5 -+-> 6. At first glance, that line looks like someone’s keyboard malfunctioned or a bit of line noise snuck into the code. Then it dawns on you: the original developer intentionally made an operator that looks like ASCII art. Cue the facepalm and an amused shake of the head. This is operator overloading on steroids — not only overloading existing operators, but inventing entirely new ones. Seasoned devs have seen this pattern before, especially coming from languages that allow operator madness (C++ and Perl flashbacks, anyone?). But F# lowers the barrier to creating custom operators so much that a sufficiently creative (or mischievous) programmer can turn a simple addition into a deciphering exercise for their peers.

Imagine you’re in a code review meeting. A fellow dev has submitted an F# module and you’re skimming through… then you hit that let z = 5 -+-> 6. Your immediate reaction: “What in the world is -+->?” It’s not a standard operator you recognize. So you scroll up, searching for its definition. There it is: let (-+->) x y = x + y. You let out a chuckle because this fancy-looking arrow-plus thing is literally just adding two numbers. It’s like someone rebranded the addition sign with extra steps. You can almost hear the dev saying, “Look, I made a new operator!” and the rest of the team replying, “...why, though?”. It’s funny on the surface — a combination of syntax humor and a gentle poke at F#’s permissiveness. But it’s also funny because it’s relatable: if you’ve been around the block, you’ve encountered code that was too clever for its own good. This is that scenario wrapped in a neat meme.

Let’s be clear: F#’s custom operators are a legitimate feature, often used to make code more elegant in contexts that call for infix notation. But there’s a line where clever becomes cryptic. When a team member zealously defines (-++->) to thread function calls in some ultra-fancy way, others might start joking that the code looks like a DSL for aliens. The meme exaggerates it with “ASCII hieroglyphics” – a perfect description when code starts to look like random symbols strung together. In fact, developers have a slang for this: “comic book swearing” or “line noise”. It’s when code is so punctuation-heavy that it resembles those symbols used in comics to represent cursing (@$%#!). A line like ((fun x -> fun y -> x + y) -++-> 5) 6 could easily be mistaken for someone swearing in ASCII at first glance!

Now, every senior dev knows that balance is key. There’s a time to be fancy and a time to be simple. This meme zeros in on a case of needless fanciness. Instead of writing 5 + 6 which everyone understands instantly, the author wrote 5 -+-> 6 and actually had to define what -+-> means. It’s a bit of a tech inside-joke: we often tease that some code is “write-only” – the original author can write it, but anyone else trying to read it will go “Huh?”. This F# trick can produce exactly that. During a real code review, a senior engineer might leave a comment like: “Pro tip: unless -+-> brings some clear benefit, stick to + for clarity.” It’s like telling a colleague, “You invented a Rube Goldberg machine for addition.” Sure, it works, but it’s overly elaborate.

There’s also an element of shared PTSD/humor here from working with codebases that abused operator overloading. In languages like C++ or Scala, you might have seen << or >>> doing things not immediately obvious (like streaming or custom shifting behaviors), and it can trip you up. F# just expands the playground: any sequence of symbols can be an operator if you’re bold enough. Senior devs often caution juniors about overusing such features. Why? Maintenance. Picture being on-call at 3 AM, trying to quickly fix a production issue, and you’re staring at a piece of code full of >>=>==>-> style operators. You’d probably scream “Why?! Who wrote this?!” and long for plain words. As the saying goes, “Code is read far more often than it’s written.” In practice, that means clarity usually trumps cleverness.

The humor in this meme is that it perfectly captures a scenario where a programmer prioritized clever syntax over clarity, and it’s something many of us have seen or done at least once. It’s a lighthearted roast of that tendency. The title text nails it: “turning simple addition into ASCII hieroglyphics at code review.” We laugh because we can imagine the code reviewer’s face, equal parts amused and exasperated, encountering this. Maybe they joke, “Do we need to hire an Egyptologist to review your code?” It’s hyperbole, of course — anyone can figure out -+-> with a bit of effort — but it chides the author for making readers do that extra work. In summary, from a seasoned perspective, this meme is a playful reminder: just because F# lets you be a syntax artist, you might want to think twice before unleashing operators gone wild on your team. It’s all fun and games until someone loses an eye… or in this case, until a code reviewer loses their mind deciphering your bespoke hieroglyphs. 😉

// A real example of "operators gone wild" in F#
let (-+->) x y = x + y    // Developer invents a custom "add" operator
let result = 5 -+-> 6     // Code reviewer: "Wait... what does -+-> do?? Why not just use + ?!"

Level 4: Arcane Syntax Wizardry

At the highest level, this meme showcases an aspect of language design and internal DSL creation in functional programming. F# (an OCaml-inspired language on .NET) allows developers to define their own infix operators using sequences of punctuation. In other words, you can extend the language’s syntax with custom symbols. This is powerful sorcery from a language theory perspective: the programmer is effectively creating new grammar. The snippet defines an operator (-+->) as a function: it takes x and y and returns x + y. The code then uses 5 -+-> 6 exactly as if -+-> were a built-in addition operator. Under the hood, F# treats -+-> like any function name (made of special characters) with a specified fixity (infix by default here) and an implied precedence (F# deduces precedence from the operator’s first character, so starting with - gives it the same precedence as the minus operator). This flexibility is reminiscent of languages like Haskell, where you might see operators like >>=, <$> or >>> defined by libraries. Each of those symbols carries a lot of semantic weight (monadic bind, functor map, function composition, respectively) compressed into a tiny glyph. F# gives you similar freedom to define symbolic operators, which means you can make your code read closer to domain-specific notation or mathematical formulas.

In the second part of the meme’s code, things get even more arcane. They define (-++->) as a three-parameter function: let (-++->) x y z = x y z. This operator expects x to be a function and y, z to be that function’s two arguments. So ((fun x -> fun y -> x + y) -++-> 5) 6 is using -++-> to feed 5 into the first slot of the lambda (fun x -> fun y -> x + y), producing a new one-argument function (add 5 to something) which is then immediately called with 6. In mathematical terms, -++-> here is acting like a custom function application or partial application operator. This works because of F#’s curried function model: any function of multiple parameters is essentially a function returning another function. The custom operator taps into that curried application. It’s a clever demonstration of how first-class functions and custom syntax can blur the line between using a language and inventing a mini-language within it.

From a language theory standpoint, this is all about expressiveness vs. simplicity. Allowing arbitrary infix operators increases the expressive power of the language — you can tailor syntax to fit a problem domain (embedding a DSL for, say, parsing, math, or concurrency). The meme hints at that by saying F# lets you turn code into “ASCII hieroglyphics,” which is a tongue-in-cheek way of saying you can invent your own symbolic notation. Historically, languages like APL took this to an extreme: APL introduced a plethora of bespoke symbols (even needing a special keyboard) to concisely express array operations, and while it was mathematically elegant, it was notoriously hard to read without knowing the symbol vocabulary. F# is far more restrained, but the option for user-defined symbols is there, inherited from the ML/Haskell tradition. It’s an embodiment of the idea that a programming language can be a toolkit for language construction. As computer scientist Philip Wadler quipped, a powerful type system (or language) lets you create “embedded languages” where you craft new abstractions that read almost like a domain’s native syntax.

However, with great power comes great responsibility (and occasional ridicule). There’s a known concept of “write-only code” – code that’s easy to write (for the author) but hard for others to read. By introducing novel operators, you risk creating write-only code if those operators aren’t a well-known convention. The term “ASCII hieroglyphics” itself evokes the image of something written in a script no one else can decipher. In an academic sense, we’re seeing the tension between writable and readable syntax: F# emphasizes giving the programmer the ability to write in new ways, but it doesn’t guarantee that others will find it readable. The meme humorously shines light on this tension by choosing the simplest operation (addition) and giving it an absurd new operator name. It’s as if a mathematician decided that the + symbol wasn’t cool enough and replaced it with a custom doodle – technically allowed, but pedagogically questionable.

In summary, this highest-level view recognizes the meme as a commentary on language extensibility. F#’s allowance for custom infix operators is a deliberate design to enable highly domain-specific expression. It’s a feature that tickles language enthusiasts: you can make your code base almost a new language dialect. That’s beautiful when used judiciously (e.g., parser combinator libraries in F# define <|> for choice, so writing grammars feels natural), but it’s bewildering when misused. The meme’s humor is rooted in that dual nature. On the one hand, admire the wizardry: turning a routine x + y into a funky arrow operator exemplifies F#’s flexibility. On the other hand, acknowledge the absurdity: it’s like casting a spell that impresses only the caster, while everyone else reaches for the Rosetta Stone. In short, F# custom operators are a bit of arcane syntax wizardry — capable of elegant internal DSLs, but also capable of producing code that looks like an esoteric puzzle if taken too far. For those fluent in the glyphs, it’s powerful and expressive; for everyone else, it might as well be Egyptian hieroglyphs in ASCII.

Description

A screenshot of F# code snippets on a plain light-gray background demonstrating the language's powerful and flexible operator overloading capabilities. The first section shows a custom operator '(-+->)' being defined to perform addition: 'let (-+->) x y = x + y' and then used: 'let z = 5 -+-> 6'. The second, more complex example defines a three-argument operator and uses it with higher-order functions. The text above the snippets reads 'In F# I can define a function like this', 'and call like this', and 'I can even do something like this'. The humor is aimed at experienced developers who recognize the double-edged sword of such features. While offering powerful syntactic sugar and domain-specific language (DSL) potential, it can easily lead to cryptic, unreadable, and unmaintainable code that looks like line noise, a classic debate in language design and code quality

Comments

7
Anonymous ★ Top Pick Your custom operator is approved, but the pull request for the custom keyboard required to type it is still pending
  1. Anonymous ★ Top Pick

    Your custom operator is approved, but the pull request for the custom keyboard required to type it is still pending

  2. Anonymous

    Nothing says "enterprise-ready" like having grep return zero hits for '-++->' yet still passing architecture review because you called it a "lightweight DSL."

  3. Anonymous

    The code review where you explain why --> doesn't mean "implies" and <++> isn't XML took longer than implementing the entire feature

  4. Anonymous

    Ah yes, F# custom operators - because sometimes 'add' is just too readable, and your team needs to spend 20 minutes deciphering whether '-->>--++-->>' is a legitimate operator or someone's cat walked across the keyboard during code review. Nothing says 'maintainable codebase' quite like operators that look like ASCII art emoticons having an existential crisis

  5. Anonymous

    F#'s custom operators: Expressiveness so high, the next maintainer needs a PhD in symbology

  6. Anonymous

    F# will happily let you define (-++->) as “apply”; the type checker nods, but onboarding now requires a legend - consistency, readability, and cleverness form a CAP theorem for syntax: choose two

  7. Anonymous

    F# custom operators are great - until you’ve reinvented a DSL where (-++>) binds tighter than |> and the only parser that understands it is the original author at 2 a.m

Use J and K for navigation