This is especially true for programming languages. Case sensitivity means that fooBar and FooBar can be valid identifies in the same scope but refer to different bindings. I see many ways where that can produce an errors and very few (possibly none) where it can help create well-structured code. If the names shadow, clash, or override then the error cases become much easier to see and diagnose.
Honestly one of my favorite tiny things about programming in Lisp is the identifier rules. The caps insensitivity, plus '-' being available because there's no infix operators, means that multi-word identifiers are easier to type (no shift key) and IMHO more aesthetically pleasing than underscores or snake case.
On the subject of spaces, I do wonder why no language has used enough punctuation to make spaces allowed in identifiers. I mean, most Algol-derived languages could get away with it if they put punctuation between type keywords and variables:
private, my class: my instance = my factory function(my parameter one, my parameter two);IIRC from my days at Cambridge, Algol68 allowed that. (Our local variant was Algol68C.)
(defun |my + function| (x y) (+ x y))
(|my + function| 2 2)
(Or maybe write a reader macro to deal with them in some other way.)We're looking for something nicer than underscores and hyphens.
I can see why this is available to the reader (it has to handles arbitrary characters), but I have no idea why anyone would ever want :INVERT.
Scheme is basically case sensitive. R5RS was insensitive; they repented from the idiocy and made R6RS sensitive. Finally, they caved in and made it configurable.
Emacs Lisp is insensitive; FOO and foo are different symbols.
TXR Lisp, ditto.
Case insensitivity is arbitrarily stupid; you're taking two subranges of a character set and making them equal. It ignores the fact that there are semantic differences linked to case: like Pole is someone from Poland, whereas pole is one end of a magnet.
I see foo and Foo as completely different; I've been programming in C and using Unix file systems for thirty years.
Case insensitivity is complicated in Unicode. To be implemented correctly, it must handle every script that exhibits a case-like duality or plurality whereby the same sounds are encoded with multiple sets of related glyphs:
CLISP fails here:
[1]> (eq 'ångstrom 'Ångstrom)
T
[2]> (eq 'フバル 'ふばる)
NIL
How about SBCL and others?If you make things completely insensitive so that different codepoints are different characters, you don't have to implement reams and reams of tables for handling all of the scripts.
There are other issues there, like similarities between glyphs and groups of glyphs that aren't in a case-like relationship. These are worse than case, even; we can have a symbol ffi that is a ligature, and one that is just the three ASCII letters.
We don't even have to go to Unicode to find visual confusion issues: should we fold together 1 and l so that someoone doesn't name different variables poll and po11? These two look more similar to me than B and b, or E and e. In some typefaces it's worse than in others. People have exploited this sort of thing in obtaining vanity license plates that are hard to transcribe correctly for police officers.
All sorts of language features can be abused. We can have nested scopes such that an identifier can have different bindings in the same apparent scope. We don't need foo and Foo to create confusion: we can just have nested let-s with foo present at different levels of nesting. Should that be banned?
Basically, the right guiding principle is to trust the users of programming languages to be grownups.
By the way, in a number of mainstream functional languages, FooBar would be a type and fooBar a value, enforced at the language level. That is monumentally idiotic; you basically have case sensitivity and the implementation still has to recognize case distinctions. If we use Japanese names in Haskell, which is the type: the one starting with katakana or the hiragana one? How do you use scripts that don't exhibit case?
I think this is backwards. Languages are top-down, and character sets are bottom-up.
A language can reasonably choose to use the common concept of "the 26 English letters (ignoring case)". This would require dealing with such implementation details as "subranges of character sets" only because that's the platform that computers today present.
It's not unique to characters. Many programming languages say that 2 is equal to 2.0 (and 2/1 and (2,0) and ...), even though their internal bit patterns are usually completely different. We simply decided that this is the semantic meaning that we wish to expose to users, and the implementor has to work out how to deal with IEEE FP and such.
> It ignores the fact that there are semantic differences linked to case: like Pole is someone from Poland, whereas pole is one end of a magnet.
There are also semantic differences from context and from pronunciation -- English is pretty stupid -- but I don't think anyone would suggest appending every identifier in a program with a pronunciation key, or the OED meaning. Just because a word without capitalization can be ambiguous doesn't mean a word with its capitalization is unambiguous, or even that this would be desirable if it were.
That sounds like the wrong question to ask. Neither script has uppercase, and you're not mixing them in a word. A better question would be: should scripts without case support be valid Haskell identifiers to begin with.
The problem here isn't case-sensitivity anyways. The problem is that many programmers think Y instead of y for years because that's how it is in many contexts. E.g., the C strftime() and strptime() functions use %Y for four-digit year.
I don't think case sensitivity is a mistake. Case is a mistake. But we have it, and we have case-sensitive and case-insensitive things. It is what it is.
“s” and “ſ” - the latter being u017F.
For example, "é" can be written as either U+00E9 LATIN SMALL LETTER E WITH ACUTE, or as the sequence U+0065 LATIN SMALL LETTER E followed by U+0301 COMBINING ACUTE ACCENT. These two options have canonical equivalence; what this means is that Unicode treats them as two ways of specifying exactly the same thing.
Now, consider "½". That's U+00BD VULGAR FRACTION ONE HALF. Generally you can replace that with the sequence U+0031 DIGIT ONE, U+002F SOLIDUS, U+0032 DIGIT TWO ("1/2"). This is not quite the same thing; most places where someone writes "½" can safely be replaced by "1/2", but not necessarily all, and it definitely doesn't work in reverse. This is compatibility equivalence, and under compatibility equivalence "½" maps to "1/2".
So to get to your actual question: U+017F LATIN SMALL LETTER LONG S has compatibility equivalence with U+0073 LATIN SMALL LETTER S. But U+03C2 GREEK SMALL LETTER FINAL SIGMA does not have any type of equivalence with U+03C3 GREEK SMALL LETTER SIGMA.
If you follow the general recommendations for things like comparing Unicode identifiers, you'll apply normalization to form NFKC (which decomposes by canonical equivalence, then recomposes by compatibility equivalence); this will turn a "ſ" into a "s". It will never turn a "ς" into a "σ".
Also, if you think you can decompose without allocating memory... well, try a code point like U+FDFA.
For reference, its decomposition is:
U+0635 U+0644 U+0649 U+0020 U+0627 U+0644 U+0644 U+0647 U+0020 U+0639 U+0644 U+064A U+0647 U+0020 U+0648 U+0633 U+0644 U+0645
(and that doesn't begin to touch any of the potential issues with variant forms, homoglyph attacks, etc.)
This is actually implemented in ZFS. (And also character-at-a-time normalization for hashing.)
I don't see how homoglyphs enter the picture. Can you explain?
Folding the cases is a continuation of the normalization operation you were going to do anyways.
Also, case-folding doesn't round-trip in Unicode. In particular, only to-lower-case conversions work well enough.
Case is a mistake. Case-insensitivity is another mistake though. Don't do it. It's a pain for users (me, for example).
Names in programming languages?
English?
Care to elaborate?
I've used systems that are case sensitive and systems that are case insensitive, and the former are responsible for an order of magnitude number of bugs more than the latter.
Every time I copy a license to the project, I edit the formatting to use Markdown bold (or sometimes italic/emphasis) instead of ALL THAT UPPERCASE SCREAMING. Much easier for the eyes.
IANAL, but I believe that was the intent. Just to highlight the important sections to be even safer with "you have been warned about this and can't say you haven't noticed it". If any lawyer out there knows if this is correct understanding or not - would be interesting to hear.
Normal people don't think of case as changing the value in the same way that even abbreviations or alternate spellings do — I know people who've had trouble boarding planes because they have ID/boarding passes which are inconsistent on, say, using ü or ue – especially annoying when the latter usage was just to work around a bug in someone else's system.
"Case-sensitive but identifiers cannot differ only by case" would be a reasonable compromise.
"Martin" and "martin" are obviously not different names. Martin may be more correct, but allowing "martin" as a separate name is worse.
It is a core spelling rule of English. They could have gone the German way, with all nouns capitalised and compound words without spaces.
> I've used systems that are case sensitive and systems that are case insensitive, and the latter are responsible for an order of magnitude number of bugs more than the former.
Do you have "latter" and "former" transposed in the second quote? If not, I'm confused.
Practically every programming language is case-sensitive. Unix filesystems are generally case-sensitive.
You statements make no sense anyways. What is the antecedent of 'it' in "... any API or programming language that is based on it ..."? Since when are APIs / programming languages "semantically thought of as English"?!