sql >> Database teknologi >  >> Database Tools >> MySQL Workbench

Uønsket evaluering i opgaver i Mathematica:hvorfor sker det, og hvordan fejlretter man det under pakkeindlæsningen?

Ser man bort fra WB'en (som egentlig ikke er nødvendig for at besvare dit spørgsmål) - ser problemet ud til at have et ligetil svar, der kun er baseret på, hvordan udtryk vurderes under opgaver. Her er et eksempel:

In[1505]:= 
notGoodQ[x_]:=True;
Clear[g];
g[x_?notGoodQ]:=(Message[g::nogood,x];Abort[])

In[1509]:= g/:cccQ[g[x0_]]:=True

During evaluation of In[1509]:= g::nogood: -- Message text not found -- (x0_)
Out[1509]= $Aborted

For at få det til at fungere lavede jeg bevidst en definition for notGoodQ for altid at returnere True . Hvorfor var g[x0_] evalueret under opgaven gennem TagSetDelayed ? Svaret er, at mens TagSetDelayed (samt SetDelayed ) i en opgave h/:f[h[elem1,...,elemn]]:=... anvender ingen regler, der f kan have, vil den evaluere h[elem1,...,elem2] , samt f . Her er et eksempel:

In[1513]:= 
ClearAll[h,f];
h[___]:=Print["Evaluated"];

In[1515]:= h/:f[h[1,2]]:=3

During evaluation of In[1515]:= Evaluated
During evaluation of In[1515]:= TagSetDelayed::tagnf: Tag h not found in f[Null]. >>
Out[1515]= $Failed  

Det faktum, at TagSetDelayed er HoldAll betyder ikke, at den ikke evaluerer sine argumenter - det betyder kun, at argumenterne ankommer til den uevalueret, og hvorvidt de vil blive evalueret eller ej afhænger af semantikken i TagSetDelayed (som jeg kort beskrevet ovenfor). Det samme gælder for SetDelayed , så den almindeligt anvendte erklæring om, at den "ikke vurderer sine argumenter" er ikke bogstaveligt talt korrekt. Et mere korrekt udsagn er, at den modtager argumenterne uevalueret og vurderer dem på en særlig måde - ikke vurderer r.h.s., mens den for l.h.s. vurderer hoved og elementer, men ikke anvender regler for hovedet. For at undgå det, kan du pakke tingene ind i HoldPattern , sådan her:

Clear[g,notGoodQ];
notGoodQ[x_]:=EvenQ[x];
g[x_?notGoodQ]:=(Message[g::nogood,x];Abort[])
g/:cccQ[HoldPattern[g[x0_]]]:=True;

Dette går igennem. Her er lidt brug:

In[1527]:= cccQ[g[1]]
Out[1527]= True

In[1528]:= cccQ[g[2]]
During evaluation of In[1528]:= g::nogood: -- Message text not found -- (2)
Out[1528]= $Aborted

Bemærk dog, at behovet for HoldPattern inde i din venstre side, når du laver en definition, er ofte et tegn på, at udtrykket inde i dit hoved også kan evaluere under funktionskaldet, hvilket kan knække din kode. Her er et eksempel på, hvad jeg mener:

In[1532]:= 
ClearAll[f,h];
f[x_]:=x^2;
f/:h[HoldPattern[f[y_]]]:=y^4;

Denne kode forsøger at fange tilfælde som h[f[something]] , men det vil åbenbart mislykkes siden f[something] vil evaluere, før evalueringen kommer til h :

In[1535]:= h[f[5]]
Out[1535]= h[25]

For mig er behovet for HoldPattern på l.h.s. er et tegn på, at jeg skal genoverveje mit design.

REDIGER

Med hensyn til debugging under indlæsning i WB, er en ting du kan gøre (IIRC, kan ikke tjekke lige nu) at bruge gode gamle print statements, hvis output vil fremkomme i WB'ens konsol. Personligt føler jeg sjældent et behov for debugger til dette formål (fejlretning af pakke ved indlæsning)

REDIGERING 2

Som svar på redigeringen i spørgsmålet:

Med hensyn til rækkefølgen af ​​definitioner:ja, det kan du gøre, og det løser netop dette problem. Men generelt er dette ikke robust, og jeg vil ikke betragte det som en god generel metode. Det er svært at give et konkret råd til en sag, da den er lidt ude af sin kontekst, men det forekommer mig, at brugen af ​​UpValues her er uberettiget. Hvis dette er gjort for fejl - håndtering, er der andre måder at gøre det uden at bruge UpValues .

Generelt UpValues bruges oftest til at overbelaste en funktion på en sikker måde uden at tilføje nogen regel til den funktion, der overbelastes. Et råd er at undgå at tilknytte UpValues med hoveder, som også har DownValues og kan evaluere -ved at gøre dette begynder du at spille et spil med evaluator, og vil til sidst tabe. Det sikreste er at vedhæfte UpValues at inerte symboler (hoveder, beholdere), som ofte repræsenterer en "type" af objekter, som du ønsker at overbelaste en given funktion på.

Med hensyn til min kommentar om tilstedeværelsen af ​​HoldPattern indikerer et dårligt design. Der er bestemt er legitim brug af HoldPattern , såsom denne (lidt kunstige) en:

In[25]:= 
Clear[ff,a,b,c];
ff[HoldPattern[Plus[x__]]]:={x};
ff[a+b+c]

Out[27]= {a,b,c} 

Her er det berettiget, fordi i mange tilfælde Plus forbliver uevalueret, og er nyttig i sin ikke-evaluerede form - da man kan udlede, at det repræsenterer en sum. Vi har brug for HoldPattern her på grund af måden Plus er defineret på et enkelt argument, og fordi et mønster tilfældigvis er et enkelt argument (selvom det generelt beskriver flere argumenter) under definitionen. Så vi bruger HoldPattern her for at forhindre, at mønsteret behandles som normalt argument, men dette er for det meste forskelligt fra de tilsigtede anvendelsestilfælde for Plus . Når dette er tilfældet (vi er sikre på, at definitionen vil fungere godt for tilsigtede anvendelsestilfælde), HoldPattern er fint. Bemærk b.t.w., at dette eksempel også er skrøbeligt:

In[28]:= ff[Plus[a]]
Out[28]= ff[a]

Grunden til, at det stadig for det meste er OK, er, at vi normalt ikke bruger Plus på et enkelt argument.

Men der er en anden gruppe af tilfælde, hvor strukturen af ​​normalt leverede argumenter er den samme som strukturen af ​​mønstre, der bruges til definitionen. I dette tilfælde indikerer mønsterevaluering under opgaven, at den samme evaluering vil ske med faktiske argumenter under funktionskaldene. Dit forbrug falder ind under denne kategori. Min kommentar til en designfejl var for sådanne tilfælde - du kan forhindre mønsteret i at evaluere, men du bliver nødt til også at forhindre argumenterne i at evaluere for at få dette til at fungere. Og mønstermatchning mod ikke fuldstændigt evalueret udtryk er skrøbeligt. Funktionen bør heller aldrig antage nogle ekstra betingelser (ud over hvad den kan typetjekke) for argumenterne.




  1. Kan ikke øge filoverførselsstørrelsen WAMP

  2. problem med at forsøge at oprette et ssms-tilføjelsesprogram

  3. Opret et databasediagram i phpMyAdmin

  4. phpmyadmin kan ikke åbne tabellens browse-visning