clojurescript

2025-09-11T22:15:10.746269Z

Hello everyone πŸ‘‹πŸΌ I'm looking for some foresight: If I were to avoid using keywords altogether in cljs (using strings and other data types instead). What will/could be the consequences of such a decision?

gaverhae 2025-09-15T09:29:20.189999Z

I'll just reiterate my point one last time, as it seems to have been lost in the noise. Programs should be written for people to understand, more than for machines to execute (though that's a nice property too). From a language design perspective, it is clear that it is useful for a language to allow for the definition of internal tokens that can be used in program logic; in nominally-typed languages these are generally called "enums"; sometimes people use strings for these, sometimes people use integers. Keywords are Clojure's answer to that specific need. The rest (hierarchies, IFn implementation, etc.) is sugar on top. In the absence of keywords, when you see "key", you don't know if that's meant for the user or for other parts of the program. When you see :key in Clojure, you know it's a program token and not a user-visible string.

πŸ‘ 1
2025-09-15T16:51:39.423979Z

@gaverhae Ya, that's my #3, they're not confused with strings.

p-himik 2025-09-11T22:19:47.137509Z

Shouldn't be any, except for self-inflicted PITA due to get and quote galore.

p-himik 2025-09-11T22:28:18.627859Z

Just in case - this is exactly what https://github.com/squint-cljs/squint does in the background. All keywords are actually strings there.

cormacc 2025-09-11T23:22:55.402309Z

Why would you want to impose that restriction on yourself? Ideological reasons? Performance? Something related to JS interop?

2025-09-12T05:07:59.059089Z

Js interop. clj->js & js->clj is lossy in that regard. It's lossy in more semantically important regards (like compound values as keys) but still I'm trying to assess if I could ease this pain in any way...

πŸ‘ 2
Roman Liutikov 2025-09-12T05:13:34.264789Z

You can add a custom transformer function for keywords to clj-js

2025-09-12T05:21:31.592679Z

I'm considering going down that road as well with something like this: https://github.com/wilkerlucio/edn-json I'm just having my doubts specifically about keywords entirely as a semantic construct so I was seeking some foresights here.

2025-09-14T12:06:33.039489Z

Well, I can't say I've reached a strong conclusion on the matter but it definitely deepen my thinking on the subject. Thank you everyone for all your time, hope it was helpful for other people as well πŸ™β˜ΊοΈ P.S If anyone is interested in language design feel free to pm and chat for fun :)

daveliepmann 2025-09-12T07:50:55.979879Z

Might it help to voice those doubts?

p-himik 2025-09-12T08:07:07.377799Z

If it's just about JSON data and not the whole project, then using string keys is actually a rather common advice.

2025-09-12T08:30:28.136009Z

Oh ok, here we go: Well so far as I'm aware, keywords are a meta/semantic construct - i.e just denoting "I'm an accessor". Most of the functional semantics stem from the "word" part of keywords - you convey the meaning of that key's value using words (in :user the word "user" let us expect the value would be some representation of user). Expressing words in programming can be (and mostly is done) by using strings. So the first claim/observation: Keyword is a word (string) that we crowned - this string shall be used to access some kv data structure. This also privileged it with one more functional ability: it's a function that can be used to access data structures (I'll refer to this point later). 2nd observation: In Clojure we can use any (hashable) value as a key which gives us a lot of options (as opposed to json which supports only strings). Why is that important? Because now when you have an "access logic" you shouldn't (IMO) count on that keyword convenient functionality of using it as the accessor (like so: (k m) where k is some key and m is a map) it will break the moment your keys will stop being keywords. For me that is enough to abandon the keyword functionality altogether in the name of uniformity and standards (I came to this conclusion after encountering these kinds of bugs quite a few times). So in conclusion: we have keywords with "shouldn't-usable" functionality that adds one more primitive and choice for the language base... If the key annotation is for the human developers I give it up (we're doing fine without keyboolean of keynumber or keywhatevervalue). The only advantage I can see at this point is that the key "annotation" of the string could be for compiler optimizations, which I do not dismiss but that makes this construct more of a performance "quirk" imposed on the developer in the absence of a better performance solution. So those were my doubts πŸ˜… I'd love to hear "language-design" perspective advantages of keywords I'm missing, quite a few languages I appreciate chose to include them, I just haven't comprehend their value myself yet...

p-himik 2025-09-12T08:42:23.964109Z

it will break the moment your keys will stop being keywordsIt makes it sound as if it's a sudden change that comes out of nowhere. :) But it's always a deliberate process that would require changing accessing code anyway, even if you weren't using keywords in the calling position. That is, unless you pass your keys around all the time. So if that switch from keyword to non-keyword keys happens, just change the affected locations as well. In my experience, keys are keywords outside of JSON in about 99% of all cases. So the uniformity here is actually on the side of keywords, and the rest are just exceptions that must be dealt with accordingly. > If the key annotation is for the human developers I give it up (we're doing fine without keyboolean of keynumber or keywhatevervalue). We're doing fine precisely because keywords deal with 99% of all cases. You don't need "keyboolean" because booleans are almost never keys in associative collections. The vast majority of time, it's some word or a few words, similar to field names in classes. Apart from that, they're relied upon by other libraries. E.g. if you use spec, you will use keywords. If you rely on multimethods a lot, you will probably use keywords because they support hierarchies. Their namespacing is very convenient with the support of ::... and ::alias/... - can't have that with strings at all, you'd have to invent some naming scheme with sentinel values or some other encoding. > The only advantage I can see at this point is that the key "annotation" of the string could be for compiler optimizations In CLJS it's less relevant. A statically constructed keyword will be just some constant somewhere and a dynamically constructed keyword will remain as such; same for strings. But it is relevant in CLJ because even dynamically constructed keywords will still use the same object as an already existing keyword with the same FQN, if it exists. So you can do (keyword "foo") a million times and it will not change the memory at all, it will all be the same object.

schadocalex 2025-09-12T08:52:10.429539Z

I also have interop to manage in my project and have both keywords and strings. Delimitation is quite natural and I think a general rule is static vs dynamic for me. I would never use a dynamic variable if it's a keyword as a caller. I'd use get instead. I think it's also related but I don't use keywords as map values most of the time, only (static) keys.

daveliepmann 2025-09-12T09:22:38.022659Z

> I came to this conclusion after encountering these kinds of bugs ["it will break the moment your keys will stop being keywords" -ed] quite a few times Seems like that's the actual problem. Why is the system (or "are the systems"?) designed such that bad data (non-keywords) keeps worming its way into the map-access position?

Roman Liutikov 2025-09-12T09:25:35.445279Z

I personally don’t remember when we had troubles with keywords in app code being an issue when the main exchange format is JSON. You’ll surely loose some of their features but things are fine as long as you use keywords as strings basically. The benefits of keywords still remain, for example project wide autocompletion

2025-09-12T09:29:04.221109Z

@p-himik > that would require changing accessing code anyway, even if you weren't using keywords in the calling position > Not sure I understand why. (get m k) Can handle any key. If upstream I changed keywords to strings this code doesn't need to know that, (k m) <- this one does... > In my experience, keys are keywords outside of JSON in about 99% of all cases. So the uniformity here is actually on the side of keywords, and the rest are just exceptions that must be dealt with accordingly. > Note that when I used the word "uniformity" I was referring to unifomally/standardly unuse the keyword access functionality so that there won't be code that assumes keyword and code that doesn't. (I.e always use get or some other generic access function for the same reason I shown in the example above). As for keywords as a uniform convention: If you meant inside clojure, I don't doubt that, I only doubt if there are good enough reasons for its existence in the first place (note that ubiquitous usage doesn't prove the need for the thing IMO). If you're talking about languages at large, then I'm not sure... Most popular languages that come to mind don't have keywords. But again, I don't consider popularity as any sort of argument in my analysis (maybe only as a hint that I might be missing something). > We're doing fine precisely because keywords deal with 99% of all cases. > Do you believe we wouldn't do fine with string instead of keywords? If so can you explain what would be the consequences that will cause us to not do fine? Again, the claim (which I agree with) that keywords cover 99% of cases aren't proving that they're necessary. If the reason they cover 99% of cases is the "word" part that could be covered by string it only means that strings would take over that 99%, it doesn't mean they'll do bad at it. The rest of the paragraph talks about the existing state of the ecosystem. It's not in itself an argument for necessity, the question is: would string be able to handle all the roles keywords fill? Would we be able to make strings hierarchies? Would we be able to implement namespaces functionality on top of strings? And if not, what exactly would we lose? I don't see a reason why not... Again for me, the main value conveyed by keywords is the "word" part, which I think can be conveyed equally well using strings. As for the performance part. Yeah, I knew that in cljs it doesn't have a significant role. I was asked for my doubts and in my reasoning I look at keywords in general, not just in the context of cljs. That's why I still expressed the performance point.

daveliepmann 2025-09-12T09:29:54.663889Z

(I quibble somewhat with defining keywords as "just denoting 'I'm an accessor'" β€” that's a major use case but I think their defining characteristic is that they're symbols with fast equality checks (because they're interned). Being an accessor falls out of that.)

schadocalex 2025-09-12T09:38:49.222949Z

@lidorcg why do you use Clojure? can't you do your project in plain JavaScript? Same thing with keywords. They are not mandatory but are different than strings. :: syntax, easier to find in a project (also related to autocompletion), readability, maybe performance. They're not meant to be used by users but developers.

2025-09-12T09:39:28.716309Z

@daveliepmann you seem to refer to properties (fast equality check) that I address in my "performance" point. So the question is: if you could get the same fast equality properties using strings would that be sufficient to make them redundant?

p-himik 2025-09-12T09:40:03.601979Z

> Not sure I understand why. The "unless" part was important. :) If you pass k around, then yeah, using get will just work. If you hard-code k it in places where it makes sense, then you'd have to go and change those places to the new keys. Hard-coding also includes things like :keys. There's also :strs of course, but nothing of the sort for compound keys. And yes, I'm talking specifically about Clojure of course. But keywords aren't too different from fields in some regards. Imagine if you had some area in a Python program where you can access a particular field of a particular object only with a run-time-only string. That would technically make the program non-uniform, because every single place doesn't use that approach and relies on the good old dot access. Changing the whole program to use getattr just because of that singular non-uniformity would not be a reasonable way to go. > Do you believe we wouldn't do fine with string instead of keywords? If so can you explain what would be the consequences that will cause us to not do fine? I like using (:x m), that fits my brain nicely, I use it a lot. I do not like (get ...) where it can be avoided. Apart from that, I have already mentioned keyword namespaces with nice syntax affordances, spec, multimethods with keyword hierarchies support. Roman has mentioned autocompletion, and I'd also add a more general IDE awareness here. E.g. in Cursive I can navigate to (rf/reg-sub ::x) from where ::x was used with just a single click - I don't need to use a full-text search and I would have to with plain strings. > would string be able to handle all the roles keywords fill? Strings don't have inherent structure. Keywords do. So the answer is no. You'd have to invent some schema on top of strings, and from some perspective that's exactly what keywords do. > Again for me, the main value conveyed by keywords is the "word" part, which I think can be conveyed equally well using strings. From that perspective, every single thing can be "word". After all, we parse tokens all day long. Even numbers are strings of characters, just of a specific kind. But that perspective is not helpful, it doesn't add structure, it only muddles things.

2025-09-12T09:44:49.664369Z

@schad.alexis I can point out many many difference points in value between JavaScript and Clojure. They are very different in some very fundamental ways (not to say that Clojure is dominantly better at every point in my opinion, but at the sum it prevails). I don't think you think JavaScript and Clojure are really the same and I must point out the difference. I pointed out the similarities and analyzed the pitfalls of the difference between keywords and strings in detail. I think it will be more beneficial to address my concrete points than doing an analogy to other different things (very rough analogy) and dismiss it as the same.

p-himik 2025-09-12T09:47:23.572859Z

Just run a thought experiment. Take each feature of keywords that distinguishes them from strings and imagine how that feature could be implemented on top of strings. Could strings be interned for performance? Only short ones, and that's already happening. But for long ones - no chance. Could strings be callable? Yes, why not. Could strings support hierarchies? Yes, but not in the same way that keywords do. Could strings be used as keys in spec? Yes, but also in a very, very limited way. Could your IDE be made aware of strings and let you navigate around strings? Probably, but I bet it would become much less performant in projects with a lot of text data. Could you get used to it? Probably, but I personally would prefer not to. I have different color schemes for keywords and strings. If everything were the same color I'd go real crazy real fast.

schadocalex 2025-09-12T09:47:38.383449Z

Sorry it was just a way to tell the argument, not to discuss about another subject. Same argument as p-himik with "words are words". I did add some arguments after. Keywords are for the developer.

daveliepmann 2025-09-12T09:49:44.362619Z

> if you could get the same fast equality properties using strings would that be sufficient to make them redundant? Yes, it's possible to program without keywords. My point isn't about properties, though. It's that they're an identifier, which is semantically distinct from a string. I find this helpful. Strings could play the role of identifiers in your system, but that would be alongside their other roles and involves manually distinguishing identifier-strings from non-identifier strings.

gaverhae 2025-09-12T09:57:42.828149Z

> Well so far as I'm aware, keywords are a meta/semantic construct - i.e just denoting "I'm an accessor". I would strongly dispute that. Code is (should be) written primarily for humans to read, and only secondarily for machines to execute. Keywords denote different semantics from strings; a string is a piece of text meant for printing, whereas a keyword is a token that is meant to be part of program logic. I personally find it very helpful to have two separate types and syntaxes for these two very different concepts. Can you overload strings to also serve as tokens for program logic? Sure. You cal also overload numbers for that (it's done a lot in older languages). Ultimately, you can program with binary, or you can program with everything-is-a-string languages (Bash, tcl), but separate types with separate syntax are useful for program clarity. Being used as accessors is a minor convenience over being essentially a generalized, nameless, dynamically-typed enum type.

βž• 1
daveliepmann 2025-09-12T10:12:44.560849Z

Returning to the original question πŸ™‚ I'd miss namespacing, IDE support, and I'd worry that using other data structures (e.g. tuples) to replicate keyword functionality would run into similar conflicts when making JSON keys. I would miss using keywords in value position, not just as accessors/keys.

2025-09-12T10:45:21.542549Z

Well, I'd address each point you raised but I'm not scalable enough for this mass discussion πŸ˜…. I think the main take away for me here: does specially annotated values for access are valuable enough? We touched some performance points but mostly dx. I will give myself a counter point: My pain stemmed mostly from the inability (or limited ability) to serialize and deserialize them to and from the js ecosystem. And so the question for myself is: Would I question the existence of keywords were they ubiquitously transferable like strings? Maybe that's the only missing piece? Because I do see value in annotating values with purpose semantics but it is a matter of balance, and in my case that annotation doesn't go very well with interoperability with other ecosystems and so I encountered a case where its usability was badly hurt, and made me question its existence.

schadocalex 2025-09-12T11:30:12.305979Z

You get a point, (de)serialization is limited and that's why in my project I keep some data with strings. It works well with static identified options / developer side string, but not alawys with user/external data. You could still use keywords for clojure side data structure tho. I think it would also be easier to discuss about it if you provide the case where it doesn't work for you.

2025-09-12T12:24:00.644039Z

Basically, I'm using keywords for access (like everyone else). I get quite a few logic data from outside of clojure (i.e json). This might include accessors as values - e.g {path: [:some :keys :to : somewhere]} And while js->clj can translate keys to keywords, keywords as values are out of the question. Anyway this problem is broader than keywords, it's the difference in expressivity between json and edn. I'm also considering moving to edn everywhere. I might be able to pull that off but it'll be costly and of course we'll assume into the future that I will not be able to carelessly interop my data with js

p-himik 2025-09-12T12:38:43.317239Z

Not related to the main discussion, but don't use js->clj with external data. There was a recent discussion with it breaking and David has risen a point that js->clj is not for external data at all.

2025-09-12T13:51:17.870439Z

What is the recommended way to json<->edn?

p-himik 2025-09-12T13:54:25.963189Z

If you have some spec/schema for that data, then there might already be some functionality for that that also coerces all the strings into the right types during conversion. At least Malli has it. For spec, there's probably a library for that.

p-himik 2025-09-12T13:56:06.011179Z

And as I mention later in that thread, you might not even need to convert JSON to EDN and use JSON directly instead. Or use something like the also mentioned there cljs-bean.

thheller 2025-09-13T06:55:53.168809Z

FWIW even JS "almost" has keywords, not quite but pretty close. They just call them Symbol and they were added much much later to the language, so their use isn't quite as common and by design not present in JSON. Other languages such as Ruby also call them Symbol. These things are pretty common and definitely more than just a "word". Your major concern seems to be the conversion to JS, which I share and often resort to using only strings for values that need to "transition" between CLJS->JS often. For example I rarely use js->clj with auto-keyword transforms, or heck even with JSON data in the backend I rarely go to keywords. I think it is totally fine to mix, even to have explicit transform functions that "translate" back and forth, since they can often serve as validators to ensure the data isn't messed up. So the main code can still use keywords just fine, but performance wise I doubt it'll make any sort of measurable differences

1
2025-09-13T17:15:48.586159Z

Since quite a few of you made the reference I'll just clarify that by "word" I mean linguistic semantic, that is to say: keywords convey most of their meaning through the language part. To reiterate my point: if each of you were faced with a choice: use keywords but in a foreign language that you don't understand or use strings in your language (of choice), you'd give up the "key" semantics in favor of the linguistic semantics (by a huge and even absolute margin I'd wager, that's a way to highlight the difference in value I was trying to make). As for another aspect I'd like to point out which will certainly help me in this discussion, notice that when making the argument in favor of the key semantics, not even a single argument had a concrete example: "Definitely more than a word" - trying to explain the importance of the key semantics but doesn't go into why, just saying "it's important". Even in the list @p-himik made of use-cases for keywords (which in my opinion is probably the pinnacle of this discussion) notice how each point says basically: "you could replace it with strings but it wouldn't be the same", not going into why and how it would be different (P.S excluding the performance part which I excluded at the beginning of this discussion). If I was concretely facing this design decision now, I couldn't wholeheartedly make it. It would help me a lot if you go into details of differences and tradeoffs. Of course you don't have to, you don't owe me anything, and I was reluctant to go into my thoughts on the matter exactly because from my experience, it's very hard to have deep design discussions on slack.

p-himik 2025-09-13T17:19:33.909079Z

if each of you were faced with a choice: use keywords but in a foreign language that you don't understand or use strings in your language (of choice), you'd give up the "key" semantics in favor of the linguistic semantics.Absolutely, 100%, not. I've learned how to program way, way before I learned English. > "you could replace it with strings but it wouldn't be the same", not going into why and how it would be different. I could go into the details, but I offered it as a thought experiment, hence why I didn't describe everything that at least I myself know or can make an educated guess on.

p-himik 2025-09-13T17:25:23.304379Z

In any case, none of that is really relevant to the OP or to #clojurescript. For a proper discussion I'd suggest making a topic in maybe #clojure (if it's specifically Clojure keywords that concern you) or #off-topic (if it's any kind of key_words/reserved words in any languages that concern you). > I was reluctant to go into my thoughts on the matter exactly because from my experience, it's very hard to have deep design discussions on slack. It's not hard if: 1. Shallow things aren't given a lot of attention 2. Questions and concerns are well formulated, in an appropriate place 3. Proper arguments and counter-arguments are properly addressed 4. Some answers are given enough thought - could even be days. I sometimes go back to some older threads where I participated and add new thoughts when they do appear and bring in more than just speculation or rehashing of what's been said Your concern is about language design. So explicitly asking resident language designers to chime in would make sense. Without tying it to optimizations, CLJS, serialization, etc.

2025-09-13T17:25:40.704489Z

> hence why I didn't describe everything that at least I myself know or can make an educated guess on. > Well, we're having a concrete discussion because I'm thinking about the subject and couldn't find something concrete. Telling me that you know and I should keep thinking about it is a brain teaser which wasn't obvious to me. Telling me that you're not sure puts you in the same position as me (perhaps more faithful) and again wasn't obvious (to me) from your phrase.

daveliepmann 2025-09-13T17:26:54.135049Z

I think digging ever deeper into the specifics of keywords-versus-strings takes us further from the actual problem as stated, which is that non-keyword values repeatedly found their way into IFn position in some code. That sounds like a failure of the translation layer, not keywords. As I wrote above, keywords > Strings as identifiers because they're distinct from other String use cases, IDEs know about keywords and provide some help tracking them, keywords (can) have namespaces, and though it doesn't necessarily come up a lot they are really fast.

p-himik 2025-09-13T17:28:34.494159Z

@lidorcg If you have some very specific questions, I will answer that. I cannot answer something like "please explain all you know". :D

2025-09-13T17:41:28.623069Z

It's ok to not go into this discussion because it's not the place or time or diverting from the original question (I was asked by someone to explain my doubts about keywords, although I'd add that I was shrinking my question in the first place, this is a way more interesting question for me that will probably cover the knowledge I need to engage with the first issue). You did choose to engage in this discussion. @p-himik I don't think I was asking you to explain all you know. We're discussing a specific topic of some size, you could say: "it's too complicated/big to explain here". You could also take a single example from the list of use-cases and demonstrate what would be lost when strings were used (without assuming the existing of keywords in other parts of the ecosystem of course). But I don't know how big of an undertaking that is because I don't know what you're going to demonstrate, if it'll cover a lot of topics and a big portion of all you know then I understand your reluctance.

2025-09-13T17:50:20.280299Z

Your concern is about language design. So explicitly asking resident language designers to chime in would make sense.> > Without tying it to optimizations, CLJS, serialization, etc. > That would be the best outcome imaginable πŸ˜„ I'll admit I'm not sure who to ask here, the only one I know for almost certain that engaged in this kind of decision is Rich, and I know (almost for certain) from another discussion that he doesn't engage with this kind of discussions. If you know someone else that would be relevant please. I'll also add that I'm somewhat familiar with you and Thomas Heller and I believe you're a lot more knowledgeable than me in the design of Clojure/Script so you were not a bad bet for me ☺️.

p-himik 2025-09-13T18:03:59.786849Z

> You could also take a single example from the list of use-cases and demonstrate what would be lost when strings were used Sure, let's take for example the smallest issue as far as I can tell: "Could strings support hierarchies? Yes, but not in the same way that keywords do." The hierarchies in Clojure currently support only namespaced keywords/symbols and, in the case of children, Java classes. Suppose we're making "Clojure--" that's the same as Clojure but without keywords and with all uses of keywords being delegated to strings. That would mean one of the following: 1. Hierarchies will be removed 2. Hierarchies will have to exclude keywords altogether and would become limited to just symbols and Java classes 3. Hierarchies will have special rules only for strings 4. Strings will have a structure imposed onto them with some part or meta-part of a string being the namespace (1) would be too much and would already answer the "why keywords" question if it were the only item here. "To have hierarchies, at least." (2) means that any kind of data processing that relies on hierarchies will not work anymore with strings. At all. So it's a definite no-go. (3) means making things more complicated for a special case. It also greatly increases the probability of clashes and accidental runtime overrides of the global hierarchy. I personally see it as a no-go. (4) unfurls into other questions. What kind of structure? How is it implemented? What are the repercussions? If it's a kind of meta thing to the original string then Clojure strings are no longer 1-to-1 compatible with Java strings. If it's something inside the string content itself, then there's still that 1-to-1 correspondence to Java strings in terms of the implementation, but no correspondence anymore in terms of content. What were "stuff" in Java would have to be translated into "my.ns_SUPER_SECRET_NS_SEPARATOR_stuff", which also by no means guarantees any correctness - it just greatly reduces the probability of issues. Most likely I have missed something because I'm writing this after having a beer and without thinking about it too hard - we aren't trying to make a new language here, after all. > I'll admit I'm not sure who to ask here, the only one I know for almost certain that engaged in this kind of decision is Rich, and I know (almost for certain) from another discussion that he doesn't engage with this kind of discussions. > If you know someone else that would be relevant please. Oh, I didn't mean that you should @ specific people. I meant something like starting with "I'm looking for some insight from actual language designers or anyone in some adjacent field." That would already shut me up. :D But would hopefully invite a higher data-to-noise ratio conversation, I've seen it before. That's also why I mentioned not paying too much attention to shallow things - they're always abound.

2025-09-13T18:12:49.063599Z

I've reached point 2 in your answer and I think you assume "migration away from keywords as the status is today" settings. Since the discussion moved more to the design plane my question is more abstract than that, I assume I'm designing the language and there are no keywords yet so I don't need to worry about backward compatibility stuff, I just need to make the decision if to include them or not. But arguments involving interoperability are valid, i.e if losing keywords would hurt my language's "hosted" abilities with java (or other significant languages) it is an important point. We're assuming a new language not a new universe.

p-himik 2025-09-13T18:40:16.534219Z

Maybe it's a philosophical subject, but to me both "Clojure without keywords" and "a Clojure-like language that is designed from the ground up and uses strings instead of keywords" can and probably will lead to conceptually the same implementation, with the same exact trade-offs. That is, if that language tries to stay "Clojure-like" and doesn't just move in the direction of "sacrifice anything for the ultimate goal of being able to use strings everywhere where Clojure would use keywords".

2025-09-13T18:42:32.656809Z

Update after reading your last sentence: πŸ˜‚. It seems we're not entirely in sync.

2025-09-13T18:45:58.664559Z

But your 3 and 4 points are interesting let's dive into them: Hierarchies as I understand them are https://en.wikipedia.org/wiki/Partially_ordered_set. To implement partial order you just need a directed graph and equality. No issue I see for strings. In fact I'm not sure why clojure coupled it with what is in the hierarchy (another design decision I don't understand and hint that I'm missing something). But my intuition says that keeping the hierarchy part clean would reduce complexity, and could even tap into well known properties from set theory (not sure if it's required but I think it boosts predictably which contrast with complexity). Now for the namespacing: the namespacing in keywords is parsed from the character sequence part (the string) delimited by the slash. You could go for the exact same thing with strings. The interface for namespace is pretty simple value (keyword/string in our discussion) -> namespace. You could parse it out from a string so no semantic problem here, but, we could be getting into performance territory. Your argument also assumed the requirement of namespacing for hierarchies because the current implementation in clojure assumes that. It's ok but I think it's more of a noise for this discussion, I think the sub-discussion of namespacing supercedes it.

p-himik 2025-09-13T19:03:19.075559Z

Partial order is just a happenstance, it's not a design requirement the way I see it. A is a B, C is a B, and we don't have to establish what A is in relation to C - that's it. Of course strings don't get in the way here - there's nothing of substance to get in the way of. The hierarchies are there to support multimethods. Specifically, being able to dispatch not just on the concrete value but on what something is. A is a B, so a multimethod for B would also work on A, unless there's a separate defmethod for A. Kinda similar to inheritance in Java. And strings here do get in the way for the reasons I mentioned above, one of which is -> > Now for the namespacing: the namespacing in keywords is parsed from the character sequence part (the string) delimited by the slash. That's only partially correct - that's for keyword literals, stuff that you see in code. It's not true at all for keywords as they are implemented, as objects of the class clojure.lang.Keyword. There's no parsing at that point, even / is not used anywhere except for toString (and some weird corner case I guess). > You could parse it out from a string so no semantic problem here, but, we could be getting into performance territory. That would require a semantic schema on top of a string value. You can't just add a namespace to "a" without altering the contents of the string itself. > Your argument also assumed the requirement of namespacing for hierarchies because the current implementation in clojure assumes that. No, it assumed that because without namespaces there would be a total chaos. That's what I meant by probabilities. "name" and :name are not that different. "user-name" and :user/name are also not that different, but the former already complects "what" with "where". But we can go further - :my.company.proj.user/name is an entirely different thing that's quite safe from any kinds of clashes. And yes, you could have a string like "my.company.proj.user/name" being lugged around. But you cannot tell just from the fact that it's a string that there's something unique about it - you'd have to parse it every single time you use it.

2025-09-14T01:01:57.064329Z

Keywords are meant to represent "keys", which is a computer thing. The benefits I believe historically are: 1. Interning - they all dedupe and are thus not taking more memory if they show up many times 2. They're easier to use syntax wise 3. They're not confused with strings #1 used to be pretty awesome, but nowadays most JS engines and Java engines intern strings as well, most likely because strings are used like keywords most of the time. #2 and #3 are still benefits. I'd say that's really it. In my opinion, it's not so much the keyword but the kebab-case versus camelCase naming that gets annoying.

πŸ’― 1