Error with function-lookup and static variable

Friday, 9 August 2024 · 15 messages · last reply 21 Sep 2024
AG
Amanda Galtman9 Aug 2024 17:51 #
Hi, all. I'm seeing an error in BaseX when I use function-lookup in both a global variable and a function, where the function relies on the variable. I reduced the situation to the following small query:
xquery version "3.1";
declare variable $local:lookup := function-lookup(QName("nonexistent", "nonexistent"), 1);
declare function local:myfcn() {
let $f := ($local:lookup, function-lookup(QName('http://www.w3.org/2005/xpath-functions','string'), 1))[1]
return $f('a')
};
local:myfcn()
When I run it with BaseX 11.1, I get [XQDY0054] Static variable depends on itself: $local:lookup When I run it with Saxon-HE 12, I don't get this error. Is there anything I can do in my code to avoid this error? Thanks, Amanda
CG
Christian Grün12 Aug 2024 10:43 #
Hi Amanda, It is high time to tackle an existing GitHub issue that most likely relates to the same bug [1]. Thanks for your observation, Christian [1] https://github.com/BaseXdb/basex/issues/1095
Quoted text · Amanda Galtman · 27 lines
On Fri, Aug 9, 2024 at 5:51 PM Amanda Galtman <galtmana at proton.me> wrote: > Hi, all. > > I'm seeing an error in BaseX when I use function-lookup in both a global > variable and a function, where the function relies on the variable. I > reduced the situation to the following small query: > > xquery version "3.1"; > declare variable $local:lookup := function-lookup(QName("nonexistent", > "nonexistent"), 1); > declare function local:myfcn() { > let $f := ($local:lookup, function-lookup(QName(' > http://www.w3.org/2005/xpath-functions','string'), 1))[1] > return $f('a') > }; > local:myfcn() > > When I run it with BaseX 11.1, I get > [XQDY0054] Static variable depends on itself: $local:lookup > > When I run it with Saxon-HE 12, I don't get this error. > > Is there anything I can do in my code to avoid this error? > > Thanks, > Amanda >
CG
Christian Grünin reply to Amanda Galtman, 9 Aug 2024, 17:5112 Aug 2024 11:16 #
I managed to fix a part of the dependency problem. Your query should now be executable with the latest snapshot [1]. – Christian [1] https://files.basex.org/releases/latest/
Quoted text · Amanda Galtman · 27 lines
On Fri, Aug 9, 2024 at 5:51 PM Amanda Galtman <galtmana at proton.me> wrote: > Hi, all. > > I'm seeing an error in BaseX when I use function-lookup in both a global > variable and a function, where the function relies on the variable. I > reduced the situation to the following small query: > > xquery version "3.1"; > declare variable $local:lookup := function-lookup(QName("nonexistent", > "nonexistent"), 1); > declare function local:myfcn() { > let $f := ($local:lookup, function-lookup(QName(' > http://www.w3.org/2005/xpath-functions','string'), 1))[1] > return $f('a') > }; > local:myfcn() > > When I run it with BaseX 11.1, I get > [XQDY0054] Static variable depends on itself: $local:lookup > > When I run it with Saxon-HE 12, I don't get this error. > > Is there anything I can do in my code to avoid this error? > > Thanks, > Amanda >
AG
Amanda Galtmanin reply to Christian Grün, 12 Aug 2024, 10:4312 Aug 2024 11:56 #
Thanks, Christian. By the way, I found a workaround for my immediate need: putting all the function-lookup usage in module functions instead of a global variable. Regards, Amanda
Quoted text · Christian Grün · 33 lines
On Monday, August 12th, 2024 at 4:43 AM, Christian Grün <christian.gruen at gmail.com> wrote: > Hi Amanda, > > It is high time to tackle an existing GitHub issue that most likely relates to the same bug [1]. > > Thanks for your observation, > Christian > > [1] https://github.com/BaseXdb/basex/issues/1095 > > On Fri, Aug 9, 2024 at 5:51 PM Amanda Galtman <galtmana at proton.me> wrote: > >> Hi, all. >> >> I'm seeing an error in BaseX when I use function-lookup in both a global variable and a function, where the function relies on the variable. I reduced the situation to the following small query: >> >> xquery version "3.1"; >> declare variable $local:lookup := function-lookup(QName("nonexistent", "nonexistent"), 1); >> declare function local:myfcn() { >> let $f := ($local:lookup, function-lookup(QName('http://www.w3.org/2005/xpath-functions','string'), 1))[1] >> return $f('a') >> }; >> local:myfcn() >> >> When I run it with BaseX 11.1, I get >> [XQDY0054] Static variable depends on itself: $local:lookup >> >> When I run it with Saxon-HE 12, I don't get this error. >> >> Is there anything I can do in my code to avoid this error? >> >> Thanks, >> Amanda
AG
Amanda Galtmanin reply to Christian Grün, 12 Aug 2024, 11:1614 Aug 2024 13:01 #
Christian, thanks very much. I returned to my actual code, and it works with the latest snapshot dated today. By the way, I also retried the variations I had created when trying to explore workarounds, and one of them still doesn't work with the latest snapshot. It's not blocking me, but in case it is helpful, I reduced it to another small query that reproduces the error with today's snapshot. I know you said you fixed part of the problem, so you might not be surprised that the following code still triggers the error. xquery version "3.1";
declare variable $variant :=
if (exists(function-lookup(QName('nonexistent','nonexistent'), 0)))
then
( (: not relevant :) )
else
function-lookup(QName('http://www.w3.org/2005/xpath-functions','string'), 1);

declare variable $variant-fcns := $variant;

declare function local:fcn() {
$variant-fcns('abc')
};

local:fcn()
The levels of indirection (variable, variable, function, function call) seem to be relevant for the problem. If I make the code more direct, it works. Regards, Amanda
Quoted text · Christian Grün · 29 lines
On Monday, August 12th, 2024 at 5:16 AM, Christian Grün <christian.gruen at gmail.com> wrote: > I managed to fix a part of the dependency problem. Your query should now be executable with the latest snapshot [1]. > – Christian > > [1] https://files.basex.org/releases/latest/ > > On Fri, Aug 9, 2024 at 5:51 PM Amanda Galtman <galtmana at proton.me> wrote: > >> Hi, all. >> >> I'm seeing an error in BaseX when I use function-lookup in both a global variable and a function, where the function relies on the variable. I reduced the situation to the following small query: >> >> xquery version "3.1"; >> declare variable $local:lookup := function-lookup(QName("nonexistent", "nonexistent"), 1); >> declare function local:myfcn() { >> let $f := ($local:lookup, function-lookup(QName('http://www.w3.org/2005/xpath-functions','string'), 1))[1] >> return $f('a') >> }; >> local:myfcn() >> >> When I run it with BaseX 11.1, I get >> [XQDY0054] Static variable depends on itself: $local:lookup >> >> When I run it with Saxon-HE 12, I don't get this error. >> >> Is there anything I can do in my code to avoid this error? >> >> Thanks, >> Amanda
CG
Christian Grün14 Aug 2024 15:43 #
…thanks. I already guessed it wasn’t that easy ;) I’ve added it to [1]. In general, I hope we could get completely rid of self-dependency checks. It was only defined for variables, not for functions, and I cannot see why we still need it today. We are currently discussing this topic for version 4.0 [2]. Best, Christian [1] https://github.com/BaseXdb/basex/issues/2324 [2] https://github.com/qt4cg/qtspecs/issues/1379
Quoted text · Amanda Galtman · 80 lines
On Wed, Aug 14, 2024 at 1:02 PM Amanda Galtman <galtmana at proton.me> wrote: > Christian, thanks very much. > > I returned to my actual code, and it works with the latest snapshot dated > today. > > By the way, I also retried the variations I had created when trying to > explore workarounds, and one of them still doesn't work with the latest > snapshot. It's not blocking me, but in case it is helpful, I reduced it to > another small query that reproduces the error with today's snapshot. I know > you said you fixed part of the problem, so you might not be surprised that > the following code still triggers the error. > > xquery version "3.1"; > > declare variable $variant := > if (exists(function-lookup(QName('nonexistent','nonexistent'), 0))) > then > ( (: not relevant :) ) > else > function-lookup(QName('http://www.w3.org/2005/xpath-functions','string'), > 1); > > declare variable $variant-fcns := $variant; > > declare function local:fcn() { > $variant-fcns('abc') > }; > > local:fcn() > > > The levels of indirection (variable, variable, function, function call) > seem to be relevant for the problem. If I make the code more direct, it > works. > > Regards, > Amanda > > On Monday, August 12th, 2024 at 5:16 AM, Christian Grün < > christian.gruen at gmail.com> wrote: > > I managed to fix a part of the dependency problem. Your query should now > be executable with the latest snapshot [1]. > – Christian > > [1] https://files.basex.org/releases/latest/ > > > > On Fri, Aug 9, 2024 at 5:51 PM Amanda Galtman <galtmana at proton.me> wrote: > >> Hi, all. >> >> I'm seeing an error in BaseX when I use function-lookup in both a global >> variable and a function, where the function relies on the variable. I >> reduced the situation to the following small query: >> >> xquery version "3.1"; >> declare variable $local:lookup := function-lookup(QName("nonexistent", >> "nonexistent"), 1); >> declare function local:myfcn() { >> let $f := ($local:lookup, function-lookup(QName(' >> http://www.w3.org/2005/xpath-functions','string'), 1))[1] >> return $f('a') >> }; >> local:myfcn() >> >> When I run it with BaseX 11.1, I get >> [XQDY0054] Static variable depends on itself: $local:lookup >> >> When I run it with Saxon-HE 12, I don't get this error. >> >> Is there anything I can do in my code to avoid this error? >> >> Thanks, >> Amanda >> > >
CG
Christian Grün18 Sep 2024 13:08 #
Hi Amanda, The last query you reported back to us is now evaluated successfully [1]. In addition, XQuery 4 will allow all of us to write self-referencing variable declarations (it’s already supported by the latest snapshot):
declare variable $factorial := fn($x) {
  if($x > 1) then $x + $factorial($x - 1) else $x
};
$factorial(5)
Quoted text · Christian Grün · 98 lines
On Wed, Aug 14, 2024 at 3:43 PM Christian Grün <christian.gruen at gmail.com> wrote: > …thanks. I already guessed it wasn’t that easy ;) I’ve added it to [1]. > > In general, I hope we could get completely rid of self-dependency checks. > It was only defined for variables, not for functions, and I cannot see why > we still need it today. We are currently discussing this topic for version > 4.0 [2]. > > Best, > Christian > > [1] https://github.com/BaseXdb/basex/issues/2324 > [2] https://github.com/qt4cg/qtspecs/issues/1379 > > > > On Wed, Aug 14, 2024 at 1:02 PM Amanda Galtman <galtmana at proton.me> wrote: > >> Christian, thanks very much. >> >> I returned to my actual code, and it works with the latest snapshot dated >> today. >> >> By the way, I also retried the variations I had created when trying to >> explore workarounds, and one of them still doesn't work with the latest >> snapshot. It's not blocking me, but in case it is helpful, I reduced it to >> another small query that reproduces the error with today's snapshot. I know >> you said you fixed part of the problem, so you might not be surprised that >> the following code still triggers the error. >> >> xquery version "3.1"; >> >> declare variable $variant := >> if (exists(function-lookup(QName('nonexistent','nonexistent'), 0))) >> then >> ( (: not relevant :) ) >> else >> function-lookup(QName(' >> http://www.w3.org/2005/xpath-functions','string'), 1); >> >> declare variable $variant-fcns := $variant; >> >> declare function local:fcn() { >> $variant-fcns('abc') >> }; >> >> local:fcn() >> >> >> The levels of indirection (variable, variable, function, function call) >> seem to be relevant for the problem. If I make the code more direct, it >> works. >> >> Regards, >> Amanda >> >> On Monday, August 12th, 2024 at 5:16 AM, Christian Grün < >> christian.gruen at gmail.com> wrote: >> >> I managed to fix a part of the dependency problem. Your query should now >> be executable with the latest snapshot [1]. >> – Christian >> >> [1] https://files.basex.org/releases/latest/ >> >> >> >> On Fri, Aug 9, 2024 at 5:51 PM Amanda Galtman <galtmana at proton.me> wrote: >> >>> Hi, all. >>> >>> I'm seeing an error in BaseX when I use function-lookup in both a global >>> variable and a function, where the function relies on the variable. I >>> reduced the situation to the following small query: >>> >>> xquery version "3.1"; >>> declare variable $local:lookup := function-lookup(QName("nonexistent", >>> "nonexistent"), 1); >>> declare function local:myfcn() { >>> let $f := ($local:lookup, function-lookup(QName(' >>> http://www.w3.org/2005/xpath-functions','string'), 1))[1] >>> return $f('a') >>> }; >>> local:myfcn() >>> >>> When I run it with BaseX 11.1, I get >>> [XQDY0054] Static variable depends on itself: $local:lookup >>> >>> When I run it with Saxon-HE 12, I don't get this error. >>> >>> Is there anything I can do in my code to avoid this error? >>> >>> Thanks, >>> Amanda >>> >> >>
AG
Amanda Galtman18 Sep 2024 21:34 #
Christian, thanks for the fix and the follow-up! Best regards, Amanda
Quoted text · Christian Grün · 89 lines
On Wednesday, September 18th, 2024 at 7:08 AM, Christian Grün <christian.gruen at gmail.com> wrote: > Hi Amanda, > > The last query you reported back to us is now evaluated successfully [1]. > > In addition, XQuery 4 will allow all of us to write self-referencing variable declarations (it’s already supported by the latest snapshot): > > declare variable $factorial := fn($x) { > if($x > 1) then $x + $factorial($x - 1) else $x > }; > $factorial(5) > > All the best, > Christian > > [1] https://github.com/BaseXdb/basex/issues/2324#issuecomment-2288790599 > > On Wed, Aug 14, 2024 at 3:43 PM Christian Grün <christian.gruen at gmail.com> wrote: > >> …thanks. I already guessed it wasn’t that easy ;) I’ve added it to [1]. >> >> In general, I hope we could get completely rid of self-dependency checks. It was only defined for variables, not for functions, and I cannot see why we still need it today. We are currently discussing this topic for version 4.0 [2]. >> >> Best, >> Christian >> >> [1] https://github.com/BaseXdb/basex/issues/2324 >> [2] https://github.com/qt4cg/qtspecs/issues/1379 >> >> On Wed, Aug 14, 2024 at 1:02 PM Amanda Galtman <galtmana at proton.me> wrote: >> >>> Christian, thanks very much. >>> >>> I returned to my actual code, and it works with the latest snapshot dated today. >>> >>> By the way, I also retried the variations I had created when trying to explore workarounds, and one of them still doesn't work with the latest snapshot. It's not blocking me, but in case it is helpful, I reduced it to another small query that reproduces the error with today's snapshot. I know you said you fixed part of the problem, so you might not be surprised that the following code still triggers the error. >>> >>> xquery version "3.1"; >>> >>> declare variable $variant := >>> if (exists(function-lookup(QName('nonexistent','nonexistent'), 0))) >>> then >>> ( (: not relevant :) ) >>> else >>> function-lookup(QName('http://www.w3.org/2005/xpath-functions','string'), 1); >>> >>> declare variable $variant-fcns := $variant; >>> >>> declare function local:fcn() { >>> $variant-fcns('abc') >>> }; >>> >>> local:fcn() >>> >>> The levels of indirection (variable, variable, function, function call) seem to be relevant for the problem. If I make the code more direct, it works. >>> >>> Regards, >>> Amanda >>> >>> On Monday, August 12th, 2024 at 5:16 AM, Christian Grün <christian.gruen at gmail.com> wrote: >>> >>>> I managed to fix a part of the dependency problem. Your query should now be executable with the latest snapshot [1]. >>>> – Christian >>>> >>>> [1] https://files.basex.org/releases/latest/ >>>> >>>> On Fri, Aug 9, 2024 at 5:51 PM Amanda Galtman <galtmana at proton.me> wrote: >>>> >>>>> Hi, all. >>>>> >>>>> I'm seeing an error in BaseX when I use function-lookup in both a global variable and a function, where the function relies on the variable. I reduced the situation to the following small query: >>>>> >>>>> xquery version "3.1"; >>>>> declare variable $local:lookup := function-lookup(QName("nonexistent", "nonexistent"), 1); >>>>> declare function local:myfcn() { >>>>> let $f := ($local:lookup, function-lookup(QName('http://www.w3.org/2005/xpath-functions','string'), 1))[1] >>>>> return $f('a') >>>>> }; >>>>> local:myfcn() >>>>> >>>>> When I run it with BaseX 11.1, I get >>>>> [XQDY0054] Static variable depends on itself: $local:lookup >>>>> >>>>> When I run it with Saxon-HE 12, I don't get this error. >>>>> >>>>> Is there anything I can do in my code to avoid this error? >>>>> >>>>> Thanks, >>>>> Amanda
CG
Christian Grünin reply to Liam R. E. Quin, 19 Sep 2024, 17:0119 Sep 2024 15:11 #
Hi Liam,
Quoted text · Liam R. E. Quin · 2 lines
Hmm, what if there's a $factorial in scope already? (this is a > technique i teach for taking advantage of closures to hide data)
Variables that are declared more than once in XQuery will continue to be rejected with the error code XQST0049 (duplicate declaration of static variable):
declare variable $a := 123;
declare variable $a := 'whatever';
Best, Christian
CG
Christian Grünin reply to Graydon, 19 Sep 2024, 17:4019 Sep 2024 16:08 #
Quoted text · Graydon · 3 lines
> > > If I use $x * $factorial($x - 1) >
True, it should have been multiplication; thanks. I get an out-of-range error as of $factorial(21).
Quoted text · Graydon · 1 line
>
Integers in BaseX are limited to 64bit (that’s something the spec allows). You can use decimals to work with greater numbers:
declare variable $factorial := fn($x) {
  if($x > 1) then $x * $factorial($x - 1) else $x
};
$factorial(1000.0)
If you need even larger results, you can use a tail-call-optimized variant…
declare variable $factorial := fn($x, $result) {
  if($x > 1) then $factorial($x - 1, $x * $result) else $result
};
$factorial(100000.0, 1)
…or fold-left: fold-left(1 to 100000, 1.0, op('*')) Hope this helps, Christian
LQ
Liam R. E. Quinin reply to Christian Grün, 18 Sep 2024, 13:0819 Sep 2024 17:01 #
Quoted text · Christian Grün · 10 lines
On Wed, 2024-09-18 at 13:08 +0200, Christian Grün wrote: > > In addition, XQuery 4 will allow all of us to write self-referencing > variable declarations (it’s already supported by the latest > snapshot): > > declare variable $factorial := fn($x) { > if($x > 1) then $x + $factorial($x - 1) else $x > }; > $factorial(5)
Hmm, what if there's a $factorial in scope already? (this is a technique i teach for taking advantage of closures to hide data)
Quoted text · Christian Grün · 1 line
> >
-- Liam Quin, https://www.delightfulcomputing.com/ Available for XML/Document/Information Architecture/XSLT/ XSL/XQuery/Web/Text Processing/A11Y training, work & consulting. Barefoot Web-slave, antique illustrations: http://www.fromoldbooks.org
G
Graydonin reply to Christian Grün, 18 Sep 2024, 13:0819 Sep 2024 17:40 #
Quoted text · Christian Grün · 8 lines
On Wed, Sep 18, 2024 at 01:08:17PM +0200, Christian Grün scripsit: > In addition, XQuery 4 will allow all of us to write self-referencing > variable declarations (it’s already supported by the latest snapshot): > > declare variable $factorial := fn($x) { > if($x > 1) then $x + $factorial($x - 1) else $x > }; > $factorial(5)
If I use $x * $factorial($x - 1) I get an out-of-range error as of $factorial(21).
declare variable $factorial := fn($x) as xs:double {
    if($x > 1) then $x * $factorial($x - 1) else $x
  };
goes until $factorial(171) gives INF. If I were to be so unfortunate as to need larger factorials, is there a better approach? It doesn't look like the math module has factorials and it does look like it uses xs:double for math:pow(); on the other hand, XQuery isn't meant for numerical analysis. Thanks! Graydon
-- Graydon Saunders | graydonish at fastmail.com Þæs oferéode, ðisses swá mæg. -- Deor ("That passed, so may this.")
LQ
Liam R. E. Quinin reply to Liam R. E. Quin, 19 Sep 2024, 17:0119 Sep 2024 18:26 #
Quoted text · Liam R. E. Quin · 4 lines
On Thu, 2024-09-19 at 09:01 -0400, Liam R. E. Quin wrote: > \ > Hmm, what if there's a $factorial in scope already? (this is a > technique i teach for taking advantage of closures to hide data)
Many thanks to Christian for taking the time to explain to me this isn’t a problem - the change provided a meaning for something that had previously been an error, and also only affecs XQuery.
Quoted text · Liam R. E. Quin · 1 line
>
-- Liam Quin, https://www.delightfulcomputing.com/ Available for XML/Document/Information Architecture/XSLT/ XSL/XQuery/Web/Text Processing/A11Y training, work & consulting. Barefoot Web-slave, antique illustrations: http://www.fromoldbooks.org
G
Graydonin reply to Christian Grün, 19 Sep 2024, 16:0820 Sep 2024 17:47 #
Quoted text · Christian Grün · 1 line
On Thu, Sep 19, 2024 at 04:08:34PM +0200, Christian Grün scripsit:
[snip]
Quoted text · Christian Grün · 20 lines
> Integers in BaseX are limited to 64bit (that’s something the spec allows). > You can use decimals to work with greater numbers: > > declare variable $factorial := fn($x) { > if($x > 1) then $x * $factorial($x - 1) else $x > }; > $factorial(1000.0) > > If you need even larger results, you can use a tail-call-optimized variant… > > declare variable $factorial := fn($x, $result) { > if($x > 1) then $factorial($x - 1, $x * $result) else $result > }; > $factorial(100000.0, 1) > > …or fold-left: > > fold-left(1 to 100000, 1.0, op('*')) > > Hope this helps,
Most helpful; thank you! It feels like my understanding of how types and processing interact has improved. -- Graydon
RS
Rob Stapper21 Sep 2024 09:34 #
Perfect. Cascaded function-calls through variables within self-recursive constructs work fine now. mvgr. Rob Stapper

⚡Generated with XQuery