Coding style and conventions #1767

Open
bjourne opened this Issue Dec 30, 2016 · 3 comments

Projects

None yet

3 participants

@bjourne
Member
bjourne commented Dec 30, 2016 edited

It occurred to me that we don't have a document detailing the coding conventions we use. So I though we can have a github issue where we discuss them and perhaps develop new ones. Here are some of the ones I think I've picked up:

Comments

  • // for C++ comments

Indentation

  • 4 spaces indent in factor code.
  • 2 spaces indent in C++ code.

Slot names

  • underlying for tuples that wrap something. Example: bit-array

Word names

  • <blah> for words that "construct" blah's.
  • >blah< for words that "explode" blah's.
  • blah? predicate words. Should always have stack effect ( something -- ? )
  • blah! mutates the container and returns it. Example map!
  • (blah) names a word that is a private helper word to a word named blah.
  • blah* has two meanings. The first one is "do what blah does, but less/differently" for example with-input-stream and with-input-stream*. The second meaning is for generic words that aren't meant to be called by the user. Example: user-input*.
  • +blah+ for symbols that signal stuff. Examples +input+, +output+ and +retry+.
  • blah-unsafe like blah, except it is unsafe meaning that it can crash Factor.
  • with-blah calls the quotation in a context binding blah somehow. The word ensures that stuff is restored afterwards. Example: with-destructors
  • >blah converts the stack input to a value of type blah.
  • blah>bleh either converts or maps a value of type blah to a bleh. Example vreg>reg.

Stack effects

  • ( ... - foo/f ) the word either returns a foo or f.
  • ( blah -- blah' ) the word takes a blah and returns a new blah which is a derivation of it. Example: quartile.
  • seq always means sequence.
  • elt element in a container.

C++ Names

  • snake_case for class names.
@jonenst
Contributor
jonenst commented Dec 30, 2016

There are some here http://docs.factorcode.org/content/article-conventions.html
It's only about factor though, not the vm.
I think there is another place where we that words can have any UTF-8 characters and this allows for great conventions, but I can't remember where.

@bjourne
Member
bjourne commented Dec 30, 2016

Ah, I should have known about that documentation page. Oh well, at least it doesn't contain all the conventions I listed.

@bjourne bjourne closed this Dec 30, 2016
@bjourne bjourne reopened this Dec 30, 2016
@AlexIljin
Contributor

For blah* I'd like to add two new notes:

  • the star can mark the inversion of an aspect of the word, e.g. head vs. head*, tail vs. tail*;
  • it can also mark an abstract method that inherited tuples can implement, e.g. draw-gadget*. It's a little bit different from "not supposed to be called by user code", but I may be wrong here. Maybe you really aren't supposed to call draw-gadget*, in which case ignore this remark.

Another interesting and potentially useful convention is the -1 suffix in relayout vs. relayout-1, which demarcates recursive vs. non-recursive application of the word. The same notion in other places is expressed with the deep- prefix (deep-map). Maybe that's something to unify (to settle on one variant: deep-relayout) or document (to encourage wider use of both).

I may also propose some conventions for words that do DB queries:

  • ...->*-... select all matching items from the database, e.g. birth-year->*-employee takes a birth-year from the stack top and load an array of employee tuples with the matching property. The result is always a sequence, which may be empty;
  • ...->1-... select one item from the database based on the stack top, e.g. id->1-employee will take an id from the stack and return a single employee tuple with the id. Will throw an error if no matching id is found;
  • ...->1/f-... select one item from the database based on the stack top, e.g. id->1/f-employee will take an id from the stack and return a single employee tuple with the id. If no matching id is found, it returns f;
  • (...)->1-... select one item from the database based on no stack input, e.g. (last-record)->1-id will return a single id, or throw if none present;
  • (...)->1/f-... same as before, but return f instead of throwing;
  • (...)->*-... return a sequence based on no stack input, e.g. (yesterday)->*-booking.

Note that in the last example I'm using singular "booking" instead of plural "bookings". The intention is to have the tuple name of the output verbatim. In all cases the left part is more of a description (not an exact type), and the right part is a type name of the output.

When id->1-employee is called with id = f, it should either return the first matching tuple or throw if none are available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment