
Programming with a love of the implicit - tmlee
https://m.signalvnoise.com/programming-with-a-love-of-the-implicit-66629bb81ee7
======
brianolson
DHH says that explicit code favors novices and those with 'fresh eyes' on a
problem while burdening experienced veteran programmers with bloat of
boilerplate to read and to write.

I may as well come with fresh eyes for any code I wrote over a year ago. I'm
reading _my own code_ with an eye to figure out how it was put together. I
should be courteous to my future self and to anyone else who wants to read my
code.

I pick up a new framework every year or two. I've been a full time software
professional for over 16 years and I'm picking up new tools all the time. I
prefer tools that tell me things explicitly so that I don't have the steep
learning cliff of grokking the entire system in order to be able to work with
one little part.

And isn't this hypocritical? So many people (probably DHH too?) gush about how
easy Rails is to get started with, but here DHH argues that it's so much
butter for the veteran who knows what all the implied magic is. Doesn't all
that implied magic also leave the beginner kinda helpless? There's so much
Rails tutorial with the attitude "here, do this, trust me, it'll work". And
I've found that trust to be misplaced. The underlying implied design isn't
actually what I wanted, and it's really hard to get it to do what I want
because the convention is so baked in.

On the other hand, Go is a bit tediously boilerplate heavy. I'm still looking
for the right balance.

~~~
cormacrelf
I find myself wanting languages and frameworks that let me write the magic
myself. Magic is about solving big sets of similar problems in really
compact/effortless ways. Rails tries to solve a really huge class of similar
problems, i.e. web development, and starts pushing back on what you can
achieve without ditching the framework entirely. I don't mean that in the
sense that you stop being able to write regular Ruby (which can do anything),
I mean that it's smooth sailing until you want to add your own magic in
'userspace'.

Take ASP.NET, for example using method attributes for authorisation:

    
    
        [Authorize(Policy = "AdminOnly")]
        public IActionResult Method(int projectId)
        {
             return Ok();
        }
    

It's great and magical if you want to lock down a controller or a method to
admins only, or people whose standard user object has an Age field > 18 or
something like that. But if you want per-project permissions, with a
user->permissions<-project relation? Sorry, you can't easily pass invocation
parameters to your AuthorizationPolicy classes because C# Attributes don't
support that. You could try having a naming scheme for your url fragments and
get the project ID from there, but this means you need to have project
parameters in every route, which is often redundant and would need to be
checked on any object in a POST request. Any way you go, you have to write
code inside your method to get the job done. You have to break out of the
magic, and let go of the automatic 403 responses to do anything beyond the
simplest case.

To actually build this without a clumsy if/else and manually returning 403
with JSON (to describe the error) in every controller method, it was necessary
to create an exception and a custom exception handler middleware, and in the
handler, produce a non-standard HTTP code and catch it again in a second
middleware after the framework would otherwise gobble up 403s and return HTML
instead of JSON. Exceptions inside controller methods are a perfectly adequate
model for authorisation failures, but because the framework expects you to
hook into their middleware for it, they made it very difficult to do it any
other way.

Ok, that was a lengthy example. But it illustrates what I mean by wanting to
write my own magic. Frameworks shouldn't cripple userspace magic by design.

~~~
wikibob
Have you taken a look at what can be done in functional languages (perhaps F#)
? I'm just starting to get into them [0] and it's been really fascinating.

Jet.com has an interesting post on why they chose F# for similar reasons [1]

[0] I'm working through the How to Design Programs book from Matthias
Felleisen which I highly recommend despite its rough edges
[http://www.ccs.neu.edu/home/matthias/HtDP2e/](http://www.ccs.neu.edu/home/matthias/HtDP2e/)

[1] [https://tech.jet.com/blog/2015/03-22-on-how-jet-
chose/](https://tech.jet.com/blog/2015/03-22-on-how-jet-chose/)

~~~
cormacrelf
Yeah, way into FP. I've used Haskell, Clojure, and hopefully some Erlang or
Elixir soon, and I pretty much use functional style wherever else I can,
including C# and JavaScript.

F# seems to be getting more attention, but I mostly just see people struggling
to get EF migrations going, and it seems general ecosystem support is still
shoddy (compiler bugs on .NET core 1.1? 3rd party VSCode support? official VS
plugins crash all the time?). I have to use C# for work, so it's just not
stable enough despite F# itself being around for ages :)

~~~
jaegerpicker
THat's not my experience with F#, I've used it with EF and .net core 1.1, and
VS. I've been extremely happy and had little to none of the issues you listed.

~~~
cormacrelf
I pulled it out of the drawer again a few days ago. It was lovely, I wrote a
monad for asynchronous HTTP results (basically the async monad + an Either
monad + some methods to produce some HttpErrors) and encoded a bunch of API
functionality (including auth filters) with early returns. The only pain was
not having anonymous dynamic objects in C# new { syntax = "syntax" } and using
Dapper.

I'd definitely like to give it a go for some bigger projects.

------
smt88
Preferring implicit code is optimization for the first person writing the code
while making it harder to understand, debug, and update.

When code is written only once and most of the cost comes afterward, that
seems like an impossible choice to defend.

Why optimize for keystrokes? How much do keystrokes really cost you? Why
optimize for conciseness, if it comes at the expense of readability?

I've maintained some PHP code bases with tons of implicitness (magic methods
in ORMs and strings dictating object behavior, mostly) and some that had no
implicitness. Guess which were more expensive for the client and painful for
me?

Another example: I've recently been working on a C#/.NET code base, and I was
wondering where the HTTP request is converted into a C# object (in this case,
a JSON to object deserialization).

Guess where I had to go to figure it out? Google. And it wasn't easy to
Google. I couldn't follow the code because of the layers of magic and
configuration that controlled my code, rather than actual code. It was a huge
waste of time and makes the code base completely opaque sometimes. It's a ball
of yarn, and you don't know where it begins or where it ends.

Why is my code behaving strangely? Is it because I wrote it to do something a
certain way? No, it's because this random config file (that I didn't know
existed) is dictating behavior instead of the code itself.

I can't imagine how anyone working on large code bases with other people would
want to do this. Yes, implicitness is more fun and beautiful at the beginning,
but it becomes a nightmare after a short time for anyone other than the
original coder.

~~~
wycats
> Preferring implicit code is optimization for the first person writing the
> code while making it harder to understand, debug, and update.

I feel that this argument has been repeated so often that it's almost
understood axiomatically: nobody thinks about what it means anymore, it just
"seems true".

I posted Aaron Turon's (of the Rust core team) article that touches on these
topics elsewhere in the thread
([https://news.ycombinator.com/item?id=14280908](https://news.ycombinator.com/item?id=14280908)),
but this topic desperately needs a better definition of "implicitness".

Virtually nobody thinks that C programming is "too implicit" because it's
"optimizing for the writer over the reader," and similarly, garbage collection
is an extremely implicit mechanism that is widely accepted, including by some
of the strongest EIBTI proponents.

On the other hand, as a strong proponent of abstraction and implicitness in
many contexts, I was extremely supportive of (and helped champion) Rust's
explicit error handling through the Result type.

I like Aaron's "reasoning footprint" rubric because it gives us a way to
debate this topic without "implicit" defined in the eye of the beholder.
Importantly, it allows us, as a community, to broadly accept changes like
garbage collection and control-flow constructs without repeatedly rehashing
the same old bumper-sticker debates that mar every generation of programming.

~~~
michaelcampbell
> > Preferring implicit code is optimization for the first person writing the
> code while making it harder to understand, debug, and update.

> I feel that this argument has been repeated so often that it's almost
> understood axiomatically: nobody thinks about what it means anymore, it just
> "seems true".

Indeed. It seems just another way to not understand "everything is hard to
read until one learns to read it".

~~~
smt88
> _It seems just another way to not understand "everything is hard to read
> until one learns to read it"._

So everything is equally difficult to read and understand? There are articles
that say "great software is like Shakespeare" and others that say "great
software is like Hemmingway". Which one of those authors is easier to read and
understand, as someone who speaks English natively?

As someone who has inherited just two code bases, I know first-hand that there
can be _massive_ differences in how easy something is to read and understand.
One of my companies had a code base that non-technical people could read and
even send PRs for. Another of the code bases took months of ramp-up time.

------
wycats
Since this thread is somewhat rehashing the old arguments ("you write once,
but read many times, therefore EIBTI"), it might be worth reading a more
modern take on the topic by Aaron Turon of the Rust core team in his essay
about the Rust language ergonomics initiative[1].

> But this, in my opinion, is a misdiagnosis of the problem, one that throws
> out the baby with the bathwater. The root issue is instead: how much
> information do you need to confidently understand what a particular line of
> code is doing, and how hard is that information to find? Let’s call this the
> reasoning footprint for a piece of code. The pitfalls above come from the
> reasoning footprint getting out of hand, rather than implicitness per se.

> Does readability then demand that we minimize the reasoning footprint? I
> don’t think so: make it too small, and code becomes hopelessly verbose,
> making it difficult to read by forcing too much information into view at all
> times. What we want is a sweet spot, where routine or easy to find details
> can be left out, but relevant or surprising information is kept front and
> center.

[1]: [https://blog.rust-lang.org/2017/03/02/lang-
ergonomics.html](https://blog.rust-lang.org/2017/03/02/lang-ergonomics.html)

~~~
hyperpape
Thanks for linking to this example. It's a great example of getting beyond
slogans and trying to suss out the actual tradeoffs that come up in practice.

------
xaa
Although this article never mentions the word, it's really about abstractions,
not "implicitness" per se.

No one would say that if you have an almost-perfect abstraction, like a
physics equation for fluid dynamics, that you should go to the effort of
dropping down to the lower level (specifying what each molecule should do, in
this case).

The problem is that this ORM example is an extremely leaky abstraction.
Several of the inferences it is making are inferences that are not predictable
if you don't already know how it will work. And they are inferences that
matter.

Anyone who has ever used an ORM knows that it _seems_ like magic, right up
until you try to run some large query and it takes an eternity, and then you
have to unpack it all and add all the explicit stuff to fix the problem that
you "avoided" in the first place.

The real art of programming is in knowing what needs to be explicit and what
can be implicit. I'd agree that if something can be made implicit _without
mystifying callers_ , it should be.

~~~
debaserab2
ORMs make the obvious and easy things even easier. They don't help out as much
with the hard stuff. The hard things are still hard regardless if you have an
ORM or not, but just because an ORM doesn't solve everything it doesn't mean
you should throw the baby out with the bath water.

You rarely have to "unpack everything", you usually just need to go down a
level of abstraction or two to get at the actual database driver in specific
parts of code.

The trade off of using an ORM is still almost always worth it in my
experience, but it certainly depends on what your app does.

------
_asummers
I would rather not leave myself a crime scene in my code that I have to figure
out before I can do my work (especially when debugging!). I bounce around way
too many systems in way too many languages to keep all the rules of every ORM
and framework in my head.There's always a balance, but you can do really
expressive things in the explicit. In the authors example of the Person, Ecto
from Elxir doesn't favor magic happening for the has_many; you have to call
out the validation AND relationships yourself. I think that's a good thing

    
    
      schema "people" do
        field :first, :string, null: false
        field :last, :string, null: false
    
        belongs_to: :company, App.Company
        has_many: :assignments, App.Assignment, foreign_key: :person_id
      end
    
      def create_changeset(attrs) do
        %Person{}
         |> Ecto.Changeset.cast(attrs, [:first, :last, :company_id])
         |> Ecto.Changeset.validate_required([:first, :last, :company_id])
         |> Ecto.Changeset.foreign_key_constraint(:company_id)
      end
    

And in the Assignment changesets you'd do the reverse for making sure the
other sides' entities exist, or in the join table for many to manies.

I think the win readability wins later FAR outweigh the few validations I have
to explicitly type out. A new person or someone under a deadline can quickly
open one of the Ecto schemas, see all the relationships, see the validation
being done, and see why stuff fails. And by turning it into a function you
must explicitly call, it makes the data the most important thing and not the
ORM itself. I could have called that function "parent_changeset" or
"lawyer_changeset" if those made sense for what those functions did; they're
not specially named. And then when you get that, you still need to actually
apply the changes to have any effect.

~~~
mercer
This whole discussion feels similar to the explicitly/implicitly typed
discussion. Sometimes I get annoyed by writing more code in an explicitly
typed language. But most of the time, especially when I get back to the
project after it being inactive for a while, I am so happy with the more
explicit version of my code.

~~~
_asummers
I tend to agree, and fall into the camp of favoring static types.

It's also extremely helpful when reading and debugging others' code bases.
Having to construct systems of rules in your head sucks. Being able to follow
the function calls and data around while validating assumptions with the REPL
makes figuring external bugs out much easier.

------
liquidise
Implicit code is indeed beautiful. DHH has also struck a great balance of
implicit code remaining remarkably expressive with Ruby on Rails. It is the
best example i have seen. But i would cite 2 shortcomings of implicit code:

\- Implicit code increases the barrier of entry to new coders. This is
counterintuitive as there is less overall code to learn. But implicit code
often relies on auto-magic. Until you know the pieces of that magic, you are
left confused. Case in point, as a web coder to find the file for `render
user`.

\- Implicit code works great until you need something to work differently than
the implicit nature intends. This is because implicit code is also opinionated
code. When your feature needs to fight against those opinions, you can expect
to write a lot of highly explicit, ugly code to break that mold.

The slider of explicit-implicit will be talked about as long as code exists.
Implicit systems result in less LoC, but you risk sacrificing expressiveness.
For growing applications supported by growing teams, some of that time gain
can slowly fade as your team gets younger and less experienced.

~~~
rocqua
There is a large extra shortcoming: debugging. When reasoning about implicit
code, there are more assumptions you need to make. Debugging is basically
verifying assumptions until you find the disconnect between your reasoning and
code execution.

The implicit code requires you check all of the implicit assumptions. Explicit
code makes checking such assumptions much easier.

~~~
mercer
Excellent point! So far I get the impression that 'level of abstraction' and
it's benefits/downsides can be separated into a bunch different categories
(readability, conciseness/concision, ease of getting back into things after
being away, protection from various classes of errors, etc.). Ease of
debugging will now be another one on my list.

------
hyperpape
This article is ok as far as it goes, which isn't very far. Embracing
implicitness can give benefits in the way that DHH describes. It can also lead
to violations of your expectations.

Now, raise your hand if you honestly think that the answer is "embrace
implicitness" or "embrace explicitness" full stop. In that context, it's worth
noting that the Tao of Python was written well after the language was
constructed, as a summary of the choices that were made. It was not originally
intended to be a design document.

Sometimes implicit behavior is easy to understand, predictable, and saves lots
of time. In those cases, it's good. In others, it borders on madness:
[http://stackoverflow.com/questions/12488705/incorrect-
plural...](http://stackoverflow.com/questions/12488705/incorrect-pluralizing-
of-model-in-rails)

What determines the cases where one side of the tradeoff is good, and the
other is bad? Show me cases where Rails does better than Django or some other
framework and vice versa, and tell a story about how you identify those cases
and judge whether the tradeoffs are worth it. That would be an article worth
studying.

~~~
kbsletten
See, the thing is that even in this example he wasn't 100% implicit. Could
rails magic up those has_many and belongs_to in method_missing? Absolutely. Do
they? Of course not since that's "too implicit." For whatever reason, rails
decided that columns are boilerplate and relationships should be declared.

------
ajmurmann
As always the answer is somewhere in the middle. For a core library that your
company or even better everyone using the framework as you uses everyday
implicitness is great. You invest a little bit upfront and it keeps paying off
everyday. For one-off code you hardly ever touch you better be explicit. Of
course there trick here is knowing which one you are writing. A good rule of
thumb might be you start explicit and over time add an implicit layer on top
while refactoring. With DHH's Active Record example that would have worked out
nicely, since from the API perspective is really just reasonable defaults that
could have been added once you realize that Active Record thing is actually
being used in frequently.

------
malyk
Implicit code is great for frameworks. The kinds of things you have to do over
and over again and a lot of the things Rails is great at. Create a database
table, link it to an ORM, take params from a POST request, save them to that
table...all that stuff should be pretty vanilla and absolutely yes, convention
over configuration is amazing for that.

Explicit code is great for business level logic. In any business, and
especially startups, things are changing so frequently that there's often very
little in the code that could be set up as a convention and the accompanying
"magic" that has to make it happen. Sales processes change weekly. Frontend
features change daily. Reporting needs can change hourly.

In those environments you have to be able to quickly look at the code and
see/know exactly what it is doing now and why so that you can be better able
to make changes without introducing defects. Testing helps this a lot, but
succinct, readable, explicit code makes life so much easier.

Implicit for frameworks; Explicit for business.

------
koolba
> Just on the database side, it implies that there’s a “people” table backing
> the “Person” record.

Plural table names are already pretty stupid, but using "people" vs "persons"
even more so.

Implicitly having the table name match the entity after some case
transformation is fine, but it should be more direct and not require an
English dictionary to handle edge cases.

~~~
cormacrelf
It's stupid, but it's approximately as stupid as having single object variable
names, type names, collections, table names etc. all with the same,
indistinguishable singular noun. It's also what programmers have dreamed about
since we realised you didn't have to use punchcards, and it's what I tell
people programming is like so they can understand what I do.

Rails lets you write code that can be read out loud and still make sense. You
can have a meeting about an ActiveRecord class and not get caught up
clarifying what you're talking about every step of the way. You could put some
code in a presentation to your manager if you really wanted. In three years'
time when you look at your code, you can read it aloud again and find yourself
saying exactly what it does. Rails lets you describe ideas at a similar level
of abstraction as common English speech. That has value, even if it lacks
precision. If having a dictionary embedded into the macros is what helps
people write code well, then they clearly value matching up with their brain
over matching up with a compiler, and good for them.

~~~
koolba
Code isn't prose and you don't read it out loud or have it read to you. You
read it with your eyes so the case of the word is clearly visible. You also
have the additional context of the language of the code and syntax
highlighting from your editor.

If I'm read app code, a "person" is a variable and a "Person" is a class.

If I'm reading SQL a "person" is a relation (e.g. a table).

I consider losing structure and adding complexity just to be able to read
something out loud a net loss.

~~~
cormacrelf
> I consider losing structure and adding complexity just to be able to read
> something out loud a net loss.

So would I. But Matz wrote early on that 'Ruby is designed to make programmers
happy,' and that is behind lots of language decisions in Ruby and Rails.
Reading aloud isn't an isolated end goal but more a way of describing that
design principle. Writing Ruby should be a pleasant interaction, and Ruby
programmers should feel like they are talking to a friendly machine. There are
many ways to write the same code, and you can develop a distinctive writing
style if you want. Many Rubyists talk about and write code like it's poetry,
and feel like they have a voice through the code they write. Can you say that
about a single Java programmer?

This isn't an accident, and effects like this are not frivolous entertainment
the Real Programmers can ignore. It isn't a perfect vision, and you're
absolutely right that sometimes it introduces complexity, but it's a real
philosophy with tangible benefits, and pluralisation is a tiny part of that
vision.

------
amasad
This is sort of a strawman, nobody on the explicit side of the debate wants
people to write more boilerplate -- it's about how discoverable the code (and
relatedly how many layers of indirection).

    
    
      class Person < ApplicationRecord
       belongs_to :company
       has_many :assignments
      end
    

For example what are the :company and :assignments symbols referring to? Why
are they symbols? If they are models it would be better if they were required
_explicitly_ and that way I know where they are defined and can go read the
code.

------
grandalf
For every _explicit_ thing in the code the programmer must pay attention to it
when reading/understanding how the code works.

For every _implicit_ thing in the code the programmer must have a mental model
of what it is doing behind the scenes.

So one taxes the attention system of the programmer, and the other taxes her
memory system.

Other things are both explicit _and_ require a complex mental representation
of state (Haskell), but the type system makes many classes of error
impossible.

I think most people would agree with DHH's aesthetic when it comes to
abstraction. What makes ActiveRecord's approach to abstraction get ugly in
many cases is its coupling to the mutable state of the underlying database,
which is not guaranteed to be in sync with the logic _impli_ ed by the
declarations, which may also have unforeseen timing side-effects.

Imagine the more typical scenario:

    
    
      class BusinessContract extends ActiveRecord::Base
        belongs_to :company
        belongs_to :client
        belongs_to :sales_rep
        
        acts_as_attachment
        acts_as_state_machine
        acts_as_versioned
        
        before_save :notify_rep
        after_save :update_salesforce_api
        after_update :generate_pdf
      end
    

This class is now doing a great deal, and the user of the code needs to
understand the time-dependent aspects of it and side-effects.

~~~
majewsky
Oh yes. Two years ago, I had to work on an in-house IaaS written as a Rails
app, where the models were particularly fat, with Instance#after_save hooks
putting jobs in the worker queue to reflect the state into the hypervisor,
e.g. starting a newly-saved instance or stopping/restarting an existing one.
Trying to follow that code flow along was an excruciating experience.

------
hmigneron
I enjoyed this article a lot because this is a problem I struggle with often
when coding. And not just at a particular point in the lifecycle of a project,
it comes up all the time.

Decisions like this are, in my case, heavily influenced by how much I _trust_
the rest of the codebase. Having "magic" code on top of a rock solid
abstraction feels nice and safe. When I debug / troubleshoot I don't feel the
need to step into the function to look at its implementation one more time.

I am much more likely to be explicit, suck it up and write the boilerplate
code once again in a messy codebase where the abstractions change all the time
(whether I'm the one who wrote the sucky code or not). In the end, I feel like
it comes down to how well your objects / concerns are designed. When the
concerns are properly separated and your objects are solid, magic code is
indeed beautiful and extremely expressive.

~~~
psyc
I find this is the best way to achieve the balance people are looking for. I
try to spread the explicitness across the abstractions, so that it doesn't
feel too heavy at any one level. For example, I get a lot of mileage from
succinct, least-surprising / 90% case methods that in turn call fully
parameterized versions of themselves.

------
49531
I wonder if maybe DHH is saying he prefers declarative code over imperative
code.

I think it is often the case where one can argue that imperative programming
is explicit, but in reality declarative syntax patterns are often easier to
approach as a beginner and an expert.

------
heisenbit
As long as the implicit does the job it is fine. However when corner cases
suddenly require the implicit to do something slightly different one is forced
to dig into all the code that made the implicit work.

------
frou_dh
> It’s the same story with product values. If you say your product is “simple”
> or “easy”, you’re rarely saying much.

The descriptions for an incredible number of projects on GitHub lead off with
something along the lines of "$PROJECT is a simple ...". My theory is that
preemptively framing one's projects as "simple" might be a subconscious
defence against accusations of triviality.

------
coding123
I agree with the author of this article. In general this is more about
implicit functionality at the language level. Why is that much different from
implicit functionality we get at the library level. In Java, when I use JPA, I
am depending on massively loaded meaning behind a set of annotations...
@OneToOne @ManyToOne, etc... at runtime you best know what all of those
annotations are. I haven't really seen anyone that LOVES JDBC complain about
tools like Hibernate/JPA. Yet it gives us lots of implicit meaning when we
write this code that someone NOT familiar with JPA would be going crazy about
- until they learn it.

To go a bit further and just state that suddenly it's NOT OK at the language
level is kinda argumentless in my humble opinion.

And yes, there are degrees of acceptability. If JPA had an annotation like
@OMGWTFBBQ and ActiveRecord supported something similar - it would be
rejected. JPA and ActiveRecord do things like this, but much of the rest of
these tools features outweigh their faults. I know for sure there are many
Java frameworks that actually love it when you write your own annotation.

For example I use a @NoAuthentication annotation in Jax-RS. There is no
standard annotation for that, yet in our company we all use it and know what
it means. We mark this REST service as a service that anonymous users or
authenticated users can call alike. This is because we favor a model of
placing our authentication code inside the stack (in our case CXF) rather than
adding code at EACH rest method. It's a very VERY implicit style, we can't
look at and adjust our authentication model, but just the same, we SHOULDN'T
be trusted to change our authentication model in each method.

Annotations are not exactly the same as implicits in other languages, but it's
the closest example of something in Java that makes our lives much easier and
hides a LOT of explicit info.

------
dwaltrip
I think it's better to view this in terms of analyzing abstractions and their
pros and cons, versus some vague notion of explicit vs implicit.

The more I learn, the more it seems an immense portion of high caliber
software engineering is knowing how to approach and analyze very general
questions related to abstractions, such as:

1\. Given the current and expected future constraints, is this the best
abstraction we can come up with?

2\. Is the abstraction worth its cost? How heavily should we invest in using
it, given how confident (or not) we are currently that it solves our problem
well?

I think of abstractions as being everything from breaking an if condition into
several local variables to splitting a large monolithic app into independent
services. We could go further of course, but I think that gets the idea
across.

------
shahmeern
There's a subjective balance to be struck between implicitness and
explicitness. The example DHH gives are basically default parameters, which is
a pretty reasonable amount of implicitness for me.

On the other end of the spectrum are things like Scala's implicit parameters,
which I abhor.

------
shazow
I just published an article arguing the exact opposite a few days ago, funny
timing:

[https://medium.com/@shazow/code-boilerplate-is-it-always-
bad...](https://medium.com/@shazow/code-boilerplate-is-it-always-
bad-934827efcfc7)

------
devdoomari
I really like scala's "implicit" syntax/feature, but sometimes I have trouble
getting "how does this work...?"

hope scala (or intellij?) would get a "find all implicits related to this
file/folder" and other things to help me around

------
fantasticsid
You can still make good abstractions with explicit code, and remove most of
boilerplates. But please at least be explicit about the fact you are using
that abstraction.

One problem with Rails is that these abstractions are applied implicitly and
burried deep in the framework. For DHH it's easy to know what it's doing
behind the scene. Not for people who did not create these implicitly applied
abstractions.

So.. Either you will have to learn ALL the Rails conventions, or you can
create your own abstractions and use them explicitly. Also, it will be easy to
put a breakpoint on the call site to your abstraction. Try that with Rails,
you don't know what/where to put that breakpoint.

------
orf
I don't think his example is great. Here is the equivalent in Django (in
Python, a language that exposes 'explicit is better than implicit' as a core
ideology):

    
    
       class Person(models.Model):
          company = models.ForeignKey('company', related_name='people')
    

How is this worse than the implicit version on the post? Basing it purely on a
LOC argument is flawed as implicit doesn't always mean less code, and explicit
doesn't always mean more code. In this example there is actually less code,
you don't need a `has_many` at all (unless it's a m2m, then it's the same
LOC).

~~~
majewsky
In my experience the Ruby community is all about LOC arguments. So many blog
articles I read about Ruby stuff is just "look what I can do in one line", and
I'm like "maybe you shouldn't?". For example:
[https://twitter.com/stefanmajewsky/status/643380134037323776](https://twitter.com/stefanmajewsky/status/643380134037323776)

------
akovaski
I'm not familiar with RoR, but that explicit version is hard to read. However,
I think the problem with implicitness is that when it becomes wide-spread,
nobody can read the code with ease (i.e. everyone made their own implicit
code, and it comes together poorly). I see nothing wrong with a little bit of
magic, especially if it is something you use often.

Side note: the author has a short paragraph about "simple/easy" and
"complicated/hard" products, which doesn't ring true with me. I would think
most people would say their software product is "complicated, but easy to
use".

------
zimbatm
When I develop in rails I tend to read the rails code a lot to understand what
kind of implicit knowledge I was supposed to know. I suspect that veteran
rails developers have done that a lot and also keep-up with framework upgrades
when the assumptions are changing.

This is the tax we pay for being part of the DHH cult following (some against
our will) :p

------
zimbatm
Implicit means that a lot of headspace is taken to remember all these details.
I'd rather focus on building something cool, rails is not the end-goal.

------
luisobo
Explicit vs implicit is a false dichotomy, or at least, an artificial one.
With Projectional Editors you can have either one depending on your needs.

------
sidlls
It seems to me the title should include "when programming with RoR/dynamic
languages" at the end.

------
33a
The examples in this are exactly the sort of thing in rails that drove me
crazy when I was learning it.

------
vinceguidry
DHH never fails to impress. As usual, he cuts to the core of his beliefs, and
delivers sound argument for them.

Program with Ruby long enough and it really starts to feel like a religious
experience. You feel like you can literally do anything. Things you can't do
with it just don't seem important anymore.

Rails just takes Ruby and puts it on steroids.

~~~
SimbaOnSteroids
Puts it on steroids you say? Seems I'm in good company.

Bad joke aside, and I may be a naïve newbie, but what is stopping someone from
writing tons of implicit code during their most productive work hours and when
they're tired go back and make comments that make the code more explicit.
Seems that this would get the best of both worlds in that you'd be able to be
hyper productive when you've got the mental resources and then taking that
extra time to make sure whoever stumbles upon your code later doesn't have to
deal with a huge learning curve.

~~~
factotum
The problem with comments is that they are too often lies. As the code
changes, the comments may not necessarily be updated, and in my experience,
they often aren't. Automated documentation and validation are superior to
static comments in general. Using a compiled language can help with some of
this, and automated tests even more.

~~~
SimbaOnSteroids
True, I know the JetBrains IDEs have automated refactoring, and I'm sure other
IDEs do this as well, I'm not sure how much of additional overhead it would be
to implement an auto comment feature/plugin that handles the job of
generating/maintaining comments like #Person refers to columnn people and
other things a more explicit language would simply state. Seems like something
that could be fairly easily automated.

------
dom0
Been there, done that, not worth it.

------
dominotw
i thought this was about implicits in scala

