diff --git a/pd/doc/5.reference/all_about_expr_and_value.pd b/pd/doc/5.reference/all_about_expr_and_value.pd
index df7756794488cc78501b0d002aa201666e3e213c..4f9f0d53a9a878535cc60878f1f4517d720d7bf3 100644
--- a/pd/doc/5.reference/all_about_expr_and_value.pd
+++ b/pd/doc/5.reference/all_about_expr_and_value.pd
@@ -1,4 +1,4 @@
-#N canvas 430 58 448 350 10;
+#N canvas 416 53 448 471 10;
 #X obj 1 1 cnv 15 445 20 empty \$0-pddp.cnv.header expr_and_value 20
 10 1 18 -261106 -33289 0;
 #X obj 407 2 pddp/pddplink http://puredata.info/dev/pddp -text pddp
@@ -23,7 +23,7 @@ aren't the names of functions or operators like some_number \, below:
 \, \$0-foo is interpretated as "\$0 minus foo". Additionally \, \$0
 cannot be at the beginning of the variable name (e.g. \, \$0foo). Underscores
 provide a workable \, if clunky \, solution:;
-#X obj 1 328 cnv 15 445 20 empty \$0-pddp.cnv.footer empty 20 12 0
+#X obj 1 478 cnv 15 445 20 empty \$0-pddp.cnv.footer empty 20 12 0
 14 -233017 -33289 0;
 #N canvas 373 194 494 164 META 0;
 #X text 12 105 HELP_PATCH_AUTHORS Dave Sabine \, May 5 \, 2003 . Jonathan
@@ -34,16 +34,26 @@ Wilkes revised the patch to conform to the PDDP template for Pd version
 two Pd objects;
 #X text 12 25 KEYWORDS expr expr~ fexpr~ value all_about_pd nonlocal
 ;
-#X restore 392 330 pd META;
+#X restore 392 480 pd META;
 #N canvas 218 216 428 141 Related_objects 0;
 #X obj 1 1 cnv 15 425 20 empty \$0-pddp.cnv.subheading empty 3 12 0
 14 -261106 -33289 0;
 #X text 7 2 [expr] and [value]- Related Objects;
-#X restore 103 330 pd Related_objects;
-#X obj 6 330 pddp/pddplink all_about.pd -text All About Pd;
+#X restore 103 480 pd Related_objects;
+#X obj 6 480 pddp/pddplink all_about.pd -text All About Pd;
+#X text 21 324 You can also use the assignment operator "=" to assign
+a new value to a [value] variable:;
+#X floatatom 24 368 5 0 0 0 - - -, f 5;
+#X obj 24 388 expr _\$0_foo = $f1 + 42;
+#X msg 215 366 bang;
+#X obj 215 388 v _\$0_foo;
+#X floatatom 215 410 5 0 0 0 - - -, f 5;
 #X connect 3 0 5 0;
 #X connect 4 0 3 0;
 #X connect 6 0 2 0;
 #X connect 7 0 11 0;
 #X connect 8 0 12 0;
 #X connect 12 0 9 0;
+#X connect 20 0 21 0;
+#X connect 22 0 23 0;
+#X connect 23 0 24 0;
diff --git a/pd/src/x_vexp.c b/pd/src/x_vexp.c
index 548174c3bef1bb3a37470ab358f139765c55404b..b11bc5f96f8d9b486af36540174aa429df3e29ea 100644
--- a/pd/src/x_vexp.c
+++ b/pd/src/x_vexp.c
@@ -20,6 +20,17 @@
  * Oct 2015
  *                              $x[-1] was not equal $x1[-1], not accessing the previous block
  *                              (bug fix by Dan Ellis)
+ *  July 2017 --sdy
+ *      - Version 0.55
+ *
+ *      - The arrays now redraw after a store into one of their members
+ *              - ex_if() (the "if()" function is reworked to only evaluate either
+ *                the left or the right args depending on the truth value of the condition.
+ *                However, if the condition is a vector, both the left and the right
+ *                are evaluated regradless.
+ *              - priority of ',' and '=' was switched ot fix the bug of using store "=" in
+ *                functions with multiple arguments, which caused an error during execution.
+ *              - The number of inlet and outlets (MAX_VARS) is now set at 100
  */
 
 /*
@@ -256,6 +267,12 @@ expr_donew(struct expr *expr, int ac, t_atom *av)
                 }
                 expr->exp_stack[expr->exp_nexpr] =
                   (struct ex_ex *)fts_malloc(max_node * sizeof (struct ex_ex));
+                                if (!expr->exp_stack[expr->exp_nexpr]) {
+                                        post_error( (fts_object_t *) expr,
+                                                "expr: malloc for expr nodes failed\n");
+                                        goto error;
+                                }
+                                expr->exp_stack[expr->exp_nexpr][max_node-1].ex_type=0;
                 expr->exp_nexpr++;
                 ret = ex_match(list, (long)0);
                 if (expr->exp_nexpr > MAX_VARS)
@@ -272,6 +289,7 @@ expr_donew(struct expr *expr, int ac, t_atom *av)
                         list, expr->exp_stack[expr->exp_nexpr - 1], (long *)0);
                 if (!ret)
                         goto error;
+                fts_free(list);
         }
         *ret = nullex;
         t_freebytes(exp_string, exp_strlen+1);
@@ -496,7 +514,7 @@ ex_match(struct ex_ex *eptr, long int op)
 }
 
 /*
- * ex_parse -- This function if called when we have already done some
+ * ex_parse -- This function is called when we have already done some
  *             parsing on the expression, and we have already matched
  *             our brackets and parenthesis.  The main job of this
  *             function is to convert the infix expression to the
@@ -518,6 +536,7 @@ ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc)
         struct ex_ex *eptr;
         struct ex_ex *lowpre = 0;       /* pointer to the lowest precedence */
         struct ex_ex savex;
+                struct ex_ex *tmpex;
         long pre = HI_PRE;
         long count;
 
@@ -551,7 +570,9 @@ ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc)
                 case ET_VI:
                 case ET_VAR:
                         if (!count && !eptr[1].ex_type) {
-                                *optr++ = *eptr;
+                                *optr = *eptr;
+                                                                tmpex = optr;
+                                                                tmpex->ex_end = ++optr;
                                 return (optr);
                         }
                         break;
@@ -569,9 +590,10 @@ ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc)
                             !((struct ex_ex *) eptr[1].ex_ptr)[1].ex_type) {
                                 savex = *((struct ex_ex *) eptr[1].ex_ptr);
                                 *((struct ex_ex *) eptr[1].ex_ptr) = nullex;
-                                *optr++ = *eptr;
-                                lowpre = ex_parse(x, &eptr[2], optr, (long *)0);
+                                *optr = *eptr;
+                                lowpre = ex_parse(x, &eptr[2], optr + 1, (long *)0);
                                 *((struct ex_ex *) eptr[1].ex_ptr) = savex;
+                                                                optr->ex_end = lowpre;
                                 return(lowpre);
                         }
                         eptr = (struct ex_ex *) eptr[1].ex_ptr;
@@ -612,8 +634,8 @@ ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc)
                                 ac = 0;
                                 savex = *((struct ex_ex *) eptr[1].ex_ptr);
                                 *((struct ex_ex *) eptr[1].ex_ptr) = nullex;
-                                *optr++ = *eptr;
-                                lowpre = ex_parse(x, &eptr[2], optr, &ac);
+                                *optr = *eptr;
+                                lowpre = ex_parse(x, &eptr[2], optr + 1, &ac);
                                 if (!lowpre)
                                         return (exNULL);
                                 ac++;
@@ -625,6 +647,7 @@ ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc)
                                         return (exNULL);
                                 }
                                 *((struct ex_ex *) eptr[1].ex_ptr) = savex;
+                                                                optr->ex_end = lowpre;
                                 return (lowpre);
                         }
                         eptr = (struct ex_ex *) eptr[1].ex_ptr;
@@ -643,6 +666,7 @@ ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc)
                                 *((struct ex_ex *) eptr->ex_ptr) = nullex;
                                 lowpre = ex_parse(x, &eptr[1], optr, (long *)0);
                                 *((struct ex_ex *) eptr->ex_ptr) = savex;
+                                                                optr->ex_end = lowpre;
                                 return (lowpre);
                         }
                         eptr = (struct ex_ex *)eptr->ex_ptr;
@@ -674,16 +698,17 @@ ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc)
                         ex_print(iptr);
                         return (exNULL);
                 }
-                *optr++ = *lowpre;
-                eptr = ex_parse(x, &lowpre[1], optr, argc);
+                *optr = *lowpre;
+                eptr = ex_parse(x, &lowpre[1], optr + 1, argc);
+                                optr->ex_end = eptr;
                 return (eptr);
         }
-                /* this is the case of using unary operator as a binary opetator */
-                if (count == 3 && unary_op(lowpre->ex_op)) {
-                                post("expr: syntax error, missing operand before unary operator\n");
-                                ex_print(iptr);
-                                return (exNULL);
-                }
+        /* this is the case of using unary operator as a binary opetator */
+        if (count == 3 && unary_op(lowpre->ex_op)) {
+                post("expr: syntax error, missing operand before unary operator\n");
+                ex_print(iptr);
+                return (exNULL);
+        }
         if (lowpre == iptr) {
                 post("expr: syntax error: mission operand\n");
                 ex_print(iptr);
@@ -691,15 +716,18 @@ ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc)
         }
         savex = *lowpre;
         *lowpre = nullex;
-        if (savex.ex_op != OP_COMMA)
-                *optr++ = savex;
-        else
-                (*argc)++;
-        eptr = ex_parse(x, iptr, optr, argc);
+        if (savex.ex_op != OP_COMMA) {
+            *optr = savex;
+                eptr = ex_parse(x, iptr, optr + 1, argc);
+                } else {
+            (*argc)++;
+                eptr = ex_parse(x, iptr, optr, argc);
+                }
         if (eptr) {
                 eptr = ex_parse(x, &lowpre[1], eptr, argc);
                 *lowpre = savex;
         }
+                optr->ex_end = eptr;
         return (eptr);
 }
 
@@ -1225,6 +1253,9 @@ ex_eval(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx)
                 return (eptr);
 }
 
+extern struct ex_ex * ex_if(t_expr *expr,  struct ex_ex *eptr,
+                                struct ex_ex *optr,struct ex_ex *argv, int idx);
+
 /*
  * eval_func --  evaluate a function, call ex_eval() on all the arguments
  *               so that all of them are terminal nodes. The call the
@@ -1249,12 +1280,24 @@ eval_func(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx)
                 return (exNULL);
         }
 
-        for (i = 0; i < f->f_argc; i++) {
+                /*
+                 * We treat the "if" function differently to be able to evaluate
+                 * the args selectively based on the truth value of the "condition"
+                 */
+                if (f->f_func != (void (*)) ex_if) {
+                        for (i = 0; i < f->f_argc; i++) {
                 args[i].ex_type = 0;
                 args[i].ex_int = 0;
                 eptr = ex_eval(expr, eptr, &args[i], idx);
-        }
-        (*f->f_func)(expr, f->f_argc, args, optr);
+                        }
+                (*f->f_func)(expr, f->f_argc, args, optr);
+        } else {
+                        for (i = 0; i < f->f_argc; i++) {
+                args[i].ex_type = 0;
+                args[i].ex_int = 0;
+                        }
+                eptr = ex_if(expr, eptr, optr, args, idx);
+                }
         for (i = 0; i < f->f_argc; i++) {
                 if (args[i].ex_type == ET_VEC)
                         fts_free(args[i].ex_vec);
@@ -1956,99 +1999,6 @@ atoif(char *s, long int *value, long int *type)
         return (p);
 }
 
-
-
-#ifdef notdef
-/*
- * atoif -- ascii to float or integer (understands hex numbers also)
- */
-char *
-atoif(char *s, long int *value, long int *type)
-{
-        char *p;
-        long int_val = 0;
-        int flt = 0;
-        t_float pos = 0;
-        t_float flt_val = 0;
-        int base = 10;
-
-        p = s;
-        if (*p == '0' && (p[1] == 'x' || p[1] == 'X')) {
-                base = 16;
-                p += 2;
-        }
-        while (8) {
-                switch (*p) {
-                case '.':
-                        if (flt || base != 10) {
-                                post("expr: syntax error: %s\n", s);
-                                return ((char *) 0);
-                        }
-                        flt++;
-                        pos = 10;
-                        flt_val = int_val;
-                        break;
-                case '0':
-                case '1':
-                case '2':
-                case '3':
-                case '4':
-                case '5':
-                case '6':
-                case '7':
-                case '8':
-                case '9':
-                        if (flt) {
-                                flt_val += (*p - '0') / pos;
-                                pos *= 10;
-                        } else {
-                                int_val *= base;
-                                int_val += (*p - '0');
-                        }
-                        break;
-                case 'e':
-                                                if (base != 16) {
-                                                        if (
-                case 'a':
-                case 'b':
-                case 'c':
-                case 'd':
-                case 'f':
-                        if (base != 16 || flt) {
-                                post("expr: syntax error: %s\n", s);
-                                return ((char *) 0);
-                        }
-                        int_val *= base;
-                        int_val += (*p - 'a' + 10);
-                        break;
-                case 'E':
-                case 'A':
-                case 'B':
-                case 'C':
-                case 'D':
-                case 'F':
-                        if (base != 16 || flt) {
-                                post("expr: syntax error: %s\n", s);
-                                return ((char *) 0);
-                        }
-                        int_val *= base;
-                        int_val += (*p - 'A' + 10);
-                        break;
-                default:
-                        if (flt) {
-                                *type = ET_FLT;
-                                *((t_float *) value) = flt_val;
-                        } else {
-                                *type = ET_INT;
-                                *value = int_val;
-                        }
-                        return (p);
-                }
-                p++;
-        }
-}
-#endif
-
 /*
  * find_func -- returns a pointer to the found function structure
  *              otherwise it returns 0
@@ -2072,8 +2022,10 @@ find_func(char *s)
 void
 ex_print(struct ex_ex *eptr)
 {
+                struct ex_ex *extmp;
 
-        while (eptr->ex_type) {
+                extmp = eptr->ex_end;
+        while (eptr->ex_type && eptr != extmp) {
                 switch (eptr->ex_type) {
                 case ET_INT:
                         post("%ld ", eptr->ex_int);
@@ -2085,10 +2037,10 @@ ex_print(struct ex_ex *eptr)
                         post("%s ", eptr->ex_ptr);
                         break;
                 case ET_TBL:
-                                                if (!eptr->ex_ptr) { /* special case of $# processing */
+                        if (!eptr->ex_ptr) { /* special case of $# processing */
                                 post("%s ", "$$");
-                                                        break;
-                                                }
+                            break;
+                        }
                 case ET_VAR:
                         post("%s ", ex_symname((fts_symbol_t )eptr->ex_ptr));
                         break;
diff --git a/pd/src/x_vexp.h b/pd/src/x_vexp.h
index 16f74ef5dd47a0f36a8a2650a92067755766fad9..608a64a486f9c94eb934fd8ed54b256d509e540a 100644
--- a/pd/src/x_vexp.h
+++ b/pd/src/x_vexp.h
@@ -5,17 +5,17 @@
 /* "expr" was written by Shahrokh Yadegari c. 1989. -msp */
 /* "expr~" and "fexpr~" conversion by Shahrokh Yadegari c. 1999,2000 */
 
-//#define MSP
-//#ifdef PD
-//#undef MSP
-//#endif
+#define MSP
+#ifdef PD
+#undef MSP
+#endif
 
-//#ifdef PD
+#ifdef PD
 #include "m_pd.h"
-//#else /* MSP */
-//#include "ext.h"
-//#include "z_dsp.h"
-//#endif
+#else /* MSP */
+#include "ext.h"
+#include "z_dsp.h"
+#endif
 
 #define fts_malloc malloc
 #define fts_calloc calloc
@@ -57,7 +57,7 @@ void pd_error(void *object, char *fmt, ...);
  * is 10.
  */
 
-#define MAX_VARS        9
+#define MAX_VARS        100
 #define MINODES         10 /* was 200 */
 
 /* terminal defines */
@@ -70,8 +70,8 @@ void pd_error(void *object, char *fmt, ...);
  */
 
 #define OP_SEMI         ((long)(1<<16|1))               /* ; */
-#define OP_STORE        ((long)(2<<16|28))             /* = */
-#define OP_COMMA        ((long)(3<<16|2))               /* , */
+#define OP_COMMA        ((long)(2<<16|2))               /* , */
+#define OP_STORE        ((long)(3<<16|28))             /* = */
 #define OP_LOR          ((long)(4<<16|3))               /* || */
 #define OP_LAND         ((long)(5<<16|4))               /* && */
 #define OP_OR           ((long)(6<<16|5))               /* | */
@@ -100,8 +100,6 @@ void pd_error(void *object, char *fmt, ...);
 #define HI_PRE          ((long)(100<<16))       /* infinite precedence */
 #define PRE_MASK        ((long)0xffff0000)      /* precedence level mask */
 
-struct ex_ex;
-
 #define name_ok(c)      (((c)=='_') || ((c)>='a' && (c)<='z') || \
                         ((c)>='A' && (c)<='Z') || ((c) >= '0' && (c) <= '9'))
 #define unary_op(x)     ((x) == OP_NOT || (x) == OP_NEG || (x) == OP_UMINUS)
@@ -120,6 +118,7 @@ struct ex_ex {
 #define ex_op           ex_cont.op
 #define ex_ptr          ex_cont.ptr
         long ex_type;           /* type of the node */
+                struct ex_ex *ex_end;   /* the node after the end of this expression */
 };
 #define exNULL  ((struct ex_ex *)0)
 
diff --git a/pd/src/x_vexp_fun.c b/pd/src/x_vexp_fun.c
index 95c323c8004bec639465d38fa71bb7342da9151b..c54cced359b5cff0ef8086bcd2c2eaa4e42debba 100644
--- a/pd/src/x_vexp_fun.c
+++ b/pd/src/x_vexp_fun.c
@@ -46,6 +46,9 @@
  *                              - fixed sum("table"), and Sum("table", x, y)
  *                              - deleted avg(), Avg() as they can be simple expressions
  *                              - deleted store as this can be achieved by the '=' operator
+ *  July 2017 --sdy
+ *
+ *              - ex_if() is reworked to only evaluate either the left or the right arg
  */
 
 
@@ -77,6 +80,9 @@
 
 #include "x_vexp.h"
 
+struct ex_ex *ex_eval(struct expr *expr, struct ex_ex *eptr,
+                                                struct ex_ex *optr, int i);
+
 /* forward declarations */
 
 static void ex_min(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr);
@@ -108,11 +114,12 @@ static void ex_abs(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex
 static void ex_fmod(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
 static void ex_ceil(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
 static void ex_floor(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
-static void ex_if(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
+struct ex_ex * ex_if(t_expr *expr, struct ex_ex *argv, struct ex_ex *optr,
+                                     struct ex_ex *args, int idx);
 static void ex_ldexp(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
 static void ex_imodf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
 static void ex_modf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
-#ifndef _WIN32
+#if !defined(_MSC_VER) || (_MSC_VER >= 17000)
 static void ex_cbrt(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
 static void ex_erf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
 static void ex_erfc(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr);
@@ -162,27 +169,27 @@ t_ex_func ex_funcs[] = {
         {"fact",        ex_fact,        1},
         {"random",      ex_random,      2},     /* random number */
         {"abs",         ex_abs,         1},
-        {"if",          ex_if,          3},
+        {"if",          (void (*))ex_if,          3},
         {"ldexp",       ex_ldexp,       2},
         {"imodf",       ex_imodf,       1},
         {"modf",        ex_modf,        1},
-#ifndef _WIN32
+#if !defined(_MSC_VER) || (_MSC_VER >= 17000)
+        {"asinh",       ex_asinh,       1},
+        {"acosh",       ex_acosh,       1},
+        {"atanh",       ex_atanh,       1},     /* hyperbolic atan */
+        {"isnan",       ex_isnan,       1},
         {"cbrt",        ex_cbrt,        1},
+        {"round",       ex_round,       1},
+        {"trunc",       ex_trunc,       1},
         {"erf",         ex_erf,         1},
         {"erfc",        ex_erfc,        1},
         {"expm1",       ex_expm1,       1},
         {"log1p",       ex_log1p,       1},
-        {"isinf",       ex_isinf,       1},
         {"finite",      ex_finite,      1},
-        {"isnan",       ex_isnan,       1},
+        {"nearbyint",   ex_nearbyint,   1},
         {"copysign",    ex_copysign,    2},
+        {"isinf",       ex_isinf,       1},
         {"remainder",   ex_remainder,           2},
-        {"asinh",       ex_asinh,       1},
-        {"acosh",       ex_acosh,       1},
-        {"atanh",       ex_atanh,       1},     /* hyperbolic atan */
-        {"round",       ex_round,       1},
-        {"trunc",       ex_trunc,       1},
-        {"nearbyint",   ex_nearbyint,   1},
 #endif
 #ifdef PD
         {"size",        ex_size,        1},
@@ -861,7 +868,7 @@ ex_tanh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 }
 
 
-#ifndef _WIN32
+#if !defined(_MSC_VER) || (_MSC_VER >= 17000)
 static void
 ex_asinh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr)
 {
@@ -979,10 +986,10 @@ ex_abs(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
 }
 
 /*
- *ex_if -- floating point modulo
+ * ex_if -- if function
  */
-static void
-ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
+struct ex_ex *
+ex_if(t_expr *e, struct ex_ex *eptr, struct ex_ex *optr, struct ex_ex *argv, int idx)
 {
         struct ex_ex *left, *right, *cond, *res;
         t_float *op; /* output pointer */
@@ -990,10 +997,14 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
         t_float *cp;              /* condition pointer */
         t_float leftvalue, rightvalue;
         int j;
+                int condtrue = 0;
 
+                // evaluate the condition
+                eptr = ex_eval(e, eptr, argv, idx);
         cond = argv++;
-        left = argv++;
-        right = argv;
+                // only either the left or right will be evaluated depending
+                // on the truth value of the condition
+                // However, if the condition is a vector, both args will be evaluated
 
         switch (cond->ex_type) {
         case ET_VEC:
@@ -1002,12 +1013,25 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
                         if (optr->ex_type == ET_VI) {
                                 /* SDY remove this test */
                                 post("expr~: Int. error %d", __LINE__);
-                                return;
+                                return (eptr);
                         }
-                                optr->ex_type = ET_VEC;
-                                optr->ex_vec = (t_float *)
+                        optr->ex_type = ET_VEC;
+                        optr->ex_vec = (t_float *)
                                   fts_malloc(sizeof (t_float) * e->exp_vsize);
+                                                if (!optr->ex_vec) {
+                                                        post("expr:if: no mem");
+                                                        /* pass over the left and right args */
+                                                        return(cond->ex_end->ex_end);
+                                                }
                 }
+                                /*
+                                 * if the condition is a vector
+                                 * the left and the right args both will get processed
+                                 */
+                                eptr = ex_eval(e, eptr, argv, idx);
+                                left = argv++;
+                                eptr = ex_eval(e, eptr, argv, idx);
+                                right = argv;
                 op = optr->ex_vec;
                 j = e->exp_vsize;
                 cp = cond->ex_vec;
@@ -1023,7 +1047,7 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
                                         else
                                                 *op++ = rightvalue;
                                 }
-                        return;
+                        return (eptr);
                         case ET_FLT:
                                 rightvalue = right->ex_flt;
                                 while (j--) {
@@ -1032,7 +1056,7 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
                                         else
                                                 *op++ = rightvalue;
                                 }
-                                return;
+                                return (eptr);
                         case ET_VEC:
                         case ET_VI:
                                 rp = right->ex_vec;
@@ -1043,13 +1067,13 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
                                                 *op++ = *rp;
                                         rp++;
                                 }
-                                return;
+                                return (eptr);
                         case ET_SYM:
                         default:
                                 post_error((fts_object_t *) e,
                               "expr: FUNC_EVAL(%d): bad right type %ld\n",
                                                       __LINE__, right->ex_type);
-                                return;
+                                return (eptr);
                         }
                 case ET_FLT:
                         leftvalue = left->ex_flt;
@@ -1062,7 +1086,7 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
                                         else
                                                 *op++ = rightvalue;
                                 }
-                                return;
+                                return (eptr);
                         case ET_FLT:
                                 rightvalue = right->ex_flt;
                                 while (j--) {
@@ -1071,7 +1095,7 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
                                         else
                                                 *op++ = rightvalue;
                                 }
-                                return;
+                                return (eptr);
                         case ET_VEC:
                         case ET_VI:
                                 rp = right->ex_vec;
@@ -1082,13 +1106,13 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
                                                 *op++ = *rp;
                                         rp++;
                                 }
-                                return;
+                                return (eptr);
                         case ET_SYM:
                         default:
                                 post_error((fts_object_t *) e,
                               "expr: FUNC_EVAL(%d): bad right type %ld\n",
                                                       __LINE__, right->ex_type);
-                                return;
+                                return (eptr);
                         }
                 case ET_VEC:
                 case ET_VI:
@@ -1103,7 +1127,7 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
                                                 *op++ = rightvalue;
                                         lp++;
                                 }
-                                return;
+                                return (eptr);
                         case ET_FLT:
                                 rightvalue = right->ex_flt;
                                 while (j--) {
@@ -1113,7 +1137,7 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
                                                 *op++ = rightvalue;
                                         lp++;
                                 }
-                                return;
+                                return (eptr);
                         case ET_VEC:
                         case ET_VI:
                                 rp = right->ex_vec;
@@ -1124,77 +1148,91 @@ ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)
                                                 *op++ = *rp;
                                         lp++; rp++;
                                 }
-                                return;
+                                return (eptr);
                         case ET_SYM:
                         default:
                                 post_error((fts_object_t *) e,
                               "expr: FUNC_EVAL(%d): bad right type %ld\n",
                                                       __LINE__, right->ex_type);
-                                return;
+                                return (eptr);
                         }
                 case ET_SYM:
                 default:
                         post_error((fts_object_t *) e,
                       "expr: FUNC_EVAL(%d): bad left type %ld\n",
                                               __LINE__, left->ex_type);
-                        return;
+                        return (eptr);
                 }
         case ET_INT:
                 if (cond->ex_int)
-                        res = left;
-                else
-                        res = right;
+                                        condtrue = 1;
+                                else
+                                        condtrue = 0;
                 break;
         case ET_FLT:
                 if (cond->ex_flt)
-                        res = left;
-                else
-                        res = right;
+                                        condtrue = 1;
+                                else
+                                        condtrue = 0;
                 break;
         case ET_SYM:
         default:
                 post_error((fts_object_t *) e,
               "expr: FUNC_EVAL(%d): bad condition type %ld\n",
                                       __LINE__, cond->ex_type);
-                return;
+                return (eptr);
         }
+                if (condtrue) {
+                                eptr = ex_eval(e, eptr, argv, idx);
+                                res = argv++;
+                                eptr = eptr->ex_end; /* no right processing */
+
+                } else {
+                                eptr = eptr->ex_end; /* no left rocessing */
+                                eptr = ex_eval(e, eptr, argv, idx);
+                                res = argv++;
+                }
         switch(res->ex_type) {
         case ET_INT:
                 if (optr->ex_type == ET_VEC) {
                         ex_mkvector(optr->ex_vec, (t_float)res->ex_int,
                                                                 e->exp_vsize);
-                        return;
+                        return (eptr);
                 }
                 *optr = *res;
-                return;
+                return (eptr);
         case ET_FLT:
                 if (optr->ex_type == ET_VEC) {
                         ex_mkvector(optr->ex_vec, (t_float)res->ex_flt,
                                                                 e->exp_vsize);
-                        return;
+                        return (eptr);
                 }
                 *optr = *res;
-                return;
+                return (eptr);
         case ET_VEC:
         case ET_VI:
                 if (optr->ex_type != ET_VEC) {
                         if (optr->ex_type == ET_VI) {
                                 /* SDY remove this test */
                                 post("expr~: Int. error %d", __LINE__);
-                                return;
+                                return (eptr);
                         }
-                                optr->ex_type = ET_VEC;
-                                optr->ex_vec = (t_float *)
+                        optr->ex_type = ET_VEC;
+                        optr->ex_vec = (t_float *)
                                   fts_malloc(sizeof (t_float) * e->exp_vsize);
+                                                if (!optr->ex_vec) {
+                                                        post("expr:if: no mem");
+                            return (eptr);
+                                                }
                 }
                 memcpy(optr->ex_vec, res->ex_vec, e->exp_vsize*sizeof(t_float));
-                return;
+                return (eptr);
         case ET_SYM:
         default:
                 post_error((fts_object_t *) e,
               "expr: FUNC_EVAL(%d): bad res type %ld\n",
                                       __LINE__, res->ex_type);
-                return;
+                return (eptr);
         }
 
 }
@@ -1231,7 +1269,7 @@ FUNC_DEF_UNARY(ex_modf, fracmodf, (double), 1);
  */
 FUNC_DEF(ex_ldexp, ldexp, (double), (int), 1);
 
-#ifndef _WIN32
+#if !defined(_MSC_VER) || (_MSC_VER >= 17000)
 /*
  * ex_cbrt - cube root
  */
diff --git a/pd/src/x_vexp_if.c b/pd/src/x_vexp_if.c
index 675bae4830e6060b982ae1acaefb97611c863fcf..260a198d7e1140fdf2afde36a9cf635900b0be89 100644
--- a/pd/src/x_vexp_if.c
+++ b/pd/src/x_vexp_if.c
@@ -13,7 +13,8 @@
  * --sdy
  *
  *
- *  version 0.50 - March 2015
+ *  version 0.50 - March 2016
+ *  version 0.55 - July 2017
  */
 
 #include <stdio.h>
@@ -22,7 +23,7 @@
 
 #include "x_vexp.h"
 
-static char *exp_version = "0.50";
+static char *exp_version = "0.55";
 
 extern struct ex_ex *ex_eval(struct expr *expr, struct ex_ex *eptr,
                                                 struct ex_ex *optr, int n);
@@ -863,6 +864,8 @@ ex_getsym(char *p, fts_symbol_t *s)
 const char *
 ex_symname(fts_symbol_t s)
 {
+        if (!s)
+            return (0);
         return (fts_symbol_name(s));
 }
 
@@ -892,7 +895,7 @@ max_ex_tab(struct expr *expr, fts_symbol_t s, struct ex_ex *arg,
         {
                 optr->ex_type = ET_FLT;
                 optr->ex_flt = 0;
-                pd_error(expr, "no such table '%s'", s->s_name);
+                pd_error(expr, "no such table '%s'", ex_symname(s));
                 return (1);
         }
         optr->ex_type = ET_FLT;
@@ -981,16 +984,19 @@ max_ex_tab_store(struct expr *expr, t_symbol *s, struct ex_ex *arg,
         switch (rval->ex_type) {
         case ET_INT:
                 wvec[indx].w_float = rval->ex_int;
-                return(0);
+                                break;
         case ET_FLT:
                 wvec[indx].w_float = rval->ex_flt;
-                return(0);
+                                break;
         default:
                 pd_error(expr, "expr:bad right value type '%ld'", rval->ex_type);
                 optr->ex_type = ET_FLT;
                 optr->ex_flt = 0;
                 return (1);
         }
+                garray_redraw(garray);
+                return(0);
+
 #else /* MSP */
         /*
          * table lookup not done for MSP yet