Clojure: a pragmatic data driven language?

I feel pragmatic and practical aren’t the same thing exactly. In that I’d say practical means that it is useful for the day to day real world use cases. While I’d say pragmatic is more a design tenet, where if there is a design challenge, which is limiting the solution space, practical compromises will be made.

I think Clojure is very much pragmatic in that way. It is also practical, in that it has everything you’d need for most day to day real world use cases, such as a large set of libraries and frameworks. But it is also pragmatic in how for example its macro system is unhygienic, but gives you the tools to address 99% of the practical use cases. Or how its data-structures can be mutated if need be, for practical performance considerations. Or how functions can be impure. Or how exceptions can still be thrown. Etc.

You’ll often see people complaining about all of these. People ask how come there is no add to the end of a list? That’s a pragmatic choice not to allow a convenient slow O(n) insertion operation. Why does Clojure have exceptions instead of using a error return instead like Either, and that’s a pragmatic choice to keep exception handling compatible with Java’s. Etc.

Haskell for example I’d say is not a pragmatic language, but it is still practical, in that it can be used effectively to solve a lot of day to day real world use cases. That said, if a use case needed something simpler to work with, or which can not currently figure out a way to do it which keeps the theory intact, it won’t be done. In Clojure, a compromise would be put in place instead.

That’s my take on it at least.

4 Likes

I’d say as a language, it is data-oriented. But it does support a lot of data-driven programming. That’s an optional thing that you can bring to your software as a programmer. The two are certainly not mutually exclusive, but I don’t think Clojure goes any extra miles to be data-driven.

I agree with you that the term pragmatic isn’t exactly the same as practical in this context. Pragmatic is a design tenet that chooses practical compromises where necessary. Very true.

Pragmatic, as well as practical, is subjective because it’s dependent on a purpose. A Python programmer might say that Clojure’s use of immutable data structures by default is not practical, both from a perspective of foreign-ness (new idioms to them) and because the algorithms they are implementing are quire natural with mutable state. You could also make the argument that they are less performant, and so they are not practical.

We, as Clojure programmers, tend to say they are practical because you never know when you will want to make a sequential algorithm parallel. Also, you never have to worry about sharing data.

Both arguments are correct. It depends on what you value more as a default.

And I would argue that you could always find lines between any two sides where you could make good arguments on both sides. That’s why I think pragmatic, without qualifications, is devoid of meaning. Just like practical is devoid of meaning without something to be practical about.

You could say “Clojure is practical for concurrent programming” or “Clojure is practical for JVM programming (due to interop)”. But then you’re better off including the context as its essence, as per the original question. That is, “Clojure’s essence is concurrent programming” and “Clojure’s essence is JVM interop”.

In the end, I think pragmatic is not specific enough to touch at the essence of Clojure’s design philosophy. I think I know what you’re getting at by using the term, after years of working in Clojure, but it’s not a good way to explain to others. Other languages could also claim pragmatism and you can’t argue with them. If you want to get at the essence, you have to go more specific and more concrete.

Eric

1 Like

That’s true, pragmatic is a bit of a weasel word.

From this discussion, I came over this: https://www.quora.com/Do-programming-languages-have-pragmatics

And the answers argue that languages have syntax-es, semantics as well as pragmatics. And the latter is very important, as well as the hardest to formalize.

I like that idea personally. Such things (and I pseudo-quote): how and why people use the language in a certain way, and what each feature is useful for.

I feel thinking of pragmatics that way is quite useful. And if I think of Clojure, I can see that the design of most features has had ample amount of thoughts happen related to this topic. Transducers weren’t added simply for syntactic or semantic reasons, or for research purpose, or for some theoretical parity. They were added for pragmatic reasons.

Now, in that sense, you could argue all languages are pragmatic. So we’re back to square one in that saying a language is pragmatic doesn’t say much. Since all languages have pragmatics, instead, you need to explain what those are, that is, what are the features given useful for, how they are meant to be used, and why it is they should be used.

I agree with @ericnormand that “practical” is better than “pragmatic”. clojure.org itself uses “practical” as one of just three adjectives in its leading “pitch” sentence.

I’ve also enjoyed the technical linguistic definition of “pragmatics” that I hadn’t come across before, but its use there (roughly the “purpose behind the meaning”) is definitely not the ubiquitous usage of pragmatic which is centred on design trade offs made to save time and effort in order to deliver. I think Clojure made a few absolutely conscious and important design trade offs, but never ever to save time and effort, and we continually reap the benefits of the extra time taken to design for simplicity and the extraordinary corpus of thought that was brought to bear on doing so - way more than I ever knew existed. Discovering these thoughts through Clojure has been my favourite part of learning the language :slight_smile:

At my workplace I had a go at summarizing “what makes Clojure different” in an onboarding README as follows. From memory this list was mostly drawn from the clojure.org pages at the time.

Clojure is simple (but not easy):

  • lisp - parenthesis, homoiconic, macros
  • functional - immutable, values
  • concurrent - atoms, epochal time model
  • dynamic - interactive, repl
  • data-driven - information, facts, open, growth, spec
  • abstraction - protocols, multimethods, ‘expression problem’
  • hosted - jvm, javascript, aws

My purpose here was to draw out that if you “get” the lispyness and functional bits - which are often the first bits everyone gets to grip with - there’s a lot more still to get! My favourite area to try and get folks to grapple with is using open information in Clojure maps (and even in the persisted layer if possible) vs closed information containers as the real “things” we model in the world.

1 Like

well first of all i think everybody has already made really excellent points,…
therefore i am not sure if my 5 cents can add anything of value, or if i am even on topic,… so here goes nothing…

to me this question is fundamentally one about classification ( pretty much my favorite
subject matter these days :-)) and therefore all that can be said in general about classification is valid and relevant in this particular case as well.
( here is the link to a youtube video in which i elaborate on classification in greater detail: https://www.youtube.com/watch?v=cDNHIGMSMhQ )

to be more concrete, classification ( most often, and this case presents no exception ( i think )) establishes an artificial / synthetic structure for the purpose of constructing a ( seemingly ) rational argument around it. ( usually an argument that is in support of someones personal convictions / interests. )

also this kind of classification / discrimination, ( after all to classify and to discriminate are just two sides of one and the same medal ) it always and necessarily entails some degree of distortion and simplification.

alright, so when i then read for example:

But Clojure either trumps, or simply lacks any competition.
So at least when you go with Clojure, you know you’re getting the best at those things that there currently is.

to me this feels somewhat like the inevitable outcome of the argument, given the predisposition and bias of the author. ( and perhaps the real reason behind and for doing the classification in the first place :-))

in other words, my worry with this type of classification / argumentation is that, it sometimes appears, to some small part at least, like an attempt to rationalize and or justify personal convictions / believes in a self-serving manner.
( socrates was ugly, right?.. so that explains it then :-))

now look, don’t get me wrong, of course it makes sense to try to highlight those aspects which are most in favor of the argument that one is trying to deliver, every sales-person / politician, worth their salt, knows this full well,… but the crucial point is, i think, to still and always make an attempt to stay as aware as possible about what it is, one is doing, because otherwise one could at some point down the road, suddenly end up with a dangerously distorted impression of reality, which then leads one to draw deeply flawed and questionable conclusions.
( … isn’t our neighbor just such a miser?.. well you know, aunt betty told me the other day over tea and biscuits that one of his grandfathers was actually a scotsman… oh is that so?.. well then, there you have it :-))

now of course, this is just programming languages and paradigms and not race, gender, religion, nationality or anything commanding some real seriousness, and of course a good deal of many an endless editor war type debate, is of a fundamentally humorous nature,… ( as st. ignucius from the church of emacs preaches to all of us ),… i get that…
still, lately i feel i have matured somewhat and hence decided to switch strategy a bit… here is what i do:

when people ask me why i like emacs or lisp better than x or y, i offer the following question as my answer:
‘what do you prefer, lasagne or sushi?’ often times this then turns what i have very often perceived as very heated yet pointless discussions, ( in fact i used to get really worked up over this sort of thing,… :-)) into a friendly chatter about grandma’s superb roast pork recipe.

the retort’s point is of course quite simple: if i happen to just really ( REALLY! ) love sushi, or say, if i happen to run a sushi restaurant, well then this means that i have a vested interest in the promotion and continued flourishing of the famous japanese dish, and of course i will ( at least try to ) come up with all kinds of arguments that will ( hopefully ) help me triumph over those evil layers of béchamel sauce, ragù and pasta; ( DO NOT FORGET ABOUT THE PECORINO ON TOP! it really does make all the difference in the world :-))… and to do so is totally legit, because i just want to share my passion about onigiri and company with the entire world, and also, it is just entirely frustrating to me, when people, ignorant as so many of them clearly are, ( ‘raw fish, seaweed and cold rice?’ she asked me with an expression of utmost bewilderment… can you believe that!!! ) simply do not seam to get the vast and obvious superiority of the far eastern delicacy ( of course enjoyed with just the right amount of wasabi and soy souce ), over some boring italian noodle dish that’s first and foremost intended for consumption by overweight cats!

… wow… i really did not think i would end up writing this much… also, doing a food metaphor made me really hungry, plus… i am afraid i have kind of forgotten what my point was to begin with…

…hmmm… well let me see… right!.. what i was trying to get at is that eclipse sucks! also clojure rules!!!..

great, now i’ll order some chicken masala,… and be a happy camper… cheers!

3 Likes

Very insightful. I too actually am quite fond of recognizing that taxonomies serve a purpose, and are really artificial construct. Most semantic debate don’t go anywhere unless purpose is defined.

I like to tell people about Tomatoes. Is it a fruit or a vegetable? People debate it for hours.

The truth is, a Tomato is a Tomato. Fruits and Vegetables are models that we have made up, abstract categorization, yes like you say, simplifications almost always of the real concrete world. These categorizations are abstract models we made for a purpose. Programming is almost the science of this process of abstracting and modeling real concrete things using computers for x, y purposes.

If you want to cook, it will be a more useful mental model to think of a Tomato as a vegetable. If you’re out of a fruit for a given recipe, please don’t substitute it for a Tomato. Nobody wants Tomatoes in their fruit cake, or Tomatoes in their fruit punch.

Botanically though, tomatoes have seeds, and are used by plants to reproduce, and that’s the class of vegetables that botanist decided on. If you need to grow another tomato plant, it’s quite useful to think of the tomato as a vegetable.

My purpose was fully to entice others to try Clojure. I think this whole thread is about coming up with an honest sales pitch.

Now, I wanted to add something to that though. Not sure how to best word it.

While you can say that classifications can be taken for the purpose of framing a certain argument to convince someone, and that’s definitely a part of my strategy here, as I try and entice people to try Clojure. Good classifications are also useful tools to reason and arrive at better than random predictions and decisions.

As long as you have that awareness like you said, of understanding where the model begins and ends, that the model isn’t the real thing, and that models have limits and can show bias, etc.

So say I reframe the question. I am someone looking to choose a new programming language to learn and use for my next project. I make an assumption that programming language choice matters to the success of my project, and to my enjoyment of working on it. That assumption means I shouldn’t go about randomly picking a language, or just sticking with what I know just because I already know it. So how can I make a better than random prediction in this scenario? What means do I have to make a reasoned choice here? Not a random one, which hopefully turns out more accurate than random.

Most likely, you’ll need to start building a model here, which probably will include categorization, classification, taxonomies, etc., as those are good tools for modeling.

With that, I think I’ve been providing a classification of Clojure in good faith. If you do choose Clojure, you should definitly not be surprised about how I had classified it. In that you should be able to reverse engineer why I did so, and see that it wasn’t all lies or gigantic mental leaps and stretches, that I didn’t leave huge gap, or provided only a tiny frame, etc. That’s my good faith. It also aligns with my incentives, in that I don’t just want you to try Clojure and then realize you’ve been duped, and leave. My purpose is for people to try it, like it, and continue to use it.

So, you can look at my list classification as, if you are looking for these things, and think they are key to your next project’s success and enjoyment of working on it, Clojure fits pretty damn well. From me trying to fit other languages I know in this model, Clojure fits the best.

Back to pasta… If someone wants protein and no carb, It’s pretty honest to say Sushi (the raw cuts of only fish) is a better fit then pasta.

With my why not Haskell, I’m appealing to people’s desire to have the best at things. And it’s a different model I’m pushing. To bring pasta back. Is Lasagna or Sushi better? Well, they have different characteristics, but assuming you decided either set of characteristics would work for you. Well then, you should really have my Moms Pasta over Miyagi’s sushi. That’s because my Moms Pasta is the best pasta around, of all the pasta, it’s the most tasteful. While Miyagi’s sushi is good, but there’s plenty of good sushi place to go by. This is also a good faith argument in the sense of the person asking me for my own opinion. I do truly think my mom’s Pasta is the best pasta I had. While Miyagi’s sushi is an alright sushi which compares pretty evenly to other sushi places. So if you were looking to try the current best in one of those, and you trust my opinion, this can be a good way to decide as well.

Eh, my reply got pretty long as well, don’t worry about length, I found the whole thing very fascinating.

3 Likes

i did already give you a like for your post, but now i feel that’s just not nearly enough! not only did you get exactly what i was trying to point out, but you took it and build from it something much better!!! really really cool! thank you.

The first time I had a look at Clojure (2014), I didn’t get it. My impression of it was “this is functional”, but I didn’t grasp any of the other concepts. In the end, my impression was that Clojure was an inferior Haskell.

The second time around (2016-2017), I stuck to my guns a little longer. In part because I had decided to learn Emacs, I think, so this time around I stumbled into using the REPL in a right way. Early on, I watched some of Rich’s videos, which I found intriguing. But as I progressed, those videos got new meaning. That was the case with “The language of the system” and “spec-ulation”.

So all in all, I think that’s a good approach. Make an honest sales pitch that becomes more true as the learner progresses. Because it’s hard to beat Javascript at marketing, we might have better luck with curiosity, followed by persistence and truth.

I found your approach to complex Boolean statements particularly interesting.

Are you using core async for your current projects?

I haven’t used core.async because it’s too complicated, I only consider using core.async when absolutely necessary.

My programming approach is a fusion of “functional programming” and “enterprise management”. It has an added benefit,It is very helpful for the communication between the information technology department and the management of the company.

1 Like

Is that ‘The Great Unification’ of 3 fundamental forces, from particle physics?

1 Like

Yes, the Great Unification Theory thinking, in scientific research, simplicity and unity are important guiding ideologies, and Clojure (lisp) and The Pure Function Pipeline Data Flow perfectly reflects this idea.

In addition, the traditional Chinese philosophy, the Tao ---- the great unification of everything.

Thanks. I entirely agree about Taoism (/Zen) philosophy being relevant too but my reading is fairly superficial so I wasn’t sure if Taoism had a Grand Theory too. I had similar reactions to homoiconicity and reading about The Way. I think humans are drawn to ever greater abstractions as a way of efficiently capturing knowledge but perhaps ‘enlightenment’ requires us to accept the possibility that some things may be unknowable, so we must trust our instincts. Acceptance of uncertainty seems to have been the direction of travel in physics for the last century.

You had me at “Lisp.” :grinning:

Pragmatism is a claim. If compared with Python for a given problem, it should be shown the equivalent Clojure code is 10 times shorter and 10 times as powerful. No concept, no Tao, just efficiency.

1 Like

simplicity and unity are a source of strength for achieving your goals. that is Tao:

Keep it Simple and Unified.

This is a job that looks simple and hard to do.

:grinning:

1 Like

That’s not the full story. You’d also want to show that it would be more maliable to future extensions and modifications, and that it would lead to fewer defects, as well as take less time to code and test, and that it performs with better performance and scale given programmers of equivalent talent and experience in the respective language.

And that’s just really hard to demonstrate. Which is why simplicity is brought up. Because the empirical proof is really hard to put together, you need to approach it from a more philosophical angle, a proof from first principles. So if you can show that independent, unwoven, composable pieces are less prone to defect, and more amenable to modifications and extensions, and can perform efficiently and at scale. And then you can show that Clojure lends itself to build apps using such independent, unwoven, composable pieces. Then you’ve made a pretty good argument in my opinion. Maybe as good as you possibly can given how hard it is to demonstrate these things.

2 Likes

it has been pointed out to me that one may try to reason in the following direction…

tomato - fruit / vegetable
light - wave / particle

but… i am not really sure if i like this parallel at all… :smile:

…now… i just came across the following… and i thought it to be quite delightful … so… i guess i just wanted to share this… you know… for the sake of promoting general amusement… :slight_smile: … also… mind you the date on that mail! :slight_smile:


Date: 3 Oct 92 08:30:03 GMT
From: gabe@angus.mi.org (B. Gabriel Helou)
Subject: A Grim Fairy Tale
Newsgroups: rec.humor.funny

I don’t know where it originated, but I’ve seen this around the office
lately. It made me chuckle; it made me sigh.


                         A Grim Fairy Tale
                         -----------------

Once upon a time, an American automobile company and a Japanese auto
company decided to have a competitive boat race on the Detroit River.
Both teams practiced hard and long to reach their peak performance. On
the big day, they were as ready as they could be.

The Japanese team won by a mile.

Afterwards, the American team became discouraged by the loss and their
moral sagged. Corporate management decided that the reason for the
crushing defeat had to be found. A Continuous Measurable Improvement
Team of “Executives” was set up to investigate the problem and to
recommend appropriate corrective action.

Their conclusion: The problem was that the Japanese team had 8 people
rowing and 1 person steering, whereas the American team had 1 person
rowing and 8 people steering. The American Corporate Steering Committee
immediately hired a consulting firm to do a study on the management
structure.

After some time and billions of dollars, the consulting firm concluded
that “too many people were steering and not enough rowing.” To prevent
losing to the Japanese again next year, the management structure was
changed to “4 Steering Managers, 3 Area Steering Managers, and 1 Staff
Steering Manager” and a new performance system for the person rowing the
boat to give more incentive to work harder and become a six sigma
performer. “We must give him empowerment and enrichment.” That ought
to do it.

The next year the Japanese team won by two miles.

The American Corporation laid off the rower for poor performance, sold
all of the paddles, cancelled all capital investments for new equipment,
halted development of a new canoe, awarded high performance awards to
the consulting firm, and distributed the money saved as bonuses to the
senior executives.


2 Likes