It's better - in so many ways that I will necessarily offer you just a short summary of some of them.
Being able to figure out a meaning of something is crucial in programming. We spend much more time reading the code than writing it and most of the time during reading is spent on resolving the meaning of symbols. To be able to tell what a symbol means, one needs to take into account many things - from OS it's running on to language it's written in to declared variables in the scope. And much more, of course.
Now back to your example: to be able to understand `x::xs` I need to know that `::` is a cons operator. Or more precisely, to understand the meaning of `x` symbol I need to take into account another symbol.
On the other hand of the spectrum is something like this: `first_element_of_list :: rest_of_list`. To understand the meaning of the first symbol in this expression you need to know exactly one symbol - itself. That's one benefit. The second is that someone who doesn't know what consing is, let alone how it's written in OCaml, can still understand this expression. So that's the second benefit.
It's worth remembering that we do not write the code for ourselves nor for the computers. We write the code to be read by other humans (always - don't argue). As with any kind of writing, then, it's helpful to know the audience. If I was writing a tutorial on constructing lists in OCaml (for beginners), I would use the second example above. But if I was writing production code (so for me and my team to read) I would use something shorter, like `head :: tail` for example. And if I was writing a quick and dirty script for my personal use, or if I was contributing to the work of hardcore OCaml hackers I would probably write `x :: xs` - because in case of script I'd be convinced that readability doesn't matter and in second case I would be certain that everyone reading and working with the code I wrote would be already so used to the construction that they would read it without problems.
That's another thing to consider: after using a language for a long enough time we tend to internalize its idioms; when this happens we are able to treat bigger constructs as one symbol. This ability helps in reading the code quickly, but it's worth remembering that not everyone developed it. Also, because longer names do not hinder quick-reading of idioms for those who know them, that's not a counterargument to longer names.
As for loops... Well, I do - sometimes - use `i` as a variable name, but I tend not to. Most often, after a while I come back to the code and replace `i` with `idx`. But to even use `i` as a name in the first place it needs to refer to the nonnegative integer value. In Python you generally iterate over collection directly, so you write `for what_is_it in a_collection:` instead of for example: `for i in 1 to 10: an_element = a_collection[i]`. Anyway, I use single letter variables very sparingly and in the smallest scope possible.
What I want to say, I guess, is that descriptive names are important in good programming and that there is really no argument for using non-descriptive ones.
I've been learning Haskell lately but I've seen the same idiom in other functional languages. I was struck by two things you said: you have to know cons'ing to understand x::xs and each symbol, x and xs should be unambiguously named in isolation (words to that effect).
What I see in "x::xs" is one simple expression at a glance. It is the cons that is the central concept in being able to understand the expression. So my next thought was to wonder what on earth someone is doing programming F# if they don't understand the first thing about working with lists? Cons is what makes the abstraction even possible. If you don't get that, longer symbols surely can't help except maybe to hide the magic gobbledygook.
"What I see in "x::xs" is one simple expression at a glance."
That's exactly what I wrote about in this: "after using a language for a long enough time we tend to internalize its idioms; when this happens we are able to treat bigger constructs as one symbol."
The thing here is that I don't believe that you would treat 'head :: tail' any different than 'x :: xs'. I believe that you would still see 'head :: tail' as one simple expression: I certainly would. If so then there is really no reason to avoid using 'head' and 'tail' as names.
"longer symbols surely can't help"
Do you know lisp? If yes, skip this; if not, read on.
I'll give you two example snippets of code in Racket. Both use exactly the same syntax and mean the same; read the first one and try to answer the question what the code does. The read the second one and try it again.
(define (drt t)
(define-values
(p l) (values 0 (s:l t)))
(λ (dc x y a)
(drc dc x y (s:s (s:r t p)) a)
(set! p (add1 p))
(when (>= p l)
(set! p 0))))
Assume that `s:l`, `s:s` and `s:r` are provided from another module that you have only in a compiled form at the moment and that drc is defined in the same module but written in the same style. Can you tell what is happening here?
>Assume that `s:l`, `s:s` and `s:r` are provided from another module that you have only in a compiled form at the moment
Why are you being so deliberately dishonest, and expecting a response like "oh, your strawman has totally convinced me to write shitty code, thank you so much first year CS student!"? The entire point is that x and xs are not defined elsewhere, they are defined by you, and used on a single line.
Why do you assume so? I'm really curious what is the difference in the readability to someone who doesn't know the syntax.
"first year CS student"
Ok, so I had enough: you're just a stupid troll. Not only you can't back your claims with arguments but now you're (for the third time, no less) using ad hominem "argument"; it's useless talking to you since you're too stupid to formulate sensible response and you're too bad a programmer to even have a chance of knowing something interesting.
I'm still waiting for your argument as to why is one-letter name better than three-letters one. What is the difference, what makes it so much harder to understand the name with two additional letters? With a link to the source please.
You write bad code. If you are using anything other than a single letter for a simple for loop iteration, then you are making your code less readable, not more. Adding cognitive load to a trivial process is bad, not good.
You summarize your argument by saying descriptive names are important, but your examples do not support that at all. Descriptive names are important for things that need to be described. If I write a function "reverse_string" with a single string argument, that argument had damn well better be named "s". There is no longer name that can convey any useful additional information. Many longer names will be distracting, and make the code harder to read.
"Many longer names will be distracting, and make the code harder to read."
Do you have any source for this? I really can't imagine this happening, seriously.
"You write bad code."
I see, it's one of those days when you just have to be a dick to someone. Ok, no problem, moving on...
To reiterate without needless things involved: can you prove that a) words between 1 and 6 letters of length are significantly harder to read for higher letter counts and b) having longer names, regardless of a, is not beneficial at all? If you can - please do.
Given that 90% of experienced programmers fall on the side of "i or gtfo", the onus is on you to prove that "counter" is beneficial. Any time I see a long variable name, I naturally assume it is important, and has a large scope. When you lie to me with your code, that makes it harder to read, not easier.
And why not on you to prove that it's harmful? Because you don't have arguments?
"Any time I see a long variable name, I naturally assume it is important"
Very good habit, keep at it - and please define 'long' by the way. For me it means 14-20 characters; and short means 3 to 6 characters.
"experienced programmers fall on the side of "i or gtfo","
Well, these are probably the same people who claim that comments in code are bad. Both claims are simply stupid. Anyone experienced enough - and not dyslectic... - will tell you that readability counts, that you should never or almost never use any name shorter than 3 characters and that you should comment your code heavily. Whoever tells you otherwise - to put it simply - writes bad code or wants you to write bad code.
I find it amusing to see so many people mistaking familiarity for readability. Just because something is very familiar to you it doesn't mean that it's readable. It's a shame that people are unable to look at the matter objectively and hence they write bad, unreadable, hard to change and extend code.
>Well, these are probably the same people who claim that comments in code are bad.
No, they are not. Please, copy this thread into a text file and hang on to it. Spend a few years actually reading and write code. Then come back and facepalm at yourself.
I have been reading and writing code for twenty years now in about a dozen languages or so. How long do you think I should wait to realize how mistaken I am now? And while we're at it, how many years have you spent writing and reading code and in how many languages?
But that's a digressions, what's important is that you provided not even a single argument; not even one. You cannot expect to convince anyone without even trying.
>I have been reading and writing code for twenty years now in about a dozen languages or so
I would strongly recommend that you stop admitting that.
>And while we're at it, how many years have you spent writing and reading code and in how many languages?
28 years, and I count 18 languages including logo and sh which you might not count.
>what's important is that you provided not even a single argument; not even one.
Yes I have. Ignoring it doesn't make it cease to exist. The vast majority of experienced programmers have already gone through writing code like you when they were beginners, and then realized it was bad and stopped. You can easily verify this yourself by noticing how the vast majority of experienced programmers tell you that you are wrong.
>You cannot expect to convince anyone without even trying.
I do not expect to convince you. You are attempting to convince others to write bad code. I am stating that you are a bad programmer, and that is why you find such resistance when you try to convince people to write bad code. The fact that you focus entirely on strawmen and demanding that other people prove you wrong rather than simply supporting your claims does not help your case.
You know, saying that someone is a bad programmer without reading their code disqualifies you even before you say anything else. And the "majority of experienced programmers" is a "citation needed" thing. Donald Knuth seems to disagree with them, anyway.
I see no other resistance than from you, by the way.
Oh, and also: aside from "citation needed" your argument that "many people think the same" is an argument from authority, which is rather weak thing to do.
Unfortunately you're right on this. I read his various works long ago and had not very accurate memory of them.
As a final note in this discussion I'd like to say that you're probably misunderstanding me. I have never said that single-letter names are completely prohibited - just that they should be avoided when possible.
I actually went and did some analysis on the code I think is good: Underscore.js. This is what I found.
I excluded all language keywords like `var` and `if`. I then calculated how many unique names there are in the code and how many of them are 1 or 2 letters long. The result I got was 4%.
I then checked how many times each of the names was used and how many times 1 or 2 letter long names were used, Surprisingly I got almost the same result - 4%.
So, to conclude - if more than 4% of names you use are shorter than 3 characters than you're writing bad - or at least worse than Underscore.js - code. I'm not guilty of this, I checked my own code too. And how about you?
Also, on a more personal note - you're infuriating as a adversary in the discussion because of at least three things: you only answer to parts of arguments that are convenient to you, you don't openly state assumption you're making and you're mixing completely irrelevant things into the discussion. Please improve :)
Being able to figure out a meaning of something is crucial in programming. We spend much more time reading the code than writing it and most of the time during reading is spent on resolving the meaning of symbols. To be able to tell what a symbol means, one needs to take into account many things - from OS it's running on to language it's written in to declared variables in the scope. And much more, of course.
Now back to your example: to be able to understand `x::xs` I need to know that `::` is a cons operator. Or more precisely, to understand the meaning of `x` symbol I need to take into account another symbol.
On the other hand of the spectrum is something like this: `first_element_of_list :: rest_of_list`. To understand the meaning of the first symbol in this expression you need to know exactly one symbol - itself. That's one benefit. The second is that someone who doesn't know what consing is, let alone how it's written in OCaml, can still understand this expression. So that's the second benefit.
It's worth remembering that we do not write the code for ourselves nor for the computers. We write the code to be read by other humans (always - don't argue). As with any kind of writing, then, it's helpful to know the audience. If I was writing a tutorial on constructing lists in OCaml (for beginners), I would use the second example above. But if I was writing production code (so for me and my team to read) I would use something shorter, like `head :: tail` for example. And if I was writing a quick and dirty script for my personal use, or if I was contributing to the work of hardcore OCaml hackers I would probably write `x :: xs` - because in case of script I'd be convinced that readability doesn't matter and in second case I would be certain that everyone reading and working with the code I wrote would be already so used to the construction that they would read it without problems.
That's another thing to consider: after using a language for a long enough time we tend to internalize its idioms; when this happens we are able to treat bigger constructs as one symbol. This ability helps in reading the code quickly, but it's worth remembering that not everyone developed it. Also, because longer names do not hinder quick-reading of idioms for those who know them, that's not a counterargument to longer names.
As for loops... Well, I do - sometimes - use `i` as a variable name, but I tend not to. Most often, after a while I come back to the code and replace `i` with `idx`. But to even use `i` as a name in the first place it needs to refer to the nonnegative integer value. In Python you generally iterate over collection directly, so you write `for what_is_it in a_collection:` instead of for example: `for i in 1 to 10: an_element = a_collection[i]`. Anyway, I use single letter variables very sparingly and in the smallest scope possible.
What I want to say, I guess, is that descriptive names are important in good programming and that there is really no argument for using non-descriptive ones.