====================
Objective-C Literals
====================

Introduction
============

Three new features were introduced into clang at the same time:
*NSNumber Literals* provide a syntax for creating ``NSNumber`` from
scalar literal expressions; *Collection Literals* provide a short-hand
for creating arrays and dictionaries; *Object Subscripting* provides a
way to use subscripting with Objective-C objects. Users of Apple
compiler releases can use these features starting with the Apple LLVM
Compiler 4.0. Users of open-source LLVM.org compiler releases can use
these features starting with clang v3.1.

These language additions simplify common Objective-C programming
patterns, make programs more concise, and improve the safety of
container creation.

This document describes how the features are implemented in clang, and
how to use them in your own programs.

NSNumber Literals
=================

The framework class ``NSNumber`` is used to wrap scalar values inside
objects: signed and unsigned integers (``char``, ``short``, ``int``,
``long``, ``long long``), floating point numbers (``float``,
``double``), and boolean values (``BOOL``, C++ ``bool``). Scalar values
wrapped in objects are also known as *boxed* values.

In Objective-C, any character, numeric or boolean literal prefixed with
the ``'@'`` character will evaluate to a pointer to an ``NSNumber``
object initialized with that value. C's type suffixes may be used to
control the size of numeric literals.

Examples
--------

The following program illustrates the rules for ``NSNumber`` literals:

.. code-block:: objc

    void main(int argc, const char *argv[]) {
      // character literals.
      NSNumber *theLetterZ = @'Z';          // equivalent to [NSNumber numberWithChar:'Z']

      // integral literals.
      NSNumber *fortyTwo = @42;             // equivalent to [NSNumber numberWithInt:42]
      NSNumber *fortyTwoUnsigned = @42U;    // equivalent to [NSNumber numberWithUnsignedInt:42U]
      NSNumber *fortyTwoLong = @42L;        // equivalent to [NSNumber numberWithLong:42L]
      NSNumber *fortyTwoLongLong = @42LL;   // equivalent to [NSNumber numberWithLongLong:42LL]

      // floating point literals.
      NSNumber *piFloat = @3.141592654F;    // equivalent to [NSNumber numberWithFloat:3.141592654F]
      NSNumber *piDouble = @3.1415926535;   // equivalent to [NSNumber numberWithDouble:3.1415926535]

      // BOOL literals.
      NSNumber *yesNumber = @YES;           // equivalent to [NSNumber numberWithBool:YES]
      NSNumber *noNumber = @NO;             // equivalent to [NSNumber numberWithBool:NO]

    #ifdef __cplusplus
      NSNumber *trueNumber = @true;         // equivalent to [NSNumber numberWithBool:(BOOL)true]
      NSNumber *falseNumber = @false;       // equivalent to [NSNumber numberWithBool:(BOOL)false]
    #endif
    }

Discussion
----------

NSNumber literals only support literal scalar values after the ``'@'``.
Consequently, ``@INT_MAX`` works, but ``@INT_MIN`` does not, because
they are defined like this:

.. code-block:: objc

    #define INT_MAX   2147483647  /* max value for an int */
    #define INT_MIN   (-2147483647-1) /* min value for an int */

The definition of ``INT_MIN`` is not a simple literal, but a
parenthesized expression. Parenthesized expressions are supported using
the `boxed expression <#objc_boxed_expressions>`_ syntax, which is
described in the next section.

Because ``NSNumber`` does not currently support wrapping ``long double``
values, the use of a ``long double NSNumber`` literal (e.g.
``@123.23L``) will be rejected by the compiler.

Previously, the ``BOOL`` type was simply a typedef for ``signed char``,
and ``YES`` and ``NO`` were macros that expand to ``(BOOL)1`` and
``(BOOL)0`` respectively. To support ``@YES`` and ``@NO`` expressions,
these macros are now defined using new language keywords in
``&LT;objc/objc.h&GT;``:

.. code-block:: objc

    #if __has_feature(objc_bool)
    #define YES             __objc_yes
    #define NO              __objc_no
    #else
    #define YES             ((BOOL)1)
    #define NO              ((BOOL)0)
    #endif

The compiler implicitly converts ``__objc_yes`` and ``__objc_no`` to
``(BOOL)1`` and ``(BOOL)0``. The keywords are used to disambiguate
``BOOL`` and integer literals.

Objective-C++ also supports ``@true`` and ``@false`` expressions, which
are equivalent to ``@YES`` and ``@NO``.

Boxed Expressions
=================

Objective-C provides a new syntax for boxing C expressions:

.. code-block:: objc

    @( <expression> )

Expressions of scalar (numeric, enumerated, BOOL) and C string pointer
types are supported:

.. code-block:: objc

    // numbers.
    NSNumber *smallestInt = @(-INT_MAX - 1);  // [NSNumber numberWithInt:(-INT_MAX - 1)]
    NSNumber *piOverTwo = @(M_PI / 2);        // [NSNumber numberWithDouble:(M_PI / 2)]

    // enumerated types.
    typedef enum { Red, Green, Blue } Color;
    NSNumber *favoriteColor = @(Green);       // [NSNumber numberWithInt:((int)Green)]

    // strings.
    NSString *path = @(getenv("PATH"));       // [NSString stringWithUTF8String:(getenv("PATH"))]
    NSArray *pathComponents = [path componentsSeparatedByString:@":"];

Boxed Enums
-----------

Cocoa frameworks frequently define constant values using *enums.*
Although enum values are integral, they may not be used directly as
boxed literals (this avoids conflicts with future ``'@'``-prefixed
Objective-C keywords). Instead, an enum value must be placed inside a
boxed expression. The following example demonstrates configuring an
``AVAudioRecorder`` using a dictionary that contains a boxed enumeration
value:

.. code-block:: objc

    enum {
      AVAudioQualityMin = 0,
      AVAudioQualityLow = 0x20,
      AVAudioQualityMedium = 0x40,
      AVAudioQualityHigh = 0x60,
      AVAudioQualityMax = 0x7F
    };

    - (AVAudioRecorder *)recordToFile:(NSURL *)fileURL {
      NSDictionary *settings = @{ AVEncoderAudioQualityKey : @(AVAudioQualityMax) };
      return [[AVAudioRecorder alloc] initWithURL:fileURL settings:settings error:NULL];
    }

The expression ``@(AVAudioQualityMax)`` converts ``AVAudioQualityMax``
to an integer type, and boxes the value accordingly. If the enum has a
:ref:`fixed underlying type <objc-fixed-enum>` as in:

.. code-block:: objc

    typedef enum : unsigned char { Red, Green, Blue } Color;
    NSNumber *red = @(Red), *green = @(Green), *blue = @(Blue); // => [NSNumber numberWithUnsignedChar:]

then the fixed underlying type will be used to select the correct
``NSNumber`` creation method.

Boxing a value of enum type will result in a ``NSNumber`` pointer with a
creation method according to the underlying type of the enum, which can
be a :ref:`fixed underlying type <objc-fixed-enum>`
or a compiler-defined integer type capable of representing the values of
all the members of the enumeration:

.. code-block:: objc

    typedef enum : unsigned char { Red, Green, Blue } Color;
    Color col = Red;
    NSNumber *nsCol = @(col); // => [NSNumber numberWithUnsignedChar:]

Boxed C Strings
---------------

A C string literal prefixed by the ``'@'`` token denotes an ``NSString``
literal in the same way a numeric literal prefixed by the ``'@'`` token
denotes an ``NSNumber`` literal. When the type of the parenthesized
expression is ``(char *)`` or ``(const char *)``, the result of the
boxed expression is a pointer to an ``NSString`` object containing
equivalent character data, which is assumed to be '\\0'-terminated and
UTF-8 encoded. The following example converts C-style command line
arguments into ``NSString`` objects.

.. code-block:: objc

    // Partition command line arguments into positional and option arguments.
    NSMutableArray *args = [NSMutableArray new];
    NSMutableDictionary *options = [NSMutableDictionary new];
    while (--argc) {
        const char *arg = *++argv;
        if (strncmp(arg, "--", 2) == 0) {
            options[@(arg + 2)] = @(*++argv);   // --key value
        } else {
            [args addObject:@(arg)];            // positional argument
        }
    }

As with all C pointers, character pointer expressions can involve
arbitrary pointer arithmetic, therefore programmers must ensure that the
character data is valid. Passing ``NULL`` as the character pointer will
raise an exception at runtime. When possible, the compiler will reject
``NULL`` character pointers used in boxed expressions.

Availability
------------

Boxed expressions will be available in clang 3.2. It is not currently
available in any Apple compiler.

Container Literals
==================

Objective-C now supports a new expression syntax for creating immutable
array and dictionary container objects.

Examples
--------

Immutable array expression:

.. code-block:: objc

    NSArray *array = @[ @"Hello", NSApp, [NSNumber numberWithInt:42] ];

This creates an ``NSArray`` with 3 elements. The comma-separated
sub-expressions of an array literal can be any Objective-C object
pointer typed expression.

Immutable dictionary expression:

.. code-block:: objc

    NSDictionary *dictionary = @{
        @"name" : NSUserName(),
        @"date" : [NSDate date],
        @"processInfo" : [NSProcessInfo processInfo]
    };

This creates an ``NSDictionary`` with 3 key/value pairs. Value
sub-expressions of a dictionary literal must be Objective-C object
pointer typed, as in array literals. Key sub-expressions must be of an
Objective-C object pointer type that implements the
``&LT;NSCopying&GT;`` protocol.

Discussion
----------

Neither keys nor values can have the value ``nil`` in containers. If the
compiler can prove that a key or value is ``nil`` at compile time, then
a warning will be emitted. Otherwise, a runtime error will occur.

Using array and dictionary literals is safer than the variadic creation
forms commonly in use today. Array literal expressions expand to calls
to ``+[NSArray arrayWithObjects:count:]``, which validates that all
objects are non-``nil``. The variadic form,
``+[NSArray arrayWithObjects:]`` uses ``nil`` as an argument list
terminator, which can lead to malformed array objects. Dictionary
literals are similarly created with
``+[NSDictionary dictionaryWithObjects:forKeys:count:]`` which validates
all objects and keys, unlike
``+[NSDictionary dictionaryWithObjectsAndKeys:]`` which also uses a
``nil`` parameter as an argument list terminator.

Object Subscripting
===================

Objective-C object pointer values can now be used with C's subscripting
operator.

Examples
--------

The following code demonstrates the use of object subscripting syntax
with ``NSMutableArray`` and ``NSMutableDictionary`` objects:

.. code-block:: objc

    NSMutableArray *array = ...;
    NSUInteger idx = ...;
    id newObject = ...;
    id oldObject = array[idx];
    array[idx] = newObject;         // replace oldObject with newObject

    NSMutableDictionary *dictionary = ...;
    NSString *key = ...;
    oldObject = dictionary[key];
    dictionary[key] = newObject;    // replace oldObject with newObject

The next section explains how subscripting expressions map to accessor
methods.

Subscripting Methods
--------------------

Objective-C supports two kinds of subscript expressions: *array-style*
subscript expressions use integer typed subscripts; *dictionary-style*
subscript expressions use Objective-C object pointer typed subscripts.
Each type of subscript expression is mapped to a message send using a
predefined selector. The advantage of this design is flexibility: class
designers are free to introduce subscripting by declaring methods or by
adopting protocols. Moreover, because the method names are selected by
the type of the subscript, an object can be subscripted using both array
and dictionary styles.

Array-Style Subscripting
^^^^^^^^^^^^^^^^^^^^^^^^

When the subscript operand has an integral type, the expression is
rewritten to use one of two different selectors, depending on whether
the element is being read or written. When an expression reads an
element using an integral index, as in the following example:

.. code-block:: objc

    NSUInteger idx = ...;
    id value = object[idx];

it is translated into a call to ``objectAtIndexedSubscript:``

.. code-block:: objc

    id value = [object objectAtIndexedSubscript:idx];

When an expression writes an element using an integral index:

.. code-block:: objc

    object[idx] = newValue;

it is translated to a call to ``setObject:atIndexedSubscript:``

.. code-block:: objc

    [object setObject:newValue atIndexedSubscript:idx];

These message sends are then type-checked and performed just like
explicit message sends. The method used for objectAtIndexedSubscript:
must be declared with an argument of integral type and a return value of
some Objective-C object pointer type. The method used for
setObject:atIndexedSubscript: must be declared with its first argument
having some Objective-C pointer type and its second argument having
integral type.

The meaning of indexes is left up to the declaring class. The compiler
will coerce the index to the appropriate argument type of the method it
uses for type-checking. For an instance of ``NSArray``, reading an
element using an index outside the range ``[0, array.count)`` will raise
an exception. For an instance of ``NSMutableArray``, assigning to an
element using an index within this range will replace that element, but
assigning to an element using an index outside this range will raise an
exception; no syntax is provided for inserting, appending, or removing
elements for mutable arrays.

A class need not declare both methods in order to take advantage of this
language feature. For example, the class ``NSArray`` declares only
``objectAtIndexedSubscript:``, so that assignments to elements will fail
to type-check; moreover, its subclass ``NSMutableArray`` declares
``setObject:atIndexedSubscript:``.

Dictionary-Style Subscripting
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When the subscript operand has an Objective-C object pointer type, the
expression is rewritten to use one of two different selectors, depending
on whether the element is being read from or written to. When an
expression reads an element using an Objective-C object pointer
subscript operand, as in the following example:

.. code-block:: objc

    id key = ...;
    id value = object[key];

it is translated into a call to the ``objectForKeyedSubscript:`` method:

.. code-block:: objc

    id value = [object objectForKeyedSubscript:key];

When an expression writes an element using an Objective-C object pointer
subscript:

.. code-block:: objc

    object[key] = newValue;

it is translated to a call to ``setObject:forKeyedSubscript:``

.. code-block:: objc

    [object setObject:newValue forKeyedSubscript:key];

The behavior of ``setObject:forKeyedSubscript:`` is class-specific; but
in general it should replace an existing value if one is already
associated with a key, otherwise it should add a new value for the key.
No syntax is provided for removing elements from mutable dictionaries.

Discussion
----------

An Objective-C subscript expression occurs when the base operand of the
C subscript operator has an Objective-C object pointer type. Since this
potentially collides with pointer arithmetic on the value, these
expressions are only supported under the modern Objective-C runtime,
which categorically forbids such arithmetic.

Currently, only subscripts of integral or Objective-C object pointer
type are supported. In C++, a class type can be used if it has a single
conversion function to an integral or Objective-C pointer type, in which
case that conversion is applied and analysis continues as appropriate.
Otherwise, the expression is ill-formed.

An Objective-C object subscript expression is always an l-value. If the
expression appears on the left-hand side of a simple assignment operator
(=), the element is written as described below. If the expression
appears on the left-hand side of a compound assignment operator (e.g.
+=), the program is ill-formed, because the result of reading an element
is always an Objective-C object pointer and no binary operators are
legal on such pointers. If the expression appears in any other position,
the element is read as described below. It is an error to take the
address of a subscript expression, or (in C++) to bind a reference to
it.

Programs can use object subscripting with Objective-C object pointers of
type ``id``. Normal dynamic message send rules apply; the compiler must
see *some* declaration of the subscripting methods, and will pick the
declaration seen first.

Caveats
=======

Objects created using the literal or boxed expression syntax are not
guaranteed to be uniqued by the runtime, but nor are they guaranteed to
be newly-allocated. As such, the result of performing direct comparisons
against the location of an object literal (using ``==``, ``!=``, ``<``,
``<=``, ``>``, or ``>=``) is not well-defined. This is usually a simple
mistake in code that intended to call the ``isEqual:`` method (or the
``compare:`` method).

This caveat applies to compile-time string literals as well.
Historically, string literals (using the ``@"..."`` syntax) have been
uniqued across translation units during linking. This is an
implementation detail of the compiler and should not be relied upon. If
you are using such code, please use global string constants instead
(``NSString * const MyConst = @"..."``) or use ``isEqual:``.

Grammar Additions
=================

To support the new syntax described above, the Objective-C
``@``-expression grammar has the following new productions:

::

    objc-at-expression : '@' (string-literal | encode-literal | selector-literal | protocol-literal | object-literal)
                       ;

    object-literal : ('+' | '-')? numeric-constant
                   | character-constant
                   | boolean-constant
                   | array-literal
                   | dictionary-literal
                   ;

    boolean-constant : '__objc_yes' | '__objc_no' | 'true' | 'false'  /* boolean keywords. */
                     ;

    array-literal : '[' assignment-expression-list ']'
                  ;

    assignment-expression-list : assignment-expression (',' assignment-expression-list)?
                               | /* empty */
                               ;

    dictionary-literal : '{' key-value-list '}'
                       ;

    key-value-list : key-value-pair (',' key-value-list)?
                   | /* empty */
                   ;

    key-value-pair : assignment-expression ':' assignment-expression
                   ;

Note: ``@true`` and ``@false`` are only supported in Objective-C++.

Availability Checks
===================

Programs test for the new features by using clang's \_\_has\_feature
checks. Here are examples of their use:

.. code-block:: objc

    #if __has_feature(objc_array_literals)
        // new way.
        NSArray *elements = @[ @"H", @"He", @"O", @"C" ];
    #else
        // old way (equivalent).
        id objects[] = { @"H", @"He", @"O", @"C" };
        NSArray *elements = [NSArray arrayWithObjects:objects count:4];
    #endif

    #if __has_feature(objc_dictionary_literals)
        // new way.
        NSDictionary *masses = @{ @"H" : @1.0078,  @"He" : @4.0026, @"O" : @15.9990, @"C" : @12.0096 };
    #else
        // old way (equivalent).
        id keys[] = { @"H", @"He", @"O", @"C" };
        id values[] = { [NSNumber numberWithDouble:1.0078], [NSNumber numberWithDouble:4.0026],
                        [NSNumber numberWithDouble:15.9990], [NSNumber numberWithDouble:12.0096] };
        NSDictionary *masses = [NSDictionary dictionaryWithObjects:objects forKeys:keys count:4];
    #endif

    #if __has_feature(objc_subscripting)
        NSUInteger i, count = elements.count;
        for (i = 0; i < count; ++i) {
            NSString *element = elements[i];
            NSNumber *mass = masses[element];
            NSLog(@"the mass of %@ is %@", element, mass);
        }
    #else
        NSUInteger i, count = [elements count];
        for (i = 0; i < count; ++i) {
            NSString *element = [elements objectAtIndex:i];
            NSNumber *mass = [masses objectForKey:element];
            NSLog(@"the mass of %@ is %@", element, mass);
        }
    #endif

Code can use also ``__has_feature(objc_bool)`` to check for the
availability of numeric literals support. This checks for the new
``__objc_yes / __objc_no`` keywords, which enable the use of
``@YES / @NO`` literals.

To check whether boxed expressions are supported, use
``__has_feature(objc_boxed_expressions)`` feature macro.
