diff --git a/src/bcon.c b/src/bcon.c
index 3229ebe..0a89a6f 100644
--- a/src/bcon.c
+++ b/src/bcon.c
@@ -52,7 +52,9 @@ bcon_token_t bcon_token(char *s) {
     case '}': if (s[1] == '\0') return Token_CloseBrace; break;
     case '[': if (s[1] == '\0') return Token_OpenBracket; break;
     case ']': if (s[1] == '\0') return Token_CloseBracket; break;
-    case '.': if (s[1] == '\0') return Token_End; break;
+    case '.': if (s[1] == '\0') return Token_End;
+              else if (s[1] == '.' && s[2] == '\0') return Token_Fun;
+              break;
     }
     return Token_Default;
 }
@@ -111,7 +113,8 @@ bcon_error_t bson_bcon_key_value(bson *b, const char *key, const char *typespec,
 
 typedef enum bcon_state_t {
     State_Element, State_DocSpecValue, State_DocValue,
-    State_ArraySpecValue, State_ArrayValue
+    State_ArraySpecValue, State_ArrayValue,
+    State_Fun, State_FunArg
 } bcon_state_t;
 
 #define DOC_STACK_SIZE 1024
@@ -132,6 +135,7 @@ bcon_error_t bson_append_bcon_with_state(bson *b, const bcon *bc, bcon_state_t s
     bcon_state_t state = start_state;
     char *key = 0;
     char *typespec = 0;
+    void (*PF)(bson *b, void *v) = 0;
     unsigned char doc_stack[DOC_STACK_SIZE];
     size_t doc_stack_pointer = 0;
     size_t array_index = 0;
@@ -153,6 +157,9 @@ bcon_error_t bson_append_bcon_with_state(bson *b, const bcon *bc, bcon_state_t s
             case Token_End:
                 end_of_data = 1;
                 break;
+            case Token_Fun:
+                state = State_Fun;
+                break;
             default:
                 key = s;
                 state = State_DocSpecValue;
@@ -227,6 +234,14 @@ bcon_error_t bson_append_bcon_with_state(bson *b, const bcon *bc, bcon_state_t s
             state = State_ArraySpecValue;
             typespec = 0;
             break;
+        case State_Fun:
+            state = State_FunArg;
+            PF = bci.PF;
+            break;
+        case State_FunArg:
+            PF(b, bci.Pv);
+            state = State_Element;
+            break;
         default: assert(NOT_REACHED); break;
         }
     }
@@ -258,6 +273,8 @@ bcon_error_t bson_from_bcon(bson *b, const bcon *bc) {
 
 void bcon_print(const bcon *bc) { /* prints internal representation, not JSON */
     char *typespec = 0;
+    char *special = 0;
+    void (*PF)(bson *b, void *v) = 0;
     char *delim = "";
     int end_of_data;
     bcon *bcp;
@@ -291,8 +308,8 @@ void bcon_print(const bcon *bc) { /* prints internal representation, not JSON */
                 case 'x': printf("%sPx(0x%lx,\"%s\")", delim, (unsigned long)bci.Px, *bci.Px); break;
                 case 'i': printf("%sPi(0x%lx,%d)", delim, (unsigned long)bci.Pi, *bci.Pi); break;
                 case 'l': printf("%sPl(0x%lx,%ld)", delim, (unsigned long)bci.Pl, *bci.Pl); break;
-                case 'D': printf("%sPD(0x%lx,..)", delim, (unsigned long)bci.PD); break;
-                case 'A': printf("%sPA(0x%lx,....)", delim, (unsigned long)bci.PA); break;
+                case 'D': printf("%sPD(0x%lx,...)", delim, (unsigned long)bci.PD); break;
+                case 'A': printf("%sPA(0x%lx,...)", delim, (unsigned long)bci.PA); break;
                 default: printf("\ntypespec:\"%s\"\n", typespec); assert(NOT_REACHED); break;
                 }
                 break;
@@ -300,12 +317,22 @@ void bcon_print(const bcon *bc) { /* prints internal representation, not JSON */
                 printf("\ntypespec:\"%s\"\n", typespec); assert(NOT_REACHED);
                 break;
             }
+        } else if (special) {
+                PF = bci.PF;
+                special = 0;
+        }
+        else if (PF) {
+                printf("%sPF(0x%lx,0x%lx,...)", delim, (unsigned long)PF, (unsigned long)bci.Pv);
+                PF = 0;
         }
         else {
             char *s = bci.s;
             switch (s[0]) {
             case '.':
-                end_of_data = (s[1] == '\0');
+                if (s[1] == '\0')
+                    end_of_data = 1;
+                else if (s[1] == '.' && s[2] == '\0')
+                    special = s;
                 break;
             case ':':
                 typespec_next = bcon_token(s) == Token_Typespec ? s : 0;
diff --git a/src/bcon.h b/src/bcon.h
index ccedb7d..86d2917 100644
--- a/src/bcon.h
+++ b/src/bcon.h
@@ -55,6 +55,12 @@ MONGO_EXTERN_C_START
  *
  * Sub-documents are framed by "{" "}" string literals, and sub-arrays are framed by "[" "]" literals.
  *
+ * Special function interpolation is indicated with a psuedo-key of ".." followed by macro BFUN with two arguments.
+ * The first argument to the macro is a pointer to a function with the following signature - void (*PF)(bson *b, void *v).
+ * The second argiment to the macro is void *v.
+ * When BSON is generated from the BCON initializer, the function is called with arguments bson *b and void *v.
+ * This is a flexible callback that allows for conditional interpolation based on state from void *v or global state.
+ *
  * All of this is needed because C arrays and initializers are mono-typed unlike dict/array types in modern languages.
  * BCON attempts to be readable and JSON-like within the context and restrictions of the C language.
  *
@@ -108,13 +114,44 @@ MONGO_EXTERN_C_START
  *         bson_print( b );
  *         bson_destroy( b );
  *
+ * Special function interpolation example
+ * --------------------------------------
+ *
+ *     struct my_fun_struct {
+ *         int condition;
+ *         char *key;
+ *         char *value;
+ *     } my_fun_struct = { 1, "fun_key", "fun_value" };
+ *
+ *     void my_fun( bson *b, void *v ) {
+ *         struct my_fun_struct *mfs = (struct my_fun_struct *)v;
+ *          if (mfs->condition)
+ *              bson_append_string(b, mfs->key, mfs->value);
+ *      }
+ *
+ *      void test_function_special_interpolation( void ) {
+ *          bson b0[1], b1[1],
+ *          bcon bc_doc_0[] = { "k10", "v10", "..", BFUN( my_fun, (void *)&my_fun_struct ), "k11", "v11", "." };
+ *          my_fun_struct.condition = 0;
+ *          bson_from_bcon( b0, bc_doc_0 );
+ *          bson_print( b0 );
+ *          bcon bc_doc_1[] = { "k10", "v10", BFN, BFUN( my_fun, (void *)&my_fun_struct ), "k11", "v11", BEND };
+ *          my_fun_struct.condition = 1;
+ *          my_fun_struct.value = "a_new_fun_value";
+ *          bson_from_bcon( b1, bc_doc_1 );
+ *          bson_print( b1 );
+ *      }
+ *
+ *
  * Peformance
  * ----------
- * BCON costs about three times as much as the equivalent bson function calls required to explicitly construct the document.
- * This is significantly less than the cost of parsing JSON and constructing BSON, and BCON allows value interpolation via pointers.
+ * With compiler optimization -O3, BCON costs about 1.1 to 1.2 times as much
+ * as the equivalent bson function calls required to explicitly construct the document.
+ * This is significantly less than the cost of parsing JSON and constructing BSON,
+ * and BCON allows value interpolation via pointers.
  *
- * Specification
- * -------------
+ * Internal Specification
+ * ----------------------
  * This specification parallels the BSON specification - http://bsonspec.org/#/specification
  *
  *     document    ::= elist
@@ -172,6 +209,8 @@ typedef union bcon {
     int *Pi;         /**< 10  e_name  int32               32-bit Integer interpolation */
     long l;          /**< 12  e_name  int64               64-bit Integer */
     long *Pl;        /**< 12  e_name  int64               64-bit Integer interpolation */
+    void (*PF)(bson *b, void *v); /**< special function for interpolation */
+    void *Pv;                     /**< special function argument for interpolation */
     /* "{" "}" */    /*   03  e_name  document            Embedded document */
     /* "[" "]" */    /*   04  e_name  document            Array */
                      /*   05  e_name  binary              Binary data */
@@ -229,6 +268,9 @@ typedef union bcon {
 /** BCON internal 04 union bcon * Array interpolation type-specifier */
 #define BTPA ":PA:"
 
+/** BCON special function specifier */
+#define BFN ".."
+
 /** BCON 02 cstring string value */
 #define BS(v) BTS, { .s = (v) }
 /** BCON 01 double Floating point value */
@@ -269,6 +311,9 @@ typedef union bcon {
 /** BCON 04 union bcon * Array interpolation value */
 #define BPA(v) BTPA, { .PA = (v) }
 
+/** BCON special function interpolation */
+#define BFUN(f, v) { .PF = (f) }, { .Pv = (v) }
+
 /*
  * References on codes used for types
  *     http://en.wikipedia.org/wiki/Name_mangling
@@ -314,6 +359,7 @@ MONGO_EXTERN_C_END
 typedef enum bcon_token_t {
     Token_Default, Token_End, Token_Typespec,
     Token_OpenBrace, Token_CloseBrace, Token_OpenBracket, Token_CloseBracket,
+    Token_Fun,
     Token_EOD
 } bcon_token_t;
 
diff --git a/test/bcon_test.c b/test/bcon_test.c
index f71a710..de57e7f 100644
--- a/test/bcon_test.c
+++ b/test/bcon_test.c
@@ -32,6 +32,8 @@ void test_bcon_token() {
     assert(Token_CloseBrace == bcon_token("}"));
     assert(Token_OpenBracket == bcon_token("["));
     assert(Token_CloseBracket == bcon_token("]"));
+    assert(Token_End == bcon_token("."));
+    assert(Token_Fun == bcon_token(".."));
     assert(Token_EOD == bcon_token(0));
 }
 
@@ -120,6 +122,28 @@ void test_high_order_interpolation() {
     test_bson_from_bcon( bc_parent_doc_array, BCON_OK, BSON_VALID );
 }
 
+struct my_fun_struct {
+    int condition;
+    char *key;
+    char *value;
+} my_fun_struct = { 1, "fun_key", "fun_value" };
+
+void my_fun(bson *b, void *v) {
+    struct my_fun_struct *mfs = (struct my_fun_struct *)v;
+    if (mfs->condition)
+        bson_append_string(b, mfs->key, mfs->value);
+}
+
+void test_special_fun_interpolation() {
+    bcon bc_doc_0[] = { "k10", "v10", "..", BFUN(my_fun, (void *)&my_fun_struct), "k11", "v11", BEND };
+    my_fun_struct.condition = 0;
+    test_bson_from_bcon( bc_doc_0, BCON_OK, BSON_VALID );
+    bcon bc_doc_1[] = { "k10", "v10", BFN, BFUN(my_fun, (void *)&my_fun_struct), "k11", "v11", BEND };
+    my_fun_struct.condition = 1;
+    my_fun_struct.value = "a_new_fun_value";
+    test_bson_from_bcon( bc_doc_1, BCON_OK, BSON_VALID );
+}
+
 void test_example_hello_world() {
     bcon_error_t ret;
     bson b[1];
@@ -283,8 +307,9 @@ struct test_suite {
     NAME_VALUE(test_valid_structure),
     NAME_VALUE(test_problematic_structure),
     NAME_VALUE(test_high_order_interpolation),
+    NAME_VALUE(test_special_fun_interpolation),
     NAME_VALUE(test_example_hello_world),
-    NAME_VALUE(test_example_awesome),
+    NAME_VALUE(test_example_awesome)
     /* NAME_VALUE(test_example_wikipedia), */
 };
 
