Skip to content
DevMeme
3586 of 7435
The Functional Programmer's Emoticons
FunctionalProgramming Post #3923, on Nov 12, 2021 in TG

The Functional Programmer's Emoticons

Why is this FunctionalProgramming meme funny?

Level 1: Serious Code, Silly Faces

Imagine you’re told not to draw any smiley faces on your homework because it’s supposed to be serious. You agree – no silly drawings. But then you open the homework book and the teacher has written instructions using a bunch of strange squiggles and symbols that look like smiley faces anyway! You’d think, “Wait, you said no cartoons, but your writing looks like a bunch of little emoticons!” The teacher then says, “Ah, but these aren’t just random doodles – they mean something important!” That’s exactly what’s happening in this meme. In the first part, Drake refuses the obvious smiley faces (the kind we use in messages just for fun). In the second part, he’s happy with a line of weird symbols that, to most people, look just as goofy as the forbidden smileys. The funny part is those weird symbol “faces” are actually real instructions in a programming language (Haskell) – they do real work, so the programmer says they’re okay. It’s like someone rejecting toy building blocks, but then approving a complicated LEGO structure that coincidentally looks like the same toys. The core joke is about hypocrisy in a playful way: “No fun icons in my serious work… unless those icons are part of my serious work!” So even if you don’t know Haskell, you can laugh because Drake is basically making an exception for smiley-looking things just because they’re in his special secret code. It’s a mix of silly and serious that makes the whole thing amusing and easy to get: sometimes, what looks silly can actually be serious, if you speak the right language.

Level 2: Operators as Emoticons

Let’s break down what’s going on in simpler terms. Haskell is a programming language (specifically, a purely functional programming language) that has a reputation for using a lot of symbols in its code. Most programming languages have a fixed set of operators (like +, -, *, == etc.) and you typically name new functions with words. Haskell is different: it allows you to define your own infix operators using almost any characters. This means a Haskell programmer can invent an operator like *** or <$?> if they want, and give it a meaning in their program. It’s part of Haskell’s flexible syntax and it’s meant to let developers write code that sometimes looks like mathematics or a specialized DSL (domain-specific language). However, this can lead to some funny-looking code! In this meme, the lower-right panel lists a bunch of such Haskell operators that, unintentionally, look like little text faces (emoticons). The joke is that a Haskell programmer will say “No” to using obvious emoticons in code (because that would be silly or unprofessional), but then happily use these fancy symbolic operators which end up looking like emoticons anyway.

Let’s look at a couple of these operators from the meme and explain them in a beginner-friendly way:

  • <$> – This is a real Haskell operator pronounced “fmap” or just “map”. It’s part of the Functor type class. Don’t worry if that sounds complex; a Functor is just a thing you can map a function over. A classic example of a Functor is a list. Mapping a function over a list means applying that function to each element of the list. In many languages you’d call a function like map(func, myList) to do this. In Haskell, you can write func <$> myList. It does the same thing. For instance:

    (+1) <$> [1, 2, 3]
    -- Result: [2, 3, 4]
    

    Here (+1) is a function that adds 1 to a number, and [1, 2, 3] is a list of numbers. Using <$>, Haskell will produce a new list [2, 3, 4] by adding 1 to each element. So <$> means “apply the function on the left to every element in the structure on the right”. It’s literally the map operation, just written with symbols. If you look at <$> sideways, some people joke it kind of looks like some animal face or an emoji, but in code it’s doing real work! The meme shows its type signature (<$>) :: Functor f => (a -> b) -> f a -> f b, which in plain English means: “if f is some kind of functor/container, then <$> takes a function from a to b and an f containing a’s, and returns an f containing b’s.” In our example, f was a list, a was a number, and b was also a number; so it took a function from number to number and a list of numbers, giving back a list of numbers.

  • (>*<) – This one looks wild, but it comes from a real scenario. It’s not as standard as <$>, but it appears in libraries like QuickCheck (a tool for testing programs by generating random data). In QuickCheck, Gen a means “a generator for random values of type a”. If you want to create a generator for pairs (two values together), you can combine a Gen a and a Gen b. The operator for that in one version of QuickCheck was >*<. Visually it has a >*< shape, and you might imagine it as two arrows pointing toward a * (almost like two things coming together). What it does is take a generator of a and a generator of b and produce a generator of (a, b) (an ordered pair of a and b). So if genInt gives you random integers and genChar gives you random characters, genInt >*< genChar would give you random pairs like (42, 'Q'). The meme shows its type Gen a -> Gen b -> Gen (a, b). To a new programmer, that notation means a function that takes two inputs (one of type Gen a and one of type Gen b) and returns an output of type Gen (a, b). It’s basically describing the combination we just talked about. And yes, >*< looks like some emoticon of a surprised face in text, but here it’s actually code for combining test data generators!

  • (<**>), (*&*), (<*+*>) – These are more examples of Haskell operators that you might encounter. All of them use a mix of <, *, +, &, etc., which are valid characters for making custom operators. <**> is very close to the more common <*> operator from the Applicative type class. If Functor was about “mapping” a normal function over a wrapped value, Applicative is about applying a wrapped function to a wrapped value. Think of it like this: imagine you have a box that contains a function (f (a -> b)) and another box that contains an a value (f a). Applicative lets you combine them to get a box containing the b result (f b). The <*> operator does exactly that. Now <**> is just a variant where the order of arguments is swapped – it’s a bit of a niche thing but it exists for convenience. Next, (*&*) as mentioned likely merges two results. If you had Just 5 and Just "hello" (both in the Maybe context), (*&*) could hypothetically give you Just (5, "hello"). It’s like running two things in parallel and keeping both outcomes. Similarly, <*+*> isn’t a standard one you’ll find in everyday code, but it’s there to illustrate how far you can go. It could be something one writes for lists of functions and values (since + often hints at list concatenation or combination). The details aren’t super important – what matters is all these operators are possible in Haskell, and people really do define stuff like this when needed. Each of those sequences of symbols is not random: the developer chose them to be suggestive or follow a pattern. For instance, many operators that start with < and end with > have to do with “wrapping” or “combining” things (because of the brackets). Those with * often indicate some kind of pairing or product (since * reminds of multiplication or pairing in math). So while they look like emoticons or cartoon cursing, there is a logic to them within the language.

Now, consider the meme’s structure with Drake. This is using the famous “Drake Hotline Bling” meme format where in the first image Drake rejects something he doesn’t like, and in the second image he is pleased by something he prefers. On the left side, Drake is rejecting the three text emoticons: ('w'), (/o▽o)/*.:°<, and (¬‿¬). These are just playful faces you might see in an online chat or forum, made out of text characters. They have no meaning in programming; if you put them in Haskell code without making them a string or comment, the compiler would be very confused! Essentially, they’re just noise in a program. In the second image, Drake is happy about the list of Haskell operators with their type explanations. The joke is that those operators, despite looking even more convoluted than the simple emoticons, are meaningful code to Haskell programmers. So Drake (the developer) says “no way” to random emoticon text in code, but “yes, exactly!” to the Haskell line that looks like emoticons because he recognizes it as useful abstractions. It’s a playful way to show the contrast between appearance and meaning. What looks like gibberish can be solid code if it follows the language’s rules.

In simpler terms: the meme is highlighting a quirk of the Haskell language (and some other languages in the functional family) – you have all these operators that look cryptic but do very powerful things. It’s poking fun at how a Haskell enthusiast’s idea of “clean code” might look like a string of symbols to everyone else. This kind of syntax humor might even resonate with someone who’s not a developer: imagine seeing a math equation full of symbols you don’t understand – it might as well be emoji to you. Haskell code can give that same impression to programmers who haven’t learned its “secret symbols” yet. But once you do learn them, you start to see faces as functions! The meme got popular in coding circles because anyone who’s dabbled in Haskell or seen Haskell source code will chuckle and think, “Yeah, it really does look like cartoon emoticons sometimes, but it’s serious business.” It’s a lighthearted reminder that in programming, things aren’t always what they appear at first glance. A line of code that looks weird or esoteric might have a perfectly logical purpose – and in Haskell’s case, might even have a cute face value as well!

Level 3: Haskell Hieroglyphics

To a seasoned developer, this meme hits on a very real programming in-joke: Haskell code can look like someone peppered the screen with emoticons, yet it all actually works. The Drake meme format (Drake disapproving in one frame, then joyfully pointing in the next) perfectly captures the typical Haskell enthusiast’s attitude. In the top frames, Drake is saying “nope” to plain ASCII smileys like ('w'), (/o▽o)/*.:°<, and (¬‿¬) – these are just random text emoticons with no meaning in code. A Haskell purist doesn’t want random cutesy glyphs cluttering their source unless they do something. In the bottom frames, Drake gives an enthusiastic thumbs-up to what looks, superficially, like an even more cryptic set of faces: (<$>), (>*<), (<**>), (*&*), (<*+*>). The twist is that those are real operators in Haskell, each with a well-defined purpose. It’s a hilarious contrast: Drake (as the Haskell developer) rejects frivolous emoticon text, but approves a line of Haskell that to an outsider looks exactly like a bunch of shrugging kaomoji. The humor lands because Haskell’s syntax is so symbol-rich that legitimate code can resemble a string of facial expressions. In other words, we’re laughing at the LanguageQuirk that Haskell’s highly abstract, math-inspired operators accidentally double as excellent “ASCII art”.

Every experienced Haskell coder has had that moment of squinting at someone else’s library and thinking, “Wow, this code is practically emoji.” It’s a shared comedic pain point: powerful abstractions often come with terseness that borders on inscrutability. The meme gives five specific examples. If you’ve been around Haskell, a few of these will ring a bell immediately. (<$>) is ubiquitous – it’s the Functor map operator, so common that Haskellers read it as easily as the word “map”. Seeing f <$> x in code is as normal to them as seeing f(x) in other languages. Then there’s (<**>) which is a variant of the Applicative apply operator <*>. It’s less common in day-to-day code, but any Haskell senior engineer knows it’s there for completeness (it allows you to sequence effects then apply a function, essentially f <*> x but with the arguments flipped). The meme also shows (*&*), which might prompt a double-take: that one isn’t in the standard Prelude, but given its type f a -> f b -> f (a, b) you can guess it packages two results into one context (for instance, combining two Maybe values into one Maybe pair, or two computations in a context f into one combined result). An experienced dev might recall that some libraries or frameworks define such an operator for convenience – it’s conceptually doing the work of something like liftA2 (,) (using Applicative to tuple things). So even if you haven’t seen *&* exactly, you infer its intent from the type. Similarly, (<*+*>) looks totally over-the-top – as if someone sprinkled an extra symbol just to maximize the emoticon resemblance. It might be a made-up example or from a niche library, but by the pattern you could imagine it’s like a specialized <*> for lists (perhaps combining a list of functions with a list of inputs to get all results – which the standard Applicative instance for lists already does with <*>. The added + could hint at some list-specific operation or just be for comic effect). The point is, Haskellers deal with this sort of operator overloading and operator proliferation all the time. It’s both a feature and a source of jokes: you end up with code that outsiders claim looks like “line noise.” In fact, a classic tease is “Haskell? Oh, the one where your code looks like you mashed the number row on your keyboard.” The meme embraces that self-awareness.

From a real-world perspective, these operators emerge from common patterns in functional code. Haskell people love point-free and combinator-heavy styles – not out of perversity, but because once you know the patterns, they actually make code more concise and compositional. For example, a Haskell dev will happily write:

makeUser <$> getLine <*> getLine <*> readMaybe <$> getLine  

to parse three inputs and construct a User record, using <$> and <*> in sequence. To the untrained eye, that looks like cartoon characters doing a conga line, but to the Haskeller it’s a straightforward way to fill a data structure from IO actions. The inside joke is that Haskellers have a kind of secret emoji language that only they and the compiler truly understand. They see (*_^) and think “compose these actions” not “winky face.”

There’s also a hint of one-upmanship being poked at here. The Haskell community is proud of its abstractions like Functor, Applicative, and Monad. These abstractions often come with their own infix operators to make usage elegant. But from the outside, it can look like an intimidation tactic — as if Haskell code is full of hieroglyphics that only initiates can read. The meme captures a Haskell programmer’s smug satisfaction: “Look, no silly emoticons in my code… only serious operators that just happen to look like emoticons!” It’s a form of SyntaxHumor that tickles programmers: we know how absurd it looks, and that’s why it’s funny.

To give some context, consider the operator (>*<) shown in the list. A seasoned Haskeller might recognize this from a library like QuickCheck (a popular property-based testing framework). In QuickCheck, Gen a represents a generator for random data of type a. Combining generators is a common task, so the library defines (>*<) (or something similar) to take Gen a and Gen b and produce Gen (a, b) – a generator for pairs. The operator’s shape >*< is no coincidence: it visually suggests “something with something” (the * looking like a cross or product, and > and < perhaps hinting at feeding the results together). It’s intuitive if you’re in on the joke. But imagine you’re new on the team, reading a test suite, and you see userGen >*< policyGen in the code – you might double-take and wonder if that’s a typo of some emoticon, until you learn it’s a defined function. As another example, Haskell’s standard libraries define <$ and <$> (one replaces all values in a functor with a constant, the other maps a function) and <*>, <* , and *> (for applying functions in a context and sequencing effects). Each pair of symbols has a specific meaning, but put them all in one place and it does resemble cartoon cursing characters or joyful faces.

This meme resonates because it’s so true: Haskell’s language quirks create a situation where a code snippet can double as an ASCII art gallery. The Drake format exaggerates the Haskell programmer’s preference: Drake won’t tolerate random smileys in code comments, but he’ll fill the code with what outsiders might call “infix emoticon syntax” if it serves a higher purpose. It’s a gentle jab at the Haskell crowd’s expense – we know we write code that looks inscrutable, and we love it anyway. An experienced dev reading this meme is likely chuckling and nodding, recalling the first time they showed their non-Haskell friends some code and got reactions like:

“I thought those were decorative emoji in the code!” – a baffled new hire, upon seeing <$> for the first time.

In summary, the senior-perspective punchline is: Haskell transforms what would normally be silly text faces into serious tools. It’s a celebration of the esoteric nature of functional programming jargon. The community’s shared experience is that once you crack the code (pun intended), those symbol soup expressions become as clear and expressive as any prose – and you start to find them kind of cute, in a nerdy way. Drake giving the thumbs-up is basically every Haskell dev saying, “Yup, looks good to me,” while everyone else is squinting at the supposed OperatorOverloading chaos asking, “Are we sure this isn’t an emoji Slack channel?” And that delicious confusion is exactly why this meme is funny.

Level 4: Category Theoretic Emotes

At first glance, the meme’s bottom panel looks like a lineup of whimsical ASCII emoticons, but it’s actually showcasing Haskell’s powerful, almost over-permissive syntax for custom operators. Under the hood, each of those symbol sequences (<$>, >*<, <**>, *&*, <*+*>) is a legitimate function name defined in Haskell’s code. The reason Haskell allows this comes from its mathematical design philosophy. Haskell is rooted in lambda calculus and heavily influenced by academic computer science theory – it treats operators as just functions with symbolic names. The language grammar lets developers define new infix operators using nearly any combination of punctuation characters. This means you can create an operator like (<🡆>) (if Unicode arrows were allowed) or (*&*) as easily as you could define a normal function name. Each operator can also have a specified fixity (precedence and associativity), which Haskell uses to parse expressions without ambiguity. This flexibility was intended to let library authors create domain-specific languages or embed mathematical notation directly in code. The result? Haskell code can look like a dense field of symbols – a “point-free” paradise where entire computations are expressed with punctuation. It’s like the language of abstract algebra found a home in source code.

Crucially, these funny-looking operators aren’t arbitrary gibberish – they’re backed by deep theory. Those type signatures in the meme are real and convey formal properties. For example, (<$>) :: Functor f => (a -> b) -> f a -> f b is telling us that <$> works for any Functor f. In category theory terms, a Functor is a mapping between categories that preserves structure; in programming, it translates to a container or context you can map a function over. So <$> is actually the infix version of the fmap operation (think of it as a fancy synonym for “apply a function inside a container”). Likewise, (<**>) :: Applicative f => f (a -> b) -> f a -> f b involves the Applicative type class, which extends Functor. Applicative functors allow function values themselves to be wrapped in contexts and applied to other context-wrapped values. This idea has a category-theoretic origin too: an Applicative can be seen as a monoidal functor (a concept from category theory meaning it combines contexts with an internal notion of “addition” or pairing). In other words, <**> and its more common cousin <*> implement the formal rules for how to apply functions when both the function and the value are wrapped in a computational context (like Maybe, List, or any effect). Each operator corresponds to a specific abstraction from mathematics, given a playful ASCII guise. Haskell’s creators and library authors often chose symbolic names that hint at their purpose: for instance, <$> includes a dollar sign $ (which in Haskell is the regular function application operator) wrapped in angle brackets to suggest “apply in a structure.” The <*> operator (not shown but implied by <**>) uses the * to hint at combining effects (and indeed some Haskell folks talk about <*> as if it’s an “applicative mash-up” operator). There’s even an operator >=> in Haskell’s Monad libraries commonly nicknamed the “fish operator” because, well, it literally looks like a little fish swimming right (>=>). It represents monadic function composition, another concept from category theory. These symbolic choices often carry a mix of rigorous algebraic meaning and a tongue-in-cheek visual pun.

From a theoretical perspective, Haskell’s allowance for such operators is almost like having a programming language of algebraic equations or hieroglyphs. Each sequence of symbols has a precise semantic definition grounded in types and laws. The meme highlights this by listing the operators with their full type signatures – an experienced eye sees not emoticons, but a contract of what each operator does. The Functor f => ... notation, for example, introduces a universally quantified type constraint: it’s saying "for all types f that are Functors, <$> can operate on them". That comes straight from formal type theory (Haskell’s type system is based on Hindley–Milner inference and lambda calculus). So when Drake is happily pointing at (<*+*>) :: [a -> b] -> [a] -> [b], it’s not because he sees a cute smiley – it’s because, in theory-land, that operator could represent a derived combinator for function lists applying to value lists (essentially a specialized Applicative for lists). In summary, the meme’s punchline is rooted in Haskell’s unique blend of theoretical purity and syntactic freedom: the language lets serious abstract mathematics be expressed in strings of symbols that coincidentally can look like ASCII art. It’s a reminder that under the hood of those “emoticon operators” lie laws of FunctionalProgramming (functor mapping, applicative composition, etc.), which are as strict and logical as any formula – even if the notation brings a smile (or smirk) to our faces.

Description

This meme uses the two-panel 'Drake Hotline Bling' format. In the top panel, Drake disapprovingly gestures towards a list of Japanese-style emoticons (kaomoji), such as (・ω・) and (¬_¬). In the bottom panel, Drake smiles and points approvingly at a screenshot of code, likely Haskell, displaying a series of cryptic infix operators and their type signatures (e.g., '<$>', '<**>', '<*+*> :: Applicative f =>'). The humor lies in the comparison: for a functional programmer, the dense, symbolic operators of languages like Haskell, which represent high-level abstractions like Functors and Applicatives, are more expressive and beautiful than actual emoticons. It's an inside joke for those familiar with the steep learning curve and abstract nature of functional programming

Comments

11
Anonymous ★ Top Pick Some see a wall of cryptic symbols. A Haskell developer sees a beautiful conversation between a Functor and an Applicative, and it's pure poetry
  1. Anonymous ★ Top Pick

    Some see a wall of cryptic symbols. A Haskell developer sees a beautiful conversation between a Functor and an Applicative, and it's pure poetry

  2. Anonymous

    Dropped (>*<) in Slack - half the team thought it was a kawaii emoji, the compiler saw “zip two Gens,” and I’m just here enjoying type-safe ambiguity

  3. Anonymous

    The real reason Haskell developers don't use emojis in Slack - they're saving all the good ASCII art for defining infix operators that make code reviews feel like deciphering ancient runes written by mathematicians who discovered category theory and never recovered

  4. Anonymous

    When you realize that '<*>' isn't just a cute ASCII bear face, but actually the applicative operator that sequences computations in a context - and suddenly your entire understanding of monadic composition shifts from 'aww' to 'aha'. The real power move is explaining to stakeholders why your codebase needs these operators: 'It's not line noise, it's just point-free style with higher-kinded polymorphism.' Meanwhile, junior devs are still trying to figure out if '(>*<)' is an emoticon or a legitimate type signature, and honestly, in Haskell, the answer is 'yes.'

  5. Anonymous

    I only send reactions that typecheck - if your mood doesn’t fmap via (<$>) under a Functor constraint, it doesn’t belong in the review

  6. Anonymous

    Kaomoji for mutable state machines; Haskell types for the pure hearts that fmap forever

  7. Anonymous

    Emoji are cute, but they don’t obey Functor or Applicative laws - give me (<$>) and (<*>) any day; at least those smiles compose

  8. Deleted Account 4y

    Nice

  9. @Pylferer 4y

    Isn't haskell beautiful?

  10. @callofvoid0 4y

    what?

  11. @callofvoid0 4y

    static method?

Use J and K for navigation