March 31, 2008

Patriarhul Daniel s-a accidentat la gleznă

Sursa: Mediafax

Nu Prea Fericitul Daniel a suferit o Nu Prea Sfinţită fractură la glezna stângă, fiind în pericol de a rata derby-ul din etapa de Înviere. Blestematul accident s-a petrecut în timp ce Sfinţia Sa se antrena pentru Înălţare, urcând treptele spre reşedinţa patriarhală.

Sursa precizată afirmă că diagnosticul exact a fost fractură bimaleolară cominutivă cu luxaţie internă astragaliană şi diastazis tibio-peronier Amin. Specialiştii sunt de părere că accidentarea a fost cauzată de calitatea precară a terenului de antrenament, recomandând ca după recuperare, Patriarhul să-şi desfăşoare pregătirea în loc luminat, în loc cu verdeaţă. Comunicatul oficial mai precizează că operaţia a durat 1h:25m şi că Luminăţiei Sale i s-a introdus un Prea Sfinţit Şurub în Binecuvântata Tibie.

Interesant este că, din cauza precedentului creat de incidentele de la meciul Rapid - Steaua, atunci când partida a fost înteruptă din cauza obiectelor aruncate din tribună, Patriarhului îi va fi interzis accesul în Paradis cu PS Şurub. Autorităţile se tem că, în cazul producerii unor incidente asemănătoare în timpul Judecăţii de Apoi, Anticristul va câştiga cu 3-0 la masa verde.

March 30, 2008

Politicienii români s-au mutat la blog

La scara A, 'nea Costică Blogheru, administratorul, are pe liste următorii locatari Geoană Mircea, Păunescu Adrian, Cârlan Dan, Prisăcaru Radu.

La scara B, unde administrator e madam Nuţi Ordprés îi putem găsi pe Năstase Adrian, Iliescu Ion, Udrea Elena, Miluţ Marian, Oprea Dumitru, Weber Renate.

Vecinii lor ne-au spus că politicienii de la blog sunt oameni liniştiţi atât timp cât nu se întâlnesc unii cu ceilalţi, căci atunci se lasă cu bălăcăreală şi scandal mare. Din spusele administratorilor, politicienii nu au datorii la întreţinere pentru că îi întreţine statul; în schimb, ceilalţi locatari au cerut deja evacuarea lor din cauza imenselor datorii morale pe care le-au acumulat. Despre preferinţele lor culinare, nu am putut afla decât că, prin ferestrele bucătăriilor politicienilor de la blog, iese adesea miros de ciolan.

Se pare că politicienii români s-au acomodat uşor cu viaţa la blog, mai puţin cu procedurile de evacuare urgentă în cazul cutremurelor politice. Atunci, în loc să acţioneze cu responsabilitate şi să iasă în mod ordonat afară, ei îşi pierd simţul raţiunii şi, instinctiv, se agaţă cu putere de scaune.

March 29, 2008

Iaşul participă la Earth Hour 2008

Via Gabi Enea.

Hai să ne mobilizăm şi noi puţin şi să punem umărul la acţiunea asta. Să arătăm tuturor că se poate, că dacă participă fiecare dintre noi cu câte puţin, împreună putem schimba lumea în mai bine.

Azi la 20:00, voi închide absolut toate aparatele alimentate cu energie electrică din casă. Apoi, voi căuta un vecin căruia nu-i pasă de Earth Hour la care să văd şi eu meciul.

Pace.

March 28, 2008

Fun with delegates

I'll start off with some dummy code for the road.


   1:  delegate void DumbDelegate();
   2:  public class DumbClass
   3:  {
   4:      public void PrintDumbStuff()
   5:      {
   6:          Console.WriteLine("Dumb stuff");
   7:      }
   8:      public void PrintClassName()
   9:      {
  10:          Console.WriteLine("Dumb Class");
  11:      }
  12:  }

First thing's first: delegate equality. You'll find it to work quite as you would have expected it.

  13:  DumbDelegate del1 = null;
  14:  DumbDelegate del2 = null;
  15:  DumbDelegate del3 = null;
  16:  DumbClass dumb1 = new DumbClass();
  17:  DumbClass dumb2 = new DumbClass();
  18:  del1 = new DumbDelegate(dumb1.PrintDumbStuff);
  19:  del2 = new DumbDelegate(dumb2.PrintDumbStuff);
  20:  Console.WriteLine(del1 == del2); // FALSE;
  21:  del2 = new DumbDelegate(dumb1.PrintDumbStuff);
  22:  Console.WriteLine(del1 == del2); // TRUE

For two delegates to be equal w.r.t. the == operator, they need to refer to the same method of the same instance. This is quite sound, actually, and with it comes the next scenario.

  23:  del3 = new DumbDelegate(dumb2.PrintClassName);
  24   del3 += del1;
  25:  del3 -= del2;
  26:  del3(); // Output: "Dumb Class"

Rememeber that we had left del1 and del2 as equal last time, so obviously, del3 will be after [25] as it was before [24]. This makes delegate "arithmetic" pretty interesting.

  27:  (del1 + del2 + del3 - del2 + del1 + del3 - del2)();
  28:  (del1 - del2)(); // NullReferenceException
  29:  (del1 - del2 + del3)();// OK
  30:  Console.WriteLine((null + del1) == del1); // TRUE

There's really nothing special about [27] except that del2 is added once and subtracted twice. If you see that kind of code anywhere else besides bored people's blogs, you might as well call consumer protection. [28] throws a NullReferenceException because the result of the subtraction is, well ... a null reference. Empty delegates do not exist. [29] works like a charm, though, basically because [30] works too.

So, little by little, we have moved towards the grand finale, towards the great conclusion, towards the mother of all scientific discoveries: .net delegates of the same signature form a monoid with respect to addition and the null reference. Seriously. You have:

Identity Element
  30:  Console.WriteLine((null + del1) == del1); // TRUE
  31:  Console.WriteLine((del1 + null) == del1); // TRUE

Associativity
  32:  Console.WriteLine((del1+del2)+del3 == del1+(del2+del3));
// TRUE

... for any three delegates del1, del2 and del3 with the same signature. And thus, a monoid. Fun, eh?

EDIT:

A rather big error sneaked into the initial version of this post.

Commutativity
  33:  Console.WriteLine(del1 + del2 == del2 + del1); // TRUE

... does not hold. del1 and del2 were coincidentally equal when I tested the equality, so commutativity seemed to hold. However, it became dubious after I realized that it's not reasonable for two delegates that make the same method calls but in a different order to be equal, because the effects of one method call may influence the results of another method call, so the order of the chain is important. So after all, the monoid formed by .net delegates together with addition and null is not commutative.

March 27, 2008

Colecţia de carte Ziarul de Iaşi

În fiecare marţi, numărul obişnuit din Ziarul de Iaşi este însoţit de o carte de la editura Polirom, preţul pachetului fiind de doar 5 RON. Colecţia propune titluri recente, aparţinând unor autori care au obţinut recunoaştere internaţională în ultimul deceniu.

Chiar dacă nu e vorba de scriitori arhicunoscuţi, cred că e o ocazie excelentă de a ne îmbogăţi săptămână de săptămână biblioteca, mai ales că preţul este unul insignifiant comparativ cu cel la care aceste cărţi se vând în librării sau chiar în cadrul târgurilor de carte. Ediţia de marţi, 1 Aprilie, este însoţită de cartea "Virusul", de Hari Kunzru, al cărei preţ de raft este de 27 RON.

Dacă nu găsiţi ediţia cu carte la chioşcul vostru de presă preferat, o găsiţi sigur la centrele de mică publicitate ale Ziarului de Iaşi de la Casa Cărţii şi Iulius Mall. În ultimă instanţă, de la sediul redacţiei de pe strada Smârdan nr. 5 puteţi cumpăra ediţii din săptămânile trecute, rămase în stoc.

Vă urez lectură plăcută, cu gogoşi şi cafea.

Virusul
În altă ordine de idei, iată că după cărţi despre viaţa oamenilor de afaceri şi a femeilor moderne încep să apară şi cărţi despre programatori. O fi bine, o fi rău ... ne mitizează sau ne demitizează?

March 26, 2008

Ia-ţi carnetul de student cu tine în Europa

Dacă eşti student şi plănuieşti să-ţi petreci vacanţa în Europa dar nu ai card ISIC, ai grijă să nu îţi uiţi acasă legitimaţia emisă de universitatea la care studiezi. Da, da, carnetul ăla boţit, lipit cu scotch şi pătat de cafea îţi poate obţine reduceri la o grămadă de instituţii de cultură şi atracţii.

Interesant e că, deşi carnetul de student are zero elemente de siguranţă, arareori vei fi întâmpinat cu vreo urmă de suspiciune de către personalul de la ghişeu, care mai degrabă pare că te crede pe cuvânt decât câ îţi verifică legitimaţia. De ce spun că e interesant? Pentru că atunci când trăieşti într-o ţară în care şmecheria e virtute de neam, eşti obişnuit să sufli şi-n iaurt ca să nu te frigi.

March 25, 2008

Case în Iaşi

De o bună bucată de vreme, piaţa imobiliarelor din România a luat-o razna. Ca să parafrazez, nu ştiu alţii cum sunt, dar eu când mă gândesc la preţurile de vânzare sau închiriere ale apartamentelor parcă-mi saltă inima în gât de frică.

Am auzit de multe ori dându-se vina pentru explozia preţurilor pe comisioanele percepute de agenţiile imobiliare şi pe specula imobiliară pe care atât acestea, cât şi "oamenii de afaceri" o practică. Nu mă pricep, dar sună plauzibil. În orice caz, mai grav e că foarte des citesc din diverse surse despre ţepe, abuzuri şi contracte dubioase practicate de agenţiile imobiliare [1], [2], [3], [4] iar veştile bune par încă departe [5].

În atare condiţii, eu unul salut apariţia pe webul românesc a unui site dedicat anunţurilor imobiliare fără intermediari la www.caseiniasi.ro şi îi urez să crească voinic în funcţionalitate şi chipeş la interfaţă.

Şi dacă se poate, aş vrea un site care să ne scape şi de notarii publici.

March 24, 2008

Avoid boxing / unboxing in C# when using IList

Suppose we need to write a method that performs some operation on lists of arbitrary elements, say a circular left shift by one position. Naturally, our method will need to take the most general type of parameter available, the IList. An 'off the top of my head' implementation would probably look something like this:

   1:  public static void ShiftList(IList list)
   2:  {
   3:      if (list != null && list.Count > 1)
   4:      {
   5:          object temp = list[0];
   6:          for (int i = 1; i < list.Count; i++)
   7:          {
   8:              list[i - 1] = list[i];
   9:          }
  10:          list[list.Count - 1] = temp;
  11:      }
  12:  }


However, suppose that, the client code calls our method like so:

  13:  ListShifter.ShiftList(new double[10000]);

In this case, using the indexers on the IList interface at [8] produces at least 1 boxing and 1 unboxing . Multiply that by 10.000 (iterations of the for loop) and we'll be spending most of our CPU time running a packaging service for doubles.

The question is: 'can this be avoided'? The only way to index the array without its values being boxed/unboxed would be to have an actual variable of type double[] refer it. But our method can only inquire about the contents of the IList (and find out that there's actually an array underneath) at runtime, whereas variables are declared at compile time. Or are they?

  14:  private static void ShiftArray<T>(IList list)
  15:  {
  16:      T[] array = list as T[];
  17:      if (array != null && array.Length > 1)
  18:      {
  19:          T temp = array[0];
  20:          for (int i = 1; i < array.Length; i++)
  21:          {
  22:              array[i - 1] = array[i];
  23:          }
  24:          array[array.Length - 1] = temp;
  25:      }
  26:  }

The code above elegantly solves our problem. There is no boxing or unboxing performed at [22], as opposed to [8], provided that the method is instantiated correctly at runtime (in our case, T has to be double - otherwise the cast at [16] fails). We can make sure of that as follows:

  27:  public static void CircularLeftShift(IList list)
  28:  {
  29:      if (list == null) return;
  30:      Type listType = list.GetType();
  31:      if (listType.IsArray)
  32:      {
  33:          Type elementType = listType.GetElementType();
  34:          if (elementType.IsValueType)
  35:          {
  36:              Type t = typeof(ListShifter);
  37:              MethodInfo m = t.GetMethod("ShiftArray",
BindingFlags.Static | BindingFlags.NonPublic);
  38:              Type[] genArgs = new Type[] {elementType};
  39:              MethodInfo gm = m.MakeGenericMethod(genArgs);
  40:              gm.Invoke(null, new object[] { list });
  41:          }
  42:          else
  43:          {
  44:              ShiftList(list);
  45:          }
  46:      }
  47:  }

What we're doing is we're using reflection to find out if our argument, list, actually holds an array [31], and if it does, of what type are its elements [33]. If the elements are instances of a value type, we instantiate our generic method using that type [39] and the we invoke it on list [40]. If any of the above conditions does not hold, we just call the ordinary method [44].

Some code to test our methods:

  48:  double[] list = new double[100000];
  49:  DateTime start = DateTime.Now;
  50:  for (int i = 0; i < 500; i++)
  51:  {
  52:      ListShifter.CircularLeftShift(list);
  53:  }
  54:  DateTime end = DateTime.Now;
  55:  TimeSpan duration = end.Subtract(start);
  56:  Console.WriteLine(duration.TotalSeconds);

Just replace CircularLeftShift with ShiftList to observe the difference.