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 2

Expressions, values and functions interview questions

Interview questions on expressions, values and functions: warm-ups, then what each harder question tests and how a good answer starts.

17 questions: 6 warm-ups and 11 with model answers · Levels: Fresher to staff

Warm-up questions

Short questions with short answers, each answered in full.

  1. Fresher to mid

    What does shadowing mean in OCaml?

    Answered in the lesson Expressions, let bindings, if and scope

  2. Fresher to mid

    Why does 3 + 2.0 not compile in OCaml?

    Answered in the lesson Integers, floats and arithmetic

  3. Fresher to mid

    Why can "abc" == "abc" be false while "abc" = "abc" is true?

    Answered in the lesson Booleans, characters, strings and bytes

  4. Fresher to mid

    What is currying in OCaml, and what does it let you do?

    Answered in the lesson Functions, currying and the pipeline operator

  5. Fresher to mid

    What does a type such as 'a -> 'a mean, and who writes it?

    Answered in the lesson Type inference, polymorphism and type errors

  6. Fresher to mid

    What do ~ and ? mean in front of an OCaml argument?

    Answered in the lesson Labelled and optional arguments

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 helper is called as log (read_user ()) (read_amount ()), and both functions print a prompt. In the native build the amount prompt appears first. Why, and how would you make the order dependable on every compiler?

    What it tests
    Knowing that OCaml leaves the evaluation order of function arguments unspecified, and fixing an order with let … in instead of relying on what one compiler happens to do.
    First step
    Recall that the manual promises no order for the arguments of an application; OCaml 5.5.1 evaluated them right to left, both native and bytecode, so read_amount ran first. Then bind each call with its own let … in, in the order you need.
    Follow-ups

    From the lesson Expressions, let bindings, if and scope

    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; a pass never renews. 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 3 minutes
  2. Fresher to mid

    A line such as save record; flush () ran in the toplevel with only a warning, but dune build stops on it with Error (warning 10 [non-unit-statement]). save returns the number of bytes written. What does the error mean, and how would you fix it?

    What it tests
    Understanding that the left side of ; should be unit, that dune's development profile turns warnings into errors, and choosing between using the value and ignore.
    First step
    Read the warning: the expression on the left of ; returned a value that nobody uses, here the int from save. The toplevel only warns, but dune's default development profile makes warnings errors, so the build stops.
    Follow-ups

    From the lesson Expressions, let bindings, if and scope

    Model answer, Pro.

    In the answer:

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

    A tool adds up file sizes in bytes with plain ints. The native build is right, but the same code built with wasm_of_ocaml for a browser page shows a negative total once the files pass about one gigabyte. Explain what happens and what you would change.

    What it tests
    Knowing that int width depends on the target (63 bits native, 32 under js_of_ocaml, 31 under wasm_of_ocaml), that int arithmetic wraps silently, and choosing Int64 when the range matters.
    First step
    Print Sys.int_size and max_int in each build: native code gives 63 bits, wasm_of_ocaml 31 bits with max_int 1,073,741,823, about one gibibyte. A total above that wraps around to a negative number without any error.
    Follow-ups

    From the lesson Integers, floats and arithmetic

    Model answer, Pro.

    In the answer:

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

    You receive prices as strings, such as "120", "99" and "abc", and must return their average. Describe an OCaml function for it: how it parses, what it does with bad or empty input, and how it divides.

    What it tests
    Parsing with the _opt functions instead of exceptions, returning an option for empty or invalid input, and converting explicitly from int to float before dividing.
    First step
    Choose the result type first: float option, None when there is no valid price. Parse each string with int_of_string_opt, which returns None for "abc" instead of raising Failure, and decide whether one bad price rejects the whole list or is skipped.
    Follow-ups

    From the lesson Integers, floats and arithmetic

    Model answer, Pro.

    In the answer:

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

    A job builds a large CSV export by appending each row to a string with ^ inside a loop, and it slows down sharply as the export grows. Explain why, and how you would rewrite it.

    What it tests
    Knowing that strings are immutable, so each ^ copies both sides and the loop does quadratic work, and that Buffer appends in amortised constant time.
    First step
    Each ^ allocates a new string and copies everything built so far, because strings cannot change. Appending n rows therefore copies about n²/2 rows in total. A Buffer grows in place and copies only when it doubles its capacity.
    Follow-ups

    From the lesson Booleans, characters, strings and bytes

    Model answer, Pro.

    In the answer:

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

    A module defines let rate = 0.02 and let fee amount = amount *. rate. A colleague adds let rate = 0.03 further down the same file to raise the fee, but fee still charges 2 %. Explain why, and how you would make the rate changeable on purpose.

    What it tests
    Knowing that a closure keeps the bindings that existed when it was made, that a later let shadows instead of assigning, and choosing between a parameter, partial application and a ref.
    First step
    The second let made a new binding called rate; it did not change the first one. fee was defined while rate meant 0.02, and its closure keeps that binding, exactly as the lesson's tax kept the rate 18. after rate was bound to 5.
    Follow-ups

    From the lesson Functions, currying and the pipeline operator

    Model answer, Pro.

    In the answer:

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

    A teammate defines let ( @- ) a b = a - b to subtract money amounts, and a report computes 100 @- 30 @- 20 as 90 where everyone expected 50. What happened, and how would you choose and test the name of a custom operator?

    What it tests
    Knowing that an operator's first character puts it in a group of the manual's precedence table, which fixes its associativity, and testing a chain of three operands.
    First step
    Look up the group of operators that start with @ in the manual's table: it groups to the right, together with ^. So the expression means 100 @- (30 @- 20), which is 100 - 10 = 90.
    Follow-ups

    From the lesson Functions, currying and the pipeline operator

    Model answer, Pro.

    In the answer:

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

    A file defines let cache = ref [] at the top level. The same line worked in the toplevel, but ocamlc now refuses the file with an error about non-generalizable type variables. Explain the error and two ways to fix it.

    What it tests
    Understanding the value restriction and weak type variables, why a compiled module needs complete types, and fixing it with an annotation or by changing the definition.
    First step
    ref [] is the result of a function call, so its type variable is not generalised: it is '_weak1 list ref, one element type not known yet. The toplevel can wait for the first use to decide it, but a compiled module's interface must be complete, so ocamlc refuses it.
    Follow-ups

    From the lesson Type inference, polymorphism and type errors

    Model answer, Pro.

    In the answer:

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

    A colleague's build fails with "This expression has type int but an expression was expected of type float", underlining a recursive call that looks right. How would you find the real mistake, and how could the code keep such errors closer to their cause?

    What it tests
    Knowing that a type error is reported where two types first met, tracing the actual type back to the expression that fixed it, and using annotations to move the message to the cause.
    First step
    Ask where the int came from. The underlined call returns whatever the function returns, so look at the other branches: a base case written 0 instead of 0. fixes the result type to int before the recursive call is checked.
    Follow-ups

    From the lesson Type inference, polymorphism and type errors

    Model answer, Pro.

    In the answer:

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

    A helper is defined as let log ~msg ?(level = "info") = print_endline (level ^ ": " ^ msg). Calls such as log ~msg:"saved"; compile with warnings in the toplevel, but nothing is ever printed. What is wrong, and how do you fix the helper and its callers?

    What it tests
    Knowing that an optional argument is erased only when a later positional argument is applied, reading warnings 16 and 5, and adding a final unit parameter.
    First step
    Read the warning at the definition: warning 16, this optional argument cannot be erased. Nothing positional follows ?level, so log ~msg:"saved" is a partial application that returns a function waiting for ?level, and print_endline never runs.
    Follow-ups

    From the lesson Labelled and optional arguments

    Model answer, Pro.

    In the answer:

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

    Your library exports resize : int -> int -> image -> image, taking width and height, and users keep swapping the two numbers. You want labels, resize ~width ~height img, without breaking every caller on one day. How would you plan the change?

    What it tests
    Knowing what labels change in a type, which calls keep compiling (complete calls, with warning 6) and which break (partial applications, functions passed to higher-order functions), and planning a gradual migration.
    First step
    List how callers use resize today. A complete call, resize 640 480 img, still compiles after labels are added, with warning 6 for omitted labels, while partial applications such as resize 640 and uses passed to List.map break, because the type has changed.
    Follow-ups

    From the lesson Labelled and optional arguments

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 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.