My recollection of the "old days" may be a bit hazy, but I think comma delimited parameters were a work around for frameworks that did not support multiple values (or users not knowing how to handle it)
Example of a "correct" url
?value=A&value=B&value=C
Complete frameworks would have a method that returned the values as a list. Some like PHP required ugly work arounds where you had to name the parameter using the array syntax: value[]=A&value[]=B&value[]=C
Even if the framework supported multi-values, many preferred the shorter version: value=A,B,C and split the values in code instead
Django actually has a special mechanism for dealing with ?value=&A&value=B
values = request.GET.getlist("value")
# values is now ["A", "B"]
We built it that way because we had seen the weird bugs that cropped up with the PHP solution, where passing ?q[]=x to a PHP application that expected ?q=x could result in an array passed to code that expected a string.
I don't know if it's something from the old days or not, but iirc URLs have a semicolon separator (;) that would go before the ?. I have never seen it being used. I'm betting it's even less support than commas!
In the OG RFC 2396, each _path segment_ can specify parameters similar to query parameters, but using a semicolon to separate them to the main segment value instead of question mark. This has effects e.g. when calculating relative URLs. This is now obsolete, but many URL-parsing libraries have an API for that for compatibility.
Example of a "correct" url
?value=A&value=B&value=C
Complete frameworks would have a method that returned the values as a list. Some like PHP required ugly work arounds where you had to name the parameter using the array syntax: value[]=A&value[]=B&value[]=C
Even if the framework supported multi-values, many preferred the shorter version: value=A,B,C and split the values in code instead