5

I am working on a compilers assignment in OCaml, and the following is an example of the pre-written code in said assignment:

(* Build a CFG and collection of global variable definitions from a stream *)
let cfg_of_stream (code:stream) : Ll.cfg * (Ll.gid * Ll.gdecl) list  =
    let gs, einsns, insns, term_opt, blks = List.fold_left
      (fun (gs, einsns, insns, term_opt, blks) e ->
        match e with
        | L l ->
           begin match term_opt with
           | None ->
              if (List.length insns) = 0 then (gs, einsns, [], None, blks)
              else failwith @@ Printf.sprintf "build_cfg: block labeled %s has\
                                               no terminator" l
           | Some term ->
              (gs, einsns, [], None, (l, {insns; term})::blks)
           end
        | T t  -> (gs, einsns, [], Some (Llutil.Parsing.gensym "tmn", t), blks)
        | I (uid,insn)  -> (gs, einsns, (uid,insn)::insns, term_opt, blks)
        | G (gid,gdecl) ->  ((gid,gdecl)::gs, einsns, insns, term_opt, blks)
        | E (uid,i) -> (gs, (uid, i)::einsns, insns, term_opt, blks)
      ) ([], [], [], None, []) code
    in
    match term_opt with
    | None -> failwith "build_cfg: entry block has no terminator"
    | Some term ->
       let insns = einsns @ insns in
       ({insns; term}, blks), gs

I find that the liberal use of extra-short identifiers (L l, gs, insns, etc.) makes this code very unreadable. Even the (fairly) short word blocks is contracted to blks.

Were I to write the same thing in C#, for instance, I would have no problems having 10+ character variable names, clearly spelt out every time.

Is this something peculiar to functional-first languages, and is this... normal? F# is almost the same language, but .NET namespaces and their contents are very long, so I see a bit of a disconnect here.

For the record, this phenomenon appears to be part of the OCaml standard library as well: consider hd for head and tl for tail.

SRSR333
  • 335

2 Answers2

7

The code probably makes reasonable sense, together with a glossary of abbreviations and a textbook on the subject, but clearly it cannot stand on its own.

I wouldn't ask what is normal for a particular language, I would ask what is normal for a particular context. Descriptive names are more valued in business programming than they are amongst academics, and different languages are themselves more common to each.

I'm not quite clear what explains that difference in culture. Perhaps it is because industrial programmers tend to encounter a wider variety of subjects and complex automations (which makes it difficult to keep the finest details of all things solely in your head for years on end), and it is more common for code to pass between two industrial programmers without the writer delivering a detailed course on the subject to the reader beforehand.

By contrast, academics and educators only deal with code in the context of delivering a course of study, or in the context of executing a study, where there will be verbal interactions between the people, there will be various written and graphical paraphernalia produced and made available, and there will be fewer subjects covered but investigated in more depth, and that perhaps allows a less thoughtful approach towards naming in the code itself.

Steve
  • 12,325
  • 2
  • 19
  • 35
5

Yes and no. Functional programming is often more abstract, so it's not unusual to have names like x and xs because there isn't really a better name at that level of abstraction.

However, there is also better and worse code depending on domain. Academic code in particular tends to not be written with maintainability in mind, because it's usually done in short snippets that doesn't need maintaining. In addition to the terse names in this example, the level of nesting and cramming everything into a 5-tuple would not typically pass a pull request in production code.

Karl Bielefeldt
  • 148,830