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
.
Best Answer
Yes and no. Functional programming is often more abstract, so it's not unusual to have names like
x
andxs
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.