The most idiomatic ways I know of are the following:
1) Use (str) to split the string over multiple lines.
(str "User " (:user context)
" is now logged in.")
This is probably the most idiomatic usage. I've seen this done in multiple libraries and projects. It is fast, since (str) uses a StringBuilder under the hood. It also allows you to mix code in transparently, as I've done in the example.
2) Allow strings to break the 80 char limit by themselves, when it makes sense.
(format
"User %s is now logged in."
(:user context))
Basically, it's ok to break the 80 char limit for strings. Chances are it's less likely you care about reading the string when you work with the code, and on the off chance you need to, exceptionally, you'll need to scroll horizontally.
I've wrapped the string in a (format) here to be able to inject code similarly to my previous example. You don't need to.
Less idiomatic ways would be:
3) Put your strings in files and load them from there.
(slurp "/path/to/userLoggedIn.txt")
With a file: /path/to/userLoggedIn.txt
containing:
User logged in.
I advise against this because:
- It introduces IO side effects
- It has the potential to fail, say the path is wrong, the resource is missing or corrupted, the disk errors, etc.
- It has performance implications, disk reads are slow.
- Its hard to inject content from code if you need too.
I would say do this only if your text is really big. Or if the content of the string needs to be changed by non devs. Or if the content is obtained externally.
4) Have a namespace where you def all your strings in, and load them from there.
(ns msgs)
(defn logged-in-msg [user]
(format
"User %s is now logged in."
user))
Which you then use like this:
(msgs/logged-in-msg (:user context))
I prefer this over #3. You still need to allow to use #2 here, where it's ok to have strings break the 80 char limit. In fact, here you put strings by themselves on a line, so they are easy to format. If you use code analysis like checkstyle, you can exclude this file from the rule. It also does not suffer from the issues of #3.
If you are going with #3 or #4, you probably have a special use case for your strings, like internationalization, or having business edit them, etc. In those cases, you might be better served building a more robust solution, that could be inspired from the above methods, or using a library that specializes in those use cases.