MySQL Workbench
 sql >> база данни >  >> Database Tools >> MySQL Workbench

Нежелана оценка в заданията в Mathematica:защо се случва и как да отстраните грешките по време на зареждането на пакета?

Оставяйки настрана WB (който всъщност не е необходим, за да се отговори на вашия въпрос) - проблемът изглежда има ясен отговор, базиран само на това как изразите се оценяват по време на задания. Ето един пример:

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

За да работи, нарочно направих дефиниция за notGoodQ за да връща винаги True . Сега, защо беше g[x0_] оценено по време на заданието чрез TagSetDelayed ? Отговорът е, че докато TagSetDelayed (както и SetDelayed ) в задание h/:f[h[elem1,...,elemn]]:=... не прилага никакви правила, които f може да има, ще оцени h[elem1,...,elem2] , както и f . Ето един пример:

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  

Фактът, че TagSetDelayed е HoldAll не означава, че не оценява своите аргументи - това означава само, че аргументите пристигат до него неоценени и дали ще бъдат оценени или не зависи от семантиката на TagSetDelayed (което накратко описах по-горе). Същото важи и за SetDelayed , така че често използваното твърдение, че "не оценява аргументите си" не е буквално правилно. По-правилното твърдение е, че той получава аргументите неоценени и ги оценява по специален начин - не оценява r.h.s, докато за l.h.s. оценява главата и елементите, но не прилага правила за главата. За да избегнете това, можете да обвиете нещата в HoldPattern , като това:

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

Това минава през. Ето някои употреби:

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

Имайте предвид обаче, че необходимостта от HoldPattern вътре в лявата ви страна, когато правите дефиниция, често е знак, че изразът в главата ви може също да се оцени по време на извикването на функция, което може да разбие вашия код. Ето пример за това, което имам предвид:

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

Този код се опитва да улови случаи като h[f[something]] , но очевидно ще се провали, тъй като f[something] ще направи оценка, преди оценката да стигне до h :

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

За мен необходимостта от HoldPattern на л.ч.с. е знак, че трябва да преразгледам своя дизайн.

РЕДАКТИРАНЕ

По отношение на отстраняването на грешки по време на зареждане в WB, едно нещо, което можете да направите (IIRC, не мога да проверя в момента) е да използвате добрите стари оператори за печат, чийто изход ще се появи в конзолата на WB. Лично аз рядко изпитвам нужда от дебъгер за тази цел (пакет за отстраняване на грешки при зареждане)

РЕДАКТИРАНЕ 2

В отговор на редакцията във въпроса:

По отношение на реда на дефинициите:да, можете да направите това и това решава този конкретен проблем. Но като цяло това не е стабилно и не бих го счел за добър общ метод. Трудно е да се даде категоричен съвет за даден случай, тъй като е малко извън контекста му, но ми се струва, че използването на UpValues тук е неоправдано. Ако това се прави за обработка на грешки, има други начини за да го направите без да използвате UpValues .

Обикновено UpValues се използват най-често за претоварване на някаква функция по безопасен начин, без да се добавя никакво правило към претоварената функция. Един съвет е да избягвате свързването на UpValues с глави, които също имат DownValues и може да оценявате - като правите това, започвате да играете игра с оценител и в крайна сметка ще загубите. Най-безопасното е да прикачите UpValues към инертни символи (глави, контейнери), които често представляват „тип“ обекти, върху които искате да претоварите дадена функция.

Относно моя коментар относно наличието на HoldPattern което показва лош дизайн. Със сигурност има законно използване на HoldPattern , като този (донякъде изкуствен):

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

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

Тук е оправдано, защото в много случаи Plus остава неоценен и е полезен в неоценената си форма - тъй като може да се заключи, че представлява сума. Нуждаем се от HoldPattern тук заради начина Plus е дефиниран с един аргумент и тъй като моделът се оказва единичен аргумент (въпреки че обикновено описва множество аргументи) по време на дефиницията. И така, ние използваме HoldPattern тук, за да предотвратите третирането на шаблона като нормален аргумент, но това е най-вече различно от предвидените случаи на употреба за Plus . Когато случаят е такъв (сигурни сме, че дефиницията ще работи добре за предвидените случаи на употреба), HoldPattern е наред. Обърнете внимание, че този пример също е крехък:

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

Причината, поради която все още е почти добре, е, че обикновено не използваме Plus на един аргумент.

Но има втора група случаи, при които структурата на обикновено предоставяните аргументи е същата като структурата на моделите, използвани за дефиницията. В този случай оценката на шаблона по време на присвояването показва, че същата оценка ще се случи с действителните аргументи по време на извикванията на функция. Вашето използване попада в тази категория. Коментарът ми за недостатък в дизайна беше за такива случаи - можете да предотвратите оценката на шаблона, но ще трябва да предотвратите и оценката на аргументите, за да работи това. А съпоставянето на образци срещу не напълно оценено изразяване е крехко. Също така, функцията никога не трябва да приема някои допълнителни условия (отвъд това, което може да провери на типа) за аргументите.




  1. DBeaver
  2.   
  3. phpMyAdmin
  4.   
  5. Navicat
  6.   
  7. SSMS
  8.   
  9. MySQL Workbench
  10.   
  11. SQLyog
  1. Как да копирам таблица между два модела в работната маса на Mysql?

  2. SQL заявката работи в Workbench, но получава грешка „Не може да се преобразува тип вариант“ с точно същата заявка в Delphi

  3. MySQL Workbench набор от знаци

  4. Mysql Workbench Mac OS липсват инструменти за управление и импортиране/експорт на данни

  5. Приложението org.eclipse.e4.ui.workbench.swt.E4 Приложението не може да бъде намерено в системния регистър