Fork me on GitHub
James Amberger15:06:15

why…. is it called a protocol?


I am fairly new to programming still but I have been studying HL7 among the other things I have been into lately and I will try answering halfway so that I can see if I understand it and say it in a way that makes sense. Hopefully someone else can correct me if I am wrong or saying things in an imprecise way. The way I understand protocols, they are sets of standards that everyone agrees to, so that separate sources of information can send and receive that information without concern for formatting errors. HL7 is the protocol governing health information exchange, and it dictates the way that we format patient record information so that hospitals can send and receive this information to and from related, but otherwise independent facilities such as labs or other hospitals. So it basically defines the structure of XML templates in the case of what I am talking about: I believe Websocket is also a protocol in this way and it defines the structure of messages passed between one computer often for A/V uses or instant messaging but I think it has a wide array of applications. So it is called a protocol because a protocol is something that everybody is agreeing to in order to ensure a process is smooth when there could be many different ways to accomplish the same thing. It also helps for many other things because it would make it easier to test and debug as well in theory.

James Amberger15:06:33

Thanks Melody. Makes sense to me but given what you have said I wonder why the thing you get from (defprotocol) is called a protocol. I mean it’s not important; I could call it a frobnitz and get on with my day, but sometimes there’s insight lurking.


Ohhhh that is a seemingly very different protocol and I have not used that in Clojure yet. It kind of looks like an interface at first glance.


It defines a standard set of functions that more than one thing adheres too. So it's like a system of rules about what functions can be used for a set of things that implement the protocol.

Ben Sless18:06:41

Let's do the Clojure thing and crack open a dictionary I like the etymology part: Borrowed from Middle French protocolle, protocole (“document, record”), from Late Latin protocollum (“the first sheet of a volume (on which contents and errata were written)”), from Byzantine Greek πρωτόκολλον (prōtókollon, “first sheet glued onto a manuscript”), from πρῶτος (prôtos, “first”) + κόλλα (kólla, “glue”).

Ben Sless18:06:24

(computing) A set of formal rules describing how to transmit or exchange data, especially across a network

Ben Sless18:06:32

It comes first and describes how we're going to communicate


Normally a protocol is defined and you follow it. Like what's the protocol to follow when a customer finds hair in their soup. This is the same. You define the protocol, and types follow it by exposing the same functions. Interface was already taken to refer to Java interfaces, so another name was needed.

James Amberger20:06:45

> Interface was already taken to refer to Java interfaces, so another name was needed. Is this what it’s really about in the end? Seems like the word for a set of method signatures with no explicit info about what to do with them would be “interface” but as you say that was taken.


Well, it depends on your familiarity background. There are other languages that call interfaces protocol, so it's not novel for Clojure to use that name. But I'd say most popular languages nowadays that you're likely to be familiar with uses interface as the name. And yes, Clojure couldn't use that because it refers to Java's interfaces and we already have definterface which is used to create a Java interface.


For example Objective-C and Swift are both prior art where interfaces are called protocol

James Amberger20:06:07

and @UK0810AQ2, this is Zen. perhaps you used my favorite website,

Jason Bullers22:06:35

FYI I think Python also calls then protocols

Ben Sless02:07:23

@U032EFN0T33 Wiktionary is excellent for etymology, that's what I use


I am looking at this very cool resource on the clojure community page: In the middle column, under the git section, it asks: "You merged in a branch and there were no conflicts, but the app doesn't work. why might that be?" I don't know why that would be. Can someone help me understand or share a video or article going over this potential situation?

James Amberger16:06:47

The merge process doesn’t care about your code working; it’s a mechanical linewise algorithm.


Oh I was just taking for granted that the code worked to begin with but I do understand that it is completely separate processes in that regard at least. Maybe I am just overthinking it then because that makes sense. I was interpreting the question as "Your code works and after merging it does not, why did that happen?"


I suspect it assumes that someone else made changes (on the other branch), so two people have working applications -- the code works independently on both branches -- but one of you may have changed a function that the other branch's code depends on in a way that prevents the merged app from working correctly.

Jason Bullers22:06:28

Yeah, same thinking for me: the two changes don't overlap, so there's no merge conflicts, but the changes themselves are not compatible

Jason Bullers22:06:02

For example, someone added a function to a protocol in their branch, and you defined a record implementing that protocol in your branch. That would be a conflict free merge, but it's broken because your record doesn't implement the new function


ty all 🙂 Followup question: In the easy column of the same thing, it indicates that git add . is a bad habit. Am I supposed to specify the files? Or automate it somehow? Using git add . is basically the only way I have learned how to get stuff ready to push other than adding them individually.


I prefer my commits to be coherent groups of changes. If I'd made multiple groups of changes, I would want to do multiple commits, so I would add just the files belonging to one group, then commit with a good message, then add the next group of files and commit, etc. You can even stage and commit just certain changes in a single file, rather than all the changes -- but that's more about how your editor integrates with git and is def. a more advanced technique but, yeah, something I do quite often.


This is a lot easier if your editor lets you add/stage individual files or individual chunks of changes within a file, and then commit from your editor. magit in Emacs, for example. VS Code has really good git integration like that too.

Jason Bullers13:07:16

I think the advice is really just about being judicious about what you include in each commit; like Sean said, each commit should be about "one thing". But if you're making small changes between commits, that's possibly true even if you add all the files with git add . The advice is more like "don't just indiscriminately dump every change into the next commit," rather than something somehow inherently wrong about git add .


Somebody has experience trying to get a clojure dev env under Android? I have an Android tablet and sometimes when I'm out of home I use it as a laptop with a BT keyboard and mouse. I got termux, lein and emacs with cider installed, but when lein tries to start the repl I get a "Cannot run program java" "/data/data/com.termux ...... I installed openjdk package and java is in the path. Some idea?


Ok i got it, I forgot to install clojure too


Ok, I noticed lein still failing. Can create a new project but can't start a repl. And if project is created with lein, seems like cider tries to start lein repl, and it fails to do it, Here an screenshot of the error

Ben Sless13:07:31

Why is it looking for java in that path?


Because I specified with :jdk-cmd where java is just to see if something changes, and forgot to rollback again


But with and without :jdk-cmd error is the same

Ben Sless14:07:00

Can you provide the output without it?

Ben Sless10:07:41

Which version of leiningen?


lein version returns Leiningen 2.11.2 on Java 21-internal OpenJDK 64-Bit Server VM

Ben Sless12:07:23

Odd. I can see this happening if the lein script for some reason isn't picking up on your $PATH What's your: $SHELL $PATH which java


~ $ which java /data/data/com.termux/files/usr/bin/java SHELL=/data/data/com.termux/files/usr/bin/bash PATH=/data/data/com.termux/files/usr/bin:/product/bin:/apex/

Ben Sless13:07:52

Okay now I'm stumped, sorry Maybe ask in #C0AB48493?


Sure, didn't know existed this channel, thanks a lot for your time

Ben Sless13:07:55

Sorry I couldn't be more helpful


I appreciate the time spent. I must say it's the first time I find some kind of implication and support on any community. Hope I can return to you in the future 😉

James Amberger20:06:41

I have a file like (ns core (:require impl.of.mymulti)) (defmulti mymulti […]) (defn -main [& args] nil) and in other namespaces I have (defmethod mymulti […]) and I build an uberjar out of this. As long as I require the other namespaces I’m good, but it seems wrong that, were I to add another namespace with another impl of mymulti, I should have to edit the core ns at all. Am I doing it right, i.e. is the right thing just to add a require to core every time I add an ns with an impl of mymulti?


1. Put (require core) in the impl namespaces.


2. Require the other namespaces from the "main program" which needs their features.

James Amberger12:07:54

ok, so if my entry point (`-main`) is in core then I should just keep on requiring the impl namespaces in (ns core) . Thanks @U0HG4EHMH


Caution, @U032EFN0T33 -- that is a blinking-yellow-light zone because it relies on an unstated load order of namespaces. In other words, it breaks the general rule that you should be able to eval any file at any time. The general rule relies on each file to require all the namespaces it uses. If doing so leads to a circular dependency, then you may break the cycle by moving the defmulti to a new namespace or moving the defmethod's into the same namespace as the defmulti.