Ivo,

FWIW there is an old branch of R with optional types which was part of the R5 
experiment (to declare R5 method argument types more intuitively):

https://svn.r-project.org/R/branches/R-exp-R5/

The parser has changed a bit in the meantime so attached is diff against the 
current R-devel if you want to play with it. This allows the following syntax:

> f <- function(a, character x, integer y=1:10) x
> str(formals(f))
Dotted pair list of 3
 $ a: symbol  
 $ x: symbol  
 $ y: language 1:10
 - attr(*, "type")=List of 3
  ..$ : NULL
  ..$ : symbol character
  ..$ : symbol integer

It doesn't actually do anything with the information, just allows to tag the 
formals so you can play with ideas at the R level.

Cheers,
Simon

-- cut here --

Index: src/include/Defn.h
===================================================================
--- src/include/Defn.h  (revision 89063)
+++ src/include/Defn.h  (working copy)
@@ -756,6 +756,10 @@
 SEXP R_tryWrap(SEXP);
 SEXP R_tryUnwrap(SEXP);
 
+/* experimental argument type macros */
+#define SET_ARGTYPE(x, type) Rf_setAttrib(x, R_TypeSymbol, type)
+#define GET_ARGTYPE(x) Rf_getAttrib(x, R_TypeSymbol)
+
 Rboolean Rf_pmatch(SEXP, SEXP, Rboolean);
 Rboolean Rf_psmatch(const char *, const char *, Rboolean);
 void Rf_printwhere(void);
Index: src/include/Rinternals.h
===================================================================
--- src/include/Rinternals.h    (revision 89063)
+++ src/include/Rinternals.h    (working copy)
@@ -457,6 +457,7 @@
 LibExtern SEXP R_SpecSymbol;   // "spec"
 LibExtern SEXP R_TripleColonSymbol;// ":::"
 LibExtern SEXP R_TspSymbol;        /* "tsp" */
+LibExtern SEXP R_TypeSymbol;       /* "type" */
 
 LibExtern SEXP  R_dot_defined;      /* ".defined" */
 LibExtern SEXP  R_dot_Method;       /* ".Method" */
Index: src/main/gram.c
===================================================================
--- src/main/gram.c     (revision 89063)
+++ src/main/gram.c     (working copy)
@@ -241,6 +241,7 @@
 
 static void    CheckFormalArgs(SEXP, SEXP, YYLTYPE *);
 static SEXP    FirstArg(SEXP, SEXP); /* create list with one element */
+static SEXP    FirstArgWithType(SEXP, SEXP, SEXP);
 static void    GrowList(SEXP, SEXP); /* add element to list end */
 
 static void    SetSingleSrcRef(SEXP);
@@ -252,6 +253,7 @@
 static int     KeywordLookup(const char *);
 static SEXP    NewList(void);
 static void    NextArg(SEXP, SEXP, SEXP); /* add named element to list end */
+static void    NextArgWithType(SEXP, SEXP, SEXP, SEXP);
 static SEXP    TagArg(SEXP, SEXP, YYLTYPE *);
 static int     processLineDirective(int *);
 static bool      checkForPlaceholder(SEXP placeholder, SEXP arg);
@@ -427,8 +429,12 @@
 static SEXP    xxnullformal(void);
 static SEXP    xxfirstformal0(SEXP);
 static SEXP    xxfirstformal1(SEXP, SEXP);
+static SEXP    xxfirstformal2(SEXP, SEXP);
+static SEXP    xxfirstformal3(SEXP, SEXP, SEXP);
 static SEXP    xxaddformal0(SEXP, SEXP, YYLTYPE *);
 static SEXP    xxaddformal1(SEXP, SEXP, SEXP, YYLTYPE *);
+static SEXP    xxaddformal2(SEXP, SEXP, SEXP, YYLTYPE *);
+static SEXP    xxaddformal3(SEXP, SEXP, SEXP, SEXP, YYLTYPE *);
 static SEXP    xxexprlist0(void);
 static SEXP    xxexprlist1(SEXP, YYLTYPE *);
 static SEXP    xxexprlist2(SEXP, SEXP, YYLTYPE *);
@@ -557,62 +563,6 @@
   };
   typedef enum yytokentype yytoken_kind_t;
 #endif
-/* Token kinds.  */
-#define YYEMPTY -2
-#define YYEOF 0
-#define YYerror 256
-#define YYUNDEF 257
-#define END_OF_INPUT 258
-#define ERROR 259
-#define STR_CONST 260
-#define NUM_CONST 261
-#define NULL_CONST 262
-#define SYMBOL 263
-#define FUNCTION 264
-#define INCOMPLETE_STRING 265
-#define LEFT_ASSIGN 266
-#define EQ_ASSIGN 267
-#define RIGHT_ASSIGN 268
-#define LBB 269
-#define FOR 270
-#define IN 271
-#define IF 272
-#define ELSE 273
-#define WHILE 274
-#define NEXT 275
-#define BREAK 276
-#define REPEAT 277
-#define GT 278
-#define GE 279
-#define LT 280
-#define LE 281
-#define EQ 282
-#define NE 283
-#define AND 284
-#define OR 285
-#define AND2 286
-#define OR2 287
-#define NS_GET 288
-#define NS_GET_INT 289
-#define COMMENT 290
-#define LINE_DIRECTIVE 291
-#define SYMBOL_FORMALS 292
-#define EQ_FORMALS 293
-#define EQ_SUB 294
-#define SYMBOL_SUB 295
-#define SYMBOL_FUNCTION_CALL 296
-#define SYMBOL_PACKAGE 297
-#define SLOT 298
-#define PIPE 299
-#define PLACEHOLDER 300
-#define PIPEBIND 301
-#define LOW 302
-#define TILDE 303
-#define UNOT 304
-#define NOT 305
-#define SPECIAL 306
-#define UMINUS 307
-#define UPLUS 308
 
 /* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
@@ -1065,7 +1015,7 @@
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  48
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   572
+#define YYLAST   601
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  75
@@ -1072,9 +1022,9 @@
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  13
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  94
+#define YYNRULES  98
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  174
+#define YYNSTATES  180
 
 /* YYMAXUTOK -- Last valid token kind.  */
 #define YYMAXUTOK   308
@@ -1128,16 +1078,16 @@
 /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_int16 yyrline[] =
 {
-       0,   446,   446,   447,   448,   449,   450,   453,   454,   455,
-     458,   459,   462,   463,   464,   465,   466,   468,   469,   471,
-     472,   473,   474,   475,   477,   478,   479,   480,   481,   482,
-     483,   484,   485,   486,   487,   488,   489,   490,   491,   492,
-     493,   494,   495,   496,   497,   498,   499,   501,   502,   503,
-     504,   505,   506,   507,   508,   509,   510,   511,   512,   513,
-     514,   515,   516,   517,   518,   519,   520,   521,   522,   523,
-     527,   530,   533,   537,   538,   539,   540,   541,   542,   545,
-     546,   549,   550,   551,   552,   553,   554,   555,   556,   559,
-     560,   561,   562,   563,   567
+       0,   452,   452,   453,   454,   455,   456,   459,   460,   461,
+     464,   465,   468,   469,   470,   471,   472,   474,   475,   477,
+     478,   479,   480,   481,   483,   484,   485,   486,   487,   488,
+     489,   490,   491,   492,   493,   494,   495,   496,   497,   498,
+     499,   500,   501,   502,   503,   504,   505,   507,   508,   509,
+     510,   511,   512,   513,   514,   515,   516,   517,   518,   519,
+     520,   521,   522,   523,   524,   525,   526,   527,   528,   529,
+     533,   536,   539,   543,   544,   545,   546,   547,   548,   551,
+     552,   555,   556,   557,   558,   559,   560,   561,   562,   565,
+     566,   567,   568,   569,   571,   572,   574,   575,   578
 };
 #endif
 
@@ -1176,7 +1126,7 @@
 }
 #endif
 
-#define YYPACT_NINF (-130)
+#define YYPACT_NINF (-138)
 
 #define yypact_value_is_default(Yyn) \
   ((Yyn) == YYPACT_NINF)
@@ -1190,24 +1140,24 @@
    STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-     139,  -130,  -130,   -11,  -130,  -130,     2,   -49,    10,    27,
-      29,  -130,  -130,   209,  -130,   209,   209,   209,   209,   209,
-    -130,   209,   209,    30,    95,    14,   281,    16,    70,    71,
-      77,    88,    89,   209,   209,   209,   209,   209,    86,    86,
-     371,   225,   225,    13,    18,   -53,   440,    88,  -130,   209,
-     209,  -130,  -130,   209,   209,   229,   209,   209,   209,   209,
-     209,   209,   209,   209,   209,   209,   209,   209,   209,   209,
-     209,   209,   209,   209,   209,   209,    82,    84,   229,   229,
-    -130,  -130,  -130,  -130,  -130,  -130,  -130,  -130,    87,    -3,
-      90,    86,   -43,   281,    -1,   -39,    86,  -130,   209,   209,
-    -130,     3,    86,    86,   281,   326,    -5,    91,     0,    55,
-      31,  -130,   485,   485,   485,   485,   485,   485,   440,   416,
-     440,   416,   206,   107,   371,   118,   118,   507,   507,   206,
-     225,   225,  -130,  -130,  -130,  -130,    35,    36,   209,  -130,
-     100,   209,   209,  -130,   209,  -130,    18,    18,  -130,   209,
-     209,   209,    39,    40,  -130,  -130,    55,   209,   101,   -38,
-    -130,    86,   209,    55,    55,    55,  -130,   229,    86,   209,
-    -130,    86,  -130,    55
+     192,  -138,  -138,    44,  -138,  -138,    70,   -55,   -48,   -35,
+     -28,  -138,  -138,   212,  -138,   212,   212,   212,   212,   212,
+    -138,   212,   212,    15,    22,    14,   332,    82,    84,    86,
+      88,    16,    77,   212,   212,   212,   212,   212,    85,    85,
+     422,    68,    68,    13,    21,     7,   491,    16,  -138,   212,
+     212,  -138,  -138,   212,   212,   280,   212,   212,   212,   212,
+     212,   212,   212,   212,   212,   212,   212,   212,   212,   212,
+     212,   212,   212,   212,   212,   212,    90,    94,   280,   280,
+    -138,  -138,  -138,  -138,  -138,  -138,  -138,  -138,     3,   -53,
+      91,    85,   -43,   332,    -4,   -42,    85,  -138,   212,   212,
+    -138,   -51,    85,    85,   332,   377,    -2,    96,     1,    62,
+      37,  -138,   536,   536,   536,   536,   536,   536,   491,   467,
+     491,   467,   114,    55,   422,   248,   248,   101,   101,   114,
+      68,    68,  -138,  -138,  -138,  -138,    41,    39,   102,   212,
+    -138,   113,   212,   212,  -138,   212,  -138,    21,    21,  -138,
+     212,   212,   212,    49,    50,  -138,  -138,   212,    62,   212,
+      63,   -40,  -138,    85,   212,    62,    62,    62,  -138,   280,
+      62,    85,   125,   212,  -138,    85,  -138,   212,    62,    62
 };
 
 /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -1226,20 +1176,20 @@
       59,    58,    63,    62,    57,    56,    61,    60,    90,     0,
        0,    51,     0,    10,    49,     0,    52,    18,    78,    76,
       17,     0,     8,     9,    44,    45,    13,    14,    16,    82,
-      94,    79,    37,    36,    32,    33,    34,    35,    38,    39,
+      98,    79,    37,    36,    32,    33,    34,    35,    38,    39,
       40,    41,    42,    43,    31,    25,    26,    27,    28,    30,
-      24,    29,    65,    64,    67,    66,    94,    94,     0,    94,
-       0,     0,     0,    71,     0,    70,    77,    75,    94,    85,
-      87,    83,     0,     0,    48,    55,    91,     0,    92,     0,
-      11,    50,     0,    86,    88,    84,    54,    81,    46,     0,
-      72,    47,    80,    93
+      24,    29,    65,    64,    67,    66,    98,    98,    92,     0,
+      98,     0,     0,     0,    71,     0,    70,    77,    75,    98,
+      85,    87,    83,     0,     0,    48,    55,     0,    91,     0,
+      94,     0,    11,    50,     0,    86,    88,    84,    54,    81,
+      93,    46,    96,     0,    72,    47,    80,     0,    95,    97
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -130,  -130,    51,   -31,   -16,  -130,  -130,  -130,  -130,   -10,
-     -52,    69,  -129
+    -138,  -138,    51,    31,   -16,  -138,  -138,  -138,  -138,    27,
+     -44,    92,  -137
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
@@ -1246,7 +1196,7 @@
 static const yytype_uint8 yydefgoto[] =
 {
        0,    24,    25,   109,    26,    37,    35,    33,    45,   110,
-     111,    89,   153
+     111,    89,   154
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -1254,126 +1204,132 @@
    number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int16 yytable[] =
 {
-      40,    41,    42,    92,   142,    95,    46,   149,   142,   142,
-     157,    49,   151,    98,    99,    31,   100,   144,    93,   162,
-      93,    80,    27,    28,    81,    49,    49,   143,    27,    28,
-      49,   145,   170,    29,    30,    29,    30,   104,   105,    93,
+      40,    41,    42,   159,   143,   143,    46,   143,    49,    31,
+     150,   138,   164,   152,   145,   139,    32,   140,    93,   149,
+      93,   141,    48,   141,    88,    49,    49,   144,   146,    34,
+     174,    27,    28,    49,    29,    30,    36,   104,   105,    93,
      112,   113,   114,   115,   116,   117,   118,   119,   120,   121,
      122,   123,   124,   125,   126,   127,   128,   129,   130,   131,
-      50,    50,    93,    93,    38,    50,    39,   139,   136,   137,
-      43,   140,    44,   148,    32,    82,    84,   140,    83,    85,
-      51,    52,    86,    97,    91,    87,    94,   132,    96,   134,
-     133,    34,   135,    36,    47,    48,    88,    90,    49,   138,
-     102,   103,   142,   150,   152,   154,   141,   156,   158,   155,
-     159,   160,   166,   169,   167,   172,   101,     0,   163,   164,
-     165,    55,    93,     0,     0,    93,    93,     0,     0,     0,
-       0,     0,    55,    93,    93,    93,     0,     0,   173,     0,
-       1,     0,     2,     0,     3,     4,     5,     6,     7,   146,
-     147,    93,     0,    93,     8,     0,     9,     0,    10,    11,
-      12,    13,    66,     0,    67,    74,     0,     0,    75,    76,
-      77,    78,    79,    71,    72,    73,    74,     0,     0,    75,
-      76,    77,    78,    79,    14,     0,    15,     0,    16,     0,
-       0,     0,    17,    18,     0,   161,     0,     0,     0,     0,
-       0,     0,     0,    19,     0,    20,     0,    21,   168,     0,
-      22,    23,     0,   171,     3,     4,     5,     6,     7,     0,
-      55,     0,     0,     0,     8,     0,     9,     0,    10,    11,
-      12,    13,     0,     0,   106,     4,   107,   108,     7,    55,
-       0,     0,     0,     0,     8,     0,     9,     0,    10,    11,
-      12,    13,    67,     0,    14,     0,    15,     0,    16,     0,
-       0,     0,    17,    18,    74,     0,     0,    75,    76,    77,
-      78,    79,     0,    19,    14,     0,    15,    21,    16,     0,
-      22,    23,    17,    18,     0,     0,    75,    76,    77,    78,
-      79,     0,    53,    19,    54,    55,     0,    21,     0,     0,
-      22,    23,     0,     0,    56,    57,    58,    59,    60,    61,
-      62,    63,    64,    65,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    66,     0,    67,     0,     0,
-      68,     0,     0,     0,    69,    70,    71,    72,    73,    74,
-      55,     0,    75,    76,    77,    78,    79,     0,     0,    56,
-      57,    58,    59,    60,    61,    62,    63,    64,    65,     0,
+      50,    50,    93,    93,    38,    92,    39,    95,    50,    55,
+      43,   172,    44,    98,    99,   173,   100,    27,    28,    47,
+      51,    52,    55,    97,    91,    90,    94,    80,    96,    82,
+      81,    84,    83,    86,    85,   132,    87,    49,   133,   134,
+     102,   103,   135,    29,    30,   136,   137,   142,   151,   143,
+     153,   155,   156,    74,   157,    55,    75,    76,    77,    78,
+      79,   160,   168,    93,   169,   176,    93,    93,    55,    75,
+      76,    77,    78,    79,    93,    93,    93,   177,     0,   101,
+       0,    93,     0,     0,     0,    66,     0,    67,     0,   147,
+     148,     0,     0,    93,     0,     0,     0,    93,    73,    74,
+      67,    93,    75,    76,    77,    78,    79,     0,     0,     0,
+     158,     0,    74,   161,   162,    75,    76,    77,    78,    79,
+       0,   165,   166,   167,     0,     0,     0,     0,   170,     0,
+       0,     0,     0,     1,     0,     2,   163,     3,     4,     5,
+       6,     7,     0,     0,   178,     0,     0,     8,   179,     9,
+     171,    10,    11,    12,    13,   175,     0,     3,     4,     5,
+       6,     7,     0,     0,     0,     0,     0,     8,     0,     9,
+       0,    10,    11,    12,    13,     0,     0,    14,     0,    15,
+       0,    16,     0,     0,     0,    17,    18,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    19,    14,    20,    15,
+      21,    16,    55,    22,    23,    17,    18,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    19,     0,     0,     0,
+      21,     0,     0,    22,    23,   106,     4,   107,   108,     7,
+       0,     0,    66,     0,    67,     8,     0,     9,     0,    10,
+      11,    12,    13,    71,    72,    73,    74,     0,     0,    75,
+      76,    77,    78,    79,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    14,     0,    15,     0,    16,
+       0,     0,     0,    17,    18,     0,     0,     0,     0,     0,
+       0,     0,     0,    53,    19,    54,    55,     0,    21,     0,
+       0,    22,    23,     0,     0,    56,    57,    58,    59,    60,
+      61,    62,    63,    64,    65,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    66,     0,    67,     0,
+       0,    68,     0,     0,     0,    69,    70,    71,    72,    73,
+      74,    55,     0,    75,    76,    77,    78,    79,     0,     0,
+      56,    57,    58,    59,    60,    61,    62,    63,    64,    65,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-      66,     0,    67,     0,     0,    68,     0,     0,     0,    69,
-      70,    71,    72,    73,    74,    55,     0,    75,    76,    77,
-      78,    79,     0,     0,    56,    57,    58,    59,    60,    61,
-      62,    63,    64,    65,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    66,     0,    67,     0,     0,
+       0,    66,     0,    67,     0,     0,    68,     0,     0,     0,
+      69,    70,    71,    72,    73,    74,    55,     0,    75,    76,
+      77,    78,    79,     0,     0,    56,    57,    58,    59,    60,
+      61,    62,    63,    64,    65,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    66,     0,    67,     0,
+       0,     0,     0,     0,     0,    69,    70,    71,    72,    73,
+      74,    55,     0,    75,    76,    77,    78,    79,     0,     0,
+      56,    57,    58,    59,    60,    61,    62,     0,    64,     0,
+       0,     0,     0,     0,     0,    55,     0,     0,     0,     0,
+       0,    66,     0,    67,    56,    57,    58,    59,    60,    61,
+      69,    70,    71,    72,    73,    74,     0,     0,    75,    76,
+      77,    78,    79,     0,     0,    66,     0,    67,     0,     0,
        0,     0,     0,     0,    69,    70,    71,    72,    73,    74,
-      55,     0,    75,    76,    77,    78,    79,     0,     0,    56,
-      57,    58,    59,    60,    61,    62,     0,    64,     0,     0,
-       0,     0,     0,     0,    55,     0,     0,     0,     0,     0,
-      66,     0,    67,    56,    57,    58,    59,    60,    61,    69,
+      55,     0,    75,    76,    77,    78,    79,     0,     0,    -1,
+      -1,    -1,    -1,    -1,    -1,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      66,     0,    67,     0,     0,     0,     0,     0,     0,    69,
       70,    71,    72,    73,    74,     0,     0,    75,    76,    77,
-      78,    79,     0,     0,    66,     0,    67,     0,     0,     0,
-       0,     0,     0,    69,    70,    71,    72,    73,    74,    55,
-       0,    75,    76,    77,    78,    79,     0,     0,    -1,    -1,
-      -1,    -1,    -1,    -1,     0,     0,     0,     0,     0,     0,
-       0,    55,     0,     0,     0,     0,     0,     0,     0,    66,
-       0,    67,     0,     0,     0,     0,     0,     0,    69,    70,
-      71,    72,    73,    74,     0,     0,    75,    76,    77,    78,
-      79,    66,     0,    67,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    73,    74,     0,     0,    75,    76,
-      77,    78,    79
+      78,    79
 };
 
 static const yytype_int16 yycheck[] =
 {
-      16,    17,    18,    34,    47,    36,    22,    12,    47,    47,
-     139,    12,    12,    66,    67,    64,    69,    18,    34,   148,
-      36,     5,    33,    34,     8,    12,    12,    70,    33,    34,
-      12,    70,    70,    33,    34,    33,    34,    53,    54,    55,
+      16,    17,    18,   140,    47,    47,    22,    47,    12,    64,
+      12,     8,   149,    12,    18,    12,    64,    70,    34,    70,
+      36,    74,     0,    74,     8,    12,    12,    70,    70,    64,
+      70,    33,    34,    12,    33,    34,    64,    53,    54,    55,
       56,    57,    58,    59,    60,    61,    62,    63,    64,    65,
       66,    67,    68,    69,    70,    71,    72,    73,    74,    75,
-      47,    47,    78,    79,    13,    47,    15,    70,    78,    79,
-      19,    74,    21,    70,    64,     5,     5,    74,     8,     8,
-      66,    67,     5,    70,    33,     8,    35,     5,    37,     5,
-       8,    64,     8,    64,    64,     0,     8,     8,    12,    12,
-      49,    50,    47,    12,    73,    70,    16,   138,     8,    73,
-     141,   142,    73,    12,    74,   167,    47,    -1,   149,   150,
-     151,    14,   138,    -1,    -1,   141,   142,    -1,    -1,    -1,
-      -1,    -1,    14,   149,   150,   151,    -1,    -1,   169,    -1,
-       1,    -1,     3,    -1,     5,     6,     7,     8,     9,    98,
-      99,   167,    -1,   169,    15,    -1,    17,    -1,    19,    20,
-      21,    22,    44,    -1,    46,    58,    -1,    -1,    61,    62,
-      63,    64,    65,    55,    56,    57,    58,    -1,    -1,    61,
-      62,    63,    64,    65,    45,    -1,    47,    -1,    49,    -1,
-      -1,    -1,    53,    54,    -1,   144,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    64,    -1,    66,    -1,    68,   157,    -1,
-      71,    72,    -1,   162,     5,     6,     7,     8,     9,    -1,
-      14,    -1,    -1,    -1,    15,    -1,    17,    -1,    19,    20,
-      21,    22,    -1,    -1,     5,     6,     7,     8,     9,    14,
-      -1,    -1,    -1,    -1,    15,    -1,    17,    -1,    19,    20,
-      21,    22,    46,    -1,    45,    -1,    47,    -1,    49,    -1,
-      -1,    -1,    53,    54,    58,    -1,    -1,    61,    62,    63,
-      64,    65,    -1,    64,    45,    -1,    47,    68,    49,    -1,
-      71,    72,    53,    54,    -1,    -1,    61,    62,    63,    64,
-      65,    -1,    11,    64,    13,    14,    -1,    68,    -1,    -1,
-      71,    72,    -1,    -1,    23,    24,    25,    26,    27,    28,
-      29,    30,    31,    32,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    44,    -1,    46,    -1,    -1,
-      49,    -1,    -1,    -1,    53,    54,    55,    56,    57,    58,
-      14,    -1,    61,    62,    63,    64,    65,    -1,    -1,    23,
-      24,    25,    26,    27,    28,    29,    30,    31,    32,    -1,
+      47,    47,    78,    79,    13,    34,    15,    36,    47,    14,
+      19,     8,    21,    66,    67,    12,    69,    33,    34,    64,
+      66,    67,    14,    70,    33,     8,    35,     5,    37,     5,
+       8,     5,     8,     5,     8,     5,     8,    12,     8,     5,
+      49,    50,     8,    33,    34,    78,    79,    16,    12,    47,
+      73,    70,    73,    58,    12,    14,    61,    62,    63,    64,
+      65,     8,    73,   139,    74,   169,   142,   143,    14,    61,
+      62,    63,    64,    65,   150,   151,   152,    12,    -1,    47,
+      -1,   157,    -1,    -1,    -1,    44,    -1,    46,    -1,    98,
+      99,    -1,    -1,   169,    -1,    -1,    -1,   173,    57,    58,
+      46,   177,    61,    62,    63,    64,    65,    -1,    -1,    -1,
+     139,    -1,    58,   142,   143,    61,    62,    63,    64,    65,
+      -1,   150,   151,   152,    -1,    -1,    -1,    -1,   157,    -1,
+      -1,    -1,    -1,     1,    -1,     3,   145,     5,     6,     7,
+       8,     9,    -1,    -1,   173,    -1,    -1,    15,   177,    17,
+     159,    19,    20,    21,    22,   164,    -1,     5,     6,     7,
+       8,     9,    -1,    -1,    -1,    -1,    -1,    15,    -1,    17,
+      -1,    19,    20,    21,    22,    -1,    -1,    45,    -1,    47,
+      -1,    49,    -1,    -1,    -1,    53,    54,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    64,    45,    66,    47,
+      68,    49,    14,    71,    72,    53,    54,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    64,    -1,    -1,    -1,
+      68,    -1,    -1,    71,    72,     5,     6,     7,     8,     9,
+      -1,    -1,    44,    -1,    46,    15,    -1,    17,    -1,    19,
+      20,    21,    22,    55,    56,    57,    58,    -1,    -1,    61,
+      62,    63,    64,    65,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    45,    -1,    47,    -1,    49,
+      -1,    -1,    -1,    53,    54,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    11,    64,    13,    14,    -1,    68,    -1,
+      -1,    71,    72,    -1,    -1,    23,    24,    25,    26,    27,
+      28,    29,    30,    31,    32,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    44,    -1,    46,    -1,
+      -1,    49,    -1,    -1,    -1,    53,    54,    55,    56,    57,
+      58,    14,    -1,    61,    62,    63,    64,    65,    -1,    -1,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      44,    -1,    46,    -1,    -1,    49,    -1,    -1,    -1,    53,
-      54,    55,    56,    57,    58,    14,    -1,    61,    62,    63,
-      64,    65,    -1,    -1,    23,    24,    25,    26,    27,    28,
-      29,    30,    31,    32,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    44,    -1,    46,    -1,    -1,
+      -1,    44,    -1,    46,    -1,    -1,    49,    -1,    -1,    -1,
+      53,    54,    55,    56,    57,    58,    14,    -1,    61,    62,
+      63,    64,    65,    -1,    -1,    23,    24,    25,    26,    27,
+      28,    29,    30,    31,    32,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    44,    -1,    46,    -1,
+      -1,    -1,    -1,    -1,    -1,    53,    54,    55,    56,    57,
+      58,    14,    -1,    61,    62,    63,    64,    65,    -1,    -1,
+      23,    24,    25,    26,    27,    28,    29,    -1,    31,    -1,
+      -1,    -1,    -1,    -1,    -1,    14,    -1,    -1,    -1,    -1,
+      -1,    44,    -1,    46,    23,    24,    25,    26,    27,    28,
+      53,    54,    55,    56,    57,    58,    -1,    -1,    61,    62,
+      63,    64,    65,    -1,    -1,    44,    -1,    46,    -1,    -1,
       -1,    -1,    -1,    -1,    53,    54,    55,    56,    57,    58,
       14,    -1,    61,    62,    63,    64,    65,    -1,    -1,    23,
-      24,    25,    26,    27,    28,    29,    -1,    31,    -1,    -1,
-      -1,    -1,    -1,    -1,    14,    -1,    -1,    -1,    -1,    -1,
-      44,    -1,    46,    23,    24,    25,    26,    27,    28,    53,
+      24,    25,    26,    27,    28,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      44,    -1,    46,    -1,    -1,    -1,    -1,    -1,    -1,    53,
       54,    55,    56,    57,    58,    -1,    -1,    61,    62,    63,
-      64,    65,    -1,    -1,    44,    -1,    46,    -1,    -1,    -1,
-      -1,    -1,    -1,    53,    54,    55,    56,    57,    58,    14,
-      -1,    61,    62,    63,    64,    65,    -1,    -1,    23,    24,
-      25,    26,    27,    28,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    14,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    44,
-      -1,    46,    -1,    -1,    -1,    -1,    -1,    -1,    53,    54,
-      55,    56,    57,    58,    -1,    -1,    61,    62,    63,    64,
-      65,    44,    -1,    46,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    57,    58,    -1,    -1,    61,    62,
-      63,    64,    65
+      64,    65
 };
 
 /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
@@ -1393,11 +1349,11 @@
       69,    86,    77,    77,    79,    79,     5,     7,     8,    78,
       84,    85,    79,    79,    79,    79,    79,    79,    79,    79,
       79,    79,    79,    79,    79,    79,    79,    79,    79,    79,
-      79,    79,     5,     8,     5,     8,    84,    84,    12,    70,
-      74,    16,    47,    70,    18,    70,    77,    77,    70,    12,
-      12,    12,    73,    87,    70,    73,    78,    87,     8,    78,
-      78,    77,    87,    78,    78,    78,    73,    74,    77,    12,
-      70,    77,    85,    78
+      79,    79,     5,     8,     5,     8,    84,    84,     8,    12,
+      70,    74,    16,    47,    70,    18,    70,    77,    77,    70,
+      12,    12,    12,    73,    87,    70,    73,    12,    78,    87,
+       8,    78,    78,    77,    87,    78,    78,    78,    73,    74,
+      78,    77,     8,    12,    70,    77,    85,    12,    78,    78
 };
 
 /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM.  */
@@ -1412,7 +1368,7 @@
       79,    79,    79,    79,    79,    79,    79,    79,    79,    79,
       80,    81,    82,    83,    83,    83,    83,    83,    83,    84,
       84,    85,    85,    85,    85,    85,    85,    85,    85,    86,
-      86,    86,    86,    86,    87
+      86,    86,    86,    86,    86,    86,    86,    86,    87
 };
 
 /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule 
RULE-NUM.  */
@@ -1427,7 +1383,7 @@
        3,     3,     3,     3,     3,     3,     3,     3,     1,     1,
        3,     3,     5,     0,     1,     3,     2,     3,     2,     1,
        4,     0,     1,     2,     3,     2,     3,     2,     3,     0,
-       1,     3,     3,     5,     0
+       1,     3,     2,     4,     3,     5,     4,     6,     0
 };
 
 
@@ -2634,15 +2590,31 @@
                                                 { yyval = 
xxfirstformal1(yyvsp[-2],yyvsp[0]);  modif_token( &(yylsp[-2]), SYMBOL_FORMALS 
) ; modif_token( &(yylsp[-1]), EQ_FORMALS ) ; }
     break;
 
-  case 92: /* formlist: formlist ',' SYMBOL  */
+  case 92: /* formlist: SYMBOL SYMBOL  */
+                                                { yyval = 
xxfirstformal2(yyvsp[0],yyvsp[-1]);   modif_token( &(yylsp[0]), SYMBOL_FORMALS 
) ; }
+    break;
+
+  case 93: /* formlist: SYMBOL SYMBOL EQ_ASSIGN expr_or_help  */
+                                                { yyval = 
xxfirstformal3(yyvsp[-2],yyvsp[0],yyvsp[-3]);   modif_token( &(yylsp[-2]), 
SYMBOL_FORMALS ) ; modif_token( &(yylsp[-1]), EQ_FORMALS ) ; }
+    break;
+
+  case 94: /* formlist: formlist ',' SYMBOL  */
                                                 { yyval = 
xxaddformal0(yyvsp[-2],yyvsp[0], &(yylsp[0]));   modif_token( &(yylsp[0]), 
SYMBOL_FORMALS ) ; }
     break;
 
-  case 93: /* formlist: formlist ',' SYMBOL EQ_ASSIGN expr_or_help  */
-                                                { yyval = 
xxaddformal1(yyvsp[-4],yyvsp[-2],yyvsp[0],&(yylsp[-2])); modif_token( 
&(yylsp[-2]), SYMBOL_FORMALS ) ; modif_token( &(yylsp[-1]), EQ_FORMALS ) ;}
+  case 95: /* formlist: formlist ',' SYMBOL EQ_ASSIGN expr_or_help  */
+                                                { yyval = 
xxaddformal1(yyvsp[-4],yyvsp[-2],yyvsp[0],&(yylsp[-2])); modif_token( 
&(yylsp[-2]), SYMBOL_FORMALS ) ; modif_token( &(yylsp[-1]), EQ_FORMALS ) ; }
     break;
 
-  case 94: /* cr: %empty  */
+  case 96: /* formlist: formlist ',' SYMBOL SYMBOL  */
+                                                { yyval = 
xxaddformal2(yyvsp[-3],yyvsp[0],yyvsp[-1],&(yylsp[-1])); modif_token( 
&(yylsp[0]), SYMBOL_FORMALS ) ; }
+    break;
+
+  case 97: /* formlist: formlist ',' SYMBOL SYMBOL EQ_ASSIGN expr_or_help  */
+                                                                        { 
yyval = xxaddformal3(yyvsp[-5],yyvsp[-2],yyvsp[0],yyvsp[-3],&(yylsp[-3])); 
modif_token( &(yylsp[-2]), SYMBOL_FORMALS ) ; modif_token( &(yylsp[-1]), 
EQ_FORMALS ) ; }
+    break;
+
+  case 98: /* cr: %empty  */
                                                 { EatLines = 1; }
     break;
 
@@ -3157,6 +3129,31 @@
     return ans;
 }
 
+static SEXP xxfirstformal2(SEXP sym, SEXP type)
+{
+    SEXP ans;
+    if (GenerateCode)
+       PRESERVE_SV(ans = FirstArgWithType(R_MissingArg, sym, type));
+    else
+       PRESERVE_SV(ans = R_NilValue);
+    RELEASE_SV(type);
+    RELEASE_SV(sym);
+    return ans;
+}
+
+static SEXP xxfirstformal3(SEXP sym, SEXP expr, SEXP type)
+{
+    SEXP ans;
+    if (GenerateCode)
+       PRESERVE_SV(ans = FirstArgWithType(expr, sym, type));
+    else
+       PRESERVE_SV(ans = R_NilValue);
+    RELEASE_SV(type);
+    RELEASE_SV(expr);
+    RELEASE_SV(sym);
+    return ans;
+}
+
 static SEXP xxaddformal0(SEXP formlist, SEXP sym, YYLTYPE *lloc)
 {
     SEXP ans;
@@ -3188,6 +3185,39 @@
     return ans;
 }
 
+static SEXP xxaddformal2(SEXP formlist, SEXP sym, SEXP type, YYLTYPE *lloc)
+{
+    SEXP ans;
+    if (GenerateCode) {
+       CheckFormalArgs(formlist, sym, lloc);
+       NextArgWithType(formlist, R_MissingArg, sym, type);
+       ans = formlist;
+    } else {
+       RELEASE_SV(formlist);
+       PRESERVE_SV(ans = R_NilValue);
+    }
+    RELEASE_SV(sym);
+    RELEASE_SV(type);
+    return ans;
+}
+
+static SEXP xxaddformal3(SEXP formlist, SEXP sym, SEXP expr, SEXP type, 
YYLTYPE *lloc)
+{
+    SEXP ans;
+    if (GenerateCode) {
+       CheckFormalArgs(formlist, sym, lloc);
+       NextArgWithType(formlist, expr, sym, type);
+       ans = formlist;
+    } else {
+       RELEASE_SV(formlist);
+       PRESERVE_SV(ans = R_NilValue);
+    }
+    RELEASE_SV(expr);
+    RELEASE_SV(sym);
+    RELEASE_SV(type);
+    return ans;
+}
+
 static SEXP xxexprlist0(void)
 {
     SEXP ans;
@@ -3473,6 +3503,40 @@
     return t;
 }
 
+/* originally, the idea was to use attribute on each entry, but
+   attrs are only allowed on the outside of LISTSXP so we collect them
+   into one attribute so they can be used in plain R */
+static SEXP fixupFormalsTypes(SEXP formals) {
+    SEXP c = CDR(formals);
+    int i = 0, xty = 0; /* find last type declaration */
+    while (c != R_NilValue) {
+       i++;
+       /* for speed we don't check the name */
+       if (ATTRIB(c) != R_NilValue)
+           xty = i;
+       c = CDR(c);
+    }
+    if (xty > 0) {
+       SEXP types = PROTECT(Rf_allocVector(VECSXP, i));
+       c = CDR(formals);
+       i = 0;
+       while (c != R_NilValue) {
+           SEXP a = GET_ARGTYPE(c);
+           if (a != R_NilValue) {
+               
+               SET_VECTOR_ELT(types, i, a);
+               /* do we want to keep them? */
+               SET_ATTRIB(c, R_NilValue);
+           }
+           c = CDR(c);
+           i++;
+       }
+       SET_ARGTYPE(CDR(formals), types);
+       UNPROTECT(1);
+    }
+    return formals;
+}
+
 static SEXP xxdefun(SEXP fname, SEXP formals, SEXP body, YYLTYPE *lloc)
 {
     SEXP ans, srcref;
@@ -3483,7 +3547,7 @@
            ParseState.didAttach = true;
        } else
            srcref = R_NilValue;
-       PRESERVE_SV(ans = lang4(fname, CDR(formals), body, srcref));
+       PRESERVE_SV(ans = lang4(fname, CDR(fixupFormalsTypes(formals)), body, 
srcref));
     } else
        PRESERVE_SV(ans = R_NilValue);
     RELEASE_SV(body);
@@ -3760,6 +3824,17 @@
     return tmp;
 }
 
+static SEXP FirstArgWithType(SEXP s, SEXP tag, SEXP type)
+{
+    SEXP tmp;
+    PROTECT(tmp = NewList());
+    GrowList(tmp, s);
+    SET_TAG(CAR(tmp), tag);
+    SET_ARGTYPE(CAR(tmp), type);
+    UNPROTECT(1);
+    return tmp;
+}
+
 /* Add named element to the end of a stretchy list */
 static void NextArg(SEXP l, SEXP s, SEXP tag)
 {
@@ -3767,6 +3842,13 @@
     SET_TAG(CAR(l), tag);
 }
 
+static void NextArgWithType(SEXP l, SEXP s, SEXP tag, SEXP type)
+{
+    GrowList(l, s);
+    SET_TAG(CAR(l), tag);
+    SET_ARGTYPE(CAR(l), type);
+}
+
 /* SrcRefs (PS_SRCREFS) are represented as R_NilValue (empty) or by 
    a stretchy list (which includes another representation for empty)
    for fast append operation. */
Index: src/main/gram.y
===================================================================
--- src/main/gram.y     (revision 89063)
+++ src/main/gram.y     (working copy)
@@ -173,6 +173,7 @@
 
 static void    CheckFormalArgs(SEXP, SEXP, YYLTYPE *);
 static SEXP    FirstArg(SEXP, SEXP); /* create list with one element */
+static SEXP    FirstArgWithType(SEXP, SEXP, SEXP);
 static void    GrowList(SEXP, SEXP); /* add element to list end */
 
 static void    SetSingleSrcRef(SEXP);
@@ -184,6 +185,7 @@
 static int     KeywordLookup(const char *);
 static SEXP    NewList(void);
 static void    NextArg(SEXP, SEXP, SEXP); /* add named element to list end */
+static void    NextArgWithType(SEXP, SEXP, SEXP, SEXP);
 static SEXP    TagArg(SEXP, SEXP, YYLTYPE *);
 static int     processLineDirective(int *);
 static bool      checkForPlaceholder(SEXP placeholder, SEXP arg);
@@ -359,8 +361,12 @@
 static SEXP    xxnullformal(void);
 static SEXP    xxfirstformal0(SEXP);
 static SEXP    xxfirstformal1(SEXP, SEXP);
+static SEXP    xxfirstformal2(SEXP, SEXP);
+static SEXP    xxfirstformal3(SEXP, SEXP, SEXP);
 static SEXP    xxaddformal0(SEXP, SEXP, YYLTYPE *);
 static SEXP    xxaddformal1(SEXP, SEXP, SEXP, YYLTYPE *);
+static SEXP    xxaddformal2(SEXP, SEXP, SEXP, YYLTYPE *);
+static SEXP    xxaddformal3(SEXP, SEXP, SEXP, SEXP, YYLTYPE *);
 static SEXP    xxexprlist0(void);
 static SEXP    xxexprlist1(SEXP, YYLTYPE *);
 static SEXP    xxexprlist2(SEXP, SEXP, YYLTYPE *);
@@ -559,9 +565,14 @@
 formlist:                                      { $$ = xxnullformal(); }
        |       SYMBOL                          { $$ = xxfirstformal0($1);      
modif_token( &@1, SYMBOL_FORMALS ) ; }
        |       SYMBOL EQ_ASSIGN expr_or_help   { $$ = xxfirstformal1($1,$3);   
modif_token( &@1, SYMBOL_FORMALS ) ; modif_token( &@2, EQ_FORMALS ) ; }
+       |       SYMBOL SYMBOL                   { $$ = xxfirstformal2($2,$1);   
modif_token( &@2, SYMBOL_FORMALS ) ; } 
+       |       SYMBOL SYMBOL EQ_ASSIGN expr_or_help
+                                               { $$ = 
xxfirstformal3($2,$4,$1);   modif_token( &@2, SYMBOL_FORMALS ) ; modif_token( 
&@3, EQ_FORMALS ) ; }
        |       formlist ',' SYMBOL             { $$ = xxaddformal0($1,$3, 
&@3);   modif_token( &@3, SYMBOL_FORMALS ) ; }
        |       formlist ',' SYMBOL EQ_ASSIGN expr_or_help
-                                               { $$ = 
xxaddformal1($1,$3,$5,&@3); modif_token( &@3, SYMBOL_FORMALS ) ; modif_token( 
&@4, EQ_FORMALS ) ;}
+                                               { $$ = 
xxaddformal1($1,$3,$5,&@3); modif_token( &@3, SYMBOL_FORMALS ) ; modif_token( 
&@4, EQ_FORMALS ) ; }
+       |       formlist ',' SYMBOL SYMBOL      { $$ = 
xxaddformal2($1,$4,$3,&@3); modif_token( &@4, SYMBOL_FORMALS ) ; }
+       |       formlist ',' SYMBOL SYMBOL EQ_ASSIGN expr_or_help       { $$ = 
xxaddformal3($1,$4,$6,$3,&@3); modif_token( &@4, SYMBOL_FORMALS ) ; 
modif_token( &@5, EQ_FORMALS ) ; }
        ;
 
 cr     :                                       { EatLines = 1; }
@@ -848,6 +859,31 @@
     return ans;
 }
 
+static SEXP xxfirstformal2(SEXP sym, SEXP type)
+{
+    SEXP ans;
+    if (GenerateCode)
+       PRESERVE_SV(ans = FirstArgWithType(R_MissingArg, sym, type));
+    else
+       PRESERVE_SV(ans = R_NilValue);
+    RELEASE_SV(type);
+    RELEASE_SV(sym);
+    return ans;
+}
+
+static SEXP xxfirstformal3(SEXP sym, SEXP expr, SEXP type)
+{
+    SEXP ans;
+    if (GenerateCode)
+       PRESERVE_SV(ans = FirstArgWithType(expr, sym, type));
+    else
+       PRESERVE_SV(ans = R_NilValue);
+    RELEASE_SV(type);
+    RELEASE_SV(expr);
+    RELEASE_SV(sym);
+    return ans;
+}
+
 static SEXP xxaddformal0(SEXP formlist, SEXP sym, YYLTYPE *lloc)
 {
     SEXP ans;
@@ -879,6 +915,39 @@
     return ans;
 }
 
+static SEXP xxaddformal2(SEXP formlist, SEXP sym, SEXP type, YYLTYPE *lloc)
+{
+    SEXP ans;
+    if (GenerateCode) {
+       CheckFormalArgs(formlist, sym, lloc);
+       NextArgWithType(formlist, R_MissingArg, sym, type);
+       ans = formlist;
+    } else {
+       RELEASE_SV(formlist);
+       PRESERVE_SV(ans = R_NilValue);
+    }
+    RELEASE_SV(sym);
+    RELEASE_SV(type);
+    return ans;
+}
+
+static SEXP xxaddformal3(SEXP formlist, SEXP sym, SEXP expr, SEXP type, 
YYLTYPE *lloc)
+{
+    SEXP ans;
+    if (GenerateCode) {
+       CheckFormalArgs(formlist, sym, lloc);
+       NextArgWithType(formlist, expr, sym, type);
+       ans = formlist;
+    } else {
+       RELEASE_SV(formlist);
+       PRESERVE_SV(ans = R_NilValue);
+    }
+    RELEASE_SV(expr);
+    RELEASE_SV(sym);
+    RELEASE_SV(type);
+    return ans;
+}
+
 static SEXP xxexprlist0(void)
 {
     SEXP ans;
@@ -1164,6 +1233,39 @@
     return t;
 }
 
+/* originally, the idea was to use attribute on each entry, but
+   attrs are only allowed on the outside of LISTSXP so we collect them
+   into one VECSXP attribute so they can be used in plain R. */
+static SEXP fixupFormalsTypes(SEXP formals) {
+    SEXP c = CDR(formals);
+    int i = 0, xty = 0; /* find last type declaration (if any) */
+    while (c != R_NilValue) {
+       i++;
+       /* for speed we don't check the name */
+       if (ATTRIB(c) != R_NilValue)
+           xty = i;
+       c = CDR(c);
+    }
+    if (xty > 0) {
+       SEXP types = PROTECT(Rf_allocVector(VECSXP, i));
+       c = CDR(formals);
+       i = 0;
+       while (c != R_NilValue) {
+           SEXP a = GET_ARGTYPE(c);
+           if (a != R_NilValue) {
+               SET_VECTOR_ELT(types, i, a);
+               /* do we want to keep them for internal use? */
+               SET_ATTRIB(c, R_NilValue);
+           }
+           c = CDR(c);
+           i++;
+       }
+       SET_ARGTYPE(CDR(formals), types);
+       UNPROTECT(1);
+    }
+    return formals;
+}
+
 static SEXP xxdefun(SEXP fname, SEXP formals, SEXP body, YYLTYPE *lloc)
 {
     SEXP ans, srcref;
@@ -1174,7 +1276,7 @@
            ParseState.didAttach = true;
        } else
            srcref = R_NilValue;
-       PRESERVE_SV(ans = lang4(fname, CDR(formals), body, srcref));
+       PRESERVE_SV(ans = lang4(fname, CDR(fixupFormalsTypes(formals)), body, 
srcref));
     } else
        PRESERVE_SV(ans = R_NilValue);
     RELEASE_SV(body);
@@ -1451,6 +1553,17 @@
     return tmp;
 }
 
+static SEXP FirstArgWithType(SEXP s, SEXP tag, SEXP type)
+{
+    SEXP tmp;
+    PROTECT(tmp = NewList());
+    GrowList(tmp, s);
+    SET_TAG(CAR(tmp), tag);
+    SET_ARGTYPE(CAR(tmp), type);
+    UNPROTECT(1);
+    return tmp;
+}
+
 /* Add named element to the end of a stretchy list */
 static void NextArg(SEXP l, SEXP s, SEXP tag)
 {
@@ -1458,6 +1571,13 @@
     SET_TAG(CAR(l), tag);
 }
 
+static void NextArgWithType(SEXP l, SEXP s, SEXP tag, SEXP type)
+{
+    GrowList(l, s);
+    SET_TAG(CAR(l), tag);
+    SET_ARGTYPE(CAR(l), type);
+}
+
 /* SrcRefs (PS_SRCREFS) are represented as R_NilValue (empty) or by 
    a stretchy list (which includes another representation for empty)
    for fast append operation. */
Index: src/main/names.c
===================================================================
--- src/main/names.c    (revision 89063)
+++ src/main/names.c    (working copy)
@@ -1132,6 +1132,7 @@
     R_SortListSymbol = install("sort.list");
     R_SourceSymbol = install("source");   /* Not used by R or core packages */
     R_TspSymbol = install("tsp");
+    R_TypeSymbol = install("type");
     /* ../include/Defn.h , i.e. non-public : */
     R_CommentSymbol = install("comment");
     R_DotEnvSymbol = install(".Environment");



> On 18/09/2025, at 5:23 AM, IVO I WELCH <[email protected]> wrote:
> 
> 
> Suggestion for Syntax Sugar:
> 
> Would it make sense to permit a simple way to allow a coder to document the 
> function argument type?
> 
> f <- function( a:chr, b:data.frame, c:logi ) { … }
> 
> presumably, what comes behind the ‘:’ should match what ‘str’ returns.
> 
> however, this need not be checked (except perhaps when a particular option is 
> set).  catching errors as soon as possible makes code easier to debug and 
> error messages clearer.
> 
> regards,
> 
> /iaw
> 
> ______________________________________________
> [email protected] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 

______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to