diff --git a/src/array.c b/src/array.c
index 39fb8928e35e19c1503ed6234bfaecdd3709b6c6..a820f36adb7a8ec992f6773e8833d727e212c13f 100644
--- a/src/array.c
+++ b/src/array.c
@@ -542,7 +542,9 @@ static int set_svalue_cmpfun(struct svalue *a, struct svalue *b)
     return a->subtype - b->subtype;
 
   case T_INT:
-    return a->u.integer - b->u.integer;
+    if(a->u.integer < b->u.integer) return -1;
+    if(a->u.integer > b->u.integer) return 1;
+    return 0;
 
   default:
     if(a->u.refs < b->u.refs) return -1;
@@ -557,7 +559,9 @@ static int switch_svalue_cmpfun(struct svalue *a, struct svalue *b)
   switch(a->type)
   {
   case T_INT:
-    return a->u.integer - b->u.integer;
+    if(a->u.integer < b->u.integer) return -1;
+    if(a->u.integer > b->u.integer) return 1;
+    return 0;
 
   case T_FLOAT:
     if(a->u.float_number < b->u.float_number) return -1;
@@ -572,6 +576,35 @@ static int switch_svalue_cmpfun(struct svalue *a, struct svalue *b)
   }
 }
 
+static int alpha_svalue_cmpfun(struct svalue *a, struct svalue *b)
+{
+  if(a->type != b->type) return a->type - b->type;
+  switch(a->type)
+  {
+  case T_INT:
+    if(a->u.integer < b->u.integer) return -1;
+    if(a->u.integer > b->u.integer) return  1;
+    return 0;
+
+  case T_FLOAT:
+    if(a->u.float_number < b->u.float_number) return -1;
+    if(a->u.float_number > b->u.float_number) return  1;
+    return 0;
+
+  case T_STRING:
+    return my_strcmp(a->u.string, b->u.string);
+
+  case T_ARRAY:
+    if(a==b) return 0;
+    if(!a->u.array->size) return -1;
+    if(!b->u.array->size) return  1;
+    return alpha_svalue_cmpfun(ITEM(a->u.array), ITEM(b->u.array));
+    
+  default:
+    return set_svalue_cmpfun(a,b);
+  }
+}
+
 /*
  * return an 'order' suitable for making mappings, lists other sets
  */
@@ -589,6 +622,15 @@ INT32 *get_switch_order(struct array *a)
 }
 
 
+/*
+ * return an 'order' suitable for sorting.
+ */
+INT32 *get_alpha_order(struct array *a)
+{
+  return get_order(a, alpha_svalue_cmpfun);
+}
+
+
 static INT32 low_lookup(struct array *v,
 			struct svalue *s,
 			cmpfun fun)
diff --git a/src/array.h b/src/array.h
index bbc7837646c05e95105e8f4aa692282e69f9905c..12c5e9ff49fedcc19f24947b656ede586c4dcac7 100644
--- a/src/array.h
+++ b/src/array.h
@@ -77,6 +77,7 @@ INT32 array_find_destructed_object(struct array *v);
 INT32 *get_order(struct array *v, cmpfun fun);
 INT32 *get_set_order(struct array *a);
 INT32 *get_switch_order(struct array *a);
+INT32 *get_alpha_order(struct array *a);
 INT32 set_lookup(struct array *a, struct svalue *s);
 INT32 switch_lookup(struct array *a, struct svalue *s);
 struct array *order_array(struct array *v, INT32 *order);