diff --git a/doc/manual/calling-c-and-fortran-code.rst b/doc/manual/calling-c-and-fortran-code.rst index 597c518bd55f8..2691c6cb85762 100644 --- a/doc/manual/calling-c-and-fortran-code.rst +++ b/doc/manual/calling-c-and-fortran-code.rst @@ -1,5 +1,7 @@ .. _man-calling-c-and-fortran-code: +.. currentmodule:: Base + **************************** Calling C and Fortran Code **************************** @@ -11,7 +13,7 @@ and efficient to call C and Fortran functions. Julia has a "no boilerplate" philosophy: functions can be called directly from Julia without any "glue" code, code generation, or compilation — even from the interactive prompt. This is accomplished just by making an appropriate call -with ``ccall`` syntax, which looks like an ordinary function call. +with :func:`ccall` syntax, which looks like an ordinary function call. The code to be called must be available as a shared library. Most C and Fortran libraries ship compiled as shared libraries already, but if you @@ -38,10 +40,10 @@ the current process. This form can be used to call C library functions, functions in the Julia runtime, or functions in an application linked to Julia. -Finally, you can use ``ccall`` to actually generate a call to the -library function. Arguments to ``ccall`` are as follows: +Finally, you can use :func:`ccall` to actually generate a call to the +library function. Arguments to :func:`ccall` are as follows: -1. (:function, "library") pair (must be a constant, but see below). +1. ``(:function, "library")`` pair (must be a constant, but see below). 2. Return type, which may be any bits type, including ``Int32``, ``Int64``, ``Float64``, or ``Ptr{T}`` for any type parameter ``T``, indicating a pointer to values of type ``T``, or ``Ptr{Void}`` for @@ -86,7 +88,7 @@ rather than ``(Ptr{Uint8})``. This is because ``(Ptr{Uint8})`` is just (Ptr{Uint8},) In practice, especially when providing reusable functionality, one -generally wraps ``ccall`` uses in Julia functions that set up arguments +generally wraps :func:`ccall` uses in Julia functions that set up arguments and then check for errors in whatever manner the C or Fortran function indicates them, propagating to the Julia caller as exceptions. This is especially important since C and Fortran APIs are notoriously @@ -164,9 +166,9 @@ a real address operator, it may be used with any syntax, such as ``&0`` or ``&f(x)``. Note that no C header files are used anywhere in the process. Currently, -it is not possible to pass structs and other non-primitive types from +it is not possible to pass ``struct``\ s and other non-primitive types from Julia to C libraries. However, C functions that generate and use opaque -struct types by passing pointers to them can return such values +``struct`` types by passing pointers to them can return such values to Julia as ``Ptr{Void}``, which can then be passed to other C functions as ``Ptr{Void}``. Memory allocation and deallocation of such objects must be handled by calls to the appropriate cleanup routines in the @@ -175,7 +177,7 @@ libraries being used, just like in any C program. Mapping C Types to Julia ------------------------ -Julia automatically inserts calls to the ``convert`` function to convert +Julia automatically inserts calls to the :func:`convert` function to convert each argument to the specified type. For example, the following call:: ccall( (:foo, "libfoo"), Void, (Int32, Float64), @@ -198,7 +200,7 @@ array matches ``T``, and the address of the first element is passed. This is done in order to avoid copying arrays unnecessarily. Therefore, if an ``Array`` contains data in the wrong format, it will -have to be explicitly converted using a call such as ``int32(a)``. +have to be explicitly converted using a call such as :func:`int32(A) `. To pass an array ``A`` as a pointer of a different type *without* converting the data beforehand (for example, to pass a ``Float64`` array @@ -212,7 +214,9 @@ Type correspondences On all systems we currently support, basic C/C++ value types may be translated to Julia types as follows. Every C type also has a corresponding -Julia type with the same name, prefixed by C. This can help for writing portable code (and remembering that an int in C is not the same as an Int in Julia). +Julia type with the same name, prefixed by C. This can help for writing +portable code (and remembering that an ``int`` in C is not the same as an +``Int`` in Julia). **System-independent:** @@ -300,11 +304,11 @@ can be called via the following Julia code:: For ``wchar_t*`` arguments, the Julia type should be ``Ptr{Wchar_t}``, and data can be converted to/from ordinary Julia strings by the -``wstring(s)`` function (equivalent to either ``utf16(s)`` or ``utf32(s)`` -depending upon the width of ``Cwchar_t``. Note also that ASCII, UTF-8, -UTF-16, and UTF-32 string data in Julia is internally NUL-terminated, so -it can be passed to C functions expecting NUL-terminated data without making -a copy. +:func:`wstring(s) ` function (equivalent to either :func:`utf16(s) +` or :func:`utf32(s) ` depending upon the width of ``Cwchar_t``. +Note also that ASCII, UTF-8, UTF-16, and UTF-32 string data in Julia is +internally NUL-terminated, so it can be passed to C functions expecting +NUL-terminated data without making a copy. Accessing Data through a Pointer -------------------------------- @@ -313,9 +317,10 @@ to terminate abruptly or corrupt arbitrary process memory due to a bad pointer or type declaration. Given a ``Ptr{T}``, the contents of type ``T`` can generally be copied from -the referenced memory into a Julia object using ``unsafe_load(ptr, [index])``. The -index argument is optional (default is 1), and performs 1-based indexing. This -function is intentionally similar to the behavior of ``getindex()`` and ``setindex!()`` +the referenced memory into a Julia object using :func:`unsafe_load(ptr, +[index]) `. The index argument is optional (default is 1), and +performs 1-based indexing. This function is intentionally similar to the +behavior of :func:`getindex` and :func:`setindex!` (e.g. ``[]`` access syntax). The return value will be a new object initialized @@ -330,21 +335,23 @@ count, but the new reference does) to ensure the memory is not prematurely freed Note that if the object was not originally allocated by Julia, the new object will never be finalized by Julia's garbage collector. If the ``Ptr`` itself is actually a ``jl_value_t*``, it can be converted back to a Julia object -reference by ``unsafe_pointer_to_objref(ptr)``. (Julia values ``v`` -can be converted to ``jl_value_t*`` pointers, as ``Ptr{Void}``, by calling -``pointer_from_objref(v)``.) +reference by :func:`unsafe_pointer_to_objref(ptr) `. +(Julia values ``v`` can be converted to ``jl_value_t*`` pointers, as +``Ptr{Void}``, by calling :func:`pointer_from_objref(v) +`.) -The reverse operation (writing data to a Ptr{T}), can be performed using -``unsafe_store!(ptr, value, [index])``. Currently, this is only supported -for bitstypes or other pointer-free (``isbits``) immutable types. +The reverse operation (writing data to a ``Ptr{T}``), can be performed using +:func:`unsafe_store!(ptr, value, [index]) `. Currently, this is +only supported for bitstypes or other pointer-free (:func:`isbits `) +immutable types. Any operation that throws an error is probably currently unimplemented and should be posted as a bug so that it can be resolved. If the pointer of interest is a plain-data array (bitstype or immutable), the -function ``pointer_to_array(ptr,dims,[own])`` may be more useful. The final +function :func:`pointer_to_array(ptr,dims,[own]) ` may be more useful. The final parameter should be true if Julia should "take ownership" of the underlying -buffer and call ``free(ptr)`` when the returned ``Array`` object is finalized. +buffer and call :func:`free(ptr) ` when the returned ``Array`` object is finalized. If the ``own`` parameter is omitted or false, the caller must ensure the buffer remains in existence until all access is complete. @@ -359,8 +366,8 @@ Passing Pointers for Modifying Inputs Because C doesn't support multiple return values, often C functions will take pointers to data that the function will modify. To accomplish this within a -``ccall`` you need to encapsulate the value inside an array of the appropriate -type. When you pass the array as an argument with a ``Ptr`` type, julia will +:func:`ccall` you need to encapsulate the value inside an array of the appropriate +type. When you pass the array as an argument with a ``Ptr`` type, Julia will automatically pass a C pointer to the encapsulated data:: width = Cint[0] @@ -372,11 +379,11 @@ is passed to LAPACK by reference, and on return, includes the success code. Garbage Collection Safety ------------------------- -When passing data to a ccall, it is best to avoid using the ``pointer()`` +When passing data to :func:`ccall`, it is best to avoid using the :func:`pointer` function. Instead define a convert method and pass the variables directly to -the ccall. ccall automatically arranges that all of its arguments will be +the :func:`ccall`. :func:`ccall` automatically arranges that all of its arguments will be preserved from garbage collection until the call returns. If a C API will -store a reference to memory allocated by Julia, after the ccall returns, you +store a reference to memory allocated by Julia, after the :func:`ccall` returns, you must arrange that the object remains visible to the garbage collector. The suggested way to handle this is to make a global variable of type ``Array{Any,1}`` to hold these values, until C interface notifies you that @@ -384,9 +391,9 @@ it is finished with them. Whenever you have created a pointer to Julia data, you must ensure the original data exists until you are done with using the pointer. Many methods in Julia such as -``unsafe_load()`` and ``bytestring()`` make copies of data instead of taking ownership +:func:`unsafe_load` and :func:`bytestring` make copies of data instead of taking ownership of the buffer, so that it is safe to free (or alter) the original data without -affecting Julia. A notable exception is ``pointer_to_array()`` which, for performance +affecting Julia. A notable exception is :func:`pointer_to_array` which, for performance reasons, shares (or can be told to take ownership of) the underlying buffer. The garbage collector does not guarantee any order of finalization. That is, if ``a`` @@ -401,35 +408,36 @@ Non-constant Function Specifications A ``(name, library)`` function specification must be a constant expression. However, it is possible to use computed values as function names by staging -through ``eval`` as follows:: +through :func:`eval` as follows:: @eval ccall(($(string("a","b")),"lib"), ... -This expression constructs a name using ``string``, then substitutes this -name into a new ``ccall`` expression, which is then evaluated. Keep in mind that -``eval`` only operates at the top level, so within this expression local +This expression constructs a name using :func:`string`, then substitutes this +name into a new :func:`ccall` expression, which is then evaluated. Keep in mind that +:func:`eval` only operates at the top level, so within this expression local variables will not be available (unless their values are substituted with -``$``). For this reason, ``eval`` is typically only used to form top-level +``$``). For this reason, :func:`eval` is typically only used to form top-level definitions, for example when wrapping libraries that contain many similar functions. Indirect Calls -------------- -The first argument to ``ccall`` can also be an expression evaluated at +The first argument to :func:`ccall` can also be an expression evaluated at run time. In this case, the expression must evaluate to a ``Ptr``, which will be used as the address of the native function to call. This -behavior occurs when the first ``ccall`` argument contains references +behavior occurs when the first :func:`ccall` argument contains references to non-constants, such as local variables or function arguments. Calling Convention ------------------ -The second argument to ``ccall`` can optionally be a calling convention +The second argument to :func:`ccall` can optionally be a calling convention specifier (immediately preceding return type). Without any specifier, the platform-default C calling convention is used. Other supported conventions are: ``stdcall``, ``cdecl``, ``fastcall``, and ``thiscall``. -For example (from base/libc.jl):: +For example (from +`libc.jl `_:: hn = Array(Uint8, 256) err=ccall(:gethostname, stdcall, Int32, (Ptr{Uint8}, Uint32), hn, length(hn)) @@ -442,15 +450,15 @@ Accessing Global Variables -------------------------- Global variables exported by native libraries can be accessed by name using the -``cglobal`` function. The arguments to ``cglobal`` are a symbol specification -identical to that used by ``ccall``, and a type describing the value stored in +:func:`cglobal` function. The arguments to :func:`cglobal` are a symbol specification +identical to that used by :func:`ccall`, and a type describing the value stored in the variable:: julia> cglobal((:errno,:libc), Int32) Ptr{Int32} @0x00007f418d0816b8 The result is a pointer giving the address of the value. The value can be -manipulated through this pointer using ``unsafe_load`` and ``unsafe_store``. +manipulated through this pointer using :func:`unsafe_load` and :func:`unsafe_store`. Passing Julia Callback Functions to C ------------------------------------- @@ -478,14 +486,14 @@ some arbitrary type T:: end Notice that we have to be careful about the return type: ``qsort`` expects a function -returning a C ``int``, so we must be sure to return ``Cint`` via a call to ``convert``. +returning a C ``int``, so we must be sure to return ``Cint`` via a call to :func:`convert`. In order to pass this function to C, we obtain its address using the function -``cfunction``:: +:func:`cfunction`:: const mycompare_c = cfunction(mycompare, Cint, (Ptr{Cdouble}, Ptr{Cdouble})) -``cfunction`` accepts three arguments: the Julia function (``mycompare``), the return +:func:`cfunction` accepts three arguments: the Julia function (``mycompare``), the return type (``Cint``), and a tuple of the argument types, in this case to sort an array of ``Cdouble`` (Float64) elements. @@ -515,7 +523,7 @@ triggered, which you'll probably just ignore) to ``SingleAsyncWork``:: cb = Base.SingleAsyncWork(data -> my_real_callback(args)) -The callback you pass to C should only execute a ``ccall`` to +The callback you pass to C should only execute a :func:`ccall` to ``:uv_async_send``, passing ``cb.handle`` as the argument. More About Callbacks @@ -534,11 +542,12 @@ Handling Platform Variations ---------------------------- When dealing with platform libraries, it is often necessary to provide special cases -for various platforms. The variable ``OS_NAME`` can be used to write these special +for various platforms. The variable :data:`OS_NAME` can be used to write these special cases. Additionally, there are several macros intended to make this easier: -``@windows``, ``@unix``, ``@linux``, and ``@osx``. Note that linux and osx are mutually -exclusive subsets of unix. Their usage takes the form of a ternary conditional -operator, as demonstrated in the following examples. +:func:`@windows`, :func:`@unix`, :func:`@linux`, and :func:`@osx`. Note that +:func:`@linux` and :func:`@osx` are mutually exclusive subsets of +:func:`@unix`. Their usage takes the form of a ternary conditional operator, +as demonstrated in the following examples. Simple blocks:: diff --git a/doc/manual/complex-and-rational-numbers.rst b/doc/manual/complex-and-rational-numbers.rst index 370852b380861..1aa9a0cf9f751 100644 --- a/doc/manual/complex-and-rational-numbers.rst +++ b/doc/manual/complex-and-rational-numbers.rst @@ -1,5 +1,7 @@ .. _man-complex-and-rational-numbers: +.. currentmodule:: Base + ****************************** Complex and Rational Numbers ****************************** @@ -122,10 +124,10 @@ Standard functions to manipulate complex values are provided: julia> angle(1 + 2im) 1.1071487177940904 -As usual, the absolute value (``abs``) of a complex number is its -distance from zero. The ``abs2`` function gives the square of the +As usual, the absolute value (:func:`abs`) of a complex number is its +distance from zero. The :func:`abs2` function gives the square of the absolute value, and is of particular use for complex numbers where it -avoids taking a square root. The ``angle`` function returns the phase +avoids taking a square root. The :func:`angle` function returns the phase angle in radians (also known as the *argument* or *arg* function). The full gamut of other :ref:`man-elementary-functions` is also defined for complex numbers: @@ -149,7 +151,7 @@ for complex numbers: Note that mathematical functions typically return real values when applied to real numbers and complex values when applied to complex numbers. -For example, ``sqrt`` behaves differently when applied to ``-1`` +For example, :func:`sqrt` behaves differently when applied to ``-1`` versus ``-1 + 0im`` even though ``-1 == -1 + 0im``: .. doctest:: @@ -172,7 +174,7 @@ multiplication must be explicitly written out: julia> a = 1; b = 2; a + b*im 1 + 2im -However, this is *not* recommended; Use the ``complex`` function instead to +However, this is *not* recommended; Use the :func:`complex` function instead to construct a complex value directly from its real and imaginary parts.: .. doctest:: @@ -182,7 +184,7 @@ construct a complex value directly from its real and imaginary parts.: This construction avoids the multiplication and addition operations. -``Inf`` and ``NaN`` propagate through complex numbers in the real +:data:`Inf` and :data:`NaN` propagate through complex numbers in the real and imaginary parts of a complex number as described in the :ref:`man-special-floats` section: @@ -200,7 +202,7 @@ Rational Numbers ---------------- Julia has a rational number type to represent exact ratios of integers. -Rationals are constructed using the ``//`` operator: +Rationals are constructed using the :func:`// ` operator: .. doctest:: @@ -227,7 +229,7 @@ are reduced to lowest terms such that the denominator is non-negative: This normalized form for a ratio of integers is unique, so equality of rational values can be tested by checking for equality of the numerator and denominator. The standardized numerator and denominator of a -rational value can be extracted using the ``num`` and ``den`` functions: +rational value can be extracted using the :func:`num` and :func:`den` functions: .. doctest:: @@ -296,7 +298,7 @@ Constructing infinite rational values is acceptable: julia> typeof(ans) Rational{Int64} (constructor with 1 method) -Trying to construct a ``NaN`` rational value, however, is not: +Trying to construct a :data:`NaN` rational value, however, is not: .. doctest:: diff --git a/doc/manual/constructors.rst b/doc/manual/constructors.rst index b73918343ce9b..e3e1b2b0a48da 100644 --- a/doc/manual/constructors.rst +++ b/doc/manual/constructors.rst @@ -1,5 +1,7 @@ .. _man-constructors: +.. currentmodule:: Base + ************** Constructors ************** @@ -427,7 +429,7 @@ the following outer method definition to make all calls to the general julia> Point(x::Real, y::Real) = Point(promote(x,y)...); -The ``promote`` function converts all its arguments to a common type +The :func:`promote` function converts all its arguments to a common type — in this case ``Float64``. With this method definition, the ``Point`` constructor promotes its arguments the same way that numeric operators like ``+`` do, and works for all kinds of real numbers: @@ -518,17 +520,17 @@ turns integer values into rationals by supplying a value of ``1`` as the denominator. Following the outer constructor definitions, we have a number of methods -for the ``//`` operator, which provides a syntax for writing rationals. -Before these definitions, ``//`` is a completely undefined operator with +for the :func:`// ` operator, which provides a syntax for writing rationals. +Before these definitions, :func:`// ` is a completely undefined operator with only syntax and no meaning. Afterwards, it behaves just as described in :ref:`man-rational-numbers` — its entire behavior is defined in these few lines. The first and most basic definition just makes ``a//b`` construct a ``Rational`` by applying the ``Rational`` constructor to ``a`` and ``b`` when they are -integers. When one of the operands of ``//`` is already a rational +integers. When one of the operands of :func:`// ` is already a rational number, we construct a new rational for the resulting ratio slightly differently; this behavior is actually identical to division of a -rational with an integer. Finally, applying ``//`` to complex integral +rational with an integer. Finally, applying :func:`// ` to complex integral values creates an instance of ``Complex{Rational}`` — a complex number whose real and imaginary parts are rationals: @@ -543,7 +545,7 @@ whose real and imaginary parts are rationals: julia> ans <: Complex{Rational} false -Thus, although the ``//`` operator usually returns an instance of +Thus, although the :func:`// ` operator usually returns an instance of ``Rational``, if either of its arguments are complex integers, it will return an instance of ``Complex{Rational}`` instead. The interested reader should consider perusing the rest of diff --git a/doc/manual/control-flow.rst b/doc/manual/control-flow.rst index 593b29608d078..0a38ce9c8ae22 100644 --- a/doc/manual/control-flow.rst +++ b/doc/manual/control-flow.rst @@ -1,5 +1,7 @@ .. _man-control-flow: +.. currentmodule:: Base + ************** Control Flow ************** @@ -13,8 +15,8 @@ Julia provides a variety of control flow constructs: ``&&``, ``||`` and chained comparisons. - :ref:`man-loops`: ``while`` and ``for``. - :ref:`man-exception-handling`: - ``try``-``catch``, ``error`` and ``throw``. -- :ref:`man-tasks`: ``yieldto``. + ``try``-``catch``, :func:`error` and :func:`throw`. +- :ref:`man-tasks`: :func:`yieldto`. The first five control flow mechanisms are standard to high-level programming languages. Tasks are not so standard: they provide non-local @@ -309,7 +311,7 @@ For example, a recursive factorial routine could be defined like this: Boolean operations *without* short-circuit evaluation can be done with the bitwise boolean operators introduced in :ref:`man-mathematical-operations`: -``&`` and ``|``. These are normal functions, which happen to support +:func:`& <&>` and :func:`| <|>`. These are normal functions, which happen to support infix operator syntax, but always evaluate their arguments: .. doctest:: @@ -579,7 +581,7 @@ built-in ``Exception``\ s listed below all interrupt the normal flow of control. | ``UndefVarError`` | +------------------------+ -For example, the ``sqrt`` function throws a ``DomainError()`` if applied to a +For example, the :func:`sqrt` function throws a ``DomainError()`` if applied to a negative real value: .. doctest:: @@ -596,11 +598,11 @@ You may define your own exceptions in the following way: julia> type MyCustomException <: Exception end -The ``throw`` function -~~~~~~~~~~~~~~~~~~~~~~ +The :func:`throw` function +~~~~~~~~~~~~~~~~~~~~~~~~~~ -Exceptions can be created explicitly with ``throw``. For example, a function -defined only for nonnegative numbers could be written to ``throw`` a ``DomainError`` +Exceptions can be created explicitly with :func:`throw`. For example, a function +defined only for nonnegative numbers could be written to :func:`throw` a ``DomainError`` if the argument is negative: .. doctest:: @@ -647,12 +649,12 @@ the way ``UndefVarError`` is written: Errors ~~~~~~ -The ``error`` function is used to produce an ``ErrorException`` that +The :func:`error` function is used to produce an ``ErrorException`` that interrupts the normal flow of control. Suppose we want to stop execution immediately if the square root of a negative number is taken. To do this, we can define a fussy version of -the ``sqrt`` function that raises an error if its argument is negative: +the :func:`sqrt` function that raises an error if its argument is negative: .. doctest:: @@ -791,7 +793,7 @@ The power of the ``try/catch`` construct lies in the ability to unwind a deeply nested computation immediately to a much higher level in the stack of calling functions. There are situations where no error has occurred, but the ability to unwind the stack and pass a value to a higher level is desirable. Julia -provides the ``rethrow``, ``backtrace`` and ``catch_backtrace`` functions for +provides the :func:`rethrow`, :func:`backtrace` and :func:`catch_backtrace` functions for more advanced error handling. finally Clauses @@ -814,7 +816,7 @@ For example, here is how we can guarantee that an opened file is closed:: end When control leaves the ``try`` block (for example due to a ``return``, or -just finishing normally), ``close(f)`` will be executed. If +just finishing normally), :func:`close(f) ` will be executed. If the ``try`` block exits due to an exception, the exception will continue propagating. A ``catch`` block may be combined with ``try`` and ``finally`` as well. In this case the ``finally`` block will run after ``catch`` has @@ -831,8 +833,8 @@ called by other names, such as symmetric coroutines, lightweight threads, cooperative multitasking, or one-shot continuations. When a piece of computing work (in practice, executing a particular -function) is designated as a ``Task``, it becomes possible to interrupt -it by switching to another ``Task``. The original ``Task`` can later be +function) is designated as a :data:`Task`, it becomes possible to interrupt +it by switching to another :data:`Task`. The original :data:`Task` can later be resumed, at which point it will pick up right where it left off. At first, this may seem similar to a function call. However there are two key differences. First, switching tasks does not use any space, so any @@ -852,8 +854,8 @@ producer may have more values to generate and so might not yet be ready to return. With tasks, the producer and consumer can both run as long as they need to, passing values back and forth as necessary. -Julia provides the functions ``produce`` and ``consume`` for solving -this problem. A producer is a function that calls ``produce`` on each +Julia provides the functions :func:`produce` and :func:`consume` for solving +this problem. A producer is a function that calls :func:`produce` on each value it needs to produce: .. doctest:: @@ -866,8 +868,8 @@ value it needs to produce: produce("stop") end; -To consume values, first the producer is wrapped in a ``Task``, -then ``consume`` is called repeatedly on that object: +To consume values, first the producer is wrapped in a :data:`Task`, +then :func:`consume` is called repeatedly on that object: .. doctest:: @@ -892,10 +894,10 @@ then ``consume`` is called repeatedly on that object: "stop" One way to think of this behavior is that ``producer`` was able to -return multiple times. Between calls to ``produce``, the producer's +return multiple times. Between calls to :func:`produce`, the producer's execution is suspended and the consumer has control. -A Task can be used as an iterable object in a ``for`` loop, in which +A :data:`Task` can be used as an iterable object in a ``for`` loop, in which case the loop variable takes on all the produced values: .. doctest:: @@ -910,7 +912,7 @@ case the loop variable takes on all the produced values: 8 stop -Note that the ``Task()`` constructor expects a 0-argument function. A +Note that the :func:`Task` constructor expects a 0-argument function. A common pattern is for the producer to be parameterized, in which case a partial function application is needed to create a 0-argument :ref:`anonymous function `. This can be done either @@ -924,35 +926,35 @@ directly or by use of a convenience macro:: # or, equivalently taskHdl = @task mytask(7) -``produce`` and ``consume`` do not launch threads that can run on separate CPUs. +:func:`produce` and :func:`consume` do not launch threads that can run on separate CPUs. True kernel threads are discussed under the topic of :ref:`man-parallel-computing`. Core task operations ~~~~~~~~~~~~~~~~~~~~ -While ``produce`` and ``consume`` illustrate the essential nature of tasks, they +While :func:`produce` and :func:`consume` illustrate the essential nature of tasks, they are actually implemented as library functions using a more primitive function, -``yieldto``. ``yieldto(task,value)`` suspends the current task, switches -to the specified ``task``, and causes that task's last ``yieldto`` call to return -the specified ``value``. Notice that ``yieldto`` is the only operation required +:func:`yieldto`. ``yieldto(task,value)`` suspends the current task, switches +to the specified ``task``, and causes that task's last :func:`yieldto` call to return +the specified ``value``. Notice that :func:`yieldto` is the only operation required to use task-style control flow; instead of calling and returning we are always just switching to a different task. This is why this feature is also called "symmetric coroutines"; each task is switched to and from using the same mechanism. -``yieldto`` is powerful, but most uses of tasks do not invoke it directly. +:func:`yieldto` is powerful, but most uses of tasks do not invoke it directly. Consider why this might be. If you switch away from the current task, you will probably want to switch back to it at some point, but knowing when to switch back, and knowing which task has the responsibility of switching back, can -require considerable coordination. For example, ``produce`` needs to maintain +require considerable coordination. For example, :func:`produce` needs to maintain some state to remember who the consumer is. Not needing to manually keep track -of the consuming task is what makes ``produce`` easier to use than ``yieldto``. +of the consuming task is what makes :func:`produce` easier to use than :func:`yieldto`. -In addition to ``yieldto``, a few other basic functions are needed to use tasks +In addition to :func:`yieldto`, a few other basic functions are needed to use tasks effectively. -``current_task()`` gets a reference to the currently-running task. -``istaskdone(t)`` queries whether a task has exited. -``istaskstarted(t)`` queries whether a task has run yet. -``task_local_storage`` manipulates a key-value store specific to the current task. +:func:`current_task` gets a reference to the currently-running task. +:func:`istaskdone(t) ` queries whether a task has exited. +:func:`istaskstarted(t) ` queries whether a task has run yet. +:func:`task_local_storage` manipulates a key-value store specific to the current task. Tasks and events ~~~~~~~~~~~~~~~~ @@ -962,27 +964,27 @@ requests, and are performed by a scheduler included in the standard library. The scheduler maintains a queue of runnable tasks, and executes an event loop that restarts tasks based on external events such as message arrival. -The basic function for waiting for an event is ``wait``. Several objects -implement ``wait``; for example, given a ``Process`` object, ``wait`` will -wait for it to exit. ``wait`` is often implicit; for example, a ``wait`` -can happen inside a call to ``read`` to wait for data to be available. +The basic function for waiting for an event is :func:`wait`. Several objects +implement :func:`wait`; for example, given a ``Process`` object, :func:`wait` will +wait for it to exit. :func:`wait` is often implicit; for example, a :func:`wait` +can happen inside a call to :func:`read` to wait for data to be available. -In all of these cases, ``wait`` ultimately operates on a ``Condition`` +In all of these cases, :func:`wait` ultimately operates on a :data:`Condition` object, which is in charge of queueing and restarting tasks. When a task -calls ``wait`` on a ``Condition``, the task is marked as non-runnable, added +calls :func:`wait` on a :data:`Condition`, the task is marked as non-runnable, added to the condition's queue, and switches to the scheduler. The scheduler will then pick another task to run, or block waiting for external events. -If all goes well, eventually an event handler will call ``notify`` on the +If all goes well, eventually an event handler will call :func:`notify` on the condition, which causes tasks waiting for that condition to become runnable again. -A task created explicitly by calling ``Task`` is initially not known to the -scheduler. This allows you to manage tasks manually using ``yieldto`` if +A task created explicitly by calling :data:`Task` is initially not known to the +scheduler. This allows you to manage tasks manually using :func:`yieldto` if you wish. However, when such a task waits for an event, it still gets restarted automatically when the event happens, as you would expect. It is also possible to make the scheduler run a task whenever it can, without necessarily -waiting for any events. This is done by calling ``schedule(task)``, or using -the ``@schedule`` or ``@async`` macros (see :ref:`man-parallel-computing` for +waiting for any events. This is done by calling :func:`schedule(task) `, or using +the :func:`@schedule` or :func:`@async` macros (see :ref:`man-parallel-computing` for more details). Task states diff --git a/doc/manual/conversion-and-promotion.rst b/doc/manual/conversion-and-promotion.rst index 9b58d9efb11e3..82960baa0e670 100644 --- a/doc/manual/conversion-and-promotion.rst +++ b/doc/manual/conversion-and-promotion.rst @@ -1,5 +1,7 @@ .. _man-conversion-and-promotion: +.. currentmodule:: Base + ************************** Conversion and Promotion ************************** @@ -63,8 +65,8 @@ defining what types they should promote to when mixed with other types. Conversion ---------- -Conversion of values to various types is performed by the ``convert`` -function. The ``convert`` function generally takes two arguments: the +Conversion of values to various types is performed by the :func:`convert` +function. The :func:`convert` function generally takes two arguments: the first is a type object while the second is a value to convert to that type; the returned value is the value converted to an instance of given type. The simplest way to understand this function is to see it in @@ -91,7 +93,7 @@ action: Float64 Conversion isn't always possible, in which case a no method error is -thrown indicating that ``convert`` doesn't know how to perform the +thrown indicating that :func:`convert` doesn't know how to perform the requested conversion: .. doctest:: @@ -109,7 +111,7 @@ representations of numbers, and only a very limited subset of them are. Defining New Conversions ~~~~~~~~~~~~~~~~~~~~~~~~ -To define a new conversion, simply provide a new method for ``convert``. +To define a new conversion, simply provide a new method for :func:`convert`. That's really all there is to it. For example, the method to convert a number to a boolean is simply this:: @@ -145,8 +147,8 @@ to zero: The method signatures for conversion methods are often quite a bit more involved than this example, especially for parametric types. The example -above is meant to be pedagogical, and is not the actual julia behaviour. -This is the actual implementation in julia:: +above is meant to be pedagogical, and is not the actual Julia behavior. +This is the actual implementation in Julia:: convert{T<:Real}(::Type{T}, z::Complex) = (imag(z)==0 ? convert(T,real(z)) : throw(InexactError())) @@ -187,7 +189,7 @@ right after the declaration of the type and its constructors:: convert{T<:FloatingPoint}(::Type{T}, x::Rational) = convert(T,x.num)/convert(T,x.den) convert{T<:Integer}(::Type{T}, x::Rational) = div(convert(T,x.num),convert(T,x.den)) -The initial four convert methods provide conversions to rational types. +The initial four :func:`convert` methods provide conversions to rational types. The first method converts one type of rational to another type of rational by converting the numerator and denominator to the appropriate integer type. The second method does the same conversion for integers by @@ -200,7 +202,7 @@ one should have ``a//b == convert(Rational{Int64}, a/b)``. The last two convert methods provide conversions from rational types to floating-point and integer types. To convert to floating point, one simply converts both numerator and denominator to that floating point -type and then divides. To convert to integer, one can use the ``div`` +type and then divides. To convert to integer, one can use the :func:`div` operator for truncated integer division (rounded towards zero). .. _man-promotion: @@ -221,7 +223,7 @@ everything to do with converting between alternate representations. For instance, although every ``Int32`` value can also be represented as a ``Float64`` value, ``Int32`` is not a subtype of ``Float64``. -Promotion to a common supertype is performed in Julia by the ``promote`` +Promotion to a common supertype is performed in Julia by the :func:`promote` function, which takes any number of arguments, and returns a tuple of the same number of values, converted to a common type, or throws an exception if promotion is not possible. The most common use case for @@ -276,8 +278,8 @@ promotion to a common numeric type for arithmetic operations — it just happens automatically. There are definitions of catch-all promotion methods for a number of other arithmetic and mathematical functions in `promotion.jl `_, -but beyond that, there are hardly any calls to ``promote`` required in -the Julia standard library. The most common usages of ``promote`` occur +but beyond that, there are hardly any calls to :func:`promote` required in +the Julia standard library. The most common usages of :func:`promote` occur in outer constructors methods, provided for convenience, to allow constructor calls with mixed types to delegate to an inner type with fields promoted to an appropriate common type. For example, recall that @@ -304,12 +306,12 @@ convenient to do promotion automatically. Defining Promotion Rules ~~~~~~~~~~~~~~~~~~~~~~~~ -Although one could, in principle, define methods for the ``promote`` +Although one could, in principle, define methods for the :func:`promote` function directly, this would require many redundant definitions for all possible permutations of argument types. Instead, the behavior of -``promote`` is defined in terms of an auxiliary function called -``promote_rule``, which one can provide methods for. The -``promote_rule`` function takes a pair of type objects and returns +:func:`promote` is defined in terms of an auxiliary function called +:func:`promote_rule`, which one can provide methods for. The +:func:`promote_rule` function takes a pair of type objects and returns another type object, such that instances of the argument types will be promoted to the returned type. Thus, by defining the rule:: @@ -329,21 +331,21 @@ order to avoid overflow. In the latter case, the result type is integers for arbitrary-precision integer arithmetic. Also note that one does not need to define both ``promote_rule(::Type{A}, ::Type{B})`` and ``promote_rule(::Type{B}, ::Type{A})`` — the symmetry is implied by -the way ``promote_rule`` is used in the promotion process. +the way :func:`promote_rule` is used in the promotion process. -The ``promote_rule`` function is used as a building block to define a -second function called ``promote_type``, which, given any number of type +The :func:`promote_rule` function is used as a building block to define a +second function called :func:`promote_type`, which, given any number of type objects, returns the common type to which those values, as arguments to -``promote`` should be promoted. Thus, if one wants to know, in absence +:func:`promote` should be promoted. Thus, if one wants to know, in absence of actual values, what type a collection of values of certain types -would promote to, one can use ``promote_type``: +would promote to, one can use :func:`promote_type`: .. doctest:: julia> promote_type(Int8, Uint16) Int64 -Internally, ``promote_type`` is used inside of ``promote`` to determine +Internally, :func:`promote_type` is used inside of :func:`promote` to determine what type argument values should be converted to for promotion. It can, however, be useful in its own right. The curious reader can read the code in diff --git a/doc/manual/dates.rst b/doc/manual/dates.rst index 451d2ce76bece..813e99a45913f 100644 --- a/doc/manual/dates.rst +++ b/doc/manual/dates.rst @@ -1,249 +1,276 @@ .. _man-dates: +.. currentmodule:: Dates + ************************************* - Date and DateTime + Date and DateTime ************************************* -The ``Dates`` module provides two types for working with dates: ``Date`` and ``DateTime``, representing day and millisecond precision, respectively; both are subtypes of the abstract ``TimeType``. The motivation for distinct types is simple: some operations are much simpler, both in terms of code and mental reasoning, when the complexities of greater precision don't have to be dealt with. For example, since the ``Date`` type only resolves to the precision of a single date (i.e. no hours, minutes, or seconds), normal considerations for time zones, daylight savings/summer time, and leap seconds are unnecessary and avoided. +The :mod:`Dates` module provides two types for working with dates: :data:`Date` and :data:`DateTime`, representing day and millisecond precision, respectively; both are subtypes of the abstract :data:`TimeType`. The motivation for distinct types is simple: some operations are much simpler, both in terms of code and mental reasoning, when the complexities of greater precision don't have to be dealt with. For example, since the :data:`Date` type only resolves to the precision of a single date (i.e. no hours, minutes, or seconds), normal considerations for time zones, daylight savings/summer time, and leap seconds are unnecessary and avoided. -Both ``Date`` and ``DateTime`` are basically immutable ``Int64`` wrappers. The single ``instant`` field of either type is actually a ``UTInstant{P}`` type, which represents a continuously increasing machine timeline based on the UT second [1]_. The ``DateTime`` type is *timezone-unaware* (in Python parlance) or is analogous to a *LocalDateTime* in Java 8. Additional time zone functionality can be added through the `Timezones.jl package `_, which compiles the `Olsen Time Zone Database `_. Both ``Date`` and ``DateTime`` are based on the ISO 8601 standard, which follows the proleptic Gregorian calendar. One note is that the ISO 8601 standard is particular about BC/BCE dates. In general, the last day of the BC/BCE era, 1-12-31 BC/BCE, was followed by 1-1-1 AD/CE, thus no year zero exists. The ISO standard, however, states that 1 BC/BCE is year zero, so ``0000-12-31`` is the day before ``0001-01-01``, and year ``-0001`` (yes, negative one for the year) is 2 BC/BCE, year ``-0002`` is 3 BC/BCE, etc. +Both :data:`Date` and :data:`DateTime` are basically immutable ``Int64`` wrappers. The single ``instant`` field of either type is actually a :data:`UTInstant{P} ` type, which represents a continuously increasing machine timeline based on the UT second [1]_. The :data:`DateTime` type is *timezone-unaware* (in Python parlance) or is analogous to a *LocalDateTime* in Java 8. Additional time zone functionality can be added through the `Timezones.jl package `_, which compiles the `Olsen Time Zone Database `_. Both :data:`Date` and :data:`DateTime` are based on the ISO 8601 standard, which follows the proleptic Gregorian calendar. One note is that the ISO 8601 standard is particular about BC/BCE dates. In general, the last day of the BC/BCE era, 1-12-31 BC/BCE, was followed by 1-1-1 AD/CE, thus no year zero exists. The ISO standard, however, states that 1 BC/BCE is year zero, so ``0000-12-31`` is the day before ``0001-01-01``, and year ``-0001`` (yes, negative one for the year) is 2 BC/BCE, year ``-0002`` is 3 BC/BCE, etc. -.. [1] The notion of the UT second is actually quite fundamental. There are basically two different notions of time generally accepted, one based on the physical rotation of the earth (one full rotation = 1 day), the other based on the SI second (a fixed, constant value). These are radically different! Think about it, a "UT second", as defined relative to the rotation of the earth, may have a different absolute length depending on the day! Anyway, the fact that ``Date`` and ``DateTime`` are based on UT seconds is a simplifying, yet honest assumption so that things like leap seconds and all their complexity can be avoided. This basis of time is formally called `UT `_ or UT1. Basing types on the UT second basically means that every minute has 60 seconds and every day has 24 hours and leads to more natural calculations when working with calendar dates. +.. [1] The notion of the UT second is actually quite fundamental. There are basically two different notions of time generally accepted, one based on the physical rotation of the earth (one full rotation = 1 day), the other based on the SI second (a fixed, constant value). These are radically different! Think about it, a "UT second", as defined relative to the rotation of the earth, may have a different absolute length depending on the day! Anyway, the fact that :data:`Date` and :data:`DateTime` are based on UT seconds is a simplifying, yet honest assumption so that things like leap seconds and all their complexity can be avoided. This basis of time is formally called `UT `_ or UT1. Basing types on the UT second basically means that every minute has 60 seconds and every day has 24 hours and leads to more natural calculations when working with calendar dates. Constructors ------------ -``Date`` and ``DateTime`` types can be constructed by integer or ``Period`` types, by parsing, or through adjusters (more on those later):: +:data:`Date` and :data:`DateTime` types can be constructed by integer or :data:`Period` types, by parsing, or through adjusters (more on those later) + +.. doctest:: - julia> DateTime(2013) - 2013-01-01T00:00:00 + julia> DateTime(2013) + 2013-01-01T00:00:00 - julia> DateTime(2013,7) - 2013-07-01T00:00:00 + julia> DateTime(2013,7) + 2013-07-01T00:00:00 - julia> DateTime(2013,7,1) - 2013-07-01T00:00:00 + julia> DateTime(2013,7,1) + 2013-07-01T00:00:00 - julia> DateTime(2013,7,1,12) - 2013-07-01T12:00:00 + julia> DateTime(2013,7,1,12) + 2013-07-01T12:00:00 - julia> DateTime(2013,7,1,12,30) - 2013-07-01T12:30:00 + julia> DateTime(2013,7,1,12,30) + 2013-07-01T12:30:00 - julia> DateTime(2013,7,1,12,30,59) - 2013-07-01T12:30:59 + julia> DateTime(2013,7,1,12,30,59) + 2013-07-01T12:30:59 - julia> DateTime(2013,7,1,12,30,59,1) - 2013-07-01T12:30:59.001 + julia> DateTime(2013,7,1,12,30,59,1) + 2013-07-01T12:30:59.001 - julia> Date(2013) - 2013-01-01 + julia> Date(2013) + 2013-01-01 - julia> Date(2013,7) - 2013-07-01 + julia> Date(2013,7) + 2013-07-01 - julia> Date(2013,7,1) - 2013-07-01 + julia> Date(2013,7,1) + 2013-07-01 - julia> Date(Dates.Year(2013),Dates.Month(7),Dates.Day(1)) - 2013-07-01 + julia> Date(Dates.Year(2013),Dates.Month(7),Dates.Day(1)) + 2013-07-01 - julia> Date(Dates.Month(7),Dates.Year(2013)) - 2013-07-01 + julia> Date(Dates.Month(7),Dates.Year(2013)) + 2013-07-01 -``Date`` or ``DateTime`` parsing is accomplished by the use of format strings. Format strings work by the notion of defining *delimited* or *fixed-width* "slots" that contain a period to parse and pass to a ``Date`` or ``DateTime`` constructor. +:data:`Date` or :data:`DateTime` parsing is accomplished by the use of format strings. Format strings work by the notion of defining *delimited* or *fixed-width* "slots" that contain a period to parse and pass to a :data:`Date` or :data:`DateTime` constructor. -Delimited slots are marked by specifying the delimiter the parser should expect between two subsequent periods; so ``"y-m-d"`` lets the parser know that between the first and second slots in a date string like ``"2014-07-16"``, it should find the ``-`` character. The ``y``, ``m``, and ``d`` characters let the parser know which periods to parse in each slot. +Delimited slots are marked by specifying the delimiter the parser should expect between two subsequent periods; so ``"y-m-d"`` lets the parser know that between the first and second slots in a date string like ``"2014-07-16"``, it should find the ``-`` character. The ``y``, ``m``, and ``d`` characters let the parser know which periods to parse in each slot. -Fixed-width slots are specified by repeating the period character the number of times corresponding to the width. So ``"yyyymmdd"`` would correspond to a date string like ``"20140716"``. The parser distinguishes a fixed-width slot by the absence of a delimiter, noting the transition ``"yyyymm"`` from one period character to the next. +Fixed-width slots are specified by repeating the period character the number of times corresponding to the width. So ``"yyyymmdd"`` would correspond to a date string like ``"20140716"``. The parser distinguishes a fixed-width slot by the absence of a delimiter, noting the transition ``"yyyymm"`` from one period character to the next. -Support for text-form month parsing is also supported through the ``u`` and ``U`` characters, for abbreviated and full-length month names, respectively. By default, only English month names are supported, so ``u`` corresponds to "Jan", "Feb", "Mar", etc. And ``U`` corresponds to "January", "February", "March", etc. Similar to other name=>value mapping functions ``dayname`` and ``monthname``, custom locales can be loaded by passing in the ``locale=>Dict{UTF8String,Int}`` mapping to the ``Dates.MONTHTOVALUEABBR`` and ``Dates.MONTHTOVALUE`` dicts for abbreviated and full-name month names, respectively. +Support for text-form month parsing is also supported through the ``u`` and ``U`` characters, for abbreviated and full-length month names, respectively. By default, only English month names are supported, so ``u`` corresponds to "Jan", "Feb", "Mar", etc. And ``U`` corresponds to "January", "February", "March", etc. Similar to other name=>value mapping functions :func:`dayname` and :func:`monthname`, custom locales can be loaded by passing in the ``locale=>Dict{UTF8String,Int}`` mapping to the ``Dates.MONTHTOVALUEABBR`` and ``Dates.MONTHTOVALUE`` dicts for abbreviated and full-name month names, respectively. A full suite of parsing and formatting tests and examples is available in `tests/dates/io.jl `_. Durations/Comparisons --------------------- -Finding the length of time between two ``Date`` or ``DateTime`` is straightforward given their underlying representation as ``UTInstant{Day}`` and ``UTInstant{Millisecond}``, respectively. The difference between ``Date`` is returned in the number of ``Day``, and ``DateTime`` in the number of ``Millisecond``. Similarly, comparing ``TimeType`` is a simple matter of comparing the underlying machine instants (which in turn compares the internal ``Int64`` values). +Finding the length of time between two :data:`Date` or :data:`DateTime` is straightforward given their underlying representation as ``UTInstant{Day}`` and ``UTInstant{Millisecond}``, respectively. The difference between :data:`Date` is returned in the number of :data:`Day`, and :data:`DateTime` in the number of :data:`Millisecond`\ s. Similarly, comparing :data:`TimeType` is a simple matter of comparing the underlying machine instants (which in turn compares the internal ``Int64`` values). -:: +.. doctest:: - julia> dt = Date(2012,2,29) - 2012-02-29 + julia> dt = Date(2012,2,29) + 2012-02-29 - julia> dt2 = Date(2000,2,1) - 2000-02-01 + julia> dt2 = Date(2000,2,1) + 2000-02-01 - julia> dump(dt) - Date - instant: UTInstant{Day} - periods: Day - value: Int64 734562 + julia> dump(dt) + Date + instant: UTInstant{Day} + periods: Day + value: Int64 734562 - julia> dump(dt2) - Date - instant: UTInstant{Day} - periods: Day - value: Int64 730151 + julia> dump(dt2) + Date + instant: UTInstant{Day} + periods: Day + value: Int64 730151 - julia> dt > dt2 - true + julia> dt > dt2 + true - julia> dt != dt2 - true + julia> dt != dt2 + true - julia> dt + dt2 - Operation not defined for TimeTypes + julia> dt + dt2 + ERROR: ArgumentError("Operation not defined for TimeTypes") + in + at dates/arithmetic.jl:10 - julia> dt * dt2 - Operation not defined for TimeTypes + julia> dt * dt2 + ERROR: ArgumentError("Operation not defined for TimeTypes") + in * at dates/arithmetic.jl:10 - julia> dt / dt2 - Operation not defined for TimeTypes + julia> dt / dt2 + ERROR: ArgumentError("Operation not defined for TimeTypes") + in / at dates/arithmetic.jl:10 - julia> dt - dt2 - 4411 days + julia> dt - dt2 + 4411 days - julia> dt2 - dt - -4411 days + julia> dt2 - dt + -4411 days - julia> dt = DateTime(2012,2,29) - 2012-02-29T00:00:00 + julia> dt = DateTime(2012,2,29) + 2012-02-29T00:00:00 - julia> dt2 = DateTime(2000,2,1) - 2000-02-01T00:00:00 + julia> dt2 = DateTime(2000,2,1) + 2000-02-01T00:00:00 - julia> dt - dt2 - 381110402000 milliseconds + julia> dt - dt2 + 381110400000 milliseconds Accessor Functions ------------------ -Because the `Date` and `DateTime` types are stored as single ``Int64`` values, date parts or fields can be retrieved through accessor functions. The lowercase accessors return the field as an integer:: +Because the :data:`Date` and :data:`DateTime` types are stored as single ``Int64`` values, date parts or fields can be retrieved through accessor functions. The lowercase accessors return the field as an integer: + +.. doctest:: + + julia> t = Date(2014,1,31) + 2014-01-31 + + julia> Dates.year(t) + 2014 + + julia> Dates.month(t) + 1 - julia> t = Date(2014,1,31) - 2014-01-31 + julia> Dates.week(t) + 5 - julia> Dates.year(t) - 2014 + julia> Dates.day(t) + 31 - julia> Dates.month(t) - 1 +While propercase accessors return the same value in the corresponding :data:`Period` type: - julia> Dates.week(t) - 5 +.. doctest:: - julia> Dates.day(t) - 31 + julia> Dates.Year(t) + 2014 years -While propercase return the same value in the corresponding ``Period`` type:: + julia> Dates.Day(t) + 31 days - julia> Dates.Year(t) - 2014 years +Compound methods are provided, as they provide a measure of efficiency if multiple fields are needed at the same time: - julia> Dates.Day(t) - 31 days +.. doctest:: -Compound methods are provided, as they provide a measure of efficiency if multiple fields are needed at the same time:: + julia> Dates.yearmonth(t) + (2014,1) - julia> Dates.yearmonth(t) - (2014,1) + julia> Dates.monthday(t) + (1,31) - julia> Dates.monthday(t) - (1,31) + julia> Dates.yearmonthday(t) + (2014,1,31) - julia> Dates.yearmonthday(t) - (2014,1,31) +One may also access the underlying :data:`UTInstant` or integer value: -One may also access the underlying ``UTInstant`` or integer value:: +.. doctest:: - julia> dump(t) - Date - instant: UTInstant{Day} - periods: Day - value: Int64 735264 + julia> dump(t) + Date + instant: UTInstant{Day} + periods: Day + value: Int64 735264 - julia> t.instant - UTInstant{Day}(735264 days) + julia> t.instant + UTInstant{Day}(735264 days) - julia> Dates.value(t) - 735264 + julia> Dates.value(t) + 735264 Query Functions --------------- -Query functions provide calendrical information about a ``TimeType``. They include information about the day of the week:: +Query functions provide calendrical information about a :data:`TimeType`. They include information about the day of the week: - julia> t = Date(2014,1,31) - 2014-01-31 +.. doctest:: - julia> Dates.dayofweek(t) - 5 + julia> t = Date(2014,1,31) + 2014-01-31 - julia> Dates.dayname(t) - "Friday" + julia> Dates.dayofweek(t) + 5 - julia> Dates.dayofweekofmonth(t) - 5 # 5th Friday of January + julia> Dates.dayname(t) + "Friday" -Month of the year:: + julia> Dates.dayofweekofmonth(t) # 5th Friday of January + 5 - julia> Dates.monthname(t) - "January" +Month of the year: - julia> Dates.daysinmonth(t) - 31 +.. doctest:: -As well as information about the ``TimeType``'s year and quarter:: + julia> Dates.monthname(t) + "January" - julia> Dates.isleapyear(t) - false + julia> Dates.daysinmonth(t) + 31 - julia> Dates.dayofyear(t) - 31 +As well as information about the :data:`TimeType`\ 's year and quarter: - julia> Dates.quarterofyear(t) - 1 +.. doctest:: - julia> Dates.dayofquarter(t) - 31 + julia> Dates.isleapyear(t) + false -The ``dayname`` and ``monthname`` methods can also take an optional ``locale`` keyword that can be used to return the name of the day or month of the year for other languages/locales:: + julia> Dates.dayofyear(t) + 31 - julia> const french_daysofweek = Dict(1=>"Lundi",2=>"Mardi",3=>"Mercredi",4=>"Jeudi",5=>"Vendredi",6=>"Samedi",7=>"Dimanche"); + julia> Dates.quarterofyear(t) + 1 - # Load the mapping into the Dates module under locale name "french" - julia> Dates.VALUETODAYOFWEEK["french"] = french_daysofweek; + julia> Dates.dayofquarter(t) + 31 - julia> Dates.dayname(t;locale="french") - "Vendredi" +The :func:`dayname` and :func:`monthname` methods can also take an optional ``locale`` keyword that can be used to return the name of the day or month of the year for other languages/locales: -Similarly for the ``monthname`` function, a mapping of ``locale=>Dict{Int,UTF8String}`` should be loaded in ``Dates.VALUETOMONTH``. +.. doctest:: + + julia> const french_daysofweek = Dict(1=>"Lundi",2=>"Mardi",3=>"Mercredi",4=>"Jeudi",5=>"Vendredi",6=>"Samedi",7=>"Dimanche"); + + # Load the mapping into the Dates module under locale name "french" + julia> Dates.VALUETODAYOFWEEK["french"] = french_daysofweek; + + julia> Dates.dayname(t;locale="french") + "Vendredi" + +Similarly for the :func:`monthname` function, a mapping of ``locale=>Dict{Int,UTF8String}`` should be loaded in ``Dates.VALUETOMONTH``. TimeType-Period Arithmetic -------------------------- It's good practice when using any language/date framework to be familiar with how date-period arithmetic is handled as there are some `tricky issues `_ to deal with (though much less so for day-precision types). -The ``Dates`` module approach tries to follow the simple principle of trying to change as little as possible when doing ``Period`` arithmetic. This approach is also often known as *calendrical* arithmetic or what you would probably guess if someone were to ask you the same calculation in a conversation. Why all the fuss about this? Let's take a classic example: add 1 month to January 31st, 2014. What's the answer? Javascript will say `March 3 `_ (assumes 31 days). PHP says `March 2 `_ (assumes 30 days). The fact is, there is no right answer. In the ``Dates`` module, it gives the result of February 28th. How does it figure that out? I like to think of the classic 7-7-7 gambling game in casinos. +The :mod:`Dates` module approach tries to follow the simple principle of trying to change as little as possible when doing :data:`Period` arithmetic. This approach is also often known as *calendrical* arithmetic or what you would probably guess if someone were to ask you the same calculation in a conversation. Why all the fuss about this? Let's take a classic example: add 1 month to January 31st, 2014. What's the answer? Javascript will say `March 3 `_ (assumes 31 days). PHP says `March 2 `_ (assumes 30 days). The fact is, there is no right answer. In the :mod:`Dates` module, it gives the result of February 28th. How does it figure that out? I like to think of the classic 7-7-7 gambling game in casinos. + +Now just imagine that instead of 7-7-7, the slots are Year-Month-Day, or in our example, 2014-01-31. When you ask to add 1 month to this date, the month slot is incremented, so now we have 2014-02-31. Then the day number is checked if it is greater than the last valid day of the new month; if it is (as in the case above), the day number is adjusted down to the last valid day (28). What are the ramifications with this approach? Go ahead and add another month to our date, ``2014-02-28 + Month(1) == 2014-03-28``. What? Were you expecting the last day of March? Nope, sorry, remember the 7-7-7 slots. As few slots as possible are going to change, so we first increment the month slot by 1, 2014-03-28, and boom, we're done because that's a valid date. On the other hand, if we were to add 2 months to our original date, 2014-01-31, then we end up with 2014-03-31, as expected. The other ramification of this approach is a loss in associativity when a specific ordering is forced (i.e. adding things in different orders results in different outcomes). For example: + +.. doctest:: -Now just imagine that instead of 7-7-7, the slots are Year-Month-Day, or in our example, 2014-01-31. When you ask to add 1 month to this date, the month slot is incremented, so now we have 2014-02-31. Then the day number is checked if it is greater than the last valid day of the new month; if it is (as in the case above), the day number is adjusted down to the last valid day (28). What are the ramifications with this approach? Go ahead and add another month to our date, ``2014-02-28 + Month(1) == 2014-03-28``. What? Were you expecting the last day of March? Nope, sorry, remember the 7-7-7 slots. As few slots as possible are going to change, so we first increment the month slot by 1, 2014-03-28, and boom, we're done because that's a valid date. On the other hand, if we were to add 2 months to our original date, 2014-01-31, then we end up with 2014-03-31, as expected. The other ramification of this approach is a loss in associativity when a specific ordering is forced (i.e. adding things in different orders results in different outcomes). For example:: + julia> (Date(2014,1,29)+Dates.Day(1)) + Dates.Month(1) + 2014-02-28 - julia> (Date(2014,1,29)+Dates.Day(1)) + Dates.Month(1) - 2014-02-28 + julia> (Date(2014,1,29)+Dates.Month(1)) + Dates.Day(1) + 2014-03-01 - julia> (Date(2014,1,29)+Dates.Month(1)) + Dates.Day(1) - 2014-03-01 +What's going on there? In the first line, we're adding 1 day to January 29th, which results in 2014-01-30; then we add 1 month, so we get 2014-02-30, which then adjusts down to 2014-02-28. In the second example, we add 1 month *first*, where we get 2014-02-29, which adjusts down to 2014-02-28, and *then* add 1 day, which results in 2014-03-01. One design principle that helps in this case is that, in the presence of multiple Periods, the operations will be ordered by the Periods' *types*, not their value or positional order; this means ``Year`` will always be added first, then ``Month``, then ``Week``, etc. Hence the following *does* result in associativity and Just Works: -What's going on there? In the first line, we're adding 1 day to January 29th, which results in 2014-01-30; then we add 1 month, so we get 2014-02-30, which then adjusts down to 2014-02-28. In the second example, we add 1 month *first*, where we get 2014-02-29, which adjusts down to 2014-02-28, and *then* add 1 day, which results in 2014-03-01. One design principle that helps in this case is that, in the presence of multiple Periods, the operations will be ordered by the Periods' *types*, not their value or positional order; this means ``Year`` will always be added first, then ``Month``, then ``Week``, etc. Hence the following *does* result in associativity and Just Works:: +.. doctest:: - julia> Date(2014,1,29) + Dates.Day(1) + Dates.Month(1) - 2014-03-01 + julia> Date(2014,1,29) + Dates.Day(1) + Dates.Month(1) + 2014-03-01 - julia> Date(2014,1,29) + Dates.Month(1) + Dates.Day(1) - 2014-03-01 + julia> Date(2014,1,29) + Dates.Month(1) + Dates.Day(1) + 2014-03-01 -Tricky? Perhaps. What is an innocent ``Dates`` user to do? The bottom line is to be aware that explicitly forcing a certain associativity, when dealing with months, may lead to some unexpected results, but otherwise, everything should work as expected. Thankfully, that's pretty much the extent of the odd cases in date-period arithmetic when dealing with time in UT (avoiding the "joys" of dealing with daylight savings, leap seconds, etc.). +Tricky? Perhaps. What is an innocent :mod:`Dates` user to do? The bottom line is to be aware that explicitly forcing a certain associativity, when dealing with months, may lead to some unexpected results, but otherwise, everything should work as expected. Thankfully, that's pretty much the extent of the odd cases in date-period arithmetic when dealing with time in UT (avoiding the "joys" of dealing with daylight saving, leap seconds, etc.). Adjuster Functions @@ -251,66 +278,68 @@ Adjuster Functions As convenient as date-period arithmetics are, often the kinds of calculations needed on dates take on a *calendrical* or *temporal* nature rather than a fixed number of periods. Holidays are a perfect example; most follow rules such as "Memorial Day = Last Monday of May", or "Thanksgiving = 4th Thursday of November". These kinds of temporal expressions deal with rules relative to the calendar, like first or last of the month, next Tuesday, or the first and third Wednesdays, etc. -The ``Dates`` module provides the *adjuster* API through several convenient methods that aid in simply and succinctly expressing temporal rules. The first group of adjuster methods deal with the first and last of weeks, months, quarters, and years. They each take a single ``TimeType`` as input and return or *adjust to* the first or last of the desired period relative to the input. +The :mod:`Dates` module provides the *adjuster* API through several convenient methods that aid in simply and succinctly expressing temporal rules. The first group of adjuster methods deal with the first and last of weeks, months, quarters, and years. They each take a single :data:`TimeType` as input and return or *adjust to* the first or last of the desired period relative to the input. -:: +.. doctest:: - # Adjusts the input to the Monday of the input's week - julia> Dates.firstdayofweek(Date(2014,7,16)) - 2014-07-14 + # Adjusts the input to the Monday of the input's week + julia> Dates.firstdayofweek(Date(2014,7,16)) + 2014-07-14 - # Adjusts to the last day of the input's month - julia> Dates.lastdayofmonth(Date(2014,7,16)) - 2014-07-31 + # Adjusts to the last day of the input's month + julia> Dates.lastdayofmonth(Date(2014,7,16)) + 2014-07-31 - # Adjusts to the last day of the input's quarter - julia> Dates.lastdayofquarter(Date(2014,7,16)) - 2014-09-30 + # Adjusts to the last day of the input's quarter + julia> Dates.lastdayofquarter(Date(2014,7,16)) + 2014-09-30 -The next two higher-order methods, ``tonext``, and ``toprev``, generalize working with temporal expressions by taking a ``DateFunction`` as first argument, along with a starting ``TimeType``. A ``DateFunction`` is just a function, usually anonymous, that takes a single ``TimeType`` as input and returns a ``Bool``, ``true`` indicating a satisfied adjustment criterion. +The next two higher-order methods, :func:`tonext` and :func:`toprev`, generalize working with temporal expressions by taking a ``DateFunction`` as first argument, along with a starting :data:`TimeType`. A ``DateFunction`` is just a function, usually anonymous, that takes a single :data:`TimeType` as input and returns a ``Bool``, ``true`` indicating a satisfied adjustment criterion. For example:: - julia> istuesday = x->Dates.dayofweek(x) == Dates.Tuesday # Returns true if the day of the week of x is Tuesday - (anonymous function) - - julia> Dates.tonext(istuesday, Date(2014,7,13)) # 2014-07-13 is a Sunday - 2014-07-15 - - # Convenience method provided for day of the week adjustments - julia> Dates.tonext(Date(2014,7,13), Dates.Tuesday) - 2014-07-15 - -This is useful with the do-block syntax for more complex temporal expressions:: - - julia> Dates.tonext(Date(2014,7,13)) do x - # Return true on the 4th Thursday of November (Thanksgiving) - Dates.dayofweek(x) == Dates.Thursday && - Dates.dayofweekofmonth(x) == 4 && - Dates.month(x) == Dates.November - end - 2014-11-27 - -The final method in the adjuster API is the ``recur`` function. ``recur`` vectorizes the adjustment process by taking a start and stop date (optionally specificed by a ``StepRange``), along with a ``DateFunction`` to specify all valid dates/moments to be returned in the specified range. In this case, the ``DateFunction`` is often referred to as the "inclusion" function because it specifies (by returning true) which dates/moments should be included in the returned vector of dates. - -:: - - # Pittsburgh street cleaning; Every 2nd Tuesday from April to November - # Date range from January 1st, 2014 to January 1st, 2015 - julia> dr = Dates.Date(2014):Dates.Date(2015); - julia> recur(dr) do x - Dates.dayofweek(x) == Dates.Tue && - Dates.April <= Dates.month(x) <= Dates.Nov && - Dates.dayofweekofmonth(x) == 2 - end - 8-element Array{Date,1}: - 2014-04-08 - 2014-05-13 - 2014-06-10 - 2014-07-08 - 2014-08-12 - 2014-09-09 - 2014-10-14 - 2014-11-11 + julia> istuesday = x->Dates.dayofweek(x) == Dates.Tuesday # Returns true if the day of the week of x is Tuesday + (anonymous function) + + julia> Dates.tonext(istuesday, Date(2014,7,13)) # 2014-07-13 is a Sunday + 2014-07-15 + + # Convenience method provided for day of the week adjustments + julia> Dates.tonext(Date(2014,7,13), Dates.Tuesday) + 2014-07-15 + +This is useful with the do-block syntax for more complex temporal expressions: + +.. doctest:: + + julia> Dates.tonext(Date(2014,7,13)) do x + # Return true on the 4th Thursday of November (Thanksgiving) + Dates.dayofweek(x) == Dates.Thursday && + Dates.dayofweekofmonth(x) == 4 && + Dates.month(x) == Dates.November + end + 2014-11-27 + +The final method in the adjuster API is the :func:`recur` function. :func:`recur` vectorizes the adjustment process by taking a start and stop date (optionally specified by a ``StepRange``), along with a ``DateFunction`` to specify all valid dates/moments to be returned in the specified range. In this case, the ``DateFunction`` is often referred to as the "inclusion" function because it specifies (by returning true) which dates/moments should be included in the returned vector of dates. + +.. doctest:: + + # Pittsburgh street cleaning; Every 2nd Tuesday from April to November + # Date range from January 1st, 2014 to January 1st, 2015 + julia> dr = Dates.Date(2014):Dates.Date(2015); + julia> Dates.recur(dr) do x + Dates.dayofweek(x) == Dates.Tue && + Dates.April <= Dates.month(x) <= Dates.Nov && + Dates.dayofweekofmonth(x) == 2 + end + 8-element Array{Date,1}: + 2014-04-08 + 2014-05-13 + 2014-06-10 + 2014-07-08 + 2014-08-12 + 2014-09-09 + 2014-10-14 + 2014-11-11 Additional examples and tests are available in `test/dates/adjusters.jl `_. @@ -318,38 +347,38 @@ Additional examples and tests are available in `test/dates/adjusters.jl ` or :data:`Month(3.0) `. Arithmetic between :data:`Period` of the same type behave like integers, and limited ``Period-Real`` arithmetic is available. - julia> y1 = Dates.Year(1) - 1 year +.. doctest:: - julia> y2 = Dates.Year(2) - 2 years + julia> y1 = Dates.Year(1) + 1 year - julia> y3 = Dates.Year(10) - 10 years + julia> y2 = Dates.Year(2) + 2 years - julia> y1 + y2 - 3 years + julia> y3 = Dates.Year(10) + 10 years - julia> div(y3,y2) - 5 years + julia> y1 + y2 + 3 years - julia> y3 - y2 - 8 years + julia> div(y3,y2) + 5 years - julia> y3 * y2 - 20 years + julia> y3 - y2 + 8 years - julia> y3 % y2 - 0 years + julia> y3 * y2 + 20 years - julia> y1 + 20 - 21 years + julia> y3 % y2 + 0 years - julia> div(y3,3) # mirrors integer division - 3 years + julia> y1 + 20 + 21 years + julia> div(y3,3) # mirrors integer division + 3 years -See the `API reference `_ for additional information on methods exported from the :mod:`Dates` module. +See the :mod:`Dates` module for for additional information. diff --git a/doc/stdlib/dates.rst b/doc/stdlib/dates.rst index d6bd8bc07b96d..d83789bc9275f 100644 --- a/doc/stdlib/dates.rst +++ b/doc/stdlib/dates.rst @@ -307,7 +307,7 @@ Adjuster Functions ``same`` allows ``dt`` to be considered in satisfying ``func``. ``negate`` will make the adjustment process terminate when ``func`` returns false instead of true. -.. function:: recur{T<:TimeType}(func::Function,dr::StepRange{T};negate=false,limit=10000) -> Vector{T} +.. function:: recur(func::Function,dr::StepRange{TimeType};negate=false,limit=10000) -> Vector{TimeType} ``func`` takes a single TimeType argument and returns a ``Bool`` indicating whether the input should be "included" in the final set. ``recur`` applies ``func`` over each element in the