.. default-domain:: chpl

.. module:: ChapelIO
   :synopsis: Basic types and utilities in support of I/O operation.

IO Support
==========


Basic types and utilities in support of I/O operation.
 
Most of Chapel's I/O support is within the :mod:`IO` module.  This section
describes automatically included basic types and routines that support the
:mod:`IO` module.
 
Writing and Reading
~~~~~~~~~~~~~~~~~~~

The :proc:`~IO.writeln` function allows for a simple implementation
of a Hello World program:

.. code-block:: chapel

 writeln("Hello, World!");
 // outputs
 // Hello, World!

The :proc:`~IO.read` functions allow one to read values into variables as
the following example demonstrates. It shows three ways to read values into
a pair of variables ``x`` and ``y``.

.. code-block:: chapel

  var x: int;
  var y: real;

  /* reading into variable expressions, returning
     true if the values were read, false on EOF */
  var ok:bool = read(x, y);

  /* reading via a single type argument */
  x = read(int);
  y = read(real);

  /* reading via multiple type arguments */
  (x, y) = read(int, real);

The readThis(), writeThis(), and readWriteThis() Methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

When programming the input and output method for a custom data type, it is
often useful to define both the read and write routines at the same time. That
is possible to do in a Chapel program by defining a ``readWriteThis`` method,
which is a generic method expecting a single :record:`~IO.channel` argument.

In cases when the reading routine and the writing routine are more naturally
separate, or in which only one should be defined, a Chapel program can define
``readThis`` (taking in a single argument - a readable channel) and/or
``writeThis`` (taking in a single argument - a writeable channel).

If none of these routines are provided, a default version of ``readThis`` and
``writeThis`` will be generated by the compiler. If ``readWriteThis`` is
defined, the compiler will generate ``readThis`` or ``writeThis`` methods - if
they do not already exist - which call ``readWriteThis``.

Note that arguments to ``readThis`` and ``writeThis`` may represent a locked
channel; as a result, calling methods on the channel in parallel from within a
``readThis``, ``writeThis``, or ``readWriteThis`` may cause undefined behavior.

Because it is often more convenient to use an operator for I/O, instead of
writing

.. code-block:: chapel

  f.readwrite(x);
  f.readwrite(y);

one can write

.. code-block:: chapel

  f <~> x <~> y;

Note that the types :type:`IO.ioLiteral` and :type:`IO.ioNewline` may be useful
when using the ``<~>`` operator. :type:`IO.ioLiteral` represents some string
that must be read or written as-is (e.g. ``","`` when working with a tuple),
and :type:`IO.ioNewline` will emit a newline when writing but skip to and
consume a newline when reading.


This example defines a readWriteThis method and demonstrates how ``<~>`` will
call the read or write routine, depending on the situation.

.. code-block:: chapel

  class IntPair {
    var x: int;
    var y: int;
    proc readWriteThis(f) {
      f <~> x <~> new ioLiteral(",") <~> y <~> new ioNewline();
    }
  }
  var ip = new IntPair(17,2);
  write(ip);
  // prints out
  // 17,2

  delete ip;

This example defines a only a writeThis method - so that there will be a
function resolution error if the class NoRead is read.

.. code-block:: chapel

  class NoRead {
    var x: int;
    var y: int;
    proc writeThis(f) {
      f.writeln("hello");
    }
    // Note that no readThis function will be generated.
  }
  var nr = new NoRead();
  write(nr);
  // prints out
  // hello

  // Note that read(nr) will generate a compiler error.

  delete nr;

.. _default-write-and-read-methods:

Default write and read Methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Default ``write`` methods are created for all types for which a user-defined
``write`` method is not provided.  They have the following semantics:

* for an array argument: outputs the elements of the array in row-major order
  where rows are separated by line-feeds and blank lines are used to separate
  other dimensions.
* for a `domain` argument: outputs the dimensions of the domain enclosed by
  ``[`` and ``]``.
* for a `range` argument: output the lower bound of the range, output ``..``,
  then output the upper bound of the range.  If the stride of the range
  is not ``1``, output the word ``by`` and then the stride of the range.
* for a tuples, outputs the components of the tuple in order delimited by ``(``
  and ``)``, and separated by commas.
* for a class: outputs the values within the fields of the class prefixed by
  the name of the field and the character ``=``.  Each field is separated by a
  comma.  The output is delimited by ``{`` and ``}``.
* for a record: outputs the values within the fields of the class prefixed by
  the name of the field and the character ``=``.  Each field is separated by a
  comma.  The output is delimited by ``(`` and ``)``.

Default ``read`` methods are created for all types for which a user-defined
``read`` method is not provided.  The default ``read`` methods are defined to
read in the output of the default ``write`` method.

.. note::

  Note that it is not currently possible to read and write circular
  data structures with these mechanisms.

 

.. function:: proc halt()

   
   Prints an error message to stderr giving the location of the call to
   ``halt`` in the Chapel source, followed by the arguments to the call,
   if any, then exits the program.
   

.. function:: proc halt(s: string)

   
   Prints an error message to stderr giving the location of the call to
   ``halt`` in the Chapel source, followed by the arguments to the call,
   if any, then exits the program.
   

.. function:: proc halt(args ...?numArgs)

   
   Prints an error message to stderr giving the location of the call to
   ``halt`` in the Chapel source, followed by the arguments to the call,
   if any, then exits the program.
   

.. function:: proc warning(s: string)

   
   Prints a warning to stderr giving the location of the call to ``warning``
   in the Chapel source, followed by the argument(s) to the call.
   

.. function:: proc warning(args ...?numArgs)

   
   Prints a warning to stderr giving the location of the call to ``warning``
   in the Chapel source, followed by the argument(s) to the call.
   

