S.i.m.p.l.e

Small
Independent
M
comPosable
L
Extendable

I was trying to come up with a cool acronym for what the Clojure’s definition of Simple is.

This is what I got till now, any idea for the missing letters?

Otherwise I thought about tricking it like:

Small
Independent
coMPosabLE

Hehe.

Maps everywhere? :wink:

I think the Clojure definition of simple is complex.

1 Like

I like malleable.

Small
Independent
Malleable
comPosable
Lispy
Extendable

This looks pretty good. I can explain them too:

Small

Keep your building blocks small in scope, for example, a function is a smaller unit than a class. When things are smaller, they are easier to reason about, and it creates better reuse opportunity, since you can reuse things at a finer grain.

Independent

Your building blocks shouldn’t depend on the outside environment. Let them be self-contained. Create a clean boundary, so that they can be called independently of the context they were designed in. For example, pure functions only use input passed into their arguments, they do not assume any implicit class fields or global variables to be present.

Malleable

Stringent building blocks with no customization create rigid systems, that can’t easily be reused in similar use case with only minor differences. In short, make sure your building blocks are always as generic as possible, try to do the right thing for whatever the input is, and allow some level of parameterization. The map function for example is very malleable, as the user can choose the mapping function, and it knows how to map over all types of collections. Thus making it much more useful then a increment-all-from-vector function.

Composable

Building blocks that are designed together in ways where we know they can be combined to create more complex behavior are best. For example, by using a common sequence abstraction, and by convention making all sequence functions take the sequence as the last argument and return a sequence, we can now use the thread last macro ->> to seamlessly compose a pipeline of transformation. Composition is about compatibility between inputs and outputs of your building blocks, and mechanism to arrange them in any order.

Lispy

Embracing Lisp in your building blocks brings many benefits. It opens up an easy path to macros, meaning that you can create building blocks that generate other building blocks. A Meta building blocks of some sort. It also means you get to work with your building blocks in a dynamic environment, where you can make changes to your blocks or their arrangement and see the effects of the change in real time. You also get a simple syntax which lets you do easy structural modifications to the code, helps static analyser parse your code for whatever linting, formatting or rewriting you want. And let’s you express all sort of building blocks coherently, without feeling ackward in the existing syntax. Finally, it lets you define convenient data literals, for a more homoiconic representation where what you see is what you get.

Extendable

Finally, you want to make sure that your building blocks as well as constructions made out of those can be extended externally by their users. Constructs that are closed for extensions don’t benefit reuse as well, since anytime a user face a case which is unsupported by the construct, they have no way to easily make the changes only where necessary to add the missing support back in. Instead they need to either start all over from scratch, or clone and fork your code. Extensibility let’s you avoid these issues, and conveniently let’s you customize or extend support of a construct to more context without changing the construct itself. Protocols for example lets you add support for additional types which wasn’t initially provided. Higher order functions and multi-methods let’s you tweak the behavior of certain parts of the construct, allowing you to reuse all that is common, and only change what needs to differ.

Should we make this a thing?

I can create a Wikipedia entry for the: SIMPLE principle. Just like there is the SOLID principle.

I can’t take credit to any of this, the Simple principle I’ve layed out here is just what idiomatic Clojure and the talks from Rich Hickey thought me. I think having a little marketing blip like a Simple principle could help to have people understand what does Clojure mean when it keeps saying Simple Simple, not easy, but Simple made easy.

In my opinion, this is a very strong set of principles that Clojure strives for. I don’t want to mischaractherized Clojure, so if I created an entry I would probably say that the Simple principle spawned out of the Clojure community and that within it there are a lot of supporters and adherent to it.

Seems reasonable?

I think that playing around with acronyms is fun and all, but hijacking the existing definition of simple (not tied or entangled with other things, unbraided, as opposed to braided/complected (edit) and also opposed to “easy” in the sense of “familiar”) introduces an unnecessary and complex competition between definitions. Creating a wikipedia article would confuse more people than it would help. I do not think this should be a thing.

5 Likes

That is not the definition of simple.That is the definition of decomplected, and the talk says that decomplected things tend to be simple, while complected things tend to be complex.

[EDIT] Well, it seems you are indeed somewhat correct about this. The talk does say Simple means: “One braid, One fold”. Decomplected is still the word for unbraided, and untangled. But it does seem the talk implies as well that Simple would mean “One braid”. Source: https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/SimpleMadeEasy.md

I still feel the talk does try to position simple and easy as orthogonal, not really as opposite. Like you can have familiar easy things that are simple, but they can also be complex, similarly you can have hard unfamiliar things that are simple. I’m also not sure the talk implies easy and familiar are synonymous. Familiarity can make certain things easier, but there are things that are easy and unfamiliar and yet they can still be complex. Global Variables tend to be easy even to people unfamiliar with programming in general for example. The idea of scopes is hard to grasp, yet it makes for simpler code, because it doesn’t tangle the function to its environment. But obviously, I’m saying most of this from my perspective on Simple, and thus from what I described prior, which includes decomplected (but I call it independent instead).

You got a lot of upvotes though, so I’ll take it I probably shouldn’t pretend that this is a shared set of values within the Clojure community. I’ll just make a blog post about it then, as something I personally endorse and promote, and won’t insinuate that this is true as well of the Clojure community.

Thanks all!

2 Likes

Good catch, I think that’s a better way to put it.