POV-Ray : Newsgroups : povray.general : Problem with name space for user-defined functions Server Time
31 Oct 2024 08:17:35 EDT (-0400)
  Problem with name space for user-defined functions (Message 1 to 8 of 8)  
From: Tor Olav Kristensen
Subject: Problem with name space for user-defined functions
Date: 3 Apr 2018 11:15:00
Message: <web.5ac3998d3d5e6ed05bf3e3600@news.povray.org>
Try this:

#macro P()
    #local B = 0;
#end

#macro Q()
    #local B = function { 0 };
    P()
#end

Q()

// Error message in version 3.7.0.msvc10.win64 and in
// version 3.8.0-alpha.9322209+av499.msvc14.win64 for the code above:
// "Parse Error: Redeclaring functions is not allowed - undef# the function
first!"

- and this:

#macro M()
    #local A = function { 0 };
#end

#declare A = 0;

M()

// Error message in version 3.7.0.msvc10.win64 for the code above:
// "Parse Error: Attemped to redefine float identifier as function identifier."
// (No error message for this in version 3.8.0-alpha.9322209+av499.msvc14.win64)


I'm aware of this part of the documentation:

http://www.povray.org/documentation/3.7.0/r3_3.html#r3_3_1_8_3
"Note: Redeclaring functions, directly, is not allowed. The way to do this is to
undef it first."

- but shouldn't it still be possible to have user defined functions that are
stored in local variables in macros without having to worry about which names to
choose for those local variables ?

I tested this on a PC with Windows 7 Professioinal 64 bit. I have not tested
this in any Linux versions of POV-Ray yet.

--
Tor Olav
http://subcube.com


Post a reply to this message

From: Kenneth
Subject: Re: Problem with name space for user-defined functions
Date: 3 Apr 2018 21:50:00
Message: <web.5ac42ec3f0f198f8a47873e10@news.povray.org>
"Tor Olav Kristensen" <tor### [at] TOBEREMOVEDgmailcom> wrote:
>
> #macro P()
>     #local B = 0;
> #end
>
> #macro Q()
>     #local B = function { 0 };
>     P()
> #end
>
> Q()
>
> // Error message in version 3.7.0.msvc10.win64 and in
> // version 3.8.0-alpha.9322209+av499.msvc14.win64 for the code above:
> // "Parse Error: Redeclaring functions is not allowed - undef# the function
> first!"

Same error message in v3.7.1 beta 9 (on Win 7)

But that construct is essentially the same as this (and the original #macro P()
can be commented-out, with no change):

#macro Q()
#local B = function { 0 };
#local B = 0;
#end
Q()

This throws the same error. So it appears that B can't be re-#local'ed there,
even though the 'new' B is not actually a new function.

However, this throws NO error...
#macro Q()
    #local B = function { 0 };
#end
#local B = 0; // or #declare
Q()

Strange. Although, in this case, the 'first' #local B to be 'processed' is
   #local B = 0;
which is NOT a function. So when B is then #local'ed again inside macro Q()--
only when Q() is INVOKED, apparently-- all is well.

BTW, there's no error at all when Q() is not actually invoked. That's
interesting; I thought your original code error might still appear, when POV-Ray
initially 'reads' #macro Q() in the SDL.

>
> - and this:
>
> #macro M()...
[snip]

No error in my version either.


Post a reply to this message

From: Kenneth
Subject: Re: Problem with name space for user-defined functions
Date: 4 Apr 2018 06:55:01
Message: <web.5ac4ad1ef0f198f8a47873e10@news.povray.org>
I just did another test...

#declare B = function{0};
#declare B = 0;

This causes the same "...#undef the function first" error-- even though the new
B is not a function. So the error result is not specific to macros.

The documentation about re-defining funtions doesn't mention this particular
behavior. It appears that if B is first assigned to a *function*, that function
'legacy' is still part of B when the attempt is made to re-declare B as
*anything* else, whether as another function or not...unless the original B is
'destroyed' first.


Post a reply to this message

From: Thorsten Froehlich
Subject: Re: Problem with name space for user-defined functions
Date: 4 Apr 2018 07:45:00
Message: <web.5ac4ba55f0f198f8f773ca290@news.povray.org>
"Kenneth" <kdw### [at] gmailcom> wrote:
> I just did another test...
>
> #declare B = function{0};
> #declare B = 0;
>
> This causes the same "...#undef the function first" error-- even though the new
> B is not a function. So the error result is not specific to macros.
>
> The documentation about re-defining funtions doesn't mention this particular
> behavior. It appears that if B is first assigned to a *function*, that function
> 'legacy' is still part of B when the attempt is made to re-declare B as
> *anything* else, whether as another function or not...unless the original B is
> 'destroyed' first.

No, B is a function and you are trying to assign some value to the function B.
The undef rule applies to B as long as it is a function, and the lack of an
undef means by the time you try to assign the value 0, B is still a defined
function. No magic, just logic here.


Post a reply to this message

From: Thorsten Froehlich
Subject: Re: Problem with name space for user-defined functions
Date: 4 Apr 2018 08:00:00
Message: <web.5ac4bd87f0f198f8f773ca290@news.povray.org>
"Kenneth" <kdw### [at] gmailcom> wrote:
> "Tor Olav Kristensen" <tor### [at] TOBEREMOVEDgmailcom> wrote:
> >
> > #macro P()
> >     #local B = 0;
> > #end
> >
> > #macro Q()
> >     #local B = function { 0 };
> >     P()
> > #end
> >
> > Q()
> >
> > // Error message in version 3.7.0.msvc10.win64 and in
> > // version 3.8.0-alpha.9322209+av499.msvc14.win64 for the code above:
> > // "Parse Error: Redeclaring functions is not allowed - undef# the function
> > first!"
>
> Same error message in v3.7.1 beta 9 (on Win 7)
>
> But that construct is essentially the same as this (and the original #macro P()
> can be commented-out, with no change):
>
> #macro Q()
> #local B = function { 0 };
> #local B = 0;
> #end
> Q()
>
> This throws the same error. So it appears that B can't be re-#local'ed there,
> even though the 'new' B is not actually a new function.
>
> However, this throws NO error...
> #macro Q()
>     #local B = function { 0 };
> #end
> #local B = 0; // or #declare
> Q()
>
> Strange. Although, in this case, the 'first' #local B to be 'processed' is
>    #local B = 0;
> which is NOT a function. So when B is then #local'ed again inside macro Q()--
> only when Q() is INVOKED, apparently-- all is well.
>
> BTW, there's no error at all when Q() is not actually invoked. That's
> interesting; I thought your original code error might still appear, when POV-Ray
> initially 'reads' #macro Q() in the SDL.
>
> >
> > - and this:
> >
> > #macro M()...
> [snip]
>
> No error in my version either.

The behavior is logical because of the scoping rules that local implies. These
rules apply at the time of invocation, not the order in which a macro is
defined. It is also perfectly legal to redefine a local variable to be a
function.

Internally the logic is very specific: The code prevents you to overwrite a
function unintentionally. The rationale is that you should always be aware of
what you are doing with functions, which do not perfectly it into the POV-Ray
pseudo-variable system.

The behavior is also necessary because internally functions, unlike variables,
exist beyond the time parsing finishes.


Post a reply to this message

From: clipka
Subject: Re: Problem with name space for user-defined functions
Date: 4 Apr 2018 14:45:01
Message: <5ac51d2d$1@news.povray.org>
Am 04.04.2018 um 03:47 schrieb Kenneth:
> "Tor Olav Kristensen" <tor### [at] TOBEREMOVEDgmailcom> wrote:
>>
>> #macro P()
>>     #local B = 0;
>> #end
>>
>> #macro Q()
>>     #local B = function { 0 };
>>     P()
>> #end
>>
>> Q()
...
> But that construct is essentially the same as this (and the original #macro P()
> can be commented-out, with no change):
> 
> #macro Q()
> #local B = function { 0 };
> #local B = 0;
> #end
> Q()

Not exactly. Technically, it is (or at least should be) equivalent to:

#declare LocalQ = dictionary; // start of macro Q
#declare LocalQ.B = function { 0 };
#declare LocalP = dictionary; // start of macro P
#declare LocalP.B = 0;
#undef LocalP // end of macro P
#undef LocalQ // end of macro Q

where LocalQ denotes the local variables context of macro Q, and LocalP
is the local variables context of macro P.

(dictionary is an actual feature in 3.8)


> BTW, there's no error at all when Q() is not actually invoked. That's
> interesting; I thought your original code error might still appear, when POV-Ray
> initially 'reads' #macro Q() in the SDL.

Nope; when initially encounters a macro definition, it only scans the
macro for directives (stuff starting with `#`), and only for the purpose
of skipping to the end of the macro (which is marked by `#end`, but
isn't trivially found because there might be nested statements such as
`#if` or the like that also have an `#end`). As soon as POV-Ray has
figured that out, it doesn't care about the macro contents at all (it
just memorizes the macro's location and length) until the macro is
actually invoked.


Post a reply to this message

From: Kenneth
Subject: Re: Problem with name space for user-defined functions
Date: 4 Apr 2018 20:45:01
Message: <web.5ac57135f0f198f8a47873e10@news.povray.org>
I'm understanding most of this-- although I confess that the 'dictionary'
feature is new to me. I knew it was added to v3.8, but I'm currently clueless as
to what it's for  :-O

From a user's standpoint re: functions, I think the actual problem-- a small
one--may be with the error message itself (and maybe the documentation about
#undefining a function). For example...

#declare B = function(0)
#declare B = 0

The error message (as Tor Olav mentioned) is...
"Redeclaring functions is not allowed-- #undef the function first!"

Until now, I've understood that to mean, "if I try to re-define the first
function as another FUNCTION".  Like,

#declare B = function{0}
#declare B = function(y){sin(2*pi*y)}

Although, I now see that there's a *different* way of reading the error
message-- the way that was probably intended: "Don't try to redeclare a function
name without undefining it first." That solves the ambiguity. It may not be
technically accurate, but it takes care of situations like my first example
above.


Post a reply to this message

From: clipka
Subject: Re: Problem with name space for user-defined functions
Date: 5 Apr 2018 02:11:54
Message: <5ac5be2a$1@news.povray.org>
Am 05.04.2018 um 02:43 schrieb Kenneth:
> I'm understanding most of this-- although I confess that the 'dictionary'
> feature is new to me. I knew it was added to v3.8, but I'm currently clueless as
> to what it's for  :-O

It can be interpreted as an array-ish structure that takes strings as
indices:

    #declare Foo = dictionary;
    #declare Foo["Some Index"] = 4711;

As syntactic sugar, if an index satisfies the rules for an identifier,
the index can also be written using dot notation; for example, the
following two lines are equivalent:

    #declare Foo["Bar"] = 815;
    #declare Foo.Bar = 815;

With this notation in mind, a dictionary can also be interpreted as what
would be called a "struct" in C/C++ or a "record" in Pascal - or as a
namespace, which is pretty much what it actually is under the hood.


The future plan is to also extend dictionaries to be able to hold
macros, which would make them usable for object-oriented programming.
But that still needs a bit of work.


Post a reply to this message

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