View Issue Details

IDProjectCategoryView StatusLast Update
0000181LDMudEfunspublic2011-02-22 00:32
ReporterlarsAssigned ToGnomi  
PrioritynormalSeverityfeatureReproducibilityN/A
Status closedResolutionwon't fix 
Summary0000181: New efuns: fold_left(), fold_right()
DescriptionShort: New efuns: fold_left(), fold_right()
From: Matthew Julius <julius.2@wright.edu>
Date: Fri, 08 Jan 1999 16:29:08 -0500
Type: Feature
State: Unclassified

varargs mixed implode(mixed*|string*, closure|string, mixed)
  The optional third argument is the value to start with if the second
  argument is a closure.
  For example,
    implode(({ 1, 2, 4 }), #'|) == 7
    implode(({ 2, 4, 7 }), #'|, 8) == 15
    implode(({ "a", "b", "c" }), #'+, " ") == " abc"
  The Timewarp mudlib has historically called this feature sum_array().
  varargs mixed *sum_array(mixed*, closure), to be precise.

alfebtcd wrote:

> actually, there should be two versions. in TubMud we call them
> fold_left() and fold_right(). the difference is in parenthesizing:
>
> fold_left(#'-,({ 0,1,2 }),3) == (((3 - 0) - 1) - 2) == 0
> fold_right(#'-,({ 0,1,2 }),3) == (0 - (1 - (2 - 3))) == -2
>
> since both versions make sense and are in use in TubMud, i propose to
> implement both. to name them something with "implode" seems not too
> unlogical; implode() and implode_right() on the other hand seem odd in my
> eyes.

With respect to compatibility again, MudOS allows this use of implode().
However, the ability to implode in either direction is nice...

Note that right or left doesn't matter with MudOS functionals, for example,
(: $1 - $2 :) and (: $2 - $1 :) do not differ at all really. However, #'-
and lambda(({ 'a, 'b }), ({ #'-, 'b, 'a })) are two very different things.

SYNOPSIS
        varargs mixed fold_left(closure c,mixed *a,mixed d);
        varargs mixed fold_right(closure c,mixed *a,mixed d);

          or

        varargs mixed fold_left(closure c,string s,mixed d);
        varargs mixed fold_right(closure c,string s,mixed d);

DESCRIPTION
        fold_left() and fold_right() receive an array as input and return
        a value that is computed by combining a start value (which can be
        given as third element or defaults to 0 otherwise) with an element
        of the array, computing an intermediate value which is combined
        with the next element (computing another intermediate value) and
        so on. When all elements are used, the last computed value is the
        result. The examples may make this clearer :-)

        The closure given as first argument will describe how each two
        values are combined, of course. (That means that this closure must
        expect exactly two values and return the next value.)

        With fold_left() and fold_right() the sum of a list of integers can
        easily be computed, for example.

        fold_left() takes the elements from the leftmost (the first) to
        the rightmost (list last) element of the array, and fold_right()
        uses the opposite order.

NOTE
        If the given array is empty, the start value given as third argument
        (or 0 if none was given) is returned as result.

EXAMPLES
        return fold_left(#'+,({ 1,2,3,4,5,6 }));
        /* return (((((0+1)+2)+3)+4)+5)+6;
         * This will return 21. The 0 added to the 1 in the innermost
         * parantheses results from the omitted third parameter to
         * fold_left().
         */

        return fold_right(#'+,({ "Hel","lo, ","wo","rld!" }),"");
        /* return "Hel"+("lo, "+("wo"+("rld!"+"")));
         * This will return "Hello, world!" of course.
         * To use implode(({ "Hel","lo, ","wo","rld!" }),"") instead is
         * cheaper though.
         */

        return fold_left(#'+,"<w`","");
        /* return '<' + ('w' + ('`' + ""));
         * Because characters in LPC are ints, in the innermost paranthesis
         * an int is added to an empty string. The ascii-value of the back-
         * tick (`) is 96, so the result of the innermost parantheses will
         * be the string "96" (if an int is added to a string, the int is
         * converted to a string which will contain its decimal representa-
         * tion). Then 119 ('w') will be prepended to this string and final-
         * ly 60 ('<'). The result will be "6011996" which is my phone num-
         * ber ;-)
         */

        mixed max(mixed a,mixed b) { return a>b? a : b; }
        return fold_left(#'max,({ 7,2,5 }),4);
        /* return max(max(max(4,7),2),5);
         * This will return the maximum of the array but at least 4.
         * The simul_efun find_extreme() would fit better for this task
         * though.
         */

SEE ALSO
        implode(), find_extreme(), arrays, strings
TagsNo tags attached.
External Data (URL)

Relationships

related to 0000160 new Extend the capabilities of closure evaluation 

Activities

zesstra

2011-02-20 00:05

administrator   ~0002006

I just noticed this issue. Since you mentionend your fold sefuns last week: do you think, the driver would benefit from this being efuns or is your sefun fine enough?

Gnomi

2011-02-22 00:18

manager   ~0002023

I don't think they're worth to be made efuns. We have them as sefuns and they are very rarely used. They can be implemented efficiently with 4 lines of code. So I'd rather add them as sefuns to the ldlib.

zesstra

2011-02-22 00:32

administrator   ~0002024

Then lets do that. :-)

Issue History

Date Modified Username Field Change
2004-11-26 22:22 lars New Issue
2009-10-06 04:22 zesstra Relationship added related to 0000160
2011-02-20 00:05 zesstra Note Added: 0002006
2011-02-20 00:05 zesstra Assigned To => Gnomi
2011-02-20 00:05 zesstra Status new => assigned
2011-02-22 00:18 Gnomi Note Added: 0002023
2011-02-22 00:32 zesstra Note Added: 0002024
2011-02-22 00:32 zesstra Status assigned => closed
2011-02-22 00:32 zesstra Resolution open => won't fix