Coming out

Posted in Slagare internationale, Stand-up philosophy on August 25th, 2011 by Mihnea

In sfirsit Apple au decis sa faca pasul cel mare si sa iasa din closet. Noul lor CEO e gheu pe fata, nu pe ascuns ca Steve. Asteptam cu interes versiunea aniversara XCode 5 unde vei scrie cod printr-o interfata cum aveau strumfii xenozoofili cu inorogii in Avatar, doar ca in loc sa-ti impletesti pleata cu coada calului, iti vei da cu iLube si-ti vei baga in cur un iDildo. Roz.

La cit mai multe puli in cur!

 

Tags: , , , , , , , , , , , , , ,

Forum

Posted in Stand-up philosophy on August 15th, 2011 by Mihnea


Avem forum la http://standupprogramming.com/autobaza/. Si ca orice demers respectabil, avem si un manifest. Cu placere.

Tags: , , , , ,

AGI +1 CHA +5 INT -200

Posted in Slagare internationale, Stand-up philosophy on August 15th, 2011 by Mihnea

In 2001, un grup de nimeni suferind de Complexul Sf. Paul si-au cumparat un domeniu si au publicat pe el Manifestul Agil. Drept raspuns imi voi permite sa-l citez pe Eddie:

Dear Paul (Saint, apparently),

FUCK OFF!

Who are you? Why do you keep sending us letters? You arrogant bastard, to send a letter to an entire city! What do you want us to do, put this up on a board or something? Just fuck off!

Din pacate oamenii sint prosti si fricosi, asa ca jegurile astea despre prieteni imaginari si ritualuri care te scapa de moarte si/sau overtime si bug-uri prind repede. Zece ani mai tirziu avem o religie in toata regula bazata pe manifestul muistilor si practicantii sint la fel de agresivi si dezgustatori ca gunoaiele alea care se zbat sa bage creationismul in programa scolara la americani. Hasa diga Eebowai!

In caz ca ati locuit intr-o pestera pe Marte din 2001 pina acum si nu stiti ce-i Agile, o sa va explic pe scurt. Agile este o metodologie de project management care ne spune ca atunci cind avem de facut un proiect, trebuie sa-l spargem in task-uri cu dimensiuni de bun simt si sa le facem. Atit. Asta e singura chestie concreta din Agile. Serios.

Sigur, nu poti construi o religie doar pe o revelatie, chiar si pe una clar venita din sfere mai inalte, inaccesibile muritorilor de rind, cum e asta. Ai nevoie de profeti, misionari, adunari, organizatii, cuvinte magice, precepte, carti, ritualuri si prosti; multi prosti care sa infecteze si mai multi prosti cu Revelatia. In concluzie, Agile are SCRUM, Extreme Programming, stand-up meetings, sprinturi, porci, gaini, timeboxes, sashimi, scrum masters, kanban, kaizen, conferinte si un trilion de principii abstracte fara nici un fel de aplicabilitate sau relevanta practica. Da, porci; in caz ca nu stiti, in jargonul agil programatorii se numesc porci. Chestia asta ma face sa suspectez ca in agilitate e ca-n crestinism: aia de la virf sint niste infecti cinici care stiu ca totul e o mare vrajeala menita sa controleze prostii si sa le ia banii, dar simt nevoia sa-si si umileasca supusii ocazional pentru amuzamentul propriu, asa ca ii pun sa mearga in genunchi in jurul meselor, respectiv le spun ca numele Luminat pentru profesia lor este “porc”; porc imatur care pute, mai exact. Va explic mai jos cum e cu putoarea, dar pina ajungem acolo as vrea sa va inchipuiti ce misto e in prima zi de lucru intr-o echipa de agili, cind vine project managerul la tine si-ti spune ca esti un porc.

E amuzant sa vezi cum incearca victimele sa implementeze agilitatea in ograda proprie, dar cel mai amuzant e sa-i vezi p-aia care cred ca au reusit. Nu e nimic de reusit, pentru ca in afara de citeva ritualuri imbecile la care vom ajunge imediat, Agile este o metodologie care se remarca prin faptul ca nu specifica nici o metoda. Totul este optional si dupa ce dai la o parte metaforele jenante si citatele din karatisti si frecatori de menta chinezi ramii cu indicatii pretioase marca Captain Obvious gen aia cu despartitul in task-uri sau aia ca dupa ce faci niste treaba, e o idee buna sa ramii cu mai putine chestii de facut decit la inceput (pe bune, asta chiar e un pilon al agilitatii). Partea misto, ca la orice religie cu pretentii, este ca modul vag si intortochiat in care sint formulate directivele sacre baga in ceata mintea prostanilor practicanti, care inteleg ce pot si aplica cum vor, iar daca le iese, o pun pe seama agilitatii. Daca nu iese, e vina lor ca n-au respectat litera legii si n-au crezut cu suficienta devotiune in puterea agilitatii. Foarte misto e si cum discursul subiectilor trece de la “hai ba sa facem si noi o treaba” la ceai chinezesc, koan-uri, software crafstmanship, filmari pe balcoane si alte cacaturi gretoase.

Ajunsi in punctul acesta al analizei, se impune sa ne uitam mai cu atentie la profilul si activitatea celor care raspindesc cuvintul agilitatii in lume. Ce mari realizari au avut Parintii Agilitatii si ce proiecte indispensabile pentru umanitate s-au dezvoltat mai curat si placut uscat ca urmare a folosirii acestei metodologii? Ei bine, aia care chiar au facut software inainte sa devina agili (jumatate din ei se ocupa doar cu conferintele si datul cu parerea) au facut state de plata si site-uri. Acum nu ca ar fi ceva intrinsic injositor in proiectele de genul asta, dar totusi, mai dati-o in pula mea. Pai evident ca ajungi sa aberezi milioane de pagini si mii de ore de conferinte despre clienti care se razgindesc si programatorul social, daca tu faci site-uri de dating si agende pentru cabinete stomatologice. Nu-i chiar limita cunoasterii, virful tehnologiei, punctul focal al cercetarii in programare, nu? E vorba de cod care se scrie singur. Cineva trebuie sa-l scrie, dar nu conteaza cine. Normal ca incepi sa spui ca programatorii sint porci si conteaza mai mult sa fie “sociali” decit sa stie sa programeze, daca singurii programatori pe care ii cunosti sint aia care calculeaza impozite pe salarii. La fel de normal, daca esti manager la asemenea proiecte de mare angajament, te plictisesti si incepi sa-ti pui intrebari in legatura cu utilitatea proprie, asa ca inventezi metafore proaste si principii evidente, ca sa para ca faci si tu ceva important, nu doar te uiti intr-un excel la cite ore au lucrat porcii de programatori vs. cite ore te-au mintit ca o sa dureze. Totusi, e nevoie de un grad foarte mare de nesimtire sa bati dupa aia toba despre cum trebuie sa programeze oamenii si sa te dai in spectacol despre pair programming sau ce inseamna sa fii programator bun. Sugeti pula, ba. Eu nu vin la voi in birouri sa va spun cum sa mutati cartile la solitaire sau cum sa comandati pizza cind se lasa cu overtime, asa ca as aprecia daca nici voi nu ati lansa in eter pareri despre cum trebuie sa scriu eu cod, sau cum sa ma evaluez, sau cum se dezvolta software in general.

Ziceam mai sus de ritualuri si porci imputiti. Puroaiele astea umblatoare au descoperit ca atunci cind ai de scris cod atit de plictisitor incit ai prefera sa-ti smulgi unghiile decit sa mai stai un minut in fata monitorului, ajuta sa ai un coleg de suferinta. Asa au aparut “pair programming” si “collective ownership”. Pair programming inseamna sa stea doi porci la un calculator, ca atunci cind unul ajunge la limita plictiselii, sa preia celalalt. Ala care sta pe bara are rolul sa-l exaspereze pe alalalt spunindu-i cum ar scrie el codul daca ar fi la timona. Agilii nu pot concepe proiecte in care cineva chiar trebuie sa stea sa se gindeasca cum s-ar face ceva inainte de a scrie codul corespunzator. Ei nu cred ca pot exista experti in anumite domenii, pentru ca la statele lor de plata n-ai cum sa fii expert sau diletant. Daca poti sa aduni numere si te exprimi semi-coerent in PHP, stii tot ce va trebui sa stii vreodata pentru ca sa lucrezi la site-urile lor. De aici si ideea de “collective ownership”, adica oricare din porci poate prelua fara efort orice parte a banalitatii pe care o dezvolta cocina, ca doar nu-i nimic complicat, care sa necesite gindire sau cunostinte speciale. Si tot de aici si ideea ca nu conteaza sa fii programator bun, ci sa ai o personalitate agreabila. Si sa nu puti, si sa faci laba din cind in cind daca n-ai ce fute. Pun pariu ca nu stiati ca Bebe Sexologul si Laura Andresan au pus-o de o carte despre pair programming:

Personal hygiene and health are important issues when pairing. Cover your mouth when you cough. Don’t come to work when you are sick. Avoid strong colognes that might affect your partner.

Working effectively together feels good. It may be a new experience in the workplace for some. When programmers aren’t emotionally mature enough to separate approval from arousal, working with a person of the opposite gender can bring up sexual feelings that are not in the best interest of the team. If these feelings arise when pairing, stop pairing with the person until you have taken responsibility for and dealt with your feelings.

Revin la software craftsmanship, ca ma roade. Software craftsmanship inseamna, in mare, sa faci software-ul asa incit sa fie bine, ca-i mai bine sa fie bine decit sa fie rau. Sa n-ai bug-uri, sa scrii cod pe care sa-l poti citi si peste 6 luni, chestii d-astea la care nu v-ati fi gindit fara sa va zica agilii de ele. Evident, si craftsmanshipu’ asta are un manifest, ca fara un manifest si o petitie online nu mai faci nimic in zilele noastre. La fel de evident, nici o conferinta, nici un site si nici o carte de-a mesterilor nu-ti spune ce sa faci ca sa n-ai bug-uri, ci cel mult iti toarna niste metafore despre unit testing. In consecinta, am incercat sa semnez si eu manifestul cu “sugeti pula”, dar mi-a zis asta:

Astia, ba. Astia ne invata pe noi cum sa fim mesteri programatori, cind ei fac proiecte in care oricine poate face orice si nici astea nu le merg; panselutele astea care isi dau aere filosofice spunind cum urmarind textu’ din stinga au descoperit ca ala din dreapta e indispensabil. Mars inapoi la saiba voastra, ba gunoaielor. Nu intereseaza pe nimeni cum vi se pare voua ca trebuie scris codul.

Bonus: pe site-ul lui Aurel este in desfasurare o discutie despre agilitate. TV preacher-ul de serviciu este Mihai Lazar, un autodenuntat student indragostit de dotniet, care dupa ce zapaceste audienta cu citeva acronime si buzzword-uri bine plasate, termina in forta cu doua citate dintr-un mare emitator de metafore cu spectru larg, Bruce Lee:

Empty your mind, be formless. Shapeless, like water. If you put water into a cup, it becomes the cup. You put water into a bottle and it becomes the bottle. You put it in a teapot it becomes the teapot. Now, water can flow or it can crash. Be water my friend.

We don’t rise to expectations, we fall to the level of our training.

Tags: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Autodesk ne invata sa programam

Posted in Codare cu premeditare, Slagare internationale on August 7th, 2011 by Mihnea

Am mai mentionat faptul ca 3D Studio Max este scris de maimute cu sindromul Down. Ei bine, unul din maimutoii in cauza, pe numele sau de botez Cristofor (adica purtatorul lui Cristos), a decis ca el e Alesul ce va scoate lumea programarii din bezna si si-a inceput lucrarea de educare a maselor postind pe blogul pus la dispozitie de uzina-mama un fel de Philosophiæ Naturalis Principia Programatica. Ópusul are toate ingredientele necesare unei nominalizari la premiul Vocea Minerului: proverbe, indemnuri, acronime si link-uri la site-uri de agili. Singura problema este ca lucrarea este in primul rind una teoretica, adresindu-se exegetilor, deci cititorii de rind pot ramine nelamuriti cu privire la modul in care Principiile se aplica in practica. De aceea imi voi face datoria de umil scrib si voi ilustra opera de geniu cu extrase din rodul lumesc al trudei din Gradina Autodeskului.

Primele doua porunci vin la pachet, dupa cum aparent s-a prins si Cristi:

DRY – Don’t repeat yourself. – Probably the single most fundamental tenet in programming is to avoid repetition.

Abstraction Principle – Related to DRY is the abstraction principle “Each significant piece of functionality in a program should be implemented in just one place in the source code.”

Un prim exemplu al modului in care aceste principii pot transforma programatorul ordinar in Ahitect se gaseste in clasa Texmap. Texmap asta e o poza care in teorie are ca scop sa primeasca niste coordonate si sa returneze un pixel. In practica, maimutele au observat ca uneori texturile astea sint folosite pentru bump mapping, caz in care trebuie luate mai multe sample-uri si calculate niste chestii. In programele care nu au auzit de Principiile Lui Cristofor, calculul asta se face separat, independent de poza, caci e la fel indiferent ca poza e un checker procedural sau un bitmap. In Max, primele doua porunci se incarneaza in felul urmator in documentatie:

To understand how this is done, let’s look at some sample code. The method responsible for returning the perturbed normal is Texmap::EvalNormalPerturb(). The code below happens to be from \MAXSDK\SAMPLES\MATERIALS\CHECKER.CPP but all the other 2D textures use a similar approach.

Point3 Checker::EvalNormalPerturb(ShadeContext& sc)
{
	Point3 dPdu, dPdv;
	if (!sc.doMaps) return Point3(0,0,0);
	if (gbufID) sc.SetGBufferID(gbufID);
	uvGen->GetBumpDP(sc,dPdu,dPdv);
	Point2 dM = uvGen->EvalDeriv(sc,&mysamp);
	return dM.x*dPdu+dM.y*dPdv;
}

Sintagma “a similar approach” se refera la faptul ca bucata de cod de mai sus se gaseste in toate sample-urile lor, si ca tu trebuie sa faci acelasi copy/paste daca implementezi un Texmap d-asta, ca ei n-au fost in stare sa scrie o functie. DRY, da?

Urmatorul exemplu se gaseste intr-unul din fisierele mele preferate din Max: blizzard.cpp. Acest fisier care implementeaza un sistem de particule simplist in doar 9000 de linii de cod contine nenumarate exemple de DRY in interiorul sau – dupa cum va las placerea sa descoperiti – dar de asemenea in exterior, deoarece celelalte sisteme de particule (parray.cpp, pcloud.cpp etc.) sint implementate luind mari bucati din el si schimbind chestii in citeva locuri. Tot in dinsul gasim si urmatorul comentariu DRY-compliant:

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// WARNING - a copy of this class description is in maxscrpt\maxnode.cpp
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Am putea zabovi mult in zona asta a copypastei, dar haideti sa facem un efort si sa trecem la urmatorul triplet leninist:

KISS (Keep it simple, stupid!) – Simplicity (and avoiding complexity) should always be a key goal.

Avoid Creating a YAGNI (You aren’t going to need it) – You should try not to add functionality until you need it.

Do the simplest thing that could possibly work

In Maya, daca vrei ca un material facut de tine sa se picteze singur in viewport, trebuie sa implementezi o metoda numita glGeometry(). Daca vrei sa faci pe desteptul, mai sint vreo trei metode pe care le poti implementa ca sa suporti batching (adica sa te cheme intii ca sa-ti setezi state-ul, dupa care sa te cheme sa te desenezi pentru fiecare mesh, dupa care sa te cheme sa faci curat) dar sint optionale. Probabil va ginditi ca e bine asa, dar gresiti. Asta nu e KISS. Daca vreti sa vedeti KISS si YAGNI, trebuie sa va uitati cum sta treaba in Max.

Intii si-ntii, in Max trebuie sa derivezi din interfata IDX9VertexShader, care contine 18 functii virtuale pure, dintre care nu te intereseaza nici una. Te intereseaza functia care se cheama la fiecare frame, ca sa pictezi din ea, dar aia e intr-o clasa de baza a lui IDX9VertexShader, numita IVertexShader. Functia aia se cheama Initialize(). Nu glumesc. Aparent ar trebui sa faci doar initializari in ea si sa-l astepti pe Max sa incerce sa deseneze cu tine mai tirziu, dar pina si lor li s-a parut prea complicat, asa ca sample-urile din SDK deseneaza direct de acolo.

Dupa IDX9VertexShader vine IDX9PixelShader cu inca vreo 6 virtuale pure. Asta nu stiu la ce foloseste. Nu vad de ce i-ai povesti lui Max despre shaderele pe care le incarci, tu vrei doar sa te cheme sa te pictezi si sa-ti dea geometria. La fel, nici aia care au facut sample-urile n-au inteles, asa ca nu implementeaza deloc interfata asta. Mai departe vine IDX9DataBridge, cu inca vreo 5 virtuale pure pe care trebuie sa le implementezi ca {}. Preferatele mele sint GetDXVersion(), din care trebuie sa returnezi tot timpul 9.0 (ca float, FFS), deoarece clasa asta oricum merge doar cu DX9 (numindu-se ea IDX9DataBridge) si DisableUI() deasupra careia troneaza urmatorul comentariu:

//! This is no longer used
/*! \remarks Currently this method is not used\n\n
  */
virtual void DisableUI()=0;

Cel mai tare princpiu este insa asta:

Principle of least astonishment

In Max, atributele nodurilor se definesc cu ajutorul clasei ParamBlockDesc2. Constructorul acestei clase este:

ParamBlockDesc2(BlockID ID, MCHAR* int_name, StringResID local_name,
ClassDesc2* cd, USHORT flags, ...);

Alea 3 puncte de acolo deschid calea catre cel mai grotesc simulacru de domain-specific language pe care l-am vazut vreodata. Pentru fiecare atribut trebuie sa pasezi diverse tag-uri urmate de valori:

static ParamBlockDesc2 link_const_paramblk (
	link_const_params, _T("LinkConsParameters"),  0, &linkCD,
	P_AUTO_CONSTRUCT + P_AUTO_UI, LINKCTRL_PBLOCK_REF,
	IDD_LINK_PARAMS, IDS_AG_LINKPARAMS, BEGIN_EDIT_MOTION, 0,
	&linkConstDlgProc,
	link_target_list,  _T(""), TYPE_INODE_TAB, 0, P_VARIABLE_SIZE,
		IDS_LINK_LIST,
		p_accessor,		&link_const_accessor,
		end,

	link_key_mode, _T("key_mode"), TYPE_INT, 0, IDS_AG_LINK_KEY_MODE,
		p_default, 		0,
		p_range, 		0, 2,
		p_ui, 			TYPE_RADIO, 3, IDC_NO_KEY,
		IDC_KEY_NODES, IDC_KHIERARCHY,
		p_accessor,		&link_const_accessor,
		end,

	link_start_time, _T(""), TYPE_TIMEVALUE_TAB, 0, P_VARIABLE_SIZE,
		IDS_START_FRAME_LIST,
		p_accessor,		&link_const_accessor,
		end,
	// etc.

Toate cacaturile alea cu p_ in fata sint valori dintr-un enum al lor si trebuie sa fie urmate de parametrii propriu-zisi. Pentru un nod cu citeva zeci de atribute trebuie sa pasezi citeva sute de parametri catre constructorul asta. Nodul lor de color correction (maxsdk\samples\materials\color_correction.cpp) are vreo 65 de atribute, ceea ce rezulta in cam 800 de parametri pasati catre constructor. Least astonishment, da?

Si mai putin surprinzator este cit de robust e maretul sistem. Daca uiti un parametru undeva pe la mijloc, Max crapa la startup fara sa-ti spuna nimic (nici macar ce definitie l-a speriat). In exemplul de mai sus, daca uiti un parametru dupa p_range la link_key_mode, o sa creada ca maximul atributului este valoarea lui p_ui, dupa care va crede ca urmatorul tag e TYPE_RADIO si in functie de valoarea aluia va face lucruri “least astonishing”. Succes la debug.

Chiar daca reusesti sa ii descrii atributele fara sa crape, urmeaza un amuzament maxim cind vrei sa adaugi atribute intr-o versiune ulterioara a plug-in-ului. In primul rind, nu ai voie sa stergi nimic, pentru ca boul citeste valorile din fisiere si le potriveste cu definitiile pe baza indexului, nu dupa nume, cum fac alte programe scrise de fraieri care nu stiu Principii. Singurul lucru pe care poti sa-l faci este sa adaugi noi atribute la coada, dar si asta cu diverse restrictii. Daca nu-ti convine, au un mecanism extrem de complicat si fragil prin care te cheama la load time sa cirpesti datele din fisier, dar deoarece au aplicat KISS cu sfintenie, e inutilizabil.

Din pacate nu pot sa dau link aici la fisierul mesh.cpp pentru ca doar aia care sint registered developers au privilegiul de a se desfata cu continutul sau. Pot insa sa va spun ca in acel fisier se afla functia Mesh::render() in valoare de 3430 de linii. Acolo se vede cum se imbina armonios toate Principiile Lui Cristofor, mai ales ala cu “Write Code for the Maintainer“: goto-uri, nenumarate catch(…)-uri, if-uri cu cite 11 conditii urmate de else if-uri cu o parte din conditiile din primul if, dar negate si in alta ordine, instantiat obiecte COM prin al saptelea nivel de nesting de if-uri si switch-uri etc. Din cind in cind prin cod se gasesc comentarii confuze, unele semnate si datate, ca scrijeliturile de pe peretii celulelor de puscarie. Cele mai tari sint astea doua, anonime din pacate:

else {
    // (How can this happen?)
    delete pSelConv;
}

12 linii mai jos:

else {
    // How can this happen?  (I'm just copying above...)
    delete pNormalSpec;
}

In fine, nu mai stau sa iau si celelalte Principii la rind, ca m-am enervat si mi s-a facut greata de la atita rascolit prin gunoi. Ce vroiam sa spun e ca-mi bag pula in Cristofor si regulile lui. In loc sa puna mina sa stearga puroiul ala de soft si sa arda toate backup-urile surselor, el se preface ca tocmai a fost in excursie pe multele Sinai si ne blagosloveste pe noi cu zicatorile despre programare pe care le-a prins din zbor dind click-uri random pe wikipedia. Muie ba!

PS: nu pot incheia un post despre Max fara citeva citate din maxsdk\samples\mr-notes.txt:

note that these probably won’t map nicely…for example, mi_img_xxx functions will map somewhat to Bitmap and GBuffer functions, but probably not exactly

Norm — actually shader versioning was kinda a mystery to me. That is…miMTShader has get/setVersion, and this is used when generating the MI, but I can’t tell where the translator gets the version from…or does it?

What follows is a rough mapping of MR shader state variables to MAX class vars, functions, etc.
(Urmeaza o lista cu o coloana de nume de variabile din mental ray si o coloana numita “MAX Class or Function” care e complet goala.)

Tags: , , , , , , , , ,