Fork me on GitHub
#clojuredesign-podcast
<
2019-12-14
>
sebastian10:12:48

I've discovered your podcast a couple of weeks ago, listened through the entire back-catalogue and felt compelled to leave some positive feedback for you guys. The podcast is a great and fun ressource for me as a beginner to get an understanding of the fundamental differences when programming in a functional language. You are doing a great job with making fundamental concepts tangible. So thank you for that.

pez10:12:31

^ What he said ^

sebastian10:12:46

An interesting subject for me right now would be a comparison of the popular webstacks, what are the main differences between them and for which kind of web applications are they most suitable for. So, what would be best used for • bigger CRUD applications without very much dynamism • dynamic frontends with a REST/GraphQL backend • and what to use for security (perhaps users with roles, voting...) and authentication It is a deep and wide topic, I know, but perhaps you can speak from experience on what works well together. What are your thoughts on "frameworks" like Luminus which collect libraries and do some amount of scaffolding to plug these libraries together. Is it easy to exchange libraries in such a setup?

8
mmeix13:12:38

Congratulation and thanks for Episode 059 “Lining it up” - to fully understand the intent and motivation of Seqs is very useful!

👍 4
mmeix19:12:59

Lot of REPLing with seqs now (and just found rebel-readline by bhaumann 👍)

neumann19:12:54

Oh yes! rebel-readline is fantastic!

mmeix20:12:46

subtle differences in here:

mmeix20:12:40

user=> (*type* '(1 2 3)) `clojure.lang.PersistentList` user=> (*type* (*seq* '(1 2 3))) `clojure.lang.PersistentList` user=> (*type* [1 2 3]) `clojure.lang.PersistentVector` user=> (*type* (*seq* [1 2 3])) `clojure.lang.PersistentVector$ChunkedSeq` user=> (*type* #{1 2 3}) `clojure.lang.PersistentHashSet` user=> (*type* (*seq* #{1 2 3})) `clojure.lang.APersistentMap$KeySeq` user=> (*type* {*:x* 12 *:y* 34}) `clojure.lang.PersistentArrayMap` user=> (*type* (*seq* {*:x* 12 *:y* 34})) `clojure.lang.PersistentArrayMap$Seq` user=> (*type* *"123"*) `java.lang.String` user=> (*type* (*seq* *"123"*)) `clojure.lang.StringSeq`

mmeix20:12:34

have to think it over tomorrow (afterthoughts for Ep 059)

neumann20:12:02

Oh! That's really interesting. Yes. Little differences. The ISeq is the parent interface of almost all of those, but it's interesting to see the cases where a Clojure function gives you something more specific (like clojure.lang.PersistentVector$ChunkedSeq.)

neumann20:12:16

@nate Check this out. Interesting!

mmeix20:12:01

(the capital “I” in ISeq is for Interface? is this JAVA-speak?)

mmeix20:12:24

(no experience with JAVA here…)

neumann20:12:25

Yes. It's a convention, but it is not mandatory.

neumann20:12:35

I = "Interface"

mmeix21:12:11

and “A” as in clojure.lang.APersistentMap$KeySeq ?

neumann21:12:51

"A" typically means "Abstract".

mmeix21:12:17

(thanks!)

neumann21:12:35

The declaration:

public abstract class APersistentMap

neumann21:12:59

So yes, it does mean "abstract" in this case.

neumann21:12:05

(I wasn't 100% sure myself!)

neumann18:12:36

@sebastian I'm happy to hear you're enjoying the podcast. Thanks so much for the feedback!

neumann18:12:49

@pez Thanks also!

neumann18:12:18

Web apps are a great topic. @nate and I work with them all the time. If we're not working on a data streaming system (with websockets, core.async, and Kafka), we're working on a web application.

neumann18:12:07

It is a deep and wide topic. I'm putting it on our list. I'm going to think about how to approach it.

neumann18:12:38

One thing comes to mind. The way ring handles requests is really interesting and idiomatic of functional programming too. There might be a nice way into the topic via that.

✔️ 4
lodin03:12:56

I think this makes for an excellent long-form exploration of how to end up with that design, just like how you in the early episodes started with a problem and evolved designs and then explained, in context, how the "functional" design is different/better.

neumann18:12:03

We could also do an overview episode where we talk about different libraries we've used and what we think of them.

neumann18:12:37

I find Luminus really interesting. I like how the authors didn't try to reinvent all the parts, but instead they found good parts and put them together.

neumann18:12:04

I personally haven't used it yet because it was created after I had already figured out how to put the necessary parts together myself.

sebastian20:12:32

and that is exactly the problem beginners like me face when coming to clojure. I'm a reasonably experienced web dev, so I know which general parts go into that kind of app but finding well established libraries that also work well together is another story 🙂

neumann20:12:39

Yeah. I can see the difficulty with it. It really is a problem. @nate and I should definitely cover this more.

neumann18:12:26

But I have used a number of the same parts that Luminus uses.

neumann18:12:06

Even talking through the "layers": what they are and how they work could be helpful.

sebastian20:12:28

both the ring and layers approach seem like a good way structuring this wide area. I'm exited about with what you come up 🙂

neumann20:12:32

@sebastian Thanks! It might sound a little strange, but I'm excited to see what we come up with too! We will start on a topic and we almost always end up having some of our own surprises as we explore it!

sebastian21:12:17

like your functional rom com

neumann18:12:14

Thanks for the topic suggestion!

mmeix20:12:51

Another minor subject: “What are real usage cases for meta?”

nate20:12:50

Ooh, that's a good one.

mmeix20:12:30

(are there any? … will wait for Ep “Meta! Meta! Meta!” 😋)

nate20:12:43

There have been many times I've come close to using meta, but I usually just merge things in to the main map or envelope.

neumann20:12:46

@mmeix I agree with Nate, that's a good topic.

neumann20:12:09

Meta baffled me at first, but I've seen some good uses.

mmeix20:12:51

I stumbled over this by trying (class …) and (type …) while reading (doc type) and (doc class)