Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

selectKeyword keyword = "select"

I don't work with Go, so this may be a requirement of the language that I don't know, but whenever I see lines like this, it automatically brings up the question why? --- do you really expect to need to rename the SELECT keyword? Especially when it's named "selectKeyword". Why not just use the string constant? Ditto for the others like "leftparenSymbol" --- I see there's explicit character constants in some of the other code too... it reminds me of the classic anti-pattern like "int five = 5;".

Also, you may find the full SQL grammars interesting to look through --- they are quite a bit more complex than the subset presented in the article: https://ronsavage.github.io/SQL/



The biggest reason is typo and type checking. Any typo is a compilation error. But the type checking is even more interesting. You basically create a subtype of string which is correspondingly type checked by the compiler. Functions might return a keyword instead of a string.

One funny thing you can do in Go is for example to create a subtype of int and change its String() method to return the hexadecimal representation of that int. Very neat.


The IDE will autocomplete selectKeyword but not "select".

Other type systems, like TypeScript, support string literal types, and in Typescript we generally would just define the keyword type to be a union of string literals and then use those string literals in the code.

But without string literal types, using a string constant gives the compiler more information it can use to make sure your code is correct. That's a useful thing to have.


Another reason is that by providing an identifier for this string literal, misspellings of it can be detected by the compiler whereas there is nothing tying separate string literals together.


I can hardly imagine a case where you would misspell "select" and not notice it at some point, nor use it in more than one place (the keyword detector) in the parser.


The pattern (which I employ only sometimes) is to have almost all literals defined in this way. Perhaps SELECT isn’t likely to be the word you misspell, but I’m a careless typist and make 10 typos a minute. Taking this added step helps your editor save you from yourself.


Having standards like that and keeping them helps a lot. Next time you have a different keyword, you don't have to think "does it deserve a constant?" - all of them do.

Similar to how linters stop you from overthinking indentation in specific cases, or some naming standards, and later rename/reformat-wars.


all of them do.

That's what leads to dogmatic cargo-culting. Good software is written by thinking about the circumstances and doing what makes the most sense, not by mindless rule-following that don't always make sense.

I don't know why someone would be so worried about typos and introduce more verbosity and redundancy in the process; but then again, I don't use an IDE and I've never had this problem.


I'm not sure you're really making the argument you think here...

Good software may mean thinking about circumstances like "we're dealing with lots of text parsing and have seen bugs from typos in common keywords" and doing what makes most sense: "let's prevent those in the future, but using constants for keywords". It's only cargo culting if you don't know why you're doing something.

Setting a rule so you don't have to debate something later is a valid solution and may still offset some redundancies introduced this way.


You'd be surprised...


It’s one of the more common bugs in our office. Before we integrated a Python linter in our CI for a prototype project, we would see several such typo errors each week with a small team (and that was with symbols, not string literals).


Python and a lot of the other dynamic languages are in a slightly different situation.


The point is that if you can make typos in identifiers in (unlinted) Python then you can make typos in string literals in Go. In both cases, there is no static analysis to help you.


The biggest reason to do this in Go is to approximate enums. Now anywhere the `keyword` type is used, it must be one of the ones specified there (or you'd have to cast a string).

Yep, it would be a little harder to implement all of the SQL spec in a single post. Maybe over time though.


Aside from obviously preventing typos, I really like being able to very quickly find all references that use the string.

For example when storing session state into a Dictionary<string,object> all access to the session state is through static strings, never a string literal. This makes is super easy to find everywhere that’s accessing that particular session variable.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: