Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/Not+Functional+Imaging+%2D+Scripting+Imaging?V=14
QUERY_STRINGV=14
CONTENT_TYPE
DOCUMENT_URI/revision/Not+Functional+Imaging+-+Scripting+Imaging
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.69.7.90
REMOTE_PORT50214
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR3.22.249.158
HTTP_CF_RAY87a4be7f3c8f6164-ORD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTMozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected])
HTTP_CF_CONNECTING_IP3.22.249.158
HTTP_CDN_LOOPcloudflare
HTTP_CF_IPCOUNTRYUS

Body


Error

Unknow state transition: LINE -> END

-code

1

-level

0

-errorstack

INNER {returnImm {Unknow state transition: LINE -> END} {}} CALL {my render_wikit {Not Functional Imaging - Scripting Imaging} '''Overview\ \ 9\ Feb\ 2004'''\n\nThe\ post\ \[Functional\ imaging\]\ looks\ at\ implementing\ a\ paradigm\ found\ in\ functional\ programming\ language\ in\ TCL.\n\nWhile\ all\ these\ contributions\ are\ useful\ in\ themselves,\ they\ also\ show\ that\ TCL\ does\ not\ always\ map\ well\ to\ these\ techniques.\n\nThe\ article\ also\ touched\ on\ a\ design\ pattern\ that\ is\ not\ well\ exploited\ in\ scripting\ languages.\ I\ attempt\ to\ elaborate\ here.\n\n''Please\ refer\ to\ the\ original\ page\ before\ reading\ further''.\n\nIn\ this\ discussion\ we\ assume\ that\ the\ example\ given\ in\ the\ above\ reference\ is\ a\ valid\ image\ processing\ technique\ and\ that\ the\ method\ of\ x\ y\ transformations\ are\ appropriate\ to\ real\ world\ tasks.\nWe\ also\ assume\ that\ the\ function\ would\ in\ real\ life\ be\ called\ more\ than\ once\ in\ the\ life\ time\ of\ the\ application.\ For\ example\ ,\ face\ recognition,\ video\ editing,\ or\ such.\n\n'''Background'''\n\nThe\ example\ implements\ a\ combinor\ function\ to\ convert\ a\ pipeline\ of\ processing\ tasks,\ as\ an\ example:\n\ \ \ o\ \{gPaint\ yellow\}\ gChecker\ \{rippleRad\ 6\ 0.2\}\ \{swirl\ 26\}\ toPolars\ \ \nThis\ creates\ a\ proc\ of\ the\ form:\n\ \ \ \ proc\ uniquename\ \{x\}\ \{\ gPaint\ yellow\ \[gChecker\ \[rippleRad\ 6\ 0.2\ \[\ swirl\ 26\ \[toPolars\ \$x\]\]\]\]\nWe\ have\ here\ the\ essence\ of\ dynamic\ programming.\ In\ the\ case\ of\ TCL,\ the\ creation\ of\ a\ proc\ is\ due\ to\ the\ need\ to\ bytecode\ for\ speed.\ Otherwise\ the\ pipeline\ could\ have\ been\ implmented\ with\ ''eval''.\n\nThe\ main\ processing\ loop\ iterates\ through\ the\ x,\ y\ coordinates\ and\ calls\ the\ arbitary\ function\ with\ the\ ''xy''\ pair.\ The\ result\ is\ then\ appended\ to\ the\ new\ image\ data.\n\n'''Extending\ dynamic\ programming'''\n\nIf\ we\ instead\ use\ specialisation\ to\ change\ the\ main\ loop\ we\ get\ a\ performance\ increase.\nTake\ the\ following\ template:\n\n======\n\ proc\ qfim\ \{f\ \{zoom\ 100\}\ \{width\ 200\}\ \{height\ -\}\}\ \{\n\ \ \ \ \ \ \ \ puts\ \"func\ \{\[info\ args\ \$f\]\}\ ->\ \[info\ body\ \$f\]\"\n\ \ \ \ #\ produce\ a\ photo\ image\ by\ applying\ function\ f\ to\ pixels\n\ \ \ \ if\ \{\$height==\"-\"\}\ \{set\ height\ \$width\}\n\ \ \ \ set\ im\ \[image\ create\ photo\ -height\ \$height\ -width\ \$width\]\n\ \ \ \ set\ data\ \{\}\n\ \ \ \ set\ xs\ \{\}\n\ \ \ \ set\ rgb\ \[rgb\ yellow\]\n\ \ \ \ set\ rgbw\ \[rgb\ white\]\n\ \ \ \ for\ \{set\ j\ 0\}\ \{\$j<\$width\}\ \{incr\ j\}\ \{\n\ \ \ \ \ \ \ \ lappend\ xs\ \[expr\ \{(\$j-\$width/2.)/\$zoom\}\]\n\ \ \ \ \}\n\ \ \ \ for\ \{set\ i\ 0\}\ \{\$i<\$height\}\ \{incr\ i\}\ \{\n\ \ \ \ \ \ \ \ set\ row\ \{\}\n\ \ \ \ \ \ \ \ set\ y0\ \[expr\ \{(\$i-\$height/2.)/\$zoom\}\]\n\ \ \ \ \ \ \ \ foreach\ x\ \$xs\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ #@FUNCTION\n\ \ \ \ \ \ \ \ \ \ \ \ #@RESULT\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ row\ \$res\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ lappend\ data\ \$row\n\ \ \ \ \}\n\ \ \ \ \$im\ put\ \$data\n\ \ \ \ set\ im\n\ \}\n======\n\nWe\ can\ specialise\ this\ proc\ for\ the\ following\ function:\n\ \ \ o\ \{gPaint\ yellow\}\ gChecker\ \{rippleRad\ 6\ 0.2\}\ \{swirl\ 26\}\ toPolars\ \ \n\nWe\ get:\n\n======\n\ proc\ uniquefim\ \{f\ \{zoom\ 100\}\ \{width\ 200\}\ \{height\ -\}\}\ \{\n\ \ \ \ \ \ \ \ puts\ \"func\ \{\[info\ args\ \$f\]\}\ ->\ \[info\ body\ \$f\]\"\n\ \ \ \ #\ produce\ a\ photo\ image\ by\ applying\ function\ f\ to\ pixels\n\ \ \ \ if\ \{\$height==\"-\"\}\ \{set\ height\ \$width\}\n\ \ \ \ set\ im\ \[image\ create\ photo\ -height\ \$height\ -width\ \$width\]\n\ \ \ \ set\ data\ \{\}\n\ \ \ \ set\ xs\ \{\}\n\ \ \ \ set\ rgb\ \[rgb\ yellow\]\n\ \ \ \ set\ rgbw\ \[rgb\ white\]\n\ \ \ \ for\ \{set\ j\ 0\}\ \{\$j<\$width\}\ \{incr\ j\}\ \{\n\ \ \ \ \ \ \ \ lappend\ xs\ \[expr\ \{(\$j-\$width/2.)/\$zoom\}\]\n\ \ \ \ \}\n\ \ \ \ for\ \{set\ i\ 0\}\ \{\$i<\$height\}\ \{incr\ i\}\ \{\n\ \ \ \ \ \ \ \ set\ row\ \{\}\n\ \ \ \ \ \ \ \ set\ y0\ \[expr\ \{(\$i-\$height/2.)/\$zoom\}\]\n\ \ \ \ \ \ \ \ foreach\ x\ \$xs\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #@FUNCTION\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ y\ \$y0\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ toPolars\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ x1\ \[expr\ \{hypot(\$x,\$y)\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ y\ \[expr\ \{\$x||\$y?\ atan2(\$y,\$x):\ 0\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ x\ \$x1\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ swirl\ 26\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ angle\ \[expr\ \{hypot(\$x,\$y)*6.283185306/26\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #rotate\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ x1\ \[expr\ \{\$x*cos(-\$angle)\ -\ \$y*sin(-\$angle)\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ y\ \[expr\ \{\$y*cos(-\$angle)\ +\ \$x*sin(-\$angle)\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ x\ \$x1\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #rippleRad\ 6\ 0.2\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #topolars\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ r\ \[expr\ \{hypot(\$x,\$y)\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ a\ \[expr\ \{\$x||\$y?\ atan2(\$y,\$x):\ 0\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #fromPolars\ \[list\ \[expr\ \{\$r*(1.+\$s*sin(\$n*\$a))\}\]\ \$a\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ r\ \[expr\ \{\$r*(1.+0.2*sin(6*\$a))\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #fromPolars\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ x\ \[expr\ \{\$r*cos(\$a)\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ y\ \[expr\ \{\$r*sin(\$a)\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ gchecker\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ greylevel\ \[expr\ \{(fmod(abs(\$x),1.)*fmod(abs(\$y),1.))\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ hex\ \[format\ %02X\ \[expr\ \{round(\$greylevel*255)\}\]\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ pixel\ #\$hex\$hex\$hex\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ gpaint\ yellow\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ abspixel\ \[lindex\ \[rgb\ \$pixel\]\ 0\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ foreach\ var\ \{r\ g\ b\}\ in\ \$rgb\ ref\ \$rgbw\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ \$var\ \[expr\ \{round(double(\$abspixel)*\$in/\$ref/\$ref*255.)\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #c2c\ \$r\ \$g\ \$b\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ res\ \[format\ #%02X%02X%02X\ \$r\ \$g\ \$b\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #@RESULT\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ row\ \$res\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ lappend\ data\ \$row\n\ \ \ \ \}\n\ \ \ \ \$im\ put\ \$data\n\ \ \ \ set\ im\n\ \}\n======\n\n''The\ passing\ of\ the\ function\ \$f\ is\ for\ debuging\ only''.\n\nNote\ that\ the\ above\ would\ have\ been\ created\ by\ the\ '''o'''\ proc\ and\ not\ hand\ crafted.\nThe\ new\ proc\ would\ be\ called\ to\ create\ the\ image.\nIn\ testing\ this\ change\ gives\ a\ 33%\ reduction\ in\ processing\ time.\ By\ moving\ constant\ expressions\ out\ of\ the\ main\ loop,\ we\ get\ a\ speedup\ of\ 2\ times,\ which\ is\ significant.\ If\ some\ optimisation\ of\ the\ use\ of\ ''expr''\ is\ done\ (programaticaly)\ then\ it\ would\ be\ expected\ that\ a\ boost\ of\ 3\ times\ could\ be\ gained\ over\ the\ original\ example.\n\nIf\ we\ were\ to\ apply\ specialization\ to\ the\ whole\ procedure\ we\ would\ also\ specialize\ the\ code\ for\ processing\ the\ width\ and\ height.\ This\ would\ include\ precreation\ of\ the\ lists\ for\ I\ and\ J\ and\ the\ removal\ of\ the\ if\ statement\ for\ testing\ if\ \$height\ is\ ''-''\ as\ we\ know\ what\ the\ value\ is.\n\nI\ have\ not\ demonstrated\ the\ code\ to\ generate\ the\ template\ because\ the\ image\ processing\ functions\ were\ originally\ coded\ as\ procs\ and\ in\ these\ example\ they\ would\ instead\ be\ implemented\ as\ lists\ so\ that\ combination\ would\ be\ a\ trivial\ process.\n\nThe\ above\ said,\ the\ use\ of\ ''\[\[info\ body\ proc\]\]''\ would\ allow\ the\ extraction\ of\ the\ code\ from\ existing\ procedures\ providing\ that\ the\ code\ can\ determine\ what\ the\ return\ values\ would\ be\ and\ inline\ them\ as\ assignments\ to\ ''x\ and\ y''.\n\n'''Further\ applications'''\n\nWe\ find\ a\ common\ task\ for\ code\ libraries\ is\ one\ of\ initialisation.\nThis\ takes\ two\ forms:\n\ \ \ 1.\ first\ invokation\ environment\ creation.\n\ \ \ 1.\ Application\ specific\ environment\ configuration.\nBoth\ of\ these\ are\ candidates\ for\ specialisation.\nConsider\ this\ example.\n\n======\ \ \ \ proc\ dbOpen\ \{args\}\ \{\n\ \ \ \ \ \ \ variable\ Data\n\ \ \ \ \ \ \ if\ \{!\ info\ exists\ Data(Init)\ \}\ \{\n\ \ \ \ \ \ \ \ \ \ dbInit\n\ \ \ \ \ \ \ \ \ \ dbConnect\n\ \ \ \ \ \ \ \ \ \ rename\ unknown\ _unknown\n\ \ \ \ \ \ \ \ \ \ proc\ unknown\ \{args\}\ \{dbUnknown\ \$args\}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ ...\n\ \ \ \}\n======\n\nTo\ remove\ the\ need\ for\ an\ application\ specific\ call\ to\ initialise\ the\ environment\ for\ the\ module,\ the\ main\ API\ function\ will\ do\ this\ automatically.\ The\ downside\ of\ this\ is\ that\ every\ call\ to\ ''dbOpen''\ has\ the\ overhead\ of\ checking\ if\ this\ is\ the\ first\ call.\n\nThe\ new\ approach:\n\n======\n\ \ \ \ proc\ real_dbOpen\ \{args\}\ \{\n\ \ \ \ \ \ \ variable\ Data\n\ \ \ \ \ \ \ \ ...\n\ \ \ \}\n\n\ \ \ \ proc\ dbOpen\ \{args\}\ \{\n\ \ \ \ \ \ \ \ dbInit\n\ \ \ \ \ \ \ \ dbConnect\n\ \ \ \ \ \ \ \ \ \ rename\ unknown\ _unknown\n\ \ \ \ \ \ \ \ \ \ proc\ unknown\ \{args\}\ \{dbUnknown\ \$args\}\n\ \ \ \ \ \ \ \ rename\ dbOpen\ \{\}\n\ \ \ \ \ \ \ \ rename\ real_dbOpen\ dbOpen\n\ \ \ \ \ \ \ \ uplevel\ dbOpen\ \$args\n\ \ \ \}\n======\n\nHere\ we\ incur\ the\ overhead\ once\ and\ then\ no\ checks\ are\ ever\ made\ on\ subsequent\ calls\ to\ ''dbOpen''.\n\nAn\ alternate\ that\ removes\ the\ need\ for\ two\ proceedures\ is:\n\n======\n\ \ proc\ dbOpen\ \{args\}\ \{\n\ \ \ \ \ \ \ #@INIT\n\ \ \ \ \ \ \ \ dbInit\n\ \ \ \ \ \ \ \ dbConnect\n\ \ \ \ \ \ \ \ \ \ rename\ unknown\ _unknown\n\ \ \ \ \ \ \ \ \ \ proc\ unknown\ \{args\}\ \{dbUnknown\ \$args\}\n\ \ \ \ \ \ \ \ set\ body\ \[info\ body\ dbOpen\]\n\ \ \ \ \ \ \ \ regsub\ \{#@INIT.*#@DONE\}\ \$body\ \{\}\ body\n\ \ \ \ \ \ \ \ proc\ dbOpen\ \[info\ args\ dbOpen\]\ \$body\n\ \ \ \ \ \ \ \ #@DONE\n\ \ \ \ \ \ \ variable\ Data\n\ \ \ \ \ \ \ \ ...\n\ \ \ \}\n======\n\nThis\ will\ work\ well\ with\ autoloading\ and\ other\ packaging\ systems.\n\n'''Conclusion''''\n\nScripting\ languages\ are\ always\ handicapped\ for\ speed\ due\ to\ the\ nature\ of\ the\ language.\ Any\ technique\ that\ can\ boost\ speed\ can\ only\ be\ good.\n\nThe\ classic\ example\ (IMHO)\ is\ \[Stephen\ Uhler\]'s\ \[html_library\]\ where\ data\ is\ the\ program.\ This\ should\ be\ required\ reading\ for\ all\ TCL\ newbies.\n\nScripting\ is\ more\ than\ just\ an\ interpretered\ vs\ compiled\ paradigm.\nThe\ ability\ to\ change\ the\ code\ during\ execution\ is\ a\ fundamental\ concept\ then\ needs\ to\ be\ demonstrated\ more.\n\n\[Philip\ Quaife\]\n----\nYou\ said\ \"...\ If\ we\ instead\ use\ specialisation\ to\ change\ the\ main\ loop\ we\ get\ a\ performance\ increase\ ...\".\nWhat\ sort\ of\ performance\ effects\ do\ the\ above\ techniques\ have\ versus\ parametrization\ through\ procs,\ evals,\ and\ variable\ expansion?\n-\[jcw\]\n\n\[PWQ\]\ I\ am\ not\ sure\ I\ understand\ the\ question\ so\ I'll\ take\ them\ literally.\nSpecialisation\ removes\ parameters.\ I\ did\ not\ show\ this,\ but\ taken\ further\ there\ would\ be\ a\ function\ called\ uniquefiq_z100_h200_w200_filter...\ proc\ that\ would\ need\ no\ arguments\ and\ has\ no\ conditionals\ in\ the\ body.\n\nEvals\ are\ to\ be\ avoided\ IMO\ as\ they\ both\ introduce\ complications\ with\ quoting\ arguments\ and\ also\ are\ inefficient.\ Evals\ would\ be\ the\ opposite\ of\ specialisation.\ The\ best\ form\ of\ specialisation\ would\ be\ ''aliases''.\n\nAnother\ example,\ take\ the\ above\ ''dbOpen''\ case.\ ''Info\ exists''\ is\ a\ classic\ case,\ we\ must\ processes\ the\ first\ argument\ ''exists''\ to\ work\ out\ what\ processing\ must\ be\ performed.\ Every\ time\ the\ code\ executes\ the\ argument\ never\ changes\ but\ we\ must\ always\ do\ the\ test.\n\nImagine\ that\ dbOpen\ was\ used\ in\ a\ web\ server\ that\ was\ to\ serve\ 100,000\ pages\ per\ day.\ While\ \[\[info\ exists\]\]\ does\ not\ take\ a\ lot\ of\ time,\ in\ the\ above\ application\ it\ would\ be\ a\ significant\ part\ of\ the\ processing.\ So\ if\ we\ can\ either\ specialise\ the\ call\ to\ \[\[info\ exists\]\]\ or\ in\ the\ above\ vase\ remove\ it\ completely\ then\ we\ have\ significant\ performance\ gains.\nOther\ obvious\ candidates\ are\ the\ switch\ statement\ as\ well\ as\ fixed\ arguments\ to\ procs\ (ie\ regexp\ -nocase).\n\nTake\ another\ technique\ as\ an\ example,\ consider\ this\ web\ server\ example\ code:\n\ \ \ \ \ \[gets\ \$socket\]\nThis\ looks\ like\ a\ mistake?,\ but\ if\ we\ leverage\ off\ unknown\ and\ aliases\ and\ then\ create\ a\ specialist\ proc\ (eg\ proc\ \{GET\ http://host/index.htm\ HTTP/1.0\}\ \{socket\}\ \{...\})\nthen\ we\ can\ cache\ page\ requests\ without\ any\ conditional\ logic\ to\ slow\ the\ process.\n\nThe\ question\ I\ would\ ask\ is\ this:\n''How\ many\ programmers\ would\ think\ of\ programming\ using\ this\ technique,\ vs\ the\ standard\ way\ it\ would\ be\ done\ in\ other\ languages\ by\ passing\ the\ request\ as\ an\ arguement\ to\ a\ generic\ procedure''?\n\nThis\ probably\ does\ not\ answer\ your\ question,\ please\ give\ examples\ to\ clarify.\n\n''\[jcw\]\ -\ Philip,\ I\ see\ it's\ me\ who\ needs\ to\ think\ more\ before\ asking\ here.\ \ I'll\ re-read\ to\ better\ understand\ what\ you're\ after...''\n----\n\[RS\]:\ Well,\ \[functional\ imaging\]\ was\ a\ Tcl\ remake\ of\ a\ research\ project,\ and\ I\ tried\ to\ follow\ the\ Haskell\ original\ as\ closely\ as\ possible,\ and\ they\ just\ used\ \[functional\ composition\].\ Also,\ the\ creation\ of\ \[proc\]s\ isn't\ very\ expensive\ in\ my\ opinion,\ and\ has\ the\ advantage\ that\ all\ available\ combinations\ can\ be\ introspected\ with\ just\n\ info\ procs\ \"o\ *\"\nand\ so\ the\ button\ bar\ was\ easily\ created.\ (Also,\ I\ think\ Tcl\ lends\ itself\ pretty\ perfectly\ to\ functional\ programming...)\n\n\[PWQ\]\ I\ hope\ you\ did\ not\ take\ these\ comments\ as\ disparaging\ remarks\ about\ \[Functional\ imaging\],\ There\ is\ no\ ideal\ way\ to\ program\ and\ I\ think\ it\ is\ important\ to\ look\ at\ how\ other\ patterns\ and\ techniques\ could\ be\ used\ in\ TCL.\n\nHowever\ since\ there\ will\ be\ a\ large\ body\ of\ novice\ users\ that\ take\ code\ from\ places\ such\ as\ this\ wiki,\ I\ feel\ that\ both\ sides\ of\ the\ coin\ as\ it\ were\ be\ represented.\n\nAs\ an\ example,\ we\ can\ show\ how\ a\ bubble\ sort\ could\ be\ implemented\ in\ TCL.\ But\ by\ doing\ this\ ,\ a\ large\ body\ of\ programmers\ will\ never\ know\ that\ there\ are\ more\ efficient\ methods\ of\ sorting.\ And\ possibly\ that\ there\ is\ an\ inbuilt\ sort\ command\ that\ can\ be\ leveraged.\n----\n\[RS\]:\ Ah,\ your\ reply\ to\ jcw\ above\ made\ your\ idea\ of\ specialization\ a\ bit\ clearer\ to\ me.\ I\ fully\ agree\ that\ redundant\ checks\ bloat\ code\ and\ make\ it\ less\ readable\ -\ \[simple\]r\ is\ better\ :)\ And\ getting\ simplicity\ without\ sacrificing\ robustness\ even\ more\ so.\ One\ (optical)\ example\ of\ simplification\ in\ Tcl\ is\ currying\ (\[Custom\ curry\]),\ but\ it\ works\ only\ for\ single\ commands,\ whose\ arguments\ may\ be\ augmented\ in\ front\ (and\ costs\ one\ name\ lookup\ more,\ so\ isn't\ faster:\n\n======\n\ interp\ alias\ \{\}\ mySpecialCase\ \{\}\ myGenericProc\ \$width\ \$height\ ...\n======\n\nwhile\ you\ advocate\ a\ more\ elaborate\ way\ of\ building\ proc\ bodies\ from\ templates,\ with\ the\ cases\ taken\ care\ of\ (by\ \[string\ map\])\ at\ generation\ time,\ rather\ than\ checking\ at\ runtime.\nSounds\ good.\ Will\ have\ to\ think..\n\n<<categories>>Concept regexp2} CALL {my render {Not Functional Imaging - Scripting Imaging} '''Overview\ \ 9\ Feb\ 2004'''\n\nThe\ post\ \[Functional\ imaging\]\ looks\ at\ implementing\ a\ paradigm\ found\ in\ functional\ programming\ language\ in\ TCL.\n\nWhile\ all\ these\ contributions\ are\ useful\ in\ themselves,\ they\ also\ show\ that\ TCL\ does\ not\ always\ map\ well\ to\ these\ techniques.\n\nThe\ article\ also\ touched\ on\ a\ design\ pattern\ that\ is\ not\ well\ exploited\ in\ scripting\ languages.\ I\ attempt\ to\ elaborate\ here.\n\n''Please\ refer\ to\ the\ original\ page\ before\ reading\ further''.\n\nIn\ this\ discussion\ we\ assume\ that\ the\ example\ given\ in\ the\ above\ reference\ is\ a\ valid\ image\ processing\ technique\ and\ that\ the\ method\ of\ x\ y\ transformations\ are\ appropriate\ to\ real\ world\ tasks.\nWe\ also\ assume\ that\ the\ function\ would\ in\ real\ life\ be\ called\ more\ than\ once\ in\ the\ life\ time\ of\ the\ application.\ For\ example\ ,\ face\ recognition,\ video\ editing,\ or\ such.\n\n'''Background'''\n\nThe\ example\ implements\ a\ combinor\ function\ to\ convert\ a\ pipeline\ of\ processing\ tasks,\ as\ an\ example:\n\ \ \ o\ \{gPaint\ yellow\}\ gChecker\ \{rippleRad\ 6\ 0.2\}\ \{swirl\ 26\}\ toPolars\ \ \nThis\ creates\ a\ proc\ of\ the\ form:\n\ \ \ \ proc\ uniquename\ \{x\}\ \{\ gPaint\ yellow\ \[gChecker\ \[rippleRad\ 6\ 0.2\ \[\ swirl\ 26\ \[toPolars\ \$x\]\]\]\]\nWe\ have\ here\ the\ essence\ of\ dynamic\ programming.\ In\ the\ case\ of\ TCL,\ the\ creation\ of\ a\ proc\ is\ due\ to\ the\ need\ to\ bytecode\ for\ speed.\ Otherwise\ the\ pipeline\ could\ have\ been\ implmented\ with\ ''eval''.\n\nThe\ main\ processing\ loop\ iterates\ through\ the\ x,\ y\ coordinates\ and\ calls\ the\ arbitary\ function\ with\ the\ ''xy''\ pair.\ The\ result\ is\ then\ appended\ to\ the\ new\ image\ data.\n\n'''Extending\ dynamic\ programming'''\n\nIf\ we\ instead\ use\ specialisation\ to\ change\ the\ main\ loop\ we\ get\ a\ performance\ increase.\nTake\ the\ following\ template:\n\n======\n\ proc\ qfim\ \{f\ \{zoom\ 100\}\ \{width\ 200\}\ \{height\ -\}\}\ \{\n\ \ \ \ \ \ \ \ puts\ \"func\ \{\[info\ args\ \$f\]\}\ ->\ \[info\ body\ \$f\]\"\n\ \ \ \ #\ produce\ a\ photo\ image\ by\ applying\ function\ f\ to\ pixels\n\ \ \ \ if\ \{\$height==\"-\"\}\ \{set\ height\ \$width\}\n\ \ \ \ set\ im\ \[image\ create\ photo\ -height\ \$height\ -width\ \$width\]\n\ \ \ \ set\ data\ \{\}\n\ \ \ \ set\ xs\ \{\}\n\ \ \ \ set\ rgb\ \[rgb\ yellow\]\n\ \ \ \ set\ rgbw\ \[rgb\ white\]\n\ \ \ \ for\ \{set\ j\ 0\}\ \{\$j<\$width\}\ \{incr\ j\}\ \{\n\ \ \ \ \ \ \ \ lappend\ xs\ \[expr\ \{(\$j-\$width/2.)/\$zoom\}\]\n\ \ \ \ \}\n\ \ \ \ for\ \{set\ i\ 0\}\ \{\$i<\$height\}\ \{incr\ i\}\ \{\n\ \ \ \ \ \ \ \ set\ row\ \{\}\n\ \ \ \ \ \ \ \ set\ y0\ \[expr\ \{(\$i-\$height/2.)/\$zoom\}\]\n\ \ \ \ \ \ \ \ foreach\ x\ \$xs\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ #@FUNCTION\n\ \ \ \ \ \ \ \ \ \ \ \ #@RESULT\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ row\ \$res\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ lappend\ data\ \$row\n\ \ \ \ \}\n\ \ \ \ \$im\ put\ \$data\n\ \ \ \ set\ im\n\ \}\n======\n\nWe\ can\ specialise\ this\ proc\ for\ the\ following\ function:\n\ \ \ o\ \{gPaint\ yellow\}\ gChecker\ \{rippleRad\ 6\ 0.2\}\ \{swirl\ 26\}\ toPolars\ \ \n\nWe\ get:\n\n======\n\ proc\ uniquefim\ \{f\ \{zoom\ 100\}\ \{width\ 200\}\ \{height\ -\}\}\ \{\n\ \ \ \ \ \ \ \ puts\ \"func\ \{\[info\ args\ \$f\]\}\ ->\ \[info\ body\ \$f\]\"\n\ \ \ \ #\ produce\ a\ photo\ image\ by\ applying\ function\ f\ to\ pixels\n\ \ \ \ if\ \{\$height==\"-\"\}\ \{set\ height\ \$width\}\n\ \ \ \ set\ im\ \[image\ create\ photo\ -height\ \$height\ -width\ \$width\]\n\ \ \ \ set\ data\ \{\}\n\ \ \ \ set\ xs\ \{\}\n\ \ \ \ set\ rgb\ \[rgb\ yellow\]\n\ \ \ \ set\ rgbw\ \[rgb\ white\]\n\ \ \ \ for\ \{set\ j\ 0\}\ \{\$j<\$width\}\ \{incr\ j\}\ \{\n\ \ \ \ \ \ \ \ lappend\ xs\ \[expr\ \{(\$j-\$width/2.)/\$zoom\}\]\n\ \ \ \ \}\n\ \ \ \ for\ \{set\ i\ 0\}\ \{\$i<\$height\}\ \{incr\ i\}\ \{\n\ \ \ \ \ \ \ \ set\ row\ \{\}\n\ \ \ \ \ \ \ \ set\ y0\ \[expr\ \{(\$i-\$height/2.)/\$zoom\}\]\n\ \ \ \ \ \ \ \ foreach\ x\ \$xs\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #@FUNCTION\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ y\ \$y0\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ toPolars\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ x1\ \[expr\ \{hypot(\$x,\$y)\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ y\ \[expr\ \{\$x||\$y?\ atan2(\$y,\$x):\ 0\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ x\ \$x1\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ swirl\ 26\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ angle\ \[expr\ \{hypot(\$x,\$y)*6.283185306/26\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #rotate\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ x1\ \[expr\ \{\$x*cos(-\$angle)\ -\ \$y*sin(-\$angle)\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ y\ \[expr\ \{\$y*cos(-\$angle)\ +\ \$x*sin(-\$angle)\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ x\ \$x1\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #rippleRad\ 6\ 0.2\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #topolars\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ r\ \[expr\ \{hypot(\$x,\$y)\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ a\ \[expr\ \{\$x||\$y?\ atan2(\$y,\$x):\ 0\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #fromPolars\ \[list\ \[expr\ \{\$r*(1.+\$s*sin(\$n*\$a))\}\]\ \$a\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ r\ \[expr\ \{\$r*(1.+0.2*sin(6*\$a))\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #fromPolars\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ x\ \[expr\ \{\$r*cos(\$a)\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ y\ \[expr\ \{\$r*sin(\$a)\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ gchecker\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ greylevel\ \[expr\ \{(fmod(abs(\$x),1.)*fmod(abs(\$y),1.))\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ hex\ \[format\ %02X\ \[expr\ \{round(\$greylevel*255)\}\]\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ pixel\ #\$hex\$hex\$hex\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ gpaint\ yellow\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ abspixel\ \[lindex\ \[rgb\ \$pixel\]\ 0\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ foreach\ var\ \{r\ g\ b\}\ in\ \$rgb\ ref\ \$rgbw\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ \$var\ \[expr\ \{round(double(\$abspixel)*\$in/\$ref/\$ref*255.)\}\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #c2c\ \$r\ \$g\ \$b\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ res\ \[format\ #%02X%02X%02X\ \$r\ \$g\ \$b\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #@RESULT\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ row\ \$res\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ lappend\ data\ \$row\n\ \ \ \ \}\n\ \ \ \ \$im\ put\ \$data\n\ \ \ \ set\ im\n\ \}\n======\n\n''The\ passing\ of\ the\ function\ \$f\ is\ for\ debuging\ only''.\n\nNote\ that\ the\ above\ would\ have\ been\ created\ by\ the\ '''o'''\ proc\ and\ not\ hand\ crafted.\nThe\ new\ proc\ would\ be\ called\ to\ create\ the\ image.\nIn\ testing\ this\ change\ gives\ a\ 33%\ reduction\ in\ processing\ time.\ By\ moving\ constant\ expressions\ out\ of\ the\ main\ loop,\ we\ get\ a\ speedup\ of\ 2\ times,\ which\ is\ significant.\ If\ some\ optimisation\ of\ the\ use\ of\ ''expr''\ is\ done\ (programaticaly)\ then\ it\ would\ be\ expected\ that\ a\ boost\ of\ 3\ times\ could\ be\ gained\ over\ the\ original\ example.\n\nIf\ we\ were\ to\ apply\ specialization\ to\ the\ whole\ procedure\ we\ would\ also\ specialize\ the\ code\ for\ processing\ the\ width\ and\ height.\ This\ would\ include\ precreation\ of\ the\ lists\ for\ I\ and\ J\ and\ the\ removal\ of\ the\ if\ statement\ for\ testing\ if\ \$height\ is\ ''-''\ as\ we\ know\ what\ the\ value\ is.\n\nI\ have\ not\ demonstrated\ the\ code\ to\ generate\ the\ template\ because\ the\ image\ processing\ functions\ were\ originally\ coded\ as\ procs\ and\ in\ these\ example\ they\ would\ instead\ be\ implemented\ as\ lists\ so\ that\ combination\ would\ be\ a\ trivial\ process.\n\nThe\ above\ said,\ the\ use\ of\ ''\[\[info\ body\ proc\]\]''\ would\ allow\ the\ extraction\ of\ the\ code\ from\ existing\ procedures\ providing\ that\ the\ code\ can\ determine\ what\ the\ return\ values\ would\ be\ and\ inline\ them\ as\ assignments\ to\ ''x\ and\ y''.\n\n'''Further\ applications'''\n\nWe\ find\ a\ common\ task\ for\ code\ libraries\ is\ one\ of\ initialisation.\nThis\ takes\ two\ forms:\n\ \ \ 1.\ first\ invokation\ environment\ creation.\n\ \ \ 1.\ Application\ specific\ environment\ configuration.\nBoth\ of\ these\ are\ candidates\ for\ specialisation.\nConsider\ this\ example.\n\n======\ \ \ \ proc\ dbOpen\ \{args\}\ \{\n\ \ \ \ \ \ \ variable\ Data\n\ \ \ \ \ \ \ if\ \{!\ info\ exists\ Data(Init)\ \}\ \{\n\ \ \ \ \ \ \ \ \ \ dbInit\n\ \ \ \ \ \ \ \ \ \ dbConnect\n\ \ \ \ \ \ \ \ \ \ rename\ unknown\ _unknown\n\ \ \ \ \ \ \ \ \ \ proc\ unknown\ \{args\}\ \{dbUnknown\ \$args\}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ ...\n\ \ \ \}\n======\n\nTo\ remove\ the\ need\ for\ an\ application\ specific\ call\ to\ initialise\ the\ environment\ for\ the\ module,\ the\ main\ API\ function\ will\ do\ this\ automatically.\ The\ downside\ of\ this\ is\ that\ every\ call\ to\ ''dbOpen''\ has\ the\ overhead\ of\ checking\ if\ this\ is\ the\ first\ call.\n\nThe\ new\ approach:\n\n======\n\ \ \ \ proc\ real_dbOpen\ \{args\}\ \{\n\ \ \ \ \ \ \ variable\ Data\n\ \ \ \ \ \ \ \ ...\n\ \ \ \}\n\n\ \ \ \ proc\ dbOpen\ \{args\}\ \{\n\ \ \ \ \ \ \ \ dbInit\n\ \ \ \ \ \ \ \ dbConnect\n\ \ \ \ \ \ \ \ \ \ rename\ unknown\ _unknown\n\ \ \ \ \ \ \ \ \ \ proc\ unknown\ \{args\}\ \{dbUnknown\ \$args\}\n\ \ \ \ \ \ \ \ rename\ dbOpen\ \{\}\n\ \ \ \ \ \ \ \ rename\ real_dbOpen\ dbOpen\n\ \ \ \ \ \ \ \ uplevel\ dbOpen\ \$args\n\ \ \ \}\n======\n\nHere\ we\ incur\ the\ overhead\ once\ and\ then\ no\ checks\ are\ ever\ made\ on\ subsequent\ calls\ to\ ''dbOpen''.\n\nAn\ alternate\ that\ removes\ the\ need\ for\ two\ proceedures\ is:\n\n======\n\ \ proc\ dbOpen\ \{args\}\ \{\n\ \ \ \ \ \ \ #@INIT\n\ \ \ \ \ \ \ \ dbInit\n\ \ \ \ \ \ \ \ dbConnect\n\ \ \ \ \ \ \ \ \ \ rename\ unknown\ _unknown\n\ \ \ \ \ \ \ \ \ \ proc\ unknown\ \{args\}\ \{dbUnknown\ \$args\}\n\ \ \ \ \ \ \ \ set\ body\ \[info\ body\ dbOpen\]\n\ \ \ \ \ \ \ \ regsub\ \{#@INIT.*#@DONE\}\ \$body\ \{\}\ body\n\ \ \ \ \ \ \ \ proc\ dbOpen\ \[info\ args\ dbOpen\]\ \$body\n\ \ \ \ \ \ \ \ #@DONE\n\ \ \ \ \ \ \ variable\ Data\n\ \ \ \ \ \ \ \ ...\n\ \ \ \}\n======\n\nThis\ will\ work\ well\ with\ autoloading\ and\ other\ packaging\ systems.\n\n'''Conclusion''''\n\nScripting\ languages\ are\ always\ handicapped\ for\ speed\ due\ to\ the\ nature\ of\ the\ language.\ Any\ technique\ that\ can\ boost\ speed\ can\ only\ be\ good.\n\nThe\ classic\ example\ (IMHO)\ is\ \[Stephen\ Uhler\]'s\ \[html_library\]\ where\ data\ is\ the\ program.\ This\ should\ be\ required\ reading\ for\ all\ TCL\ newbies.\n\nScripting\ is\ more\ than\ just\ an\ interpretered\ vs\ compiled\ paradigm.\nThe\ ability\ to\ change\ the\ code\ during\ execution\ is\ a\ fundamental\ concept\ then\ needs\ to\ be\ demonstrated\ more.\n\n\[Philip\ Quaife\]\n----\nYou\ said\ \"...\ If\ we\ instead\ use\ specialisation\ to\ change\ the\ main\ loop\ we\ get\ a\ performance\ increase\ ...\".\nWhat\ sort\ of\ performance\ effects\ do\ the\ above\ techniques\ have\ versus\ parametrization\ through\ procs,\ evals,\ and\ variable\ expansion?\n-\[jcw\]\n\n\[PWQ\]\ I\ am\ not\ sure\ I\ understand\ the\ question\ so\ I'll\ take\ them\ literally.\nSpecialisation\ removes\ parameters.\ I\ did\ not\ show\ this,\ but\ taken\ further\ there\ would\ be\ a\ function\ called\ uniquefiq_z100_h200_w200_filter...\ proc\ that\ would\ need\ no\ arguments\ and\ has\ no\ conditionals\ in\ the\ body.\n\nEvals\ are\ to\ be\ avoided\ IMO\ as\ they\ both\ introduce\ complications\ with\ quoting\ arguments\ and\ also\ are\ inefficient.\ Evals\ would\ be\ the\ opposite\ of\ specialisation.\ The\ best\ form\ of\ specialisation\ would\ be\ ''aliases''.\n\nAnother\ example,\ take\ the\ above\ ''dbOpen''\ case.\ ''Info\ exists''\ is\ a\ classic\ case,\ we\ must\ processes\ the\ first\ argument\ ''exists''\ to\ work\ out\ what\ processing\ must\ be\ performed.\ Every\ time\ the\ code\ executes\ the\ argument\ never\ changes\ but\ we\ must\ always\ do\ the\ test.\n\nImagine\ that\ dbOpen\ was\ used\ in\ a\ web\ server\ that\ was\ to\ serve\ 100,000\ pages\ per\ day.\ While\ \[\[info\ exists\]\]\ does\ not\ take\ a\ lot\ of\ time,\ in\ the\ above\ application\ it\ would\ be\ a\ significant\ part\ of\ the\ processing.\ So\ if\ we\ can\ either\ specialise\ the\ call\ to\ \[\[info\ exists\]\]\ or\ in\ the\ above\ vase\ remove\ it\ completely\ then\ we\ have\ significant\ performance\ gains.\nOther\ obvious\ candidates\ are\ the\ switch\ statement\ as\ well\ as\ fixed\ arguments\ to\ procs\ (ie\ regexp\ -nocase).\n\nTake\ another\ technique\ as\ an\ example,\ consider\ this\ web\ server\ example\ code:\n\ \ \ \ \ \[gets\ \$socket\]\nThis\ looks\ like\ a\ mistake?,\ but\ if\ we\ leverage\ off\ unknown\ and\ aliases\ and\ then\ create\ a\ specialist\ proc\ (eg\ proc\ \{GET\ http://host/index.htm\ HTTP/1.0\}\ \{socket\}\ \{...\})\nthen\ we\ can\ cache\ page\ requests\ without\ any\ conditional\ logic\ to\ slow\ the\ process.\n\nThe\ question\ I\ would\ ask\ is\ this:\n''How\ many\ programmers\ would\ think\ of\ programming\ using\ this\ technique,\ vs\ the\ standard\ way\ it\ would\ be\ done\ in\ other\ languages\ by\ passing\ the\ request\ as\ an\ arguement\ to\ a\ generic\ procedure''?\n\nThis\ probably\ does\ not\ answer\ your\ question,\ please\ give\ examples\ to\ clarify.\n\n''\[jcw\]\ -\ Philip,\ I\ see\ it's\ me\ who\ needs\ to\ think\ more\ before\ asking\ here.\ \ I'll\ re-read\ to\ better\ understand\ what\ you're\ after...''\n----\n\[RS\]:\ Well,\ \[functional\ imaging\]\ was\ a\ Tcl\ remake\ of\ a\ research\ project,\ and\ I\ tried\ to\ follow\ the\ Haskell\ original\ as\ closely\ as\ possible,\ and\ they\ just\ used\ \[functional\ composition\].\ Also,\ the\ creation\ of\ \[proc\]s\ isn't\ very\ expensive\ in\ my\ opinion,\ and\ has\ the\ advantage\ that\ all\ available\ combinations\ can\ be\ introspected\ with\ just\n\ info\ procs\ \"o\ *\"\nand\ so\ the\ button\ bar\ was\ easily\ created.\ (Also,\ I\ think\ Tcl\ lends\ itself\ pretty\ perfectly\ to\ functional\ programming...)\n\n\[PWQ\]\ I\ hope\ you\ did\ not\ take\ these\ comments\ as\ disparaging\ remarks\ about\ \[Functional\ imaging\],\ There\ is\ no\ ideal\ way\ to\ program\ and\ I\ think\ it\ is\ important\ to\ look\ at\ how\ other\ patterns\ and\ techniques\ could\ be\ used\ in\ TCL.\n\nHowever\ since\ there\ will\ be\ a\ large\ body\ of\ novice\ users\ that\ take\ code\ from\ places\ such\ as\ this\ wiki,\ I\ feel\ that\ both\ sides\ of\ the\ coin\ as\ it\ were\ be\ represented.\n\nAs\ an\ example,\ we\ can\ show\ how\ a\ bubble\ sort\ could\ be\ implemented\ in\ TCL.\ But\ by\ doing\ this\ ,\ a\ large\ body\ of\ programmers\ will\ never\ know\ that\ there\ are\ more\ efficient\ methods\ of\ sorting.\ And\ possibly\ that\ there\ is\ an\ inbuilt\ sort\ command\ that\ can\ be\ leveraged.\n----\n\[RS\]:\ Ah,\ your\ reply\ to\ jcw\ above\ made\ your\ idea\ of\ specialization\ a\ bit\ clearer\ to\ me.\ I\ fully\ agree\ that\ redundant\ checks\ bloat\ code\ and\ make\ it\ less\ readable\ -\ \[simple\]r\ is\ better\ :)\ And\ getting\ simplicity\ without\ sacrificing\ robustness\ even\ more\ so.\ One\ (optical)\ example\ of\ simplification\ in\ Tcl\ is\ currying\ (\[Custom\ curry\]),\ but\ it\ works\ only\ for\ single\ commands,\ whose\ arguments\ may\ be\ augmented\ in\ front\ (and\ costs\ one\ name\ lookup\ more,\ so\ isn't\ faster:\n\n======\n\ interp\ alias\ \{\}\ mySpecialCase\ \{\}\ myGenericProc\ \$width\ \$height\ ...\n======\n\nwhile\ you\ advocate\ a\ more\ elaborate\ way\ of\ building\ proc\ bodies\ from\ templates,\ with\ the\ cases\ taken\ care\ of\ (by\ \[string\ map\])\ at\ generation\ time,\ rather\ than\ checking\ at\ runtime.\nSounds\ good.\ Will\ have\ to\ think..\n\n<<categories>>Concept} CALL {my revision {Not Functional Imaging - Scripting Imaging}} CALL {::oo::Obj1386432 process revision/Not+Functional+Imaging+%2D+Scripting+Imaging} CALL {::oo::Obj1386430 process}

-errorcode

NONE

-errorinfo

Unknow state transition: LINE -> END
    while executing
"error $msg"
    (class "::Wiki" method "render_wikit" line 6)
    invoked from within
"my render_$default_markup $N $C $mkup_rendering_engine"
    (class "::Wiki" method "render" line 8)
    invoked from within
"my render $name $C"
    (class "::Wiki" method "revision" line 31)
    invoked from within
"my revision $page"
    (class "::Wiki" method "process" line 56)
    invoked from within
"$server process [string trim $uri /]"

-errorline

4