Fork me on GitHub

At the moment in germany the object-oriented paradigm is king in computer science education in schools. It is used because OO lets us describe the world around us with ease and OO is used widely in the industry. In most states Java is used as the default language. But the more I am learning about the functional paradigm and Clojure, the more I am asking myself if it would be reasonable to start learning the functional paradigm and let's say clojure 😉. Since you are more experienced, than I am. Do you think that the functional paradigm and clojure are harder to get than oo and Java?

👍 4

The relative easiness or hardness of learning Clojure was discussed somewhat here


There wasn't really a defining conclusion. Basically, we don't know. It seems coming from imperative and OO languages, Clojure does feel harder to learn. But coming from not knowing programming at all we aren't sure.


And I'd say the take away is that easy and hard are personal. Each person will feel differently about how easy or hard Clojure was to learn.


In my experience Clojure is harder to learn, but much easier to build real programs with. But it is a lot easier to work in Clojure if you understand Java


As I'm finding out trying to use ClojureScript without knowing anything about modern JavaScript, it's really confusing


The concepts in object oriented programming, and more importantly imperative programming are easier to get your head around. But in my experience teaches students to write bad code. Imperative programming can be awesome and practical (as in scripting in python), but it also comes with alot of responsibility that doesn’t present itself before you start working with other people on bigger systems. Also coming from a background in both paradigms I must say that functional programming is a lot more clean and beautiful to read.


There is a reason why all the traditionally imperative languages such as java are adopting elements from functional programming, such as a more reserved approach to changing state; with mapping functions instead of using loops for example.


Learning Clojure is really like learning Calculus. It's harder to get, but an infinitely better tool for a lot of problems

😎 8

@UQ5EVP2LW I feel the same. And it is very rewarding.


When you script in Python you're not really doing OO though. You're also not really doing imperative in that generally there's barely any state involved. You mostly just list out instructions to the OS with a few conditions sprinkled in it. I'm not sure that's really apple to apple. Scripting that way in Clojure is almost similar in practice beyond parenthesis and infix notation

👍 4

@U0K064KQV that’s exactly why I like it 🙃


Also I might add that knowing something about java and what capabilities that language, and the jvm has is helpful when learning clojure.


When we introduce OOP we often uses contexts like games or simulated worlds. For this purpose we use educational ides like greenfoot ( We do that, because we do not want to start from nothing, so the students are more motivated. Do you know educational ides for clojure or a functional language? And do you think that a similar approach would be possible with clojure, for example with playclj?


Scheme has been used as the language in first programming university course in several places, using SICP as text book. This was 10-20 years ago.

Jacques Desmarais18:11:44

I’m not sure there is an answer to your question of which one is harder, But perhaps take a look at the following article by Uncle Bob: . What I got from this article is that functional and OO are actually both valid paradigms, but which one to choose when solving a particular sub-domain of whatever code you are working on depends a lot on how you foresee future changes happening to your code. So really they are both worth learning.


Clojure it's simpler and easier to get than OO. ..... that said if your mind is already been "corrupted" it may not feel simpler and easier to get, at the start :D

👍 12

We have to be more specific too about what OO we're talking about. OO without inheritance, without encapsulation, without polymorphism, without information hiding, without classes and their hierarchies, etc. is quite simple. In Clojure it would be just as simple, write a map constructor (maybe use a record for it even) and put functions in a namespace alongside which takes the map/record as first argument and return it modified.


Learning just that is easy, but learning OO fully and getting to understand all those things I listed are pretty hard.


I'd say the hardest part of Clojure and other Lisps is probably that it has no guard Rails, no guiding design. You're forced to really understand paradigms to be able to choose what to use to model your particular problem. In a weird way, I think OOP forces you more down a path, this is how you do everything. Not so much in Clojure. But again, I think that's also a teaching issue. Someone could teach Clojure in a particularly easy way and wait a much longer time before introducing alternatives.


I totally agree with you. In schools most of the time a pseudo object-oriented style is taught. Object and Classes are used but there is no emphasis on the fundamental object-oriented concepts like encapsulation. So objects-oriented programming is taught in a simple very reduced way (most of the time focusing on attributes, methods and inheritance). What are the steps to teach clojure in a easy way, which you have proposed?


@U3U3XL72S my mind is "corrupted". But I my opinion my mind would also be " corrupted" if I had only learned functional programming. I think that the knowledge about various paradigms really helps you to think about problems and to write programs in a nice and elegant way.

👍 4

Hum... to be honest, I haven't really thought about it. I'm assuming there might be a way to do so .


Using Clojure first as a scripting language probably would help. No namespaces at all. Just code in a .clj file executed from top to bottom. No main method either. And running it with clj file.clj


Using calls to require and import, but not ns


And keeping it simple like, using only maps, vectors and def/defn.


Maybe looping only with loop/recur. And simple use of for comprehension, and doseq, dotimes.


As well as cond, case, if, when


From that, show how to deal with command line IO. And teach basic logic, or, and, truthy/falsy, and I guess that's it.


That would probably be good enough for most school style exercises.

Filipe Silva22:11:00

In the university I went to in Portugal, I started learning first with Scheme, then C. Java and OO only came up in the second year.


I just gave a talk that I think answers your question. Clojure/FP may be unfamiliar, but that is subjective. It is certainly reasonable that you can build simpler systems in Clojure than in traditional OO.


There was a study showing that functional programming is what beginners naturally expect.


@U09LZR36F do you have a reference?


I don't, and a quick Google just overwhelmed me with people selling courses


@U0JUR9FPH thanks for the hint. I am watching it at the moment.


@UQR0LSUQ0 @U09LZR36F functional programming is closer to classic mathematics, so it sounds plausible


I think FP suffers from a problem though. It's incomplete. Like the paradigm doesn't offer solutions to managing long lived state and IO. So it's thought from a smaller perspective. Teaching composition, recursion, map, reduce, filter, and other such constructs.


In that sense, it resembles more an algorithm class.


Where people start getting familiar with loops, logic, data structures etc.


OO on the other hand begins with an answer for managing long lived state and IO


So I wonder if in Clojure it would be helpful similarly to start teaching about medium size system design and how to deal with state and IO from the get go.


You're assuming people know they have that problem

✔️ 4

One can remember without state. SICP goes very far without state, its amazing.

👍 4

As a designer-that-codes data point; Clojure was easier for me than the other languages I’ve made contact with since (like Rust). Learn the (verb noun noun …) pattern. Learn that it can be nested. Learn how to make a function. Make a function call another function. Setting up a project was probably the biggest PITA when I started. Things are different now.


Those were the very, very basic considerations when I started learning it (around a decade ago now). From my current vantage point, I can appreciate much of the rest, at least “cognitively”, as extensions, with higher-order functions probably being the next logical step (though I don’t remember for sure). I don’t think more guard rails or stricter syntax would have helped much in grokking the fundamental nature of what I was doing.


There has been studies made (in the 60s, 70s) about expertise, across all kinds of fields and crafts. There are not many common denominators between them, but one that actually exists is that as a person get better at something, they spend more time designing and less time doing as compared to novices.


Initially, the concerns are “apply hammer to nail.” Eventually, this transforms into “apply the right tool to the correct target”, and then “map a sequence of tool applications such that the end result is a house that passes building standards”.


Different constructs in programming appear to me to be targeted at different layers of the problem hierarchy. OO is decidedly in a more “high-level” solution bracket, and I don’t really see the point of applying it everywhere throughout, as if it were a universal panacea, when in fact it’s a very specialized tool good at very certain things. The design decisions that went into Clojure appear to me to be largely about breaking down composite (complex) tools into composable elements. I’d argue that this is a good thing for experts, who can know when and how to combine them into something specialized, but also that it’s good for beginners, who as a result are less likely to end up conditioned to complex notions that are useful, but not universally useful.

👍 4

Right, but again, OO is vast. And it depends what we're talking about. In Clojure, you can encapsulate things in namespaces or in closures. You can hide information by making it private or local.


I think the more interesting part of OOP is abstraction. A thing and what it can do. And this can be done with protocols and records. In fact, it's better then most other OO languages, because what can be done on records for example can be extended or customized based on what you require. And combined with multi-methods, you can have hierarchies even and multiple dispatch and all that.


But even all that is often overkill


For having just a map with a name, and some functions that have names and doc-string to make you know they can operate over that map is often good enough.


I think few people go back and learn why you'd want OOPs featureset. Why do you want to encapsulate methods and their fields? Why do you want to hide information? Why do you want to derive a class? Why do you want to have methods of the same name do different things based on their arguments? Etc


If you did, you could realize that either Clojure has a different solution to the same problem, or that problem just doesn't even exist to begin with.


For example, keeping methods and fields together. Why? I'm not sure either to be honest. All I can think is it's nice to be able to know what operations are availaible for some given data. So by putting those together, it's very clear and obvious. Instead of wondering: ? Can I add this data? And that one? Etc.


What do we do in Clojure for this? I think namespaces can help. You might have a user namespace with the functions that work over your user map. Maybe you even have a user map constructing function. And records are the natural formalism of this pattern.


What about information hiding? Seems like that's because the fields are mutable. Can't let anyone mess around with them. But when everything is immutable do we have this problem? Not really. We can hide things just so it's more clear what the logical external interface is and so that internal details don't show up on auto-complete. But you don't need to absolutely prevent people from peeking in, since things are immutable.


And if you had mutable internals, well deftype let's you hide them. In fact I think it prevents you from exposing them at all. And closures can hide information as well which is completely opaque.


I know there's (bean x) but is there not a version that would allow me to pick only selected bean properties to the map? i.e. something like (bean x prop-names)


(select-keys (bean x) [:field1 :field2]) something like this? (untested)


@U1G5P6G0L yeah, that would work for simple cases


actually, I ended up rolling my own based on The java objects I'm working are not even proper beans (so far...) so needed the flexibility