FAQ

Some additional FAQs are answered here.

Do I need to end statements with semi-colons?

In Mitchell, as in Standard ML, semi-colons are optional at the end of declarations. They are required in only a few places.

Using the val _ = ... construct for statements at the top-level and in let expressions (even when a function is only called for its side-effect) is not optional.

How do I modify a variable in Mitchell?

In Mitchell, variables cannot be modified. If you assign to a variable more than once, the later declaration will shadow the earlier one. For example, the following

val x = "goodbye\n"

val _ = let
          val x = "hello\n"
        in
          print x
        end

val _ = print x

will print

hello
goodbye

Several kinds of values in Mitchell are mutable, however. For example, even though a variable that points to an array will always point to that array, the array itself can be changed (e.g., using Array.update).

When you need to have a value of an arbitrary type that you can modify, you can use refs. However, use of refs is discouraged. See this documentation for information on using refs.

Why does Mitchell say something is wrong at a spot in my code that looks fine?

Mitchell checks your code to make sure that you are using types of data in a consistent way. It reports errors where it finds a problem, but that isn’t always where the root cause of the problem is. Details on how to pin down a type error in your program can be found here.

How do I write tests in Mitchell?

There currently is no library to support unit testing in Mitchell. However, anything that you write at the top-level in your .sml file (e.g., val _ = print “hello”) will be executed when you run your program with run-mitchell. That can be used to implement tests manually as a workaround.

How do I generate random numbers in Mitchell?

See the Mitchell Random library.

How do I print values?

See the libraries for converting data to strings.

What Standard ML functions are available in Mitchell?

Everything in the Standard Basis Library is available. Some functions are available without prefixing with the module name. You can see the list of those functions here.

For the purpose of this evaluation, we have included Standard ML libraries that is not supported on the hardware accelerators. Therefore, while you may write arbitrary Standard ML code as a Mitchell program, we ask that you keep any IO you do separate from your core algorithm implementation. This will allow us to re-target the implementation to the hardware accelerator for performance evaluation.

How to write a library in Mitchell?

You can build a library using Standard ML modules. See How Mitchell Builds on Standard ML for more information on using Standard ML constructs within Mitchell, and see this reference for information on the Standard ML module system.

What is the difference between Mitchell and Standard ML?

Mitchell is currently Standard ML with the addition of new libraries for machine learning and graph analytic, and with the removal of functionality that is not supported on hardware accelerators.

See /usr/local/bin/run-mitchell for how Mitchell uses the MLton Standard ML compiler.

What does this compiler error mean?

See Reading Compiler Errors.

How do I get a value out of a pair or tuple?

There are two ways to use the invidivual values from a pair or tuple. One way is via pattern matching:

val pair = (42, "hello")
val (leftValue, rightValue) = pair
(* Now leftValue = 42 and rightValue = "hello" *)

The other way is to use the projection functions:

val pair = (42, "hello")
val leftValue = #1 pair
val rightValue = #2 pair
(* Now leftValue = 42 and rightValue = "hello" *)

Both ways extend to larger-sized tuples.

How do I get a value out of an array?

See the Array.sub function in the Standard Basis Library.

How do I get the inferred type of a specific variable?

The easiest way to find out what type a variable was inferred to be is to annotate it with the unit type and get the inferred type from the error message.

For example, compiling

val pair : unit = (42, 1.5)

Will produce the error

  Pattern and expression disagree.
    pattern:    [unit]
    expression: [int * real]
    in: val pair: unit = (42, 1.5)

where int * real is the inferred type of the variable.

How do I convert between numeric types?

For converting between int and real, see the Real.toInt and Real.fromInt functions from the Standard Basis Library.

Numeric types of specific size (e.g., Real32.real and Real64.real) can be converted between by converting to and from LargeReal.real (using Real<N>.toLarge and Real<N>.fromLarge) or LargeInt.int (using Int<N>.toLarge and Int<N>.fromLarge).

Similar functions are available for the word types.


Table of contents