I want to pass a procedure to another procedure. I checked the User guide and it doesn't seem too difficult. For example,

`proc myproc(&f, x, a, b);`

local f:proc;

retp(f(x, a, b));

endp;

where `f`

is an arbitrary procedure/function.

This is fine, but I want something a little different. Assume that if `f`

is a linear function, I don't need the procedure/function `f`

because it's easier to do it in `myproc`

and the body of `myproc`

also changes. In other words, I only need `f`

if it's not linear. Something like this:

`proc myproc(&f, x, a, b, ind);`

local f:proc, z;

if ind eq 1;

z = a*x+b;

else;

z=f(x,a,b);

endif;

retp(z);

endp;

How can I do this? Can I just pass an empty argument in `myproc`

such as `myproc({}, x, a, b, ind)`

? Or do I have to define `f`

anyway?

I know, I could write a simple f function for the linear specification, but the point is that if `f`

is linear, then the procedure `myproc`

is different. This is why I define the indicator variable `ind`

. Is there a way to do this?

## 4 Answers

1

accepted

You do not have to define your procedure pointer `f` to point to a procedure. If the procedure pointer is not referenced, you can pass in any placeholder. However, you cannot define an empty matrix in a procedure call like this: `myproc({}, x, a, b, ind)`.

Here is one way to do it:

b = 1.5; x = 2; a = rndn(100, 1).^2; z = myproc(&logAproc, x, a, b, 0); z = myproc("NULL", x, a, b, 1); proc myproc(&f, x, a, b, ind); local f:proc, z; if ind eq 1; z = a*x+b; else; z=f(x,a,b); endif; retp(z); endp; proc (1) = logAproc(x, a, b); local z; z = a * ln(x) + b; retp(z); endp;

There is nothing special about the string `"NULL"`. You could replace `"NULL"` with a scalar 0 or a scalar error code. The code will even work if you replace `"NULL"` with an integer value. I would not recommend that, however, since procedure pointers are scalar integer pointers that provide the location of the procedure they point at. If you made a mistake in the code, you could end up with a much more confusing bug that way.

Since GAUSS does not treat the procedure pointer as a procedure pointer until after `local f:proc`, you could use the procedure pointer value as the indicator instead of `ind`. Below I use `"NULL"` as the indicator to perform the linear calculation, but you could also use a scalar 0 or a scalar error code as well.

b = 1.5; x = 2; a = rndn(100, 1).^2; z = myproc(&logAproc, x, a, b); z = myproc("NULL", x, a, b); proc myproc(&f, x, a, b); local z; if f == "NULL"; z = a*x+b; else; local f:proc; z=f(x,a,b); endif; retp(z); endp; proc (1) = logAproc(x, a, b); local z; z = a * ln(x) + b; retp(z); endp;

While this is maybe a little more concise, there is no real significant advantage. I would recommend you choose the solution that seems most clear to you.

0

Great answer, thanks!

I like more your second solution, it seems more elegant and parsimonious.

Just one quick question. In the second version you write:

`if f "NULL";`

Should it not be this?

`if f eq "NULL";`

If I use, say, a scalar zero instead of the string, I assume it should be

`if f eq 0;`

Is this correct?

A final question, unrelated to this. How do you create these nice codes with indentations, colours, etc? I can't find these features in the forum editor, but perhaps you have a more fancy version:)

0

- Your are correct. I made a mistake. It should read either
`if f eq "NULL"`or`if f == "NULL"`. I corrected the earlier post for future reference. - Yes, if you want to use a scalar zero instead of
`"NULL`, then you would change`if f eq "NULL"`to`if f eq 0` - If you surround code snippets with
`pre`tags like this:<pre> //insert code here </pre>

then your code will be: inside the light grey box, printed with a monospace font and any indentation will be preserved. As to color: for now you have to use

`span`tags with one of the following clases: gkeyword, gcomment or gstring. Adding something like Markdown to do this portion automatically is on our backlog, but I do not have an estimate of when it will be completed.

0

Thanks for the answer!