27
$\begingroup$

Almost every programming language requires strings (or char* or equivelent) to be marked with quotes. Few languages allow other delimiters, many languages allow single and double quotes.

Why is it that we even need delimiters to mark strings? What's wrong with code like this?

name = I do not want to give my name

As I see it, there is one primary problem - using one variable name = safwan might cause confusion as to whether safwan is a variable or a word. However, a language could enforce quotes in this case alone. For a similar situation, {hey: 9} is valid JS, but if you wanted a key like hey-foo, you'd have to say {"hey-foo": 9}. No quotes except when it's necessary in key definitions - why couldn't that be extended to all strings in general? Another possible area of problem might be concatenation, but concatenating two string literals is highly unusual, after all, so hello and world in hello + world might be assumed to be variables instead of strings.

It admittedly will cause a few problems, but I'm wondering why it's so rare (if it's ever occurred). It would not be the first widespread programming concept that's been questioned. Multiple languages have rebelled against the parenthesis around function calls phenomenon. If Python's print("Hello World") is pretty to a C programmer, Ruby has print "Hello World" - even better.

Why not print(Hello World)?

$\endgroup$
17
  • 9
    $\begingroup$ printf so, the result is %d, 10. Good luck! $\endgroup$
    – jcaron
    Commented Aug 29, 2023 at 9:48
  • 1
    $\begingroup$ In some languages you can omit dots and parentheses from function calls. val y = x filter odd map square reduce multiply is perfectly valid syntax in Scala. $\endgroup$
    – Wombatz
    Commented Aug 29, 2023 at 13:14
  • 6
    $\begingroup$ print(hello); string hello = world; print(hello) $\endgroup$
    – Ray
    Commented Aug 29, 2023 at 15:25
  • 1
    $\begingroup$ Seems related to why variable-identifiers can't be numbers (e.g., no string 2 = "Hello, world!";) since languages could have numbers as variable-identifiers if they didn't have bare-numerics. For example, int 1 = "2";. $\endgroup$
    – Nat
    Commented Aug 30, 2023 at 11:55
  • 3
    $\begingroup$ Your example is using "= " and newline as it's string delimiters. $\endgroup$ Commented Aug 30, 2023 at 15:21

6 Answers 6

50
$\begingroup$

The feature you're asking about is called "barewords" or "bare words", which means that identifiers in some contexts are taken to be string literals, and possibly also that consecutive identifiers are taken to be joined as strings with spaces between. However, some other languages or communities use the term "bareword" to mean other things (e.g. function invocations without parentheses in Ruby and Elixir), so be aware of that when searching for information about this topic.

Before discussing why languages don't have this feature, it's worth noting that some actually do, or did:

  • Perl is most known for having them, and the term "bareword" appears to come from the Perl community. Apparently they don't exist in Raku (formerly known as Perl 6).
  • PHP used to have them, but they were deprecated in version 7.2.
  • The esolang Squire apparently has them, and uses Fraktur Unicode letters to disambiguate between identifiers and barewords.

Some other languages including Lua, Ruby, Python and Javascript don't have barewords as a feature, but can be given them in user code by combining other language features in unintended and hacky ways.

Bbrk24's answer notes also that markup languages and data languages may have barewords, but very different considerations apply to such languages as to traditional programming languages.


So why not have them in a programming language? There are so many reasons they're a bad idea, but there are two main reasons:

  • They can turn spelling mistakes from simple errors that get noticed immediately, into bugs which don't happen until runtime ─ and typically, not recoverable ones. If a misspelled identifier has some meaning despite being undeclared, then a static checker or linter can't reject it without banning all use of barewords anyway. Then at runtime, either a string value is used where some other type was expected, or the wrong string value is used.
  • They make the meaning of an expression dependent on outside context which can easily change. If an identifier used as a bareword is later declared in some outer scope ─ either in the same codebase, as a wildcard import from a third-party library, or as a built-in in a later version of the language ─ then it's no longer a bareword and now refers to that declaration. The same isn't true for other uses of identifiers, due to shadowing.

Another reason is that it makes it harder to introduce new keywords or reserved words in the language's syntax, since those words are more likely to already appear in existing code.

For a more in-depth discussion of why not to have them, take a look at the rationale for deprecating them in PHP, or relatedly the rationale for now requiring parentheses for zero-argument function calls in Elixir.

$\endgroup$
11
  • 12
    $\begingroup$ A stronger example of an existing language with unquoted strings would be shell script. Perl barewords are also somewhat complex and often not strings, which wasn’t the case when they were copied into PHP. $\endgroup$
    – Michael Homer
    Commented Aug 28, 2023 at 19:12
  • 1
    $\begingroup$ As I understand about the second point in why programming languages don't often use barewords, it's useful in the case of differentiating var x = Null and var x = "Null" - where you need a word that would be a bareword for determining that there is an uninitialized string versus a string with the text "Null". $\endgroup$ Commented Aug 28, 2023 at 23:13
  • 1
    $\begingroup$ I get it, thanks for the detailed reply! $\endgroup$ Commented Aug 29, 2023 at 0:37
  • 3
    $\begingroup$ @CodeCaster The same is true in many dynamic languages. In some (e.g. Javascript "use strict", or Python doc comments) statements which consist only of a string literal may nonetheless have some meaning. But mainly I think it's just because dynamic languages tend to prefer making things valid if they don't need to be invalid. Having Expression ';' as a production rule for statements in the grammar is also simpler than excluding some syntactical forms of expression which aren't useful as statements. I suspect there is more to say on the topic, so perhaps you should ask it as a question. $\endgroup$
    – kaya3
    Commented Aug 29, 2023 at 11:45
  • 1
    $\begingroup$ From the "Good uses of barewords" section of your perlmaven.com link, it shows a bareword for a hash index (e.g.) $myhash{foo} = 123;. Since perl doesn't have [true] struct/class support, this was a way to get them: $ptr = {}; $ptr->{foo} = 123; with a syntax similar to C doing struct xxx { int foo; }; ... ptr->foo = 123;. Doing $ptr->{"foo"} gets old fast (trust me, I know because I've been using the barewords for this for 3 decades). With raku, you have real struct/class support, and can do: %ptr.foo = 123; $\endgroup$ Commented Aug 30, 2023 at 23:26
15
$\begingroup$

The feature you're asking about is known as barewords, and they're common in markup languages such as HTML and (La)TeX, where the "strings" indicate text to be displayed, and data languages such as YAML and CSV, where there are no identifiers to confuse them with.

Perl and most shells also support barewords, since every use of a variable has to be prefixed with a "sigil" (i.e. $foo) in those languages. Ruby and JS can support barewords -- by defining a particular method_missing or using with + a Proxy respectively -- but this is rare in practice, since it makes it difficult to tell apart unquoted strings from local variables, and mistyping a variable name won't be an error. In JavaScript specifically, barewords are common in React's JSX syntax, which is meant to look as similar to HTML as possible, and because variables can only be used inside brace expansion.

$\endgroup$
4
  • 8
    $\begingroup$ I wouldn't say barewords are common in markup languages. There it's just a reversal of what you quote: instead of quoting the strings, you quote the rest. $\endgroup$
    – G. Sliepen
    Commented Aug 28, 2023 at 14:41
  • 2
    $\begingroup$ You can use barewords in python too: stackoverflow.com/questions/29492895/… $\endgroup$
    – mousetail
    Commented Aug 28, 2023 at 20:13
  • $\begingroup$ LaTeX comes to mind $\endgroup$ Commented Aug 31, 2023 at 14:26
  • 2
    $\begingroup$ “YAML, where there are no identifiers to confuse them with” Norway would like to have a word with you… $\endgroup$
    – xigoi
    Commented Aug 31, 2023 at 22:48
13
$\begingroup$

Bare words make the language irregular and harder to maintain

It will be almost impossible to generate an abstract syntax tree from the source code alone, as it may be necessary the run state to determine if almost every /[A-Za-z0-9_]/ in code is an identifier or a bare word.

You can think of this as an extreme example of lexer hack, and may generate exponential performance problems in big projects, even if you do not use the resource, as every identifier must be checked anyways.

Say, print(Hello World) is:

  • (call "print" (arg (var Hello) (var World) )
  • (call "print" (arg (str "Hello") (var World) )
  • (call "print" (arg (var Hello) (str "World") )
  • (call "print" (arg (str "Hello World") )

Bare words make code easy to write, but harder to understand or reason. In other words, the code will be very hard to debug or change.

Every time you change an identifier or a string, will need to verify all identifiers and all strings in code scope, because any string or identifier naming change may impact both of these things.

// code ...
// code ...
// code ...
// code ...
// code ...
// code ...
// code ...
// code ...
// code ...
// code ...
// code ...
// code ...
// code ...
// code ...

// The only way to determine if
// "Hello" here is a string
// OR is a identifier is to
// to read AND interpret ALL
// code above this line

print(Hello)
$\endgroup$
2
  • 3
    $\begingroup$ To add to what you said, consider that, according to thought leaders like Martin Fowler, we write code for humans, not for computers. The problem of strings without quotes goes beyond what we can or cannot teach the compiler to do. Like you said, changing any string requires a review of every single word of code and strings. $\endgroup$
    – Dale
    Commented Aug 28, 2023 at 23:37
  • $\begingroup$ Thanks for answering! This is definitely an important point. $\endgroup$ Commented Aug 29, 2023 at 0:38
5
$\begingroup$

Your question can be very simply answered by another two questions. As you wrote that, did you want a single space at the start of your string or not? And were there any spaces at the end or not?

In general, whitespace is useful for making code more readable. In most human languages, we put spaces between words, so doing the same in code is natural. You did it yourself there without even thinking about it - even in a question where you're asking about implicit string parsing without delimiters. Should your hypothetical language use the "you get what you ask for" principle and give you an extra space, then? And if not, how do you get an initial space if you do want one?

And then there's whitespace at the end. Unless you turn on glyphs for non-printing characters in your text editor, a reader/reviewer simply won't know whether there are extra characters there or not. The least worst consequence might be text not being displayed how you want it. The worst might be an array overflow or a runtime assert.

You also have an incorrect belief that using text delimiters such as quotes is somehow hard or unnatural for people to use. Every written European language uses some form of delimiters for representing speech though - not necessarily quote marks, but something. If you're literate enough to read and write code, then you can already read and write at least your own native language - and therefore you are already fully familiar with this convention. I can't say whether this is true for other languages around the world, but it certainly is true for every European language. Your proposal therefore could never benefit even one individual in the entire Western world in the entire past and future of code writing.

So. Provable parsing issues. Provable lack of any benefit to any user. Yep, we're not going there. ;-)

$\endgroup$
5
  • $\begingroup$ "Every written European language uses these for representing speech" This is being nitpicky, but a significant chunk of European languages (maybe most of them?) use guillemets for this purpose, not English quotation marks. See en.wikipedia.org/wiki/Guillemet#As_quotation_marks for examples. :P Edit: Though I realize in hindsight that you might have just meant that they use text delimiters at all; my mistake if so! $\endgroup$
    – Idran
    Commented Aug 30, 2023 at 16:00
  • $\begingroup$ @JustinHilyard Yes, I meant that they all use some form of delimiters. I can make that clearer. $\endgroup$
    – Graham
    Commented Aug 30, 2023 at 16:56
  • $\begingroup$ I think this is overstating the case against unquoted string literals; consider for example PHP, which used to have them, so that it was possible to write e.g. $_GET[foo] instead of $_GET['foo']. The former is a bit easier to read, and a bit easier to type. To be clear, I think that's not enough for it to be worth having the feature in the language, but it answers your questions: whitespace before and after should be ignored, because the keys in a dictionary will very rarely contain whitespace at the start or end. If there was no benefit then people wouldn't have written PHP this way. $\endgroup$
    – kaya3
    Commented Aug 30, 2023 at 17:23
  • 1
    $\begingroup$ @kaya3 Really it shows how PHP wasn't actually designed. The original author said himself that he had no idea what he was doing, never designed it, and never even intended it to become a full language. PHP is a great example of what you get when you don't do a proper design and think about stuff like that. $\endgroup$
    – Graham
    Commented Aug 30, 2023 at 22:00
  • 1
    $\begingroup$ I didn't claim that PHP is well-designed. What I said is that PHP had this feature and people who wrote in PHP found it beneficial for this use-case. To say there is a "lack of any benefit to any user" is hyperbole. $\endgroup$
    – kaya3
    Commented Aug 30, 2023 at 22:20
3
$\begingroup$

There are conflicting requirements: I want it to be easy to create a string literal in the source code containing whatever character sequence I want it to contain. I want it to be easy to see a string literal in the source code and figure out which character sequence it represents. And I want it to be hard to make stupid mistakes. What is not an argument for a feature is "I can do it".

Being able to write a sequence of ASCII letters to indicate a string is nice, but then what about other ASCII characters? Other Unicode letters and other Unicode characters? ASCII letters that match keywords in the language? That's where the proposal fails IMO.

Many languages start with a simple rule: A string literal is any sequence of characters enclosed between double quotes. Then someone realises that you can't create a string literal representing a double quote. Three methods are used that are more or less helpful: "" in a string literal doesn't indicate the end of one string literal followed immediately by another one, but means a double quote becomes part of the string literal. Or we use escape sequences, for example \" means a double quote character, \\ means a single backslash character (otherwise we can't include a backslash character in a string literal) and some more. Or we state that a string literal may be enclosed in single quotes instead, which is often a simple solution avoiding escape sequences.

Swift (and others I believe) has multi-line string literals. An example:

let s = """
This is a string literal
containing a line break
"""

Here the string literal can contain anything except a """ sequence, which makes it quite useful to create help text to be displayed on the screen, or source code and so on. It's meaning is clear because the """ at the start and end stand out.

And C has the feature that what looks like two consecutive string literals with nothing but white space in between is merged by the compiler into a single string literal. For example "Hello" ", " "world" and "Hello, world" are compiled to exactly the same string literal. This would be a problem with bare words because now two words are a single string literal with no space between them.

$\endgroup$
-7
$\begingroup$

In addition to all of the other reasons, consider that when computer languages were first created, computers didn't have the CPU power, memory, and other resources for doing complex code interpretations that a modern, AI-based compiler or interpreter might have.

It might (or might not) be possible to create a reliable interpreter for barewords today, and it might (or might not) have been theoretically possible 80 years ago but it is sure there were other priorities for CPU cycles for most of those 80 years.

Now it is so embedded into our minds and practices, just as it is in our spoken languages, that the cost of keeping it that way is far, far, less than the cost of trying to change it.

Consider that Abraham Lincoln once said four score and seven years ago and computer memory and power has increased by a power of thousands.

Bet you didn't even know that Mr. Lincoln knew about computers, did you?

$\endgroup$
20
  • 5
    $\begingroup$ What modern compilers or interpreters for programming languages are AI-based? $\endgroup$
    – kaya3
    Commented Aug 28, 2023 at 21:08
  • 2
    $\begingroup$ Well, most of the rest of your answer is unsupported too, but I figured it would be easier to only ask you about one thing. If you only meant this to be speculation then I suggest you edit to remove it. Is there any reason you think supporting barewords would require enormous computational resources, besides speculation? What do speech patterns have to do with it? $\endgroup$
    – kaya3
    Commented Aug 28, 2023 at 21:40
  • 2
    $\begingroup$ I am not suggesting that at all, and why would that be necessary to support barewords in a programming language's syntax? Note that some existing languages do support them (see other answers for details). I think you have seriously misunderstood the question. $\endgroup$
    – kaya3
    Commented Aug 28, 2023 at 22:40
  • 2
    $\begingroup$ Unix shell has unquoted string values and dates back more than fifty years; I don't see how this CPU-power argument holds water and it would help to edit the answer to provide some more backing to the claims it makes. $\endgroup$
    – Michael Homer
    Commented Aug 28, 2023 at 22:50
  • 4
    $\begingroup$ "Consider that Abraham Lincoln once said four score and seven years ago and computer memory and power has increased by a power of thousands." - a "Chewbacca defence" if I ever saw one! $\endgroup$
    – Steve
    Commented Aug 29, 2023 at 6:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .