KatrinaHoffert / EatSafe

An app for finding safe places to eat
Other
2 stars 2 forks source link

General: Style guide #21

Closed KatrinaHoffert closed 9 years ago

KatrinaHoffert commented 9 years ago

We really need to come up with a style guide. We need to maintain consistency in all our code. This is complicated by the fact that we have several languages: SQL, Scala, HTML, CSS, and JS.

I won't waste time repeating any of the things that the prof would discuss in class (like "use good variable names").

Here's my thoughts, based on past experience:

  1. Scala practically needs 2 space indentation. The language uses closures heavily and thus we usually have a lot of indentation going on. For consistency, we should use this everywhere. It's very useful in HTML for the same reasons (with 4 space indentation, it's very easy for the middle of an HTML page to be half spaces). The reason to use spaces instead of tabs is for consistency with most existing Scala code (it's pretty much the Scala convention), but is also useful because web browsers think tabs should be 8 spaces wide.
  2. We should use "K & R" braces. That is, the braces start on the first line, after whatever necessary identifiers. This is sometimes necessary in Scala, since there's no semicolons. It's very helpful for JS, since JS loves its nested functions. Example:

    $("#collapsableSection").hide(function() {
     if(foo) {
       // Do something
     }
     else {
       for(var i = 0; i < list.length; i++) {
         // More something
       }
     }
    })
  3. As the above example shows, I prefer not to have a space between keywords like if and the parenthesis. But I do prefer to have a space before opening braces as well as between binary operators (so it's width = perimeter / shape.numSides and not width=perimeter/shape.numSides).
  4. Nested functions start on the same line, but have their closing brace on a new line (which continues as normal. This was illustrated above, where the nested function starts on the same line as the hide call and the closing brace is followed by the parenthesis that makes up the end of the hide call.
  5. 120 character line length. We don't need our code to be viewable in a tiny little console and we'd want to minimize wrapping lines. But if many of you are using small screens, a 100 character limit can also work (but that's as low as we should go).
  6. Wrapped lines are indented twice (ie, for 2 space indentation, wrapped lines are indented 4 spaces). Example:

    // Pretend we're wrapping at 60 chars
    def someLongFunction(someInt: Int, someChar: Char,
       somethingElse: ThingElse, somebody: Body) {
     // Do something
    }
  7. Don't wrap HTML. In my experience, indentation is really important for HTML, so that we can follow nesting. wrapping just confuses that. On the topic of indentation in HTML, not every element needs the contents to be indented. Just use whatever looks best. Example:

    <div class="modal-content">
     <div class="modal-header">
       <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
       <h4 class="modal-title">Modal title</h4>
     </div>
     <div class="modal-body">
       <p>One fine body&hellip;</p>
     </div>
     <div class="modal-footer">
       <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
       <button type="button" class="btn btn-primary">Save changes</button>
     </div>
    </div>

    This is an actual example from the Bootstrap documentation, by the way. As you can see, they also use 2 space indentation. Note how tags like the h4 button are all one line.

    In particular, note that sometimes it will be necessary to have tags on the same line to prevent unwanted spaces from appearing in the output.

  8. Scala methods should never throw exceptions. Return a Try instead. Note that all database access can throw an exception, so must be wrapped in a Try.
  9. Otherwise, do whatever the hell looks best. You're not morons who need to be micromanaged. Just try and style things in a fashion that is readable and somewhat consistent with existing code. For example, in the Application.scala file, I've implemented the JavaScript routing as:

    def javascriptRoutes = Action { implicit request =>
     import routes.javascript._
     Ok(
       Routes.javascriptRouter("jsRoutes")(
         LocationController.findLocation,
         LocationController.showLocation
       )
     ).as("text/javascript")
    }

    Note I usually have arguments on the same line as a function call, constructor etc (eg, foo(1, "abc")), but here I put the content indented inside the Ok, using the parenthesis akin to how braces are usually used. This is because the arguments are quite long here and makes it clear that the actual listed part is an argument to Routes.javascriptRouter("jsRoutes") and not to Ok.

  10. Document all CSS rules (by the way, the main CSS file is in public/stylesheets/main.css). CSS is rarely self documenting and it's difficult to tell where CSS rules are being used (much less their intent), so document that shit.
  11. Minimize in-line CSS (that is, CSS applied with the HTML style attribute). The style tag is useful for simple, single element styles, but anything else should go in the CSS file.
  12. For SQL, use ALL CAPS for keywords and lowercase for everything else. Example:

    CREATE TABLE inspection(
      id SERIAL NOT NULL,
      location_id INT NOT NULL,
      inspection_date DATE NOT NULL,
      inspection_type TEXT NOT NULL,
      reinspection_priority TEXT NOT NULL,
      PRIMARY KEY (id),
      FOREIGN KEY (location_id)
        REFERENCES location
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
    );
  13. When naming things in Scala, JS, CSS, etc, use camelcase. Treat acronyms like regular words. Examples: foo, isEmpty, xmlParser, httpJsonRequest. Class names, however, start with a capital letter (eg,Foo,XmlParser`, etc).
  14. The exception is SQL, since Postgres doesn't preserve case. We'll use snake case (underscores) there. Examples: is_empty, xml_parser, etc.
  15. Never use null in Scala. Use Option[SomeType] instead.
  16. In JS, use double quotes for strings. This is mostly for consistency, although one reason to use them is because single quotes within our strings is far more common than double quotes (so less escaping is required). Also, JSON requires the use of double quotes, which is another argument for consistency.
KatrinaHoffert commented 9 years ago

We discussed this in the meeting and accepted it.