Qqwy

Qqwy

TypeCheck Core Team

Hello there, everyone,

I just listened to the ‘break it down like a fraction’ episode of Elixir Outlaws on my way back home. It is mostly about the subject ‘explicit vs implicit’. I found it very interesting, since I thought it had a very clear and simple meaning, to find out that in actuality, people have given very different interpretations to what ‘explicit is better than implicit’ actually means.

So that’s why I think it might be worth talking more about this, because I agree with show-hosts Chris Keathley (@keathley) Amos King (@adkron) and Anna Neyzberg that applying a guideline without thinking about the context it was conceived in is a dangerous thing.


Personally, I’ve always thought that the main idea of ‘explicit is better than implicit’, which I believe has its origins in the Zen of Python is not about how (if at all) complexity should be abstracted away (which is an interpretation that a lot of the podcast episode focuses on), but rather the (mostly) orthogonal concept of (a) clear naming and (b) making it as clear as possible how the data/state flows through the program.

So the idea that “a user should understand with as little cognitive effort as possible what a call to a function does”. Importantly, not how it does it! (this is what is hopefully abstracted away).
This has been used as an argument in many aspects of the design of the language itself, as well as the standard library:

  • The use of defining new infix operators is often discouraged, and José has made the choice to only allow a handful of operators to be (re)defined, rather than allowing arbitrary new ones to be used.
  • Pipelines prefix module names (for non-local functions), which make it more clear what the subject is (expected to be) w.r.t. a chain of member methods that work on ‘whatever the last member method returned’ in Ruby.
  • The separation of functions that create/transform datastructures from functions that perform an effect. A prime example here would be creating an Ecto query or changeset vs. running it on a particular Repo.

So I am very eager to hear what other people think about this:

  1. Have you seen ‘explicit is better than implicit’ been used in the wild as justification for something where you think it is not applicable?
  2. What is your interpretation of ‘explicit is better than implicit’? Do you try to apply it to your code in one way or another, or not?

Showing Posts 1 to 10

JEG2

JEG2

Author of Designing Elixir Systems with OTP
Phillipp

Phillipp

Personally, I love to write rather explicit code (and more code) than implicit code with hidden side effects.

Over the last 1,5 years, I had to work on a few client projects in javascript/nodejs and one thing was the same on all of them:

I wrote rather explicit code where the “data path” is easy to see and reason about. Then a couple weeks in, the javascript/nodejs developers at the client started to rewrite everything just to end up with the minimum amount of code but with maximum complexity and implicity. Especially things like “factories” and “currying” were their favorite solutions to everything.

The functionality to the outside was the same, the performance of the application wasn’t improved but IMO the code smelt like a dead fish.

For me, explicit vs. implicit is mostly about code design and readability. When I look at code, I want to understand what it does without following a handful of helper functions and modelling of the data structure in my head first.

josevalim

josevalim

Creator of Elixir

My take on the “explicit better than implicit” is that we want to make the complexity explicit. This makes its interpretation a bit more personal, because what is complex for some is not necessarily complex for others, but I believe it aligns well with FP. Mutability is troublesome? So let’s make it explicitly opt-in. Communication is hard? Let’s be explicit with messages! Oh, you have side-effects? Let’s keep them in their own corner.

In particular, explicit does not mean dropping things like “convention over configuration”. In fact, I would argue that making everything verbose makes it less explicit, because you don’t know what to focus on (i.e. if everything is explicit, then nothing is explicit).

PS: I didn’t listen to the episode yet.

25
Post #3
OvermindDL1

OvermindDL1

This is so true!

Go is a prime example of this, the sheer huge amount of code just to do simple algorithms obscures the work actually being done.

It’s a fine balance. I’m finding this thread quite interesting to read so far to see everyone’s ideas on it. :slight_smile:

dimitarvp

dimitarvp

To me, “explicitness” must be married to “readable for humans”. I’m fully okay with some implicit variable somewhere – say, an Agent storing a base URL to a 3rd party API, or Ecto’s Repo config (or almost any config really). If that implicit variable changes rarely then the reduced human cognitive cost of calling functions with less arity is indispensable.

adkron

adkron

Implicit vs explicit is about the functionality of an API and communication. The discussion that we were having on the show was born out of some developers avoiding putting parts of the code into functions and the argument is that things aren’t explicit once they were in another function.

I find this to be a fallacious argument. Placing code into a function doesn’t make it implicit. In fact, it often creates a more explicit API when paired with an intention revealing name. Naming something in a way that communicates the intention and what it does is one secret to a self-documenting API. In the end, we want code that communicates its intention in an explicit way. Often the intention is lost when the reader has to wade through conditionals and Enum calls to figure out the intention of the code.

peerreynders

peerreynders

This sounds like my regular rant about the habit of many JavaScript developers of using inline anonymous functions instead of factoring the functionality into a well-named function.

However that is not the impression I got from the podcast.

To me the argument seemed to be that the Python-style preference of Explicit Is Better Than Implicit is wrongheaded:

#Explicit
def read_csv(filename):
    # code for reading a csv

def read_json(filename):
    # code for reading a json

#Implicit
def read(filename):
    # code for reading a csv or json
    # depending on the file extension

i.e. read(filename) is implicit but also more loosely coupled; read_x(filename) is more explicit but a) more tightly coupled and b) forces the complexity of determining the file type onto the user code.

PragTob

PragTob

(didn’t listen to podcast as podcast really isn’t my kinda medium)

Thanks for bringing the discussion here, never thought there would be so many different opinions/views on this :slight_smile:

My major interpretation of explicit vs. implicit is to a degree how much I can easily see what’s going on and control it.

My favorite example is ActiveRecord vs. Ecto.

In ActiveRecord I define all the validations and callbacks in the model. Somewhere else I then call save and all of these are magically executed (with all the weird conditions applied in the model). I don’t see what is executed and in what order.
In Ecto on the other hand I specifically choose a changeset that I want this to be run through, I can easily see what is done and in what order. If I don’t want something to happen I can easily remove it or explicitly call another changeset. Makes my intentions very clear.

Similar thing about automatic preloading of associations vs. not or the way in which you need a PhD in ActiveRecord to know what triggers a database case vs. modeling it more explicitly through use of a Repo in Ecto.

As it still rings in my head from an early Ruby Rogues episode where @JEG2 said “magic is always bad” - the more experience I have, the truer that statement rings - kudos James :slight_smile:

keathley

keathley

Oh that’s fine lots of people don’t listen to podcasts. No big deal.

Hey wait a minute!

13
Post #9
Rich_Morin

Rich_Morin

This! Anonymous functions complect the function code with the call, turning two (or more) simpler expressions into a single, complicated one. I don’t like this in general and I particularly dislike it when I’m creating a pipeline.

So, I almost always stuff my anonymous functions into local variables and then use them by name. However, I’m still struggling with the definition of a “well-named function”. My current (idiosyncratic) idiom looks like:

|> Enum.map(map_fn)

This works fine for many simple situations, but it can get a bit ugly when there are naming collisions:

|> Enum.map(map_fn1)
|> Enum.map(map_fn2)

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 94592 917
New
cblavier
Hey there, It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
heathen
Quite interesting article Google brought me. Didn’t find any mentions about it here. What do you think in general? Would you use togethe...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
AstonJ
Since we have deprecated our Erlang sections (as we have dedicated Erlang Forums now) let’s add this thread for those who’d like to post ...
New
Null-logic-0
What IDE or editor are you using for Elixir development? Personally, I use Zed, and I really like it, but sometimes I wish there were a ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews