Pascal wrote:
> Anyway, does anyone have a style guide they could share, or point me to one 
> in the wiki?


I can point you at:

  http://code.jsoftware.com/wiki/PersonalTaste 
<http://code.jsoftware.com/wiki/PersonalTaste>

and

  http://code.jsoftware.com/wiki/User:Dan_Bron/Style 
<http://code.jsoftware.com/wiki/User:Dan_Bron/Style>

and

  http://rosettacode.org/wiki/J/HouseStyle 
<http://rosettacode.org/wiki/J/HouseStyle>

But these were all created many years ago, and they’re all just initial 
braindumps: disorganized and far from comprehensive. They really never got past 
the “initial thoughts” phase (and mostly represent only my [Dan’s] initial 
thoughts, at that).

> Of course I could make my own rules, but I'd like to stay somewhat consistent 
> with whatever other people are doing.


I can tell you my personal guidelines, which are broadly consistent with what I 
see on the Forums and other places I find code in the wild:

> I'm talking about things like camelCase vs snake_case, verbs start with 
> capital letters etc etc.


  + Capitalization is primarily used to distinguish the parts of speech with 
visual hints:
    - Global nouns (particularly constants) are UPPERCASE
       o As a subclass of global nouns, for members of enums (fixed set of 
enumerated values), I often use ENUMNAME_MEMBERNAME (i.e. with underscores)

    - Verbs, having primacy in J and being the most common wordclass, are 
lowercase, or, when called for, camelCase with an initial lowercase letter.

    - Adverbs and conjunctions, being the remaining and least common wordclass, 
get the remaining distinguishable case: InitialUppercase (again, with CamelCase 
as needed)   

    - I tend to aim for purely tacit formulations, where I can get them, so I 
don’t use explicit code as much, but when I do, local nouns are simply 
lowercase.

Other considerations:

  + Code layout:
    - When writing large tacit verbs, I try to break them up into functional, 
digestible pieces (which individually are easy to analyze on sight, or with 
less than 2 minutes of review). 

    - This is made possible by J’s assumption that of as-yet-undefined names 
are verbs (which is a strong clue that that’s how J, i.e. Ken, expected you to 
do it).

    - I lay these pieces out in my script with indentation that reflects their 
calling tree, so that I can grok the high-level verb first, refining my 
understanding of the details as I progress down the script. 

    - Another benefit is, at any given level, the implementation details of 
that level are indented to the right, so if I’m not interested in those yet, I 
can simply scan down the file to the next entry at the same indentation level.

    - Typically, these intermediate names are ephemeral, meaning they are never 
called outside the scope of the enclosing function, so I assign them locally.

    - At the bottom/end of the top-level definition, I assign

    theVerb =: theVerb f.

    to remove the dependency on these intermediate, ephemeral names (otherwise, 
you’d get value errors invoking theVerb, because the definitions of its 
components would have gone out of scope).

  + Indentation
    - I indent tacit definitions with two space characters (32{a.), because it 
keeps the “paragraph” defining the top-level function compact and easy to 
distinguish as an atomic grouping. Also because tacit code, even when 
modularized, can lead to some very long lines already.
 
    - I indent explicit definitions with a single tab character (9{a.) because 
I find anything narrower makes it hard to pick out the lone ) which terminates 
that specific definition. 

       o One quibble I’ve always had with the Project Manager is that when it 
coalesces scripts, it removes this indentation, and so it makes it really hard 
to identify where one explicit definition ends and another begins, an issue 
exacerbated when the ultimate script has many sequential explicit definitions.

  + Naming
    - Is the hardest problem in computer science. I’d prefer a job doing cache 
invalidation any day.

    - That said, (J) verbs tend to be (English) verbs, (J) nouns tend to be 
(English) nouns, and operators tend to be ad-hoc (i.e. I have no rules yet).

  + Data
    - Inline (noun defines) to permit, to the extent possible, data-driven or 
table-driven code, with the minimum of overhead or redundancy. Data speaks for 
itself, and to the extent you can allow it to speak for your code, the better.

    - Sometimes a (noun define) at the bottom that either uses 0!:2 or a bunch 
of asserts as a kind of informal test script (turned off by default, but when 
turned on, tests correctness when the script is load’ed)

  + Comments
    - Large comment at the top of the script, laying out its purposes, usage, 
and caveats.

    - I also tend to make mention of any limitations imposed by the 
language/notation/implementation proper, so if/when the language evolves, I’ll 
be able to refactor or simplify my definitions accordingly.

    - About a paragraph of comments above every public (exported) name. Again, 
a sentence or two on motivations / purposes, and then examples of expected 
inputs and outputs, and caveats if any. I used to prefix executable examples 
with NB. EG: but I didn’t keep up the habit.

    - Large (noun define) at the bottom of the script walking through concrete 
examples (simulating or literal copy/paste of a live J session)    
   
Here’s an example of my indentation style and preference for data- or 
table-driven logic, from something I knocked together for a poster on the J 
forums in 2013 [1]:

NB.  Scoring tables
'GROUPS POINTS' =. <"_1 |: ".;._2 noun define
 5  ;  3 2 1                NB.  5 <= #riders <= 10
 11 ;  7 5 4 3 2 1          NB. 11 <= #riders <= 20 
 21 ;  8 6 5 4 3 2 1        NB. 21 <= #riders <= 49
 50 ; 10 8 7 6 5 4 3 2 1    NB. 50 or more #riders 
)

NB.  Logic
report             =:  tally/@:|:@:record
  tally            =.  ~.@[  sortStich catSumCount@;/.
    sortStich      =.  ,. /: ]
    catSumCount    =.  +/ (category ; ;) #
      category     =.  4 <. 1 + 35 30 20 I. (* 2&<:) 
  record           =.  [: ; (,: <"0@scores)~/&.|:&.>@:races 
    scores         =.  [: score 0 ". ;:^:_1
      score        =.  scorePlace pointGroup
        scorePlace =.  (0,]) {~ [ * (<: #)
        pointGroup =.  (0;POINTS) {::~ (<:;GROUPS) I. #
      races        =.  [: cutRaces LF , toJ@fread@jpath Pf 
        cutRaces   =.  <@:cutFields;.1~ (LF,'--') E. ]
          cutFields=.  0 1 }. RE (rxmatches rxfrom ])Pf ]

You’ll need the complete script, from [2], to actually get it to run.  There 
are more scripts in my SVN repository — of, I must warn you, wildly varying and 
inconsistent quality — illustrating the other considerations I’ve discussed 
here, in particular heavy commenting, automated testing, (noun defines), etc.

-Dan
    

[1] Scoring a road race in J, from “my programm looks terrible” in Oct 2013:
    http://www.jsoftware.com/pipermail/chat/2013-October/005364.html 
<http://www.jsoftware.com/pipermail/chat/2013-October/005364.html>

[2] The complete script which will allow you to run the above code, 
scoreRoadRace.ijs:
    http://jsoftware.com/svn/DanBron/trunk/uncategorized/scoreRoadRace.ijs 
<http://jsoftware.com/svn/DanBron/trunk/uncategorized/scoreRoadRace.ijs>

This script illustrates some, but not all, of the conventions I’ve expounded on 
here. If you remove the /uncategorized/scoreRoadRace.ijs suffix from the URL, 
you will be able to browse my larger code base. Most of the more mature scripts 
are in /environment, /general, and /uncategorized, but there’s really no good 
way to to tell what type of quality you’re dealing with just from the 
filenames, you’ll just have to poke around.


----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to