====================
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
``<objc/objc.h>``:

.. 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.

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
``<NSCopying>`` 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.
