octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Octave 2.2.x Was: A group in Norway ...


From: John W. Eaton
Subject: Re: Octave 2.2.x Was: A group in Norway ...
Date: Fri, 20 Jun 2003 23:41:50 -0500

On 20-Jun-2003, Paul Kienzle <address@hidden> wrote:

| BTW, I tried inline('if x<3, 3; else x; end') in
| octave-forge, but it didn't work for x>=3, even
| after I changed the code from
|     function r=inline_func_<id>(<args>)
|         r = <expr>;
|     endfunction
| to
|     function r=inline_func_<id>(<args>)
|         <expr>;
|         r=ans;
|     endfunction
| 
| That's because the statement
|     x;
| does not change ans, but the statement
|     3;
| does.  Bug for bug compatibility?
| 
| Skipping the r= business and setting
|     return_last_computed_value = 1
| didn't help.

Either the meaning of return_last_computed_value is not clear, or
it is not implemented correctly...

It really seems to mean "if the last statement executed is an
expression, return its value".

If return_last_computed_value == 1 when the function created by inline
is evaluated, it should just work if the input string is a simple
expression.  No need to do any assignment to an output variable.  But,
as an extension to Matlab, you could have any arbitrary function body,
provided that it ends with an expression, the value of which you want
to return.

Here is a real kluge.  Replace the end of your inline.m with the
following code

  ## Choose a name (naive way : won't work zillions of times)
  while 1
    fname = sprintf ("inline_func_%06i",floor (rand()*1e6));
    if ! exist (fname), break; end
  end

  while 1
    fname2 = sprintf ("inline_func_%06i",floor (rand()*1e6));
    if ! exist (fname2), break; end
  end

  fcode = sprintf (["function %s (%s)\n",\
                    str,";\n",\
                    "endfunction;\n",\
                    "function r = %s (%s)\n",\
                    "__rlcv__ = return_last_computed_value;\n",\
                    "unwind_protect\n",\
                    "return_last_computed_value = 1;\n",\
                    "r = %s (%s);\n",\
                    "unwind_protect_cleanup\n",\
                    "return_last_computed_value = __rlcv__;\n",\
                    "end_unwind_protect\n",\
                    "endfunction;"],\
                   fname2, argstr, fname, argstr, fname2, argstr);
  eval (fcode);
  endfunction

and then you can write

  f = inline ('if (x < 3) y = 3; else y = x; end; y;')
  feval (f, 2) ==> 3
  feval (f, 5) ==> 5

or you can write anything that can be handled by Matlab's inline
function (a simple expression).  The downside is that it requires two
functions to be generated and called to evaluate the inline function
code when you run it.

Although it might be possible to do this in an M-file, I think this
really needs to be implemented internally as a new data type.  Then
you could overload the () indexing operator so that instead of having
to use feval, you could write:

  f = inline ('t^2')
  f (2) ==> 4

Also, by doing this in C++, it would be easier to detect what
variables are arguments by generating an anonymous function and then
examining its symbol table for variables using the rules of Matlab's
inline function.  To do a better job, you could try to analyze the
parse tree and figure out which variables need values (and must be
parameters).

jwe



reply via email to

[Prev in Thread] Current Thread [Next in Thread]