Actually, something much like Wolfgang's "apply$" is already built
into recent versions of Jess; it's called "map". But I actually don't
think that's what the O.P. is after: rather than calling a function
with each element of a list as successive arguments, I think he wants
to call the function on all the arguments in a list at once. In Lisp
this function is called "reduce", and although it currently doesn't
appear in Jess (it should, soon) I do have the code for an
implementation of reduce by Win Carus of Information Extraction
Systems, Inc. You can compile this, load it using load-function, and
use it as shown in the examples below.

--------------------------------
/** ReduceMF
*
* Function to reduce a list of multifields to a single value.
* (reduce <init> <function) <multifield>+)
* For example:
*
* (reduce 0 + (create$ 1 2 3 4)) => 10
* (reduce "" str-cat (create$ "this" "that" "those")) => "thisthatthose"
* (reduce 0 (lambda (?n ?m ?o) (+ ?n (/ ?m ?o))) (create$ 1 2 3)
(create$ 4 5 6)
) => 1.15
*
* <P>
* (C) 2007 Information Extraction Systems, Inc.<br>
*/
class ReduceMF implements Userfunction, Serializable {
   /** Get the name of the jess function
    * @see jess.Userfunction#getName()
    */
   public String getName() {
       return "reduce";
   }

   /** Call the userfunction
    * @see jess.Userfunction#call(jess.ValueVector, jess.Context)
     */       public Value call(ValueVector vv, Context context)
throws JessExce
ption {
       Value tmpValue = vv.get(1).resolveValue(context);
       Userfunction function = vv.get(2).functionValue(context);
              if (vv.size() > 3) {

           ValueVector args = new ValueVector();
           args.add(new Value("lambda", RU.SYMBOL));
           for (int i = 0; i < vv.size()-2; ++i)
               args.add(Funcall.NIL);

           for (int i = 0; i < (vv.get(3).listValue(context)).size
(); ++i) {
               args.set(tmpValue, 1);
               for (int j = 3; j < vv.size(); j++) {
                    args.set((vv.get(j).listValue(context)).get(i),
j-1);
               }
               tmpValue = function.call(args, context);
           }
       }
       return tmpValue;
   }
}
--------------------------------

On Mar 10, 2008, at 3:36 AM, Wolfgang Laun wrote:

Why do you want to avoid foreach which happens to cater
for your needs? Just write a simple wrapper (I'll call
it apply$) and use it just like (apply):

; a function to be called on each element of a list
(deffunction show (?x)
   (printout t "show: " ?x crlf)
)

; (apply$ <function> <expression>*)
; calls 1st argument for each successive argument,
; flattening list arguments
(deffunction apply$ (?func $?list)
   (foreach ?el $?list (apply ?func ?el))
)

; example for calling apply$
(bind ?alist (create$ foo bar blech))
(apply$ show ?alist)

Regards
Wolfgang


JKBM wrote:

I was wondering if there was any way to call a function on a variable
containing a list without having to use a foreach/while loop.
(apply + 1 2
3) obviously works, but (apply + (create$ 1 2 3)) doesn't, so that
doesn't
help me.  This sort of problem comes up a lot, and I usually
handle it by
implode$-ing the list, str-cat-ing the function and parentheses,
and then
build-ing it as follows:


(bind ?list (create$ 1 2 3))

(apply + ?bind) ;ERROR, as mentioned above
(build (str-cat "(+ " (implode$ ?list) ")) ;SUCCESS


However, this time, I'm dealing with a list of fact-ids, and this
method
doesn't work because Jess doesn't parse "<Fact-2>" to a fact-id
from the
implode$-ed string.  I thought maybe I could create$ a new list
with the
function at the beginning, but there is no way that I could find
to evaluate
a list, only a string.  E.g.:

(bind ?list (create$ 1 2 3))

(bind ?flist (create$ + ?list)) ;?flist is (+ 1 2 3), but can't
evaluate


So, I guess I'm looking for three possible solutions:
1) calling a function on a list
2) getting Jess to correctly parse a fact-id from a string
3) getting Jess to evaluate a list as a function

Any ideas?  Or should I just give up and resort to iterative
measures?
--
View this message in context: http://www.nabble.com/Calling-a-
function-on-all-elements-in-a-list-tp15921074p15921074.html
Sent from the Jess mailing list archive at Nabble.com.


--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users
[EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the list
(use your own address!) List problems? Notify owner-jess-
[EMAIL PROTECTED]
--------------------------------------------------------------------





--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users
[EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the list
(use your own address!) List problems? Notify owner-jess-
[EMAIL PROTECTED]
--------------------------------------------------------------------

---------------------------------------------------------
Ernest Friedman-Hill
Informatics & Decision Sciences          Phone: (925) 294-2154
Sandia National Labs                FAX:   (925) 294-2234
PO Box 969, MS 9012                 [EMAIL PROTECTED]
Livermore, CA 94550                 http://www.jessrules.com



--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the list
(use your own address!) List problems? Notify [EMAIL PROTECTED]
--------------------------------------------------------------------

Reply via email to