Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

OCaml Module 9

Printing, polymorphic variants and objects interview questions

Interview questions on printing, polymorphic variants and objects: warm-ups, then what each harder question tests and how a good answer starts.

7 questions: 2 warm-ups and 5 with model answers · Levels: Fresher to staff

Warm-up questions

Short questions with short answers, each answered in full.

  1. Fresher to mid

    When would you reach for Format rather than Printf in OCaml?

    Answered in the lesson Printing with Printf and Format

  2. Fresher to mid

    In a polymorphic variant type that OCaml infers, what do the < of a closed row and the > of an open row each promise?

    The < marks a closed row: a value of that type carries at most the listed tags, so a function taking it, such as a match on the tags Green and Red with no wildcard, refuses any other tag at compile time. The > marks an open row: the value carries at least the listed tags and may carry more, like a lone tag or the argument of a match that ends in a wildcard. Both signs hide a row variable, so the type can still change as more uses are checked; a type with neither sign is exact.

    From the lesson Polymorphic variants

Questions with model answers

What each question tests, the first step of a good answer and the follow-ups to expect.

  1. Mid to senior

    A service logs with let debug fmt = if verbose then Printf.eprintf fmt else Printf.ifprintf stderr fmt. With verbose off, handlers that call debug "rows %d\n" (count_rows db) are still slow, although nothing is printed. Explain why, and design a debug helper whose disabled calls do almost no work.

    What it tests
    Knowing that OCaml evaluates arguments before a call, what ifprintf and ksprintf still do, how a closure or %t puts work off, and how to keep a wrapping helper polymorphic and type-checked.
    First step
    Count before you change anything: make count_rows increment a counter, run 1,000 debug calls with verbose off and read the counter. Then ask which part of debug "rows %d\n" (count_rows db) runs before debug itself is entered.
    Follow-ups

    From the lesson Printing with Printf and Format

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page.

    Opening the model answers with your pass…

    Model answers open with any MySmartCoPilot pass.

    • Pro pass · 1 week₹79$2.99
    • 30 days₹179$5.99
    • 1 year₹1,699$45

    One payment; nothing renews unless you choose to. The price shown is the total you pay: no fees or charges are added at checkout.

    It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 4 minutes
  2. Mid to senior

    Bills are printed with Printf.printf "%-20s|%8.2f\n" name amount. Rows whose item names are written in Hindi, such as मसाला डोसा, push the amount column out of line, while English names line up. Explain what the width 20 counts, and how you would line up UTF-8 names in OCaml 5.5.

    What it tests
    Knowing what a Printf width measures, how UTF-8 stores Devanagari and accented letters, how to count characters in OCaml, and where a character count still differs from the columns a terminal draws.
    First step
    Measure before you fix: print String.length of the Hindi name and of an English name that lines up, and compare both with the number of letters and marks you see on the screen.
    Follow-ups

    From the lesson Printing with Printf and Format

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 4 minutes
  3. Mid to senior

    A payments service has three modules, a ledger, a bank client and a fraud screen, and each .mli declares its own exact error type as polymorphic variant tags. Design the error type and the one handler that turns every failure into a message, and say what happens when a fourth module adds a tag.

    What it tests
    Joining exact polymorphic variant types into one union, converting each result with a coercion, and writing the handler without a wildcard so that warning 8 or a type error points at every new tag.
    First step
    Exact types cannot unify, so chaining the three results with let* fails. Declare the union once in the service, type error = [ Ledger.error | Bank.error | Fraud.error ], convert each module's result into it with :>, and give the handler the annotation error -> string, with one case per tag and no wildcard.
    Follow-ups

    From the lesson Polymorphic variants

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 5 minutes
  4. Fresher to mid

    A logging helper maps levels to names with a match on the tags Debug, Warn and Error that ends in a wildcard returning INFO. A call with the misspelt tag Eror compiled and logged a disk-full failure as INFO. Explain why the compiler accepted it, and change the code so that it refuses such typos.

    What it tests
    Reading the open row a wildcard gives, knowing that open rows unify by adding up their tags, and closing the type where callers meet it with an exact annotation.
    First step
    Read the type the toplevel prints for the helper: the wildcard gave its argument an open row, at least Debug, Warn and Error, so Eror is one more tag it accepts. Declare a level type with the four tags and annotate the public log function's argument with it; the misspelt call is then refused on the line where it is written.
    Follow-ups

    From the lesson Polymorphic variants

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 4 minutes
  5. Senior to staff

    Your service parses JSON with Yojson.Basic, whose type has seven tags, and a reporting library takes and returns Yojson.Safe.t, which adds one tag for integers too large for an OCaml int. How do you hand your values to the library, what does that cost, and how do you take its results back?

    What it tests
    Knowing that a coercion into a larger exact type returns the same value, recursion included, that the reverse needs a conversion, and deciding at the boundary what a large integer means.
    First step
    Every tag of Yojson.Basic.t is also a tag of Yojson.Safe.t with the same argument, so a coercion with :> converts a whole tree, and returns the very same value. The way back cannot be a coercion, because a Safe.t value may hold the extra tag Intlit: convert once at the boundary with Yojson.Safe.to_basic, or reject such values there.
    Follow-ups

    From the lesson Polymorphic variants

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 4 minutes

All OCaml interview questions · The OCaml track

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.