Re: Are functional objects (functors/closures) possible?

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Re: Are functional objects (functors/closures) possible?

John W. Eaton-6
In a message to the help-octave mailing list on 22-Nov-2002,
Paul Kienzle <[hidden email]> wrote:

| This is a little cleaner if curry were a text function:
|
| f = curry x y "g(x,y,$a,$b)"
|
| but right now you cannot tag a function as a text function
| unless it is a built-in.

How about the following patch, relative to the current CVS?  With it,
Octave behaves like this:

  octave:1> mark_as_text_function doit
  octave:2> function doit (a, b, c) printf ("%s:%s:%s\n", a, b, c); end
  octave:3> doit foo bar baz
  foo:bar:baz
  octave:4> unmark_text_function doit
  octave:5> doit foo bar baz
  parse error:

  >>> doit foo bar baz
              ^

  octave:5> doit ("foo", "bar", "baz")
  foo:bar:baz
  octave:6> mark_as_text_function doit
  octave:7> doit ("foo", "bar", "baz")
  foo:bar:baz

So you could set up a collection of text functions either in a script
file or just by marking them in your ~/.octaverc file.  I think this
is all that is required, but perhaps I'm missing something?  If you
already submitted a patch like this and I'm reinventing something,
then I apologize for that.  I didn't try to locate it because it
seemed simple enough to implement.

Note that these changes require the STL std::set<std::string>
template, which works best with g++ 3.2, at least for me (see my
previous post).

jwe


src/ChangeLog:

2002-11-22  John W. Eaton  <[hidden email]>

        * variables.cc (text_function_set): New static data.
        (mark_as_text_function, unmark_text_function,
        is_marked_as_text_function, Fmark_as_text_function,
        Funmark_text_function): New functions.
        (is_text_function_name): Handle functions marked as text functions
        in special list, not just those marked in the symbol record.
        * symtab.h (symbol_record::mark_as_text_function,
        symbol_record::unmark_text_function,
        symbol_record::symbol_def::mark_as_text_function,
        symbol_record::symbol_def::unmark_text_function): New functions.


Index: src/symtab.h
===================================================================
RCS file: /usr/local/cvsroot/octave/src/symtab.h,v
retrieving revision 1.60
diff -u -r1.60 symtab.h
--- src/symtab.h 20 Nov 2002 16:56:49 -0000 1.60
+++ src/symtab.h 22 Nov 2002 21:38:06 -0000
@@ -106,6 +106,12 @@
     bool is_user_variable (void) const
       { return (symbol_type & symbol_record::USER_VARIABLE); }
 
+    void mark_as_text_function (void)
+      { symbol_type |= symbol_record::TEXT_FUNCTION; }
+
+    void unmark_text_function (void)
+      { symbol_type &= ~symbol_record::TEXT_FUNCTION; }
+
     bool is_text_function (void) const
       { return (symbol_type & symbol_record::TEXT_FUNCTION); }
 
@@ -236,6 +242,12 @@
 
   bool is_function (void) const
     { return definition->is_function (); }
+
+  void mark_as_text_function (void)
+    { definition->mark_as_text_function (); }
+
+  void unmark_text_function (void)
+    { definition->unmark_text_function (); }
 
   bool is_text_function (void) const
     { return definition->is_text_function (); }
Index: src/variables.cc
===================================================================
RCS file: /usr/local/cvsroot/octave/src/variables.cc,v
retrieving revision 1.234
diff -u -r1.234 variables.cc
--- src/variables.cc 14 Nov 2002 04:31:19 -0000 1.234
+++ src/variables.cc 22 Nov 2002 21:38:07 -0000
@@ -27,6 +27,7 @@
 #include <cstdio>
 #include <cstring>
 
+#include <set>
 #include <string>
 
 #include "file-stat.h"
@@ -103,11 +104,108 @@
 
 // Is this a text-style function?
 
+static std::set <std::string> text_function_set;
+
+static inline bool
+is_marked_as_text_function (const std::string& s)
+{
+  return text_function_set.find (s) != text_function_set.end ();
+}
+
+static inline void
+mark_as_text_function (const std::string& s)
+{
+  text_function_set.insert (s);
+}
+
+static inline void
+unmark_text_function (const std::string& s)
+{
+  text_function_set.erase (s);
+
+  symbol_record *sr = fbi_sym_tab->lookup (s);
+
+  if (sr)
+    sr->unmark_text_function ();
+}
+
+DEFUN_TEXT (mark_as_text_function, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} mark_as_text_function (@var{name})\n\
+Enter @var{name} into the list of text functions\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    {
+      int argc = nargin + 1;
+
+      string_vector argv = args.make_argv ("mark_as_text_function");
+
+      if (! error_state)
+ {
+  for (int i = 1; i < argc; i++)
+    mark_as_text_function (argv[i]);
+ }
+    }
+  else
+    print_usage ("mark_as_text_function");
+
+  return retval;
+}
+
+DEFUN_TEXT (unmark_text_function, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} mark_as_text_function (@var{name})\n\
+Enter @var{name} into the list of text functions\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin > 0)
+    {
+      int argc = nargin + 1;
+
+      string_vector argv = args.make_argv ("unmark_text_function");
+
+      if (! error_state)
+ {
+  for (int i = 1; i < argc; i++)
+    unmark_text_function (argv[i]);
+ }
+    }
+  else
+    print_usage ("unmark_text_function");
+
+  return retval;
+}
+
 bool
 is_text_function_name (const std::string& s)
 {
+  bool retval = false;
+
   symbol_record *sr = fbi_sym_tab->lookup (s);
-  return (sr && sr->is_text_function ());
+
+  if (sr)
+    {
+      if (sr->is_text_function ())
+ retval = true;
+      else if (is_marked_as_text_function (s))
+ {
+  sr->mark_as_text_function ();
+  retval = true;
+ }
+    }
+  else
+    retval = is_marked_as_text_function (s);
+
+  return retval;
 }
 
 // Is this a built-in function?