# Mailinglist Archive: yast-devel (116 mails)

 < Previous Next >
##### [yast-devel] reduce builtin
• From: Arvin Schnell <aschnell@xxxxxxx>
• Date: Fri, 20 Jun 2008 10:01:16 +0200
• Message-id: <20080620080115.GA7962@xxxxxxx>

Hi,

it's ITO Friday again. I still have an improved patch for the reduce
function (http://en.wikipedia.org/wiki/Reduce_%28higher-order_function%29)
lying around (see attachment). It adds two versions of the function:

1) One that takes an initial value.

integer sum = list::reduce(integer x, integer y, 0, [ 1, 2, 3 ], { return x
+ y; });
integer product = list::reduce(integer x, integer y, 1, [ 1, 2, 3 ], {
return x * y; })

2) One were the initial value is the value of the first list entry. Here
the list must of course have at least one entry.

integer min = list::reduce(integer x, integer y, [ 1, 2, 3 ], { return x <
y ? x : y; });
integer max = list::reduce(integer x, integer y, [ 1, 2, 3 ], { return x >
y ? x : y; });

The behaviour is now analogous to Python's reduce so it shouldn't be
completely screwed. The patch contains no binary incompatibility to libycp
or the bytecode.

ciao Arvin

Index: YCPBuiltinList.cc
===================================================================
--- YCPBuiltinList.cc (revision 48433)
+++ YCPBuiltinList.cc (working copy)
@@ -1083,6 +1083,121 @@

static YCPValue
+l_reduce1 (const YCPSymbol &x, const YCPSymbol &y, const YCPList &list, const
YCPCode &expr)
+{
+ /**
+ * @builtin list::reduce
+ * @id reduce_1
+ * @short Reduces a list to a single value.
+ * @param flex1 x
+ * @param flex1 y
+ * @param list<flex1> list
+ * @param block<flex1> expr
+ * @return flex1
+ *
+ * TODO
+ */
+
+ if (list.isNull())
+ {
+ return YCPNull();
+ }
+
+ if (list->size() < 1)
+ {
+ ycp2error("Bad list %s for 'reduce'", list->toString().c_str());
+ return YCPNull();
+ }
+
+ SymbolEntryPtr xs = x->asEntry()->entry();
+ SymbolEntryPtr ys = y->asEntry()->entry();
+
+ YCPValue ret = list->value(0);
+
+ for (int i = 1; i < list->size(); i++)
+ {
+ xs->setValue(ret);
+ ys->setValue(list->value(i));
+
+ YCPValue tmp = expr->evaluate();
+ if (tmp.isNull())
+ {
+ ycp2error("Bad 'reduce' expression %s", expr->toString().c_str());
+ continue;
+ }
+ if (tmp->isVoid())
+ {
+ ycp2error("The expression for 'reduce' returned 'nil'");
+ continue;
+ }
+ if (tmp->isBreak())
+ {
+ break;
+ }
+
+ ret = tmp;
+ }
+
+ return ret;
+}
+
+
+static YCPValue
+l_reduce2 (const YCPSymbol &x, const YCPSymbol &y, const YCPValue &initial,
const YCPList &list, const YCPCode &expr)
+{
+ /**
+ * @builtin list::reduce
+ * @id reduce_2
+ * @short Reduces a list to a single value.
+ * @param flex1 x
+ * @param flex2 y
+ * @param flex1 value
+ * @param list<flex2> list
+ * @param block<flex1> expr
+ * @return flex1
+ *
+ * TODO
+ */
+
+ if (list.isNull())
+ {
+ return YCPNull();
+ }
+
+ SymbolEntryPtr xs = x->asEntry()->entry();
+ SymbolEntryPtr ys = y->asEntry()->entry();
+
+ YCPValue ret = initial;
+
+ for (int i = 0; i < list->size(); i++)
+ {
+ xs->setValue(ret);
+ ys->setValue(list->value(i));
+
+ YCPValue tmp = expr->evaluate();
+ if (tmp.isNull())
+ {
+ ycp2error("Bad 'reduce' expression %s", expr->toString().c_str());
+ continue;
+ }
+ if (tmp->isVoid())
+ {
+ ycp2error("The expression for 'reduce' returned 'nil'");
+ continue;
+ }
+ if (tmp->isBreak())
+ {
+ break;
+ }
+
+ ret = tmp;
+ }
+
+ return ret;
+}
+
+
+static YCPValue
l_tolist (const YCPValue &v)
{
/**
@@ -1143,5 +1258,14 @@
{ 0 }
};

+ // must be static, registerDeclarations saves a pointer to it!
+ static declaration_t declarations_ns[] = {
+ { "list", "",
NULL, DECL_NAMESPACE },
+ { "reduce", "flex1 (variable <flex1>, variable <flex1>, const list
<flex1>, const block <flex1>)", (void *)l_reduce1,
DECL_LOOP|DECL_SYMBOL|DECL_FLEX },
+ { "reduce", "flex1 (variable <flex1>, variable <flex2>, const
flex1, const list <flex2>, const block <flex1>)", (void *)l_reduce2,
DECL_LOOP|DECL_SYMBOL|DECL_FLEX },
+ { 0 }
+ };
+
static_declarations.registerDeclarations ("YCPBuiltinList", declarations);
+ static_declarations.registerDeclarations ("YCPBuiltinList",
declarations_ns);
}
 < Previous Next >