SPECIFICATION VERSION

     1.1

ABSTRACT

    This document describes Rinci, a set of extensible, language-neutral
    metadata specifications for your code (functions/methods, variables,
    packages, classes, and so on). Rinci allows various helper tools, from
    code generator to web middleware to documentation generator to other
    protocols, to act on your code, making your life easier as a
    programmer. Rinci also allows better interoperability between
    programming languages. Rinci is geared towards dynamic scripting
    languages like Perl, Python, Ruby, PHP, JavaScript, but is not limited
    to those languages.

STATUS

    The 1.1 series does not guarantee full backward compatibility between
    revisions, so caveat implementor. However, major incompatibility will
    bump the version to 1.2 or 2.0.

TERMINOLOGIES

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
    "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
    document are to be interpreted as described in RFC 2119.

    Rinci is a set of specifications of metadata for your code entities.
    Each different type of code entity, like function/method, variable,
    namespace, etc, has its own metadata specification.

    Metadata is a defhash (see DefHash). Each specification will specify
    what properties should be supported. So the Rinci::function
    specification will describe metadata for functions/methods,
    Rinci::package will describe metadata for namespace/package, and so on.

    Rinci defines properties pertaining to documentation (like summary,
    description, examples, links), function argument and return value
    validation (args and result), dependencies (deps), standardized feature
    description (features), also a few conventions/protocols for doing
    stuffs like undo (others like callback/progress report will follow).
    Basically anything that can describe the code entity. The specification
    is extensible: you can define more properties, or more deps, or more
    features.

    Since defhash can contain keys that are ignored (those that start with
    underscore, _), extra information can be put here.

WHAT ARE THE BENEFITS OF RINCI?

    By adding Rinci metadata to your code, you can write/use tools to do
    various things to your program. Rinci is designed with code generation
    and function wrapping in mind. At the time of this writing, in Perl
    there exists several tools (mostly modules under Perinci namespace) to
    do the following:

      * Perinci::Sub::Wrapper

      Wrap functions with a single generated function that can do the
      following: validate input (using information from the args property),
      validate return value (the result property), add execution
      time-limiting (timeout), add automatic retries (retry), interactive
      confirmation, logging, and more.

      * Perinci::Exporter, Exporter::Rinci

      More convenient replacements/wrappers for Exporter or Sub::Exporter
      if your functions are equipped with Rinci metadata. Automatically
      provide export tags (using information in the tags property).
      Automatically wrap functions using Perinci::Sub::Wrapper when
      exporting (Perinci::Exporter).

      * Perinci::To::* modules

      Convert metadata to various other documents, for example
      Perinci::To::POD to generate documentation.

      * Perinci::CmdLine (several flavors: Perinci::CmdLine::Classic,
      Perinci::CmdLine::Lite, Perinci::CmdLine::Inline)

      Riap command-line client. Call local/remote functions. Automatically
      convert command-line options/arguments to function arguments.
      Generate help/usage message (for --help). Check dependencies (e.g.
      you can specify that in order to run your functions, you need some
      executables/other functions to exist, an environment variable being
      set, and so on), perform bash shell completion (using
      Perinci::Sub::Complete).

      * Perinci::Access::HTTP::Server

      A PSGI application (a set of PSGI middlewares, really) to serve
      metadata and function call requests over HTTP, according to the
      Riap::HTTP protocol.

      * Serabi

      An alternative for Perinci::Access::HTTP::Server for REST-style
      service.

      * Perinci::Use

      Use remote packages and import their functions/variables
      transparently like you would use local Perl modules. The remote
      server can be any Riap-compliant service, even when implemented in
      other languages.

      * Perinci::Sub::Gen::*

      Since Rinci metadata are just normal data structure, they can be
      easily generated. The Perinci::Sub::Gen::* Perl modules can generate
      functions as well as their metadata, for example to access table data
      (like from a regular array or from a SQL database).

    More tools will be written in the future.

RINCI VS ...

    Some features offered by Rinci (or Rinci tools) are undoubtedly already
    offered by your language or existing language libraries. For example,
    for documentation Perl already has POD and Python has docstrings. There
    are numerous libraries for argument validation in every language.
    Python has decorators that can be used to implement various features
    like argument validation and logging. Perl has subroutine attributes to
    stick additional metadata to your subroutines and variables. And so on.

    The benefits that Rinci offer include richer metadata, language
    neutrality, extensibility, and manipulability.

    Richer metadata. Rinci strives to provide enough metadata for tools to
    do various useful things. For example, the description and summary
    properties support translations. Argument specification is pretty rich,
    with a quite powerful and flexible schema language.

    Language neutrality. You can share metadata between languages,
    including documentation and rules for argument validation. Perl 6
    allows very powerful argument validation, for example, but it is
    language-specific. With Rinci you can easily share validation rules and
    generate validators in Perl and JavaScript (and other target
    languages).

    Manipulability. Being a normal data structure, your Rinci metadata is
    easier to manipulate (clone, merge, modify, export, what have you) as
    well as access (from your language and others). Perl's POD
    documentation is not accessible from the language (but Perl 6's Pod and
    Python docstrings are, and there are certainly tools to parse POD). On
    the other hand, Python docstrings are attached in the same file with
    the function, while with Rinci you can choose to separate the metadata
    into another file more easily.

    Other things to consider. If you stack multiple decorators in Python,
    for example, it usually results in wrapping your Python function
    multiple times, which can add overhead. A single wrapper like
    Perinci::Sub::Wrapper, on the other hand, uses a single level of
    wrapping to minimize subroutine call overhead.

    Working together. There is no reason why Rinci metadata has to compete
    against existing features from language/libraries. A code generator for
    Rinci metadata can generate code that utilize those features. For
    example, the timeout property can be implemented in Python using
    decorator, if you want. Rinci basically just provides a way for you to
    express desired properties/constraints/behaviours, separate from the
    implementation. A tool is free to implement those properties using
    whatever technique is appropriate.

SPECIFICATION

    Note: Examples are usually written in Perl, but this does not mean they
    only apply to a particular language.

 Terminologies

    Code entities, or just entities for short, are elements in your code
    that can be given metadata. Currently supported entities are
    function/method, namespace/package, and variable. Other entities
    planned to be supported: class, object, library, application.

 Specification common to all metadata

    This section describes specification common to all kinds of Rinci
    metadata.

    Where to put the metadata. The specification does not specify where to
    put metadata in: it might be put alongside the code, separated in
    another source code, encoded in YAML/JSON, put in database, or
    whatever. It is up to the tools/implementations to provide the
    mechanism. If you use Perinci in Perl, there is a great deal of
    flexibility, you basically can do all of the above, even split the
    metadata in several files. See its documentation for more details.

    Common properties. Below are properties common to all metadata:

  Property: v => FLOAT (required)

    From DefHash. Declare specification version. This property is required.
    It should have the value of 1.1. If v is not specified, it is assumed
    to be 1.0 and metadata is assumed to be the old, Sub::Spec 1.0.x
    metadata.

    Example:

     v => 1.1

  Property: entity_v => STR

    Specify entity version (like package or function version). This is
    version as in software implementation version, not to be confused with
    v which is the metadata specification version (1.1).

    Example:

     entity_v => 0.24

    In Perl, modules usually put version numbers in package variable called
    $VERSION. If not set, tools like Perinci::Access::Perl automatically
    fills this property from that variable, to relieve authors from
    manually setting this property value.

  Property: default_lang => STR

    From DefHash. Specify default language used in the text properties like
    summary and description. Default is 'en_US'.

    To specify translation texts in other languages, you can use
    PROPERTY.alt.lang.CODE, e.g.:

     summary => "Perform the foo ritual",
     "summary.alt.lang.id_ID" => "Laksanakan ritual foo",

  Property: name => STR

    From DefHash. The name of the entity. Useful when aliasing entity (and
    reusing the metadata) and wanting to find out the canonical/original
    entity.

    Examples:

     name => 'foo'
     name => '$var'  # only in languages where variables have prefix

  Property: summary => STR

    From DefHash. A one-line summary. It should be plain text without any
    markup. Please limit to around 72 characters.

    Example:

     # in variable metadata for $Answer
     summary => 'The answer to the question: what is the meaning of life'
    
     # in function metadata foo
     summary => 'Perform the foo ritual',

    For variable metadata, it should describe what the variable contain.
    You do not need to say "Contains ..." or "A variable that ..." since
    that is redundant; just say directly the content of the variable
    (noun). You also do not need to say what kinds of values the variable
    should contain, like "An integer, answer to the ..." or "..., should be
    between 1..100" since that should go to the schema property.

    For function metadata, it should describe what the function does.
    Suggestion: use active, bare infinitive verb like in the example (not
    "Performs ..."). Avoid preamble like "This function ..." or "Function
    to ..." since that is redundant. Also avoid describing the arguments
    and its values like "..., accepts a single integer argument" as that
    should go to the args property.

    To specify translations in other language, use the
    summary.alt.lang.CODE. Or change the default_lang property. Examples:

     # default language is 'en_US'
     summary => 'Perform the foo ritual',
     "summary.alt.lang.id_ID" => 'Laksanakan ritual foo',
    
     # change default language to id_ID, so all summaries are in Indonesian, except
     # when explicitly set otherwise
     default_lang => 'id_ID',
     summary => 'Laksanakan ritual foo',
     "summary.alt.lang.en_US" => 'Perform the foo ritual',

  Property: tags => ARRAY OF (STR OR HASH)

    From DefHash. A list of tags, useful for categorization. Can also be
    used by tools, e.g. Perinci::Exporter in Perl uses the tags property of
    the function metadata as export tags.

    Tag can be a simple string or a tag metadata hash.

    Example:

     # tag a function as beta
     tags => ['beta']
    
     # the second tag is a detailed metadata
     tags => ['beta',
              {
                  name    => 'category:filtering',
                  summary => 'Filtering',
                  "summary.alt.lang.id_ID" => 'Penyaringan',
              }
             ]

  Property: description => STR

    From DefHash. A longer description text. The text should be in marked
    up in format specified by text_markup and is suggested to be formatted
    to 78 columns.

    To avoid redundancy, you should mentioning things that are already
    expressed as properties, for example: return value of function (specify
    it in result property instead), arguments that the function accepts
    (args), examples (examples), function's features (features) and
    dependencies/requirements (deps).

    For function, description should probably contain a more detailed
    description of what the function does (steps, algorithm used, effects
    and other things of note).

    Example:

     {
         name => 'foo',
         summary => 'Perform the foo ritual',
         description => <<EOT,
    
     Foo ritual can be performed by humans or machines. This program will perform a
     machine-based ritual using [the best available
     algorithm](http://example.org/foo-with-bar-algo.html).
    
     Note that you still have to perform foo ritual manually from time to time, just
     to be safe.
    
     EOT
     }

    Like in summary, to specify translations in other language, use the
    description.alt.lang.CODE property.

  Property: links => ARRAY OF HASHES

    List to related entities or resources. Can be used to generate a SEE
    ALSO and/or LINKS sections in documentation. Each link is a defhash
    with the following keys:

      * url => STR (required)

      URI is used as a common syntax to refer to resources. If URI scheme
      is not specified, tools can assume that it is a riap URI (see Riap).

      * caption => STR

      From DefHash. A short plaintext title for the link.

      * description => STR

      From DefHash. A longer marked up text description for the link.
      Suggested to be formatted to 76 columns.

      * tags => ARRAY OF (STR OR HASH)

      From DefHash. Can be used to categorize or select links. For
      generating SEE ALSO sections, use the tag 'see'.

    Example:

     # links in the Bar::foo function metadata
     links => [
         {
             url     => "http://example.org/foo-with-bar-algo.html",
             caption => "Article describing foo using Bar algorithm",
         },
         {
             url     => "../Bar2/",
             caption => "Another implementation of the Bar algorithm",
             tags    => ['see'],
         },
     ],

  Property: x => ANY

    From DefHash. This property is used to store extended
    (application-specific) attributes, much like the X- prefix in HTTP or
    email headers. This property can be used as an alternative to using
    underscore prefix (e.g. _foo). Some processing tools strip
    properties/attributes that begin with underscores, so to pass extended
    metadata around, it might be more convenient to use the x property.

    It is recommended that you put an application prefix.

    Example:

     "x.myapp.foo" => "some value",

    Another example:

     "x.dux.strip_newlines" => 0,

 Entity-specific specifications

    Each entity-specific specification is described on a separate
    subdocument. Currently these specifications are defined:

      * Rinci::function - Metadata for functions/methods

      * Rinci::package - Metadata for namespaces/packages

      * Rinci::variable - Metadata for variables

      * Rinci::result - Function/method result metadata

    These specifications are planned or considered, but not yet defined:

      * Rinci::class - Metadata for classes

      * Rinci::object - Metadata for objects

      * Rinci::application - Metadata for applications

      * Rinci::library - Metadata for libraries

      * Rinci::distribution - Metadata for software distribution

      * Rinci::language - Metadata for programming languages

      * Rinci::author - Metadata for software authors

      * Rinci::project - Metadata for software projects

      * Rinci::repository - Metadata for code repository (like git, svn)

FAQ

 What does Rinci mean?

    Rinci is taken from Indonesian word perincian or rincian, meaning:
    specification, detail.

 Why use Sah for data schema?

    Sah is a flexible and extensible schema language, while still not being
    language-specific, making it easy for code generator tools to generate
    validator code in various target languages (Perl, Ruby, etc).

HISTORY

    Below is the general history of the project and major changes to the
    specifications. For more detailed changes between releases, see the
    Changes file in the distribution.

1.1 (Jan 2012)

    To clearly separate specification from implementation, rename
    specification from Sub::Spec to Rinci (the namespace Perinci is now
    used for the Perl implementation). Support code entities other than
    functions/methods. Bump specification version from 1.0 to 1.1 due to
    several incompatibilities like changed args and result properties,
    terminologies, defaults. Versioning property (v) now required.

 1.0 (Aug 2011)

    First release version of Sub::Spec.

 0.x (Feb-Aug 2011)

    Series of Sub::Spec drafts.

 Spanel project (2009-2010)

    I started using some metadata for API functions, calling them spec and
    putting them in %spec instead of in POD, so I can list and grab all the
    summaries easily as a single dump for API catalog (instead of having to
    parse POD from my source code files). Later on I kept adding more and
    more stuffs to this, from argument specification, requirements, and so
    on.

SEE ALSO

 Related specifications

    DefHash

    Sah schema language, Sah

    Riap

 Related ideas/concepts

    .NET attributes, http://msdn.microsoft.com/en-us/library/z0w1kczw.aspx

    Python Decorators, http://www.python.org/dev/peps/pep-0318/ ,
    http://wiki.python.org/moin/PythonDecorators

 Other related links

    Acmeism, http://www.acmeism.org/

