<p>In Go, <a href="https://go.dev/ref/spec#Exported_identifiers" rel="noreferrer">capitalized identifiers are public (exported)</a>, while lowercase identifiers are private (within the package it's defined in). Most other programming languages don't have this sort of semantic difference of public/private by capitalization.</p>
<p>Cognate <a href="https://github.com/cognate-lang/cognate#cognate-is-readable" rel="noreferrer">ignores non-capitalized tokens</a> to allow for more natural language-looking code. Most programming languages don't have this due to their case-sensitivity for identifiers.</p>
<p><strong>What are the pros and cons of semantically significant capitalization?</strong></p>

<semantics><identifiers>
Pros and cons of semantically-significant capitalization
CC BY-SA 4.0
2023-07-13T20:39:49.593Z
CON: NOT ALL COMPUTERS CAN GENERATE LOWERCASE LETTERS, WELL, NOT A PROBLEM WITH CURRENT COMPUTERS, BUT IN THE PAST THIS WAS THE CASE.
Glen Yates
CC BY-SA 4.0
2023-07-14T01:53:16.357Z
@GlenYates Aʜ, ꜰᴀɪʀ ᴘᴏɪɴᴛ. Bᴜᴛ ꜱᴜʀᴇʟʏ ᴛʜᴇʏ ᴄᴏᴜʟᴅ ꜱᴛɪʟʟ ᴅᴏ ꜱᴍᴀʟʟ ᴄᴀᴘꜱ?
leftaroundabout
CC BY-SA 4.0
2023-07-14T07:14:53.190Z
Historically, I believe the significance of a leading capital was introduced by Smalltalk in the early 70s. As @GlenYates has so strikingly reminded us, this was roughly at the point where the industry started moving from 6-bit single-case character sets to ASCII and EBCDIC.
Mark Morgan Lloyd
CC BY-SA 4.0
2023-07-14T13:04:04.927Z
One drawback is that when case is semantically significant in natural language, as occasionally it is in German and English, being forced to use a particular case for the sake of the programming language can be awkward.
LarsH
CC BY-SA 4.0
2023-07-15T06:22:23.177Z
@GlenYates Ummm... what?
CPlus
CC BY-SA 4.0
2023-07-15T19:11:39.563Z
@user16217248-OnStrike: Some older computer systems have character sets that lack case! The DEC PDP-10 is a notable example—the system used a form of case-folded ASCII called SIXBIT for symbols and filenames, so you could pack a six-character name into a single 36-bit word. Some video terminals’ bitmap character sets lacked graphics for lowercase letters, too. So cased languages like Prolog had provisions for this: in DECsystem-10 Prolog you could set a flag with `:-'NOLC'.` to let you write a statement like `p(X, Y):-q(Y).` as `P(_X, _Y):-Q(_Y).` instead.
Jon Purdy
<p>Case has long been used by convention to indicate roles of identifiers. For instance, in C it's conventional to use ALLUPPER for macros, and either snake_case or camelCase for other identifiers. In many languages, classes are conventionally named with an initial uppercase letter; this usually goes along with camelCase for the rest of the name.</p>
<p>Making this semantically significant simply formalizes these common programming styles. It's analogous to the way languages like Python make indentation significant to the parser, rather than it just being used to make the code easier for humans to read.</p>
<p>So the main &quot;pro&quot; is that programs in the language are forced to follow a consistent style, making it easier for everyone to read each other's programs.</p>
<p>This can also make it easier for programming tools to provide assistance.</p>
<p>The con, as other answers say, is that it doesn't work well when programming in (human) languages that don't have upper/lowercase similar to Latin alphabets.</p>

CC BY-SA 4.0
2023-07-12T20:15:27.023Z
2023-07-12T20:15:27.023Z
Barmar
CC BY-SA 4.0
2023-07-14T22:58:26.243Z
In C, macros are not always capitalized. For instance `bool` is a macro expanding to `_Bool`, dating back to C99.  There is often a `getc` macro in `<stdio.h>` implementations.  Lower cased macros are used for shortening nested member access in structures: `#define s6_addr in6_u.u6_addr8`. It would be bad for macros to be restricted to upper case or even a leading upper case character.
Kaz
CC BY-SA 4.0
2023-07-14T23:57:51.007Z
@Kaz `getc()` is specified as a function, but built-in functions are allowed to be implemented as macros. I think `bool` is an exception because it was originally an implementation extension keyword, and when it became a standard macro they kept the lowercase name for compatibility.
Barmar
CC BY-SA 4.0
2023-07-15T00:17:29.730Z
In ISO C there are other examples of lower case macros. The `errno` symbol from `<errno.h>` is explicitly defined a macro in ISO C which "expands to a modifiable lvalue".  The behavior is undefined if a program uses `#undef` on it to access an `errno` object.   In `<stdio.h>`, `stdin`, `stdout` and `stderr` are also defined as macros. (And have were that way in ancient Unix; something along the lines of `#define stdin __filetab[0]` or whatever.)  In `<assert.h>`, `assert` is a macro.
Kaz
CC BY-SA 4.0
2023-07-15T00:23:35.537Z
@Kaz The common denominator is that these things are used as if they're variables or functions, but they've been implemented as macros for various reasons (e.g. `errno` because of multi-threading).
Barmar
<h2>Con: Doesn't work well for identifiers in alphabets other than latin</h2>
<p>Most programing langues nowadays support unicode identifiers. This allows writing identifiers in languages other than english. However, capitalization does not exist in every language and may have other roles than in English.</p>
<p>Is מזהה public or private? You can't really tell. People writing code in such languages will be forced to prefix their identifiers with latin letters to get the desired behavior. Not an ideal situation.</p>
<p>Even in languages that have the concept of capitalization it may not be trivial to substitute a lower case word with one that starts with a upper case. For example in Greek different cases of constants have different meanings.</p>

CC BY-SA 4.0
2023-07-12T17:54:57.893Z
2023-07-12T18:45:10.033Z
2023-07-12T18:45:10.033Z
mousetail 'he-him'
CC BY-SA 4.0
2023-07-12T18:21:23.960Z
Technically, case sensitivity *would* work for Greek/Coptic, Cyrillic, Armenian, and a few other scripts.  But yeah, you can't really capitalize a Hebrew letter or Chinese ideograph.
dan04
CC BY-SA 4.0
2023-07-12T19:48:44.340Z
(for the curious, מזהה means "id")
pxeger
CC BY-SA 4.0
2023-07-13T08:14:40.530Z
I'm never convinced there's a significant portion of programs written in non-English languages. Do you have stats?
Passer By
CC BY-SA 4.0
2023-07-13T09:32:12.533Z
@PasserBy try searching for a relatively obscure problem, and many times after the first couple of pages of google results you usually start seeing chinese coding Q&A sites
Pyritie
CC BY-SA 4.0
2023-07-13T09:36:45.590Z
@Pyritie But do they _code_ in Chinese? Or are you saying the discussion is in Chinese, which of course there'd be plenty.
Passer By
CC BY-SA 4.0
2023-07-13T09:38:13.893Z
@PasserBy Yes, you will find variable and function names are often a mix between English scripts and other scripts
mousetail 'he-him'
CC BY-SA 4.0
2023-07-13T12:08:15.687Z
@PasserBy I’ve seen quite a bit of code old code using Cyrillic (remember, the USSR was isolated technologically during the early years of electronic computers), and a nontrivial amount of modern code that uses CJK unified ideographs mixed with Latin characters (this is rather common for isolated projects coming out of China). And then there’s always the cases of ALGOL 68, Citrine, Internaitional Scheme, Scratch, or FOCAL (all localized to varying degrees to numerous languages).
Austin Hemmelgarn
CC BY-SA 4.0
2023-07-13T12:38:41.350Z
@AustinHemmelgarn The part where code coming from China often contains Chinese characters is a lot more significant. I don't think anyone designing a new language should bother about what happened with the USSR.
Passer By
CC BY-SA 4.0
2023-07-15T06:23:25.350Z
Well, you could take the C approach and just disallow Unicode identifiers.
CPlus
CC BY-SA 4.0
2023-07-15T10:53:57.253Z
“For example in Greek different cases of constants have different meanings” — What does this mean, exactly? What is the difference in meaning between _αναγνωριστικό_ and _Αναγνωριστικό_?
Janus Bahs Jacquet
CC BY-SA 4.0
2023-07-15T15:03:31.873Z
@JanusBahsJacquet If you are writing Greek as someone from greece there is no difference but in mathematics you use the same symbols and the meaning is completely different
mousetail 'he-him'
CC BY-SA 4.0
2023-07-15T15:59:15.467Z
The case distinction applies to single Greek letters.  For example, in statistics, `Σ` is a sum, while `σ` is a standard deviation.
dan04
CC BY-SA 4.0
2023-07-15T16:15:08.737Z
Usually yes, you might hypothetically have a variable named something like `ζ_squared`. However, even if you use just single letter variables treating them differently seems ill advised
mousetail 'he-him'
CC BY-SA 4.0
2023-07-15T17:05:39.930Z
@PasserBy: The reason there aren't many is at least partly that languages have had very poor support for non-latin source text...
R.. GitHub STOP HELPING ICE
CC BY-SA 4.0
2023-07-15T17:06:07.583Z
@user16217248-OnStrike: C does not "disallow Unicode identifiers".
R.. GitHub STOP HELPING ICE
CC BY-SA 4.0
2023-07-15T17:12:54.927Z
@R..GitHubSTOPHELPINGICE In C, you cannot have any characters other than `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_` in identifiers.
CPlus
CC BY-SA 4.0
2023-07-15T17:21:07.810Z
@user16217248-OnStrike: 6.4.2.1 ¶1 specifically defines the syntax for identifier swith `universal-character-name` as one of the cases for `identifier-nondigit`. While only the `\u` encoding is **required** to be supported by any implementation, ¶3 allows that literal multibyte sequences may also be accepted and interpreted as corresponding to Unicode characters if the implementation chooses to do so.
R.. GitHub STOP HELPING ICE
CC BY-SA 4.0
2023-07-15T17:22:16.130Z
So, far from "disallowing Unicode identifiers", it mandates support for them in at least one form, and gives implementations the freedom (which all modern ones take) to accept them in the preferred form (literal UTF-8 text).
R.. GitHub STOP HELPING ICE
CC BY-SA 4.0
2023-07-15T17:22:42.950Z
@user16217248-OnStrike https://ato.pxeger.com/run?1=m700OT49OXnBgqWlJWm6Fhsz80oUrs-7Pu36lOtTFGwNjawh4je1QBK5iZl5GpoK1VwKQFBQBBRK01BSTVHSgWvRtOaqheiAmQgA
mousetail 'he-him'
<h2>Con: inflexibility</h2>
<p>Using Go as an example, if you have a private identifier and want to make it public, you have to effectively rename it, which means changing code at every point where the identifier is used, as opposed to just changing the declaration. And since there are only two letter cases, it prevents the language from adding another option, such as some kind of partially exported identifiers.</p>
<p>As another example, if a language uses capitalization to distinguish between types and variables, it's going to cause problems if you later want to add the ability to use types as values (“first-class types”):</p>

CC BY-SA 4.0
2023-07-13T09:37:54.547Z
2023-07-13T09:37:54.547Z
xigoi
CC BY-SA 4.0
2023-07-13T14:12:43.753Z
In my personal experience (we use a prefix for non-public members in C# which we're supposed to remove if we make it public), your first point is rarely a problem: Since a public method is part of the API, it has different requirements (regarding parameter validation etc.) than a private method. So, often, you need to change other aspects of the method as well when making it public or just "wrap" it with a new public method. If the method can really be made public as it is, the IDE makes renaming it everywhere easy, since it had limited scope so far.
Heinzi
CC BY-SA 4.0
2023-07-24T13:00:02.817Z
Javascript's `#private` fields are another example where you have to rename things to change their visibility.
kaya3
<p>Cons:</p>
<p>You move representation of a binary property into the identifier concept. Go is actually a good example of why this is a bad idea. With their decision, they are now stuck with a binary visibility concept. Most language have either nothing ore a lot more granularity than that. The Go way, you can't share definitions between an API and an implementation package.</p>
<p>For most languages, there is syntax highlighting which allows you to colorize the visibility definition and ignore it, if you don't care.</p>
<p>The highlevel point against is that such decisions are usually made at a stage where the language is still very simple and the decision looks reasonable. However, languages get more complex if they are successful. But such fundamental decisions cannot be undone in a compatible way. Adding another keyword or braces where they weren't allowed before is a mostly or completely compatible change.</p>

CC BY-SA 4.0
2023-07-13T07:13:15.180Z
2023-07-13T07:13:15.180Z
feldentm
CC BY-SA 4.0
2023-07-13T08:26:24.710Z
What do you mean by _"you can't share definitions between an API and an implementation package"_? What isn't shared? Why do you have two packages? What hypothetically solves your problem?
Passer By
CC BY-SA 4.0
2023-07-13T09:21:53.553Z
If a struct in your API has a field, that field is either public or your implementation is in the API package. Having API and implementation in the same package is uncommon in all languages and doesn't play well with code generators often used in Go. A solution is to restrict visibility to a group of packages like private[package] in Scala. Java modules also provide a solution that is more complex as they had to add it at a later point.
feldentm
CC BY-SA 4.0
2023-07-13T09:35:34.587Z
I have no experience in Go code generators, but having the API and implementation in the same package is pretty much intended isn't it?
Passer By
CC BY-SA 4.0
2023-07-13T18:13:44.857Z
"For most languages, there is syntax highlighting which allows you to colorize the visibility definition and ignore it, if you don't care." I have seen color highlights, but never what you are describing. What language and editor combo has this?
James
CC BY-SA 4.0
2023-07-13T19:46:05.003Z
@James most languages use ordinary keywords for this purpose and all IDEs I've seen in the last two decades had special colors for at least the entire keyword group. Am I missing something here?
feldentm
CC BY-SA 4.0
2023-07-13T20:49:12.593Z
I think I was misreading "ignore it" as the IDE hiding the accessibility modifier words from you.
James
<p>Con: screenreaders typically either don’t announce all-caps any differently to lowercase words, or, worse, can read them letter by letter as if they were an abbreviation.</p>
<p>Language developers shouldn’t bake in inaccessible practices into the base system.</p>

CC BY-SA 4.0
2023-07-14T06:46:32.620Z
2023-07-14T06:46:32.620Z
Robin Whittleton
CC BY-SA 4.0
2023-07-14T08:30:35.253Z
This is an issue with screen readers (which are generally not designed to read code), not the with code itself.
Trang Oul
CC BY-SA 4.0
2023-07-14T11:04:03.733Z
Well, that boils down to a philosophical code-is-for-computers can code-is-for-users. Personally I always go for the second option.
Robin Whittleton
CC BY-SA 4.0
2023-07-14T13:43:30.020Z
I somehow agree, but does _any_ screen reader read the code correctly (as e.g. "tab string my string equals quote foo quote semicolon new line")?
Trang Oul
CC BY-SA 4.0
2023-07-15T13:14:23.370Z
Anyone using a screen reader for working with code in detail is likely to need to find one that is able to distinguish between cases anyway, as most languages are case significant.   Most visually-impaired programmers I've talked to use a program called NVDA, which [seems to support this](https://nvda.groups.io/g/nvda/topic/nvda_announcing_capital/88508837?p=)
occipita
<p>Similar to occipita's answer, but for humans instead of compilers:</p>
<p>When reading code, it can be useful to immediately be able to tell whether a given identifier is public or private, without going to find its definition (using the example of Go). This will make it easier to pick out identifiers that definitely came from the current file, and which might have come from elsewhere. It might also allow you to make quicker and better decisions on whether you can safely change a function: if it's capitalised, then it's likely to be used somewhere else in the codebase, so changing it might be riskier.</p>

CC BY-SA 4.0
2023-07-12T19:55:55.657Z
2023-07-12T19:55:55.657Z
pxeger
CC BY-SA 4.0
2023-07-13T07:05:24.783Z
Because the behavior of private functions is never exposed through the public API? This is complete nonsense. It does not matter if a bug is introduced from code that can be called directly or not.
feldentm
CC BY-SA 4.0
2023-07-13T11:37:31.360Z
@feldentm Ok maybe not the behaviour necessarily, but the type signature for example. Surely you can see what I mean even if the example isn't totally applicable
pxeger
<h1>Cons: not extensible</h1>
<p>There are only two cases. It can be a hard time if, for example, we need to add <code>protected</code> support to a newer version of the language.</p>
<h1>Cons: dynamic keys</h1>
<p>For example, in JavaScript, objects are often used as maps, and class properties can be dynamic too. A static analyser cannot tell if <code>obj.x</code> is accessing a private property, or reading the value corresponding to a user input <code>x</code>.</p>
<h1>Cons: special words</h1>
<p>Some words are written in specific cases. For example, forcing <code>iOS</code> to be <code>ios</code> or <code>IOS</code> at language level can be a bit ugly.</p>

CC BY-SA 4.0
2023-07-15T17:16:52.507Z
2023-07-15T17:18:44.640Z
2023-07-15T17:18:44.640Z
tonychow1997
<p>One advantage is that you can lexically distinguish between two different classes of identifier, which could be useful if they need to be parsed differently.</p>
<p>A good example of this is Haskell, which uses capitalized identifiers to denote types, and non-capitalized for functions.  This avoids the need for its parser to determine based on the context which kind of identifier it is looking at, and results in a simpler, more efficient parser.</p>

CC BY-SA 4.0
2023-07-12T19:39:18.813Z
2023-07-12T19:39:18.813Z
occipita
CC BY-SA 4.0
2023-07-14T22:34:41.143Z
I think your remark about Haskell is wrong. In value contexts, it uses lowercase for variables and uppercase for constructors; in type contexts, it uses lowercase for type variables and uppercase for types.
xigoi
CC BY-SA 4.0
2023-07-15T12:45:02.223Z
@xigoi - probably; it's been a while since I last used Haskell, so could easily have misremembered the details.  I think my point still remains valid, though.
occipita
# Pros and cons of semantically-significant capitalization
Posted by: username_0 on 2023-07-12
In Go, [capitalized identifiers are public (exported)](https://go.dev/ref/spec#Exported_identifiers), while lowercase identifiers are private (within the package it's defined in). Most other programming languages don't have this sort of semantic difference of public/private by capitalization.

Cognate [ignores non-capitalized tokens](https://github.com/cognate-lang/cognate#cognate-is-readable) to allow for more natural language-looking code. Most programming languages don't have this due to their case-sensitivity for identifiers.

**What are the pros and cons of semantically significant capitalization?**
**Tags:** semantics identifiers
> **Comments:**
> **username_1**: CON: NOT ALL COMPUTERS CAN GENERATE LOWERCASE LETTERS, WELL, NOT A PROBLEM WITH CURRENT COMPUTERS, BUT IN THE PAST THIS WAS THE CASE.  
> **username_2**: @GlenYates Aʜ, ꜰᴀɪʀ ᴘᴏɪɴᴛ. Bᴜᴛ ꜱᴜʀᴇʟʏ ᴛʜᴇʏ ᴄᴏᴜʟᴅ ꜱᴛɪʟʟ ᴅᴏ ꜱᴍᴀʟʟ ᴄᴀᴘꜱ?  
> **username_3**: Historically, I believe the significance of a leading capital was introduced by Smalltalk in the early 70s. As @GlenYates has so strikingly reminded us, this was roughly at the point where the industry started moving from 6-bit single-case character sets to ASCII and EBCDIC.  
> **username_4**: One drawback is that when case is semantically significant in natural language, as occasionally it is in German and English, being forced to use a particular case for the sake of the programming language can be awkward.  
> **username_5**: @GlenYates Ummm... what?  
> **username_6**: @user16217248-OnStrike: Some older computer systems have character sets that lack case! The DEC PDP-10 is a notable example—the system used a form of case-folded ASCII called SIXBIT for symbols and filenames, so you could pack a six-character name into a single 36-bit word. Some video terminals’ bitmap character sets lacked graphics for lowercase letters, too. So cased languages like Prolog had provisions for this: in DECsystem-10 Prolog you could set a flag with `:-'NOLC'.` to let you write a statement like `p(X, Y):-q(Y).` as `P(_X, _Y):-Q(_Y).` instead.  
---
## 8 answers
### Answer by username_9 on 2023-07-12. Score: 39
## Con: Doesn't work well for identifiers in alphabets other than latin

Most programing langues nowadays support unicode identifiers. This allows writing identifiers in languages other than english. However, capitalization does not exist in every language and may have other roles than in English.

Is מזהה public or private? You can't really tell. People writing code in such languages will be forced to prefix their identifiers with latin letters to get the desired behavior. Not an ideal situation.

Even in languages that have the concept of capitalization it may not be trivial to substitute a lower case word with one that starts with a upper case. For example in Greek different cases of constants have different meanings.
> **Comments:**
> **username_10** (2023-07-12): Technically, case sensitivity *would* work for Greek/Coptic, Cyrillic, Armenian, and a few other scripts.  But yeah, you can't really capitalize a Hebrew letter or Chinese ideograph.  
> **username_11** (2023-07-12): (for the curious, מזהה means "id")  
> **username_12** (2023-07-13): I'm never convinced there's a significant portion of programs written in non-English languages. Do you have stats?  
> **username_13** (2023-07-13): @PasserBy try searching for a relatively obscure problem, and many times after the first couple of pages of google results you usually start seeing chinese coding Q&A sites  
> **username_12** (2023-07-13): @Pyritie But do they _code_ in Chinese? Or are you saying the discussion is in Chinese, which of course there'd be plenty.  
> **username_9** (2023-07-13): @PasserBy Yes, you will find variable and function names are often a mix between English scripts and other scripts  
> **username_14** (2023-07-13): @PasserBy I’ve seen quite a bit of code old code using Cyrillic (remember, the USSR was isolated technologically during the early years of electronic computers), and a nontrivial amount of modern code that uses CJK unified ideographs mixed with Latin characters (this is rather common for isolated projects coming out of China). And then there’s always the cases of ALGOL 68, Citrine, Internaitional Scheme, Scratch, or FOCAL (all localized to varying degrees to numerous languages).  
> **username_12** (2023-07-13): @AustinHemmelgarn The part where code coming from China often contains Chinese characters is a lot more significant. I don't think anyone designing a new language should bother about what happened with the USSR.  
> **username_5** (2023-07-15): Well, you could take the C approach and just disallow Unicode identifiers.  
> **username_15** (2023-07-15): “For example in Greek different cases of constants have different meanings” — What does this mean, exactly? What is the difference in meaning between _αναγνωριστικό_ and _Αναγνωριστικό_?  
> **username_9** (2023-07-15): @JanusBahsJacquet If you are writing Greek as someone from greece there is no difference but in mathematics you use the same symbols and the meaning is completely different  
> **username_10** (2023-07-15): The case distinction applies to single Greek letters.  For example, in statistics, `Σ` is a sum, while `σ` is a standard deviation.  
> **username_9** (2023-07-15): Usually yes, you might hypothetically have a variable named something like `ζ_squared`. However, even if you use just single letter variables treating them differently seems ill advised  
> **username_16** (2023-07-15): @PasserBy: The reason there aren't many is at least partly that languages have had very poor support for non-latin source text...  
> **username_16** (2023-07-15): @user16217248-OnStrike: C does not "disallow Unicode identifiers".  
> **username_5** (2023-07-15): @R..GitHubSTOPHELPINGICE In C, you cannot have any characters other than `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_` in identifiers.  
> **username_16** (2023-07-15): @user16217248-OnStrike: 6.4.2.1 ¶1 specifically defines the syntax for identifier swith `universal-character-name` as one of the cases for `identifier-nondigit`. While only the `\u` encoding is **required** to be supported by any implementation, ¶3 allows that literal multibyte sequences may also be accepted and interpreted as corresponding to Unicode characters if the implementation chooses to do so.  
> **username_16** (2023-07-15): So, far from "disallowing Unicode identifiers", it mandates support for them in at least one form, and gives implementations the freedom (which all modern ones take) to accept them in the preferred form (literal UTF-8 text).  
> **username_9** (2023-07-15): @user16217248-OnStrike https://ato.pxeger.com/run?1=m700OT49OXnBgqWlJWm6Fhsz80oUrs-7Pu36lOtTFGwNjawh4je1QBK5iZl5GpoK1VwKQFBQBBRK01BSTVHSgWvRtOaqheiAmQgA  
---
### Answer by username_17 on 2023-07-13. Score: 27
## Con: inflexibility

Using Go as an example, if you have a private identifier and want to make it public, you have to effectively rename it, which means changing code at every point where the identifier is used, as opposed to just changing the declaration. And since there are only two letter cases, it prevents the language from adding another option, such as some kind of partially exported identifiers.

As another example, if a language uses capitalization to distinguish between types and variables, it's going to cause problems if you later want to add the ability to use types as values (“first-class types”):
> **Comments:**
> **username_18** (2023-07-13): In my personal experience (we use a prefix for non-public members in C# which we're supposed to remove if we make it public), your first point is rarely a problem: Since a public method is part of the API, it has different requirements (regarding parameter validation etc.) than a private method. So, often, you need to change other aspects of the method as well when making it public or just "wrap" it with a new public method. If the method can really be made public as it is, the IDE makes renaming it everywhere easy, since it had limited scope so far.  
> **username_19** (2023-07-24): Javascript's `#private` fields are another example where you have to rename things to change their visibility.  
---
### Answer by username_20 on 2023-07-13. Score: 18
Cons:

You move representation of a binary property into the identifier concept. Go is actually a good example of why this is a bad idea. With their decision, they are now stuck with a binary visibility concept. Most language have either nothing ore a lot more granularity than that. The Go way, you can't share definitions between an API and an implementation package.

For most languages, there is syntax highlighting which allows you to colorize the visibility definition and ignore it, if you don't care.

The highlevel point against is that such decisions are usually made at a stage where the language is still very simple and the decision looks reasonable. However, languages get more complex if they are successful. But such fundamental decisions cannot be undone in a compatible way. Adding another keyword or braces where they weren't allowed before is a mostly or completely compatible change.
> **Comments:**
> **username_12** (2023-07-13): What do you mean by _"you can't share definitions between an API and an implementation package"_? What isn't shared? Why do you have two packages? What hypothetically solves your problem?  
> **username_20** (2023-07-13): If a struct in your API has a field, that field is either public or your implementation is in the API package. Having API and implementation in the same package is uncommon in all languages and doesn't play well with code generators often used in Go. A solution is to restrict visibility to a group of packages like private[package] in Scala. Java modules also provide a solution that is more complex as they had to add it at a later point.  
> **username_12** (2023-07-13): I have no experience in Go code generators, but having the API and implementation in the same package is pretty much intended isn't it?  
> **username_21** (2023-07-13): "For most languages, there is syntax highlighting which allows you to colorize the visibility definition and ignore it, if you don't care." I have seen color highlights, but never what you are describing. What language and editor combo has this?  
> **username_20** (2023-07-13): @James most languages use ordinary keywords for this purpose and all IDEs I've seen in the last two decades had special colors for at least the entire keyword group. Am I missing something here?  
> **username_21** (2023-07-13): I think I was misreading "ignore it" as the IDE hiding the accessibility modifier words from you.  
---
### Answer by username_7 on 2023-07-12. Score: 13
Case has long been used by convention to indicate roles of identifiers. For instance, in C it's conventional to use ALLUPPER for macros, and either snake\_case or camelCase for other identifiers. In many languages, classes are conventionally named with an initial uppercase letter; this usually goes along with camelCase for the rest of the name.

Making this semantically significant simply formalizes these common programming styles. It's analogous to the way languages like Python make indentation significant to the parser, rather than it just being used to make the code easier for humans to read.

So the main "pro" is that programs in the language are forced to follow a consistent style, making it easier for everyone to read each other's programs.

This can also make it easier for programming tools to provide assistance.

The con, as other answers say, is that it doesn't work well when programming in (human) languages that don't have upper/lowercase similar to Latin alphabets.
> **Comments:**
> **username_8** (2023-07-14): In C, macros are not always capitalized. For instance `bool` is a macro expanding to `_Bool`, dating back to C99.  There is often a `getc` macro in `<stdio.h>` implementations.  Lower cased macros are used for shortening nested member access in structures: `#define s6_addr in6_u.u6_addr8`. It would be bad for macros to be restricted to upper case or even a leading upper case character.  
> **username_7** (2023-07-14): @Kaz `getc()` is specified as a function, but built-in functions are allowed to be implemented as macros. I think `bool` is an exception because it was originally an implementation extension keyword, and when it became a standard macro they kept the lowercase name for compatibility.  
> **username_8** (2023-07-15): In ISO C there are other examples of lower case macros. The `errno` symbol from `<errno.h>` is explicitly defined a macro in ISO C which "expands to a modifiable lvalue".  The behavior is undefined if a program uses `#undef` on it to access an `errno` object.   In `<stdio.h>`, `stdin`, `stdout` and `stderr` are also defined as macros. (And have were that way in ancient Unix; something along the lines of `#define stdin __filetab[0]` or whatever.)  In `<assert.h>`, `assert` is a macro.  
> **username_7** (2023-07-15): @Kaz The common denominator is that these things are used as if they're variables or functions, but they've been implemented as macros for various reasons (e.g. `errno` because of multi-threading).  
---
### Answer by username_24 on 2023-07-12. Score: 7
One advantage is that you can lexically distinguish between two different classes of identifier, which could be useful if they need to be parsed differently.

A good example of this is Haskell, which uses capitalized identifiers to denote types, and non-capitalized for functions. This avoids the need for its parser to determine based on the context which kind of identifier it is looking at, and results in a simpler, more efficient parser.
> **Comments:**
> **username_17** (2023-07-14): I think your remark about Haskell is wrong. In value contexts, it uses lowercase for variables and uppercase for constructors; in type contexts, it uses lowercase for type variables and uppercase for types.  
> **username_24** (2023-07-15): @xigoi - probably; it's been a while since I last used Haskell, so could easily have misremembered the details.  I think my point still remains valid, though.  
---
### Answer by username_22 on 2023-07-14. Score: 6
Con: screenreaders typically either don’t announce all-caps any differently to lowercase words, or, worse, can read them letter by letter as if they were an abbreviation.

Language developers shouldn’t bake in inaccessible practices into the base system.
> **Comments:**
> **username_23** (2023-07-14): This is an issue with screen readers (which are generally not designed to read code), not the with code itself.  
> **username_22** (2023-07-14): Well, that boils down to a philosophical code-is-for-computers can code-is-for-users. Personally I always go for the second option.  
> **username_23** (2023-07-14): I somehow agree, but does _any_ screen reader read the code correctly (as e.g. "tab string my string equals quote foo quote semicolon new line")?  
> **username_24** (2023-07-15): Anyone using a screen reader for working with code in detail is likely to need to find one that is able to distinguish between cases anyway, as most languages are case significant.   Most visually-impaired programmers I've talked to use a program called NVDA, which [seems to support this](https://nvda.groups.io/g/nvda/topic/nvda_announcing_capital/88508837?p=)  
---
### Answer by username_11 on 2023-07-12. Score: 5
Similar to occipita's answer, but for humans instead of compilers:

When reading code, it can be useful to immediately be able to tell whether a given identifier is public or private, without going to find its definition (using the example of Go). This will make it easier to pick out identifiers that definitely came from the current file, and which might have come from elsewhere. It might also allow you to make quicker and better decisions on whether you can safely change a function: if it's capitalised, then it's likely to be used somewhere else in the codebase, so changing it might be riskier.
> **Comments:**
> **username_20** (2023-07-13): Because the behavior of private functions is never exposed through the public API? This is complete nonsense. It does not matter if a bug is introduced from code that can be called directly or not.  
> **username_11** (2023-07-13): @feldentm Ok maybe not the behaviour necessarily, but the type signature for example. Surely you can see what I mean even if the example isn't totally applicable  
---
### Answer by username_25 on 2023-07-15. Score: 5
# Cons: not extensible

There are only two cases. It can be a hard time if, for example, we need to add `protected` support to a newer version of the language.

# Cons: dynamic keys

For example, in JavaScript, objects are often used as maps, and class properties can be dynamic too. A static analyser cannot tell if `obj.x` is accessing a private property, or reading the value corresponding to a user input `x`.

# Cons: special words

Some words are written in specific cases. For example, forcing `iOS` to be `ios` or `IOS` at language level can be a bit ugly.
---
