POV-Ray : Newsgroups : povray.newusers : functions and macros Server Time
4 May 2024 03:37:55 EDT (-0400)
  functions and macros (Message 1 to 7 of 7)  
From: kurtz le pirate
Subject: functions and macros
Date: 18 Jun 2023 10:58:34
Message: <648f1b9a$1@news.povray.org>
Hello,


Can a function call a macro ?

I have defined this function :

114:#declare dayfrac_to_local_hr = function (df, tz) {
115:  24.0*limit_zero2one(df + (tz/24.0))
116:  }

and i get this error :
line 115
Parse Error: Cannot pass uninitialized identifier as non-optional macro
parameter.



Of course the macro is defined before

73:#macro limit_zero2one(_value)
74:  #local limited = _value - floor(_value);
75:  #if (limited < 0)
76:    #local limited = limited + 1.0;
77:  #end
78:  limited
79: #end



Hence the question : Can a function call a macro ?



-- 
Kurtz le pirate
Compagnie de la Banquise


Post a reply to this message

From: Leroy
Subject: Re: functions and macros
Date: 18 Jun 2023 13:10:00
Message: <web.648f397f1d2497943807ba4ef712fc00@news.povray.org>
kurtz le pirate <kur### [at] gmailcom> wrote:
> Hello,
>
>
> Can a function call a macro ?
>
> I have defined this function :
>
> 114:#declare dayfrac_to_local_hr = function (df, tz) {
> 115:  24.0*limit_zero2one(df + (tz/24.0))
> 116:  }
>
> and i get this error :
> line 115
> Parse Error: Cannot pass uninitialized identifier as non-optional macro
> parameter.
>
>
>
> Of course the macro is defined before
>
> 73:#macro limit_zero2one(_value)
> 74:  #local limited = _value - floor(_value);
> 75:  #if (limited < 0)
> 76:    #local limited = limited + 1.0;
> 77:  #end
> 78:  limited
> 79: #end
>
>
>
> Hence the question : Can a function call a macro ?
>
>
>
> --
> Kurtz le pirate
> Compagnie de la Banquise

short answer: NO
Long answer: If you can turn that macro into a function then you can call that
function.


Post a reply to this message

From: Leroy
Subject: Re: functions and macros
Date: 18 Jun 2023 13:35:00
Message: <web.648f400a1d2497943807ba4ef712fc00@news.povray.org>
kurtz le pirate <kur### [at] gmailcom> wrote:
> Hence the question : Can a function call a macro ?
>
Sorry, I was working on a function for you and while going back to the message I
got happy fingers and hit Preview then Post before adding the function.
here it is:
#declare Fnc=function(a){a-floor(a)+(a-floor(a)<0)}

Have Fun!


Post a reply to this message

From: Bald Eagle
Subject: Re: functions and macros
Date: 18 Jun 2023 14:15:00
Message: <web.648f48e21d2497941f9dae3025979125@news.povray.org>
kurtz le pirate <kur### [at] gmailcom> wrote:
> Hello,
>
>
> Can a function call a macro ?

Hi Kurtz,

You cannot use macros or arrays in functions.
Heck, there are even certain "functions" that you can't use in functions
(vlength, etc).

Under certain circumstances, you can write macros that assemble a function, and
while doing that, the macro can plug in the results of macro calls.

Or you can declare a set of values that are the result of macro call
evaluations, and use those values in your function.

The key concept is that any non-argument values in a function have to be
completely static.  So if you have a function of t, and want to do t*2, then 2
will be a static value, and can never change once the function is declared.

If you can express the types of variable results you want as separate functions,
then you can daisy-chain your functions together, such that you can write
formulas such as t*f(x).

Things can get pretty challenging trying to get the syntax right, and the
functions can get long, since we don't have vector functions, but a lot of
things are doable if you just keep trying to make it work and ask for help.

- BW


Post a reply to this message

From: Cousin Ricky
Subject: Re: functions and macros
Date: 18 Jun 2023 18:44:01
Message: <648f88b1$1@news.povray.org>
On 2023-06-18 10:58 (-4), kurtz le pirate wrote:
> 
> 114:#declare dayfrac_to_local_hr = function (df, tz) {
> 115:  24.0*limit_zero2one(df + (tz/24.0))
> 116:  }
> 
> and i get this error :
> line 115
> Parse Error: Cannot pass uninitialized identifier as non-optional macro
> parameter.
> 
> [snip]
> 
> Hence the question : Can a function call a macro ?

As Leroy said, the short answer is no.

Technically, it is possible to include a macro in a function definition,
but the macro is evaluated only in the process of defining the function.
 Thereafter, whatever the macro was expanded to *at that particular
time* becomes a permanent part of the function definition.  The macro is
never called from the function itself.

In your case, this means that the parser tries to evaluate df and tz
during the *definition* of the function, at which point df and tz are
undefined because the function is not in the process of being called.
(In Computerese, they are mere formal parameters, with no actual
arguments to back them up.)

So, a macro can be included in the function definition, but it cannot do
what you are trying to do.


Post a reply to this message

From: kurtz le pirate
Subject: Re: functions and macros
Date: 25 Jun 2023 04:48:18
Message: <6497ff52$1@news.povray.org>
On 18/06/2023 16:58, kurtz le pirate wrote:

> Hence the question : Can a function call a macro ?
> 

ok, it's clear.

indeed, converting the macro into functions is the best solution ... but
functions also have limitations.

thanks @Leroy for the translation. but given what i have to write, it's
going to be complicated and, I think, not always possible.


I'll have to find the "right balance".






-- 
Kurtz le pirate
Compagnie de la Banquise


Post a reply to this message

From: Bald Eagle
Subject: Re: functions and macros
Date: 25 Jun 2023 07:30:00
Message: <web.649824c41d2497941f9dae3025979125@news.povray.org>
kurtz le pirate <kur### [at] gmailcom> wrote:

> indeed, converting the macro into functions is the best solution ... but
> functions also have limitations.

They do, but you can still do a surprising amount with them.

I've converted your macro to a set of two daisy-chained functions to show you
how that would work.

However, you only need a single stock function, instead of an
algorithmic/programmatic approach.  mod (N, 1) returns the fractional part of
any value, which is what you're looking for.



#macro limit_zero2one(_value)
 #local limited = _value - floor(_value);
 #if (limited < 0)
  #local limited = limited + 1.0;
 #end

 limited

#end

#declare precalc = function (_value) {_value - floor(_value)}

#declare Limit_zero2one = function (_value) {select (precalc (_value), precalc
(_value) + 1, precalc (_value), precalc (_value) )}


#local Seed = seed (123);
#for (N, 0, 10)
 #local N2 = rand (Seed) * N + rand (Seed);

 #debug concat( " Initial value = ", str(N2, 0, 3),  " Function result = ",
str(Limit_zero2one (N2), 0, 3), "\n")

#end

#debug "\n"


#for (N, 0, 10)
 #local N2 = rand (Seed) * N + rand (Seed);

 #debug concat( " Initial value = ", str(N2, 0, 3),  " Function result = ",
str(mod (N2, 1), 0, 3), "\n")

#end

#debug "\n"


#error "No objects in scene."


- BW


Post a reply to this message


Attachments:
Download 'kurtz_functions.pov.txt' (1 KB)

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.