Oct 26, 2013

Closures in C# - Answer


In the previous post I've asked what would be the output of a simple C# application:

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
   private static void Main(string[] args)
   {
      foreach (var func in GetFuncs1())
      {
         Console.WriteLine("[first] {0}", func());
      }

      foreach (var func in GetFuncs2())
      {
         Console.WriteLine("[second] {0}", func());
      }
   }

   private static List<Func<int>> GetFuncs1()
   {
      var fs = new List<Func<int>>();

      for (int i = 0; i < 3; i++)
      {
         fs.Add(() => i);
      }
      return fs;
   }

   private static List<Func<int>> GetFuncs2()
   {
      var fs = new List<Func<int>>();

      foreach (var i in Enumerable.Range(0, 3))
      {
         fs.Add(() => i);
      }
      return fs;
    }  
}
The correct answer is: it depends!

In order to understand the issue you need to undertand Closures and captured variables in C# (for a deeper understanding about these subjects I recomed reading here and here).

Basically in both methods (GetFuncs1 and 2) we are creating lambda expressions that references a local variable (i); since the CLR garantees that the memory allocated for such variable will be reclaimed as soon as it is not referenced, i.e, long before the usage of the lambda expression, the C# compiler "captures" the variable (if you are curious about how it does it, open the assembly using ILDASM or ILSpy to inspect the IL code, I do recommend) and here start our issues.

As I said the compiler captures the variable, not its value; so, calling GetFuncs1() produces code that is equivalent to something like (see the highlighted lines 20, 25-28 and 29) (the actual code is quite different but for our purposes the following code can be seen as equivalent):

using System;
using System.Collections.Generic;

class Program
{
 private static void Main(string[] args)
 {
  foreach (var func in GetFuncs1())
  {
   Console.WriteLine("[first] {0}", func());
  }
 }

 private static List<Func<int>> GetFuncs1()
 {
  var fs = new List<Func<int>>();

  for (ret = 0; ret < 3; ret++)
  {
   fs.Add(ret_func);
  }
  return fs;
 }

 private static int ret_func()
 {
  return ret;
 }

 private static int ret;
}
That means that we are always calling ret_func() and this function will return the value of ret which is updated in the for loop!

Ok, so now you understand why the output was 3,3,3 but two questions come up (at least):

  1. Is there a way to avoid this behavior so the output would be 0, 1 and 2 ?
  2. Why the hell I said that the output of the program "depends" ? And more importantly, depends on what?
The answer for the first question is yes; simply declare a new variable inside the for loop and assign "i" to it (line 20), then return the value of this new variable from within the lambda expression (line 21) :
using System;
using System.Collections.Generic;

class Program
{
 private static void Main(string[] args)
 {
  foreach (var func in GetFuncs1())
  {
   Console.WriteLine("[first] {0}", func());
  }
 }

 private static List<Func<int>> GetFuncs1()
 {
  var fs = new List<Func<int>>();

  for (int i = 0; i < 3; i++)
  {
   var capture = i;
   fs.Add(() => capture);
  }
  return fs;
 }
}
Running the application now produces the expected result. What changed is that now, since we are creating a new variable in every iteration, the compiler will emit code equivalent to:
using System;
using System.Collections.Generic;

class Program
{
 private static void Main(string[] args)
 {
  foreach (var func in GetFuncs1())
  {
   Console.WriteLine("[first] {0}", func());
  }
 }

 private static List<Func<int>> GetFuncs1()
 {
  var fs = new List<Func<int>>();

  for (int i = 0; i < 3; i++)
  {
   var h = new Holder {value = i};
   fs.Add(h.GetIt);
  }
  return fs;
 }

 class Holder
 {
  public int value;

  public int GetIt()
  {
   return value;
  }
 }
}
Again, now it became pretty easy to understand why we get the expected output; in each iteration the compiler is simply instantiating a new object to hold the value of "i" at that point in time.

Ok, so from now on, everytime you create lambda expressions / anonymous functions that capture local variables I am sure you'll pay attention and make sure you get the behaviour you want.

Regarding the second point, i.e, the "depends" part, if this blog happens to have more than a few readers I am sure that, when running the program, some of you got "unexpected" different outputs twice (i.e, 3,3,3 and 2,2,2) while some of you got 3,3,3 and 0,1,2!

The difference? The version of the C# compiler used!

See the picture below:

It happens that in C# 5 the behavior for captured variables of a foreach loop has changed! In this case the compiler will emit code as if in each iteration a new local variable were allocated (the same trick I showed you before); if you followed me you now understand why when compiling with VS 2012 the code produced the expected result.

Now the 1 million dollars question: why on earth the version that uses a simple for has not been updated with the same behavior? Well, I don't have (and I don't pretend to have) the definitive answer. What I can say is that IMHO it is at least "confusing". New developers (which are most likely unaware of this behavior) will, invariably, be caught by this at least once (but it can be twice)!

If these new developers happen to first use a for loop (always with lambdas / anonymous methods capturing local variables) they may find themselves wondering why their lambdas/anonymous methods are observing the updated value of a captured variable and then, when they finally realize what's going on, they will tend to use the "declare a local variable in each iteration" trick everywhere (including in foreach loops). By the other hand if these developers happen to first use a foreach loop then they will most likely find themselves wondering why they observe different behaviors when using lambdas/anonymous methods!

Even though I understand the reasoning in this discussion I don't fully agree - parts of my brain still thinks this simply introduces inconsitencies - but this is just my opnion.

If you are interested in reading about this topic in the C# language specification, it can be found in chapter 8.8.4.

What do you think?

Closures em C# - Resposta


No post anterior eu deixei como pergunta qual seria a saída de um programa simples em C#:

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
   private static void Main(string[] args)
   {
      foreach (var func in GetFuncs1())
      {
         Console.WriteLine("[first] {0}", func());
      }

      foreach (var func in GetFuncs2())
      {
         Console.WriteLine("[second] {0}", func());
      }
   }

   private static List<Func<int>> GetFuncs1()
   {
      var fs = new List<Func<int>>();

      for (int i = 0; i < 3; i++)
      {
         fs.Add(() => i);
      }
      return fs;
   }

   private static List<Func<int>> GetFuncs2()
   {
      var fs = new List<Func<int>>();

      foreach (var i in Enumerable.Range(0, 3))
      {
         fs.Add(() => i);
      }
      return fs;
    }  
}

A resposta para a pergunta é: depende.

(antes de continuar quero ressaltar que toda vez que me referir a um laço for/foreach, assuma que o mesmo se encontra no contexto de lambda expressions / métodos anônimos que capturam variáveis locais / parâmetros)

Para que você possa enterder o problema melhor é necessário antes entender um pouco sobre closures e a sua relação com o uso de variáveis (locais / parâmetros). Se você precisar refrescar a memória recomendo a leitura deste blog post e também deste outro).

Basicamente ambos os métodos do exemplo (GetFuncs1 e 2) criam lambda expressions as quais em seus corpos referenciam a variável local (i)(linhas 26 e 37); para evitar que a área de memória reservada para tal variável seja reutilizada pela CLR o compilador C# "captura" a variável (você pode utilizar o ILDASM ou ILSpy para verificar o código IL gerado e assim entender melhor este processo) e é aqui que os nossos "problemas" começam.

Observe que eu disse que o compilador "captura" as variáveis, não seus valores no momento da criação das lambda expressions; assim, supondo que tivessemos apenas a chamada ao método GetFuncs1(), o código resultante seria equivalente ao código abaixo (note as linhas marcadas: 20, 25-28 e 30) (o código gerado na realidade é bem diferente mas para nossos propósitos podemos tratá-lo como equivalente):

using System;
using System.Collections.Generic;

class Program
{
 private static void Main(string[] args)
 {
  foreach (var func in GetFuncs1())
  {
   Console.WriteLine("[first] {0}", func());
  }
 }

 private static List<Func<int>> GetFuncs1()
 {
  var fs = new List<Func<int>>();

  for (ret = 0; ret < 3; ret++)
  {
   fs.Add(ret_func);
  }
  return fs;
 }

 private static int ret_func()
 {
  return ret;
 }

 private static int ret;
}
Como vemos, ao invés de criar um método para representar o corpo das lambda expressions em cada iteração do laço, o compilador emitiu um único método estático (ret_func() inserindo referências para o mesmo na lista de funções) que simplesmente retorna o valor do campo ret o qual, por sua vez, é atualizado no laço for!

Agora que você já entende porque a saída do programa foi 3,3,3 restam, pelo menos, duas questões:

  1. Como obter o comportamento desejado, ou seja, que a saída do programa seja 0, 1 e 2 ?
  2. Porque eu disse que a saída do programa "dependia" de algo, e o mais importante, depende do que?
A resposta para a primeira pergunta é sim; (veja o programa abaixo) basta declarar uma variável local dentro do laço for e atribuir a variável "i" para a mesma (linha 20) e, então, retornar o valor desta variável no corpo da lambda expression (linha 21) :
using System;
using System.Collections.Generic;

class Program
{
 private static void Main(string[] args)
 {
  foreach (var func in GetFuncs1())
  {
   Console.WriteLine("[first] {0}", func());
  }
 }

 private static List<Func<int>> GetFuncs1()
 {
  var fs = new List<Func<int>>();

  for (int i = 0; i < 3; i++)
  {
   var capture = i;
   fs.Add(() => capture);
  }
  return fs;
 }
}
Se você executar o programa agora verá que a saída do mesmo é exatamente a esperada; isto ocorre porque, agora, como declaramos uma variável local dentro do laço o compilador irá emitir código equivalente ao código abaixo (efetivamente capturando o valor da variável no momento em que a lambada expression é criada):
using System;
using System.Collections.Generic;

class Program
{
 private static void Main(string[] args)
 {
  foreach (var func in GetFuncs1())
  {
   Console.WriteLine("[first] {0}", func());
  }
 }

 private static List<Func<int>> GetFuncs1()
 {
  var fs = new List<Func<int>>();

  for (int i = 0; i < 3; i++)
  {
   var h = new Holder {value = i};
   fs.Add(h.GetIt);
  }
  return fs;
 }

 class Holder
 {
  public int value;

  public int GetIt()
  {
   return value;
  }
 }
}
Novamente ficou mais simples entender porque este código produz o resultado esperado: em cada iteração do laço o compilador instanciou um objeto para armazenar o valor de "i" naquele momento.

Estou certo de que, de agora em diante, toda vez que você utilizar lambda expressions / métodos anônimos você irá certificar-se de usar a construção compatível com o resultado desejado.

Quanto à segunda questão, se este blog tiver um número razoável de leitores, teremos dois grupos com resultados diferentes: 3,3,3 / 2,2,2 e 3,3,3 / 0,1,2 (que é a saída esperada)!

A diferença nos resultados esta relacionada à versão do compilador C# utilizado.

Veja a imagem abaixo:

A versão 5 do C# mudou o comportamento de variáveis capturadas em laços foreach! A partir desta versão o compilador emite código como se a cada iteração uma nova variável local fosse alocada (o mesmo truque que eu apresentei acima);

Agora eu me questiono porque o comportamento de laços for não foram modificados também. O que posso dizer é que, na minha opinião, esta decisão só introduz confusão. Desenvolvedores iniciantes na linguagem irão, invariavelmente, ser surpreendidos por esta diferença de comportamento.

Caso estes desenvolvedores tenham contato primeiramente com laços for os mesmos ficaram tentando entender porque suas lambdas expressions/métodos anônimos estão observando uma valor atualizado da variável capturada e, então, quando eles entenderem o que esta ocorrendo tenderão a usar o truque de "declarar uma variável local dentro do laço" (inclusive em laços foreach). Por outro lado, caso estes desenvolvedores tenham contato com o laço foreach primeiro, eles correm o risco de em algum momento usar um laço for e introduzir bugs (uma vez que os mesmos assumirão que o valor da variável do laço será capturada).

Há uma discussão sobre o assunto que, ainda que eu compreenda os argumentos, não concordo completamente com os mesmos - partes do meu cérebro ainda acham que esta diferença no comportamento é uma inconsistência gratuíta - mas esta é apenas minha opinião.

Se você estiver interessado em mais detalhes sobre o assunto recomendo a leitura do capítulo 8.8.4 da especificação da linguagem C#.

Finalmente um alerta: se você for portar projetos de uma versão do C# anterior à 5.0 para a versão 5.0 ou mais nova preste atenção na combinação lambda expressions / laços for pois como vimos é possível ocorrer mudanças de comportamento.

O que você acha?

(read this post in english)

Oct 5, 2013

Closures in C#


Hi

Given the following code:

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
   private static void Main(string[] args)
   {
      foreach (var func in GetFuncs1())
      {
         Console.WriteLine("[first] {0}", func());
      }

      foreach (var func in GetFuncs2())
      {
         Console.WriteLine("[second] {0}", func());
      }
   }

   private static List<Func<int>> GetFuncs1()
   {
      var fs = new List<Func<int>>();

      for (int i = 0; i < 3; i++)
      {
         fs.Add(() => i);
      }
      return fs;
   }

   private static List<Func<int>> GetFuncs2()
   {
      var fs = new List<Func<int>>();

      foreach (var i in Enumerable.Range(0, 3))
      {
         fs.Add(() => i);
      }
      return fs;
    }  
}

What do you expect as the output? (try answering before running it)

Does it produces the results you expected? No? Do you understand why?

(If you are using Resharper it will warn you that you wrote code that captures variables and can produce "unexpected" results)

In the next post I'll give the answer and discuss it.

Happy coding.

(leia este post em Português)

Closures em C#


Olá.

Dado o seguinte programa em C# o que você espera que o mesmo imprima? (tente responder a pergunta sem compilar/executar o mesmo):

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
   private static void Main(string[] args)
   {
      foreach (var func in GetFuncs1())
      {
         Console.WriteLine("[first] {0}", func());
      }

      foreach (var func in GetFuncs2())
      {
         Console.WriteLine("[second] {0}", func());
      }
   }

   private static List<Func<int>> GetFuncs1()
   {
      var fs = new List<Func<int>>();

      for (int i = 0; i < 3; i++)
      {
         fs.Add(() => i);
      }
      return fs;
   }

   private static List<Func<int>> GetFuncs2()
   {
      var fs = new List<Func<int>>();

      foreach (var i in Enumerable.Range(0, 3))
      {
         fs.Add(() => i);
      }
      return fs;
    }  
}


Se você rodar o mesmo, o resultado obtido é compatível com sua expectativa? Não? Você entende o porque?

No próximo post vou discutir o comportamento deste programa e também como evitar algumas "armadilhas" relacionadas a Closures em C#.

(read this post in english)

Sep 17, 2013

Useful utility: ConEmu

Have you ever used cmd.exe (a.k.a Windows Console)? In my day to day tasks usually I have from 2 ~ 3 consoles open, which brings me to this post.

Lets be fair: Anyone that has used any *nix based shell (bash comes to my mind), usually considers (seriously) moving to Linux or some *nix based OS ;)

Even though I do recommend using a different OS, such a radical change is not required all you want is a better experience when using a console; on Windows, there are some alternatives to cmd.exe; for instance, I have used console2 for some time and recently I switched to ConEmu (mostly because it has been updated more frequently); in any case I do recommend you to take the time to check both to see which one you adapt better, if any :).

Since I started using such console replacements I don't miss cmd.exe even for a second ;)

(Este post em Português)


Happy coding.

Utilitário útil da semana: ConEmu

Se você é um usuário avançado do Windows provavelmente recorre ao console (cmd.exe) para executar várias das suas tarefas diárias. Eu, em geral, tenho 2 ~ 3 consoles abertos normalmente e este fato é exatamente a motivação deste post.

Vamos ser sinceros: se você já usou algum shell (tipo bash) que acompanha uma instalação Linux moderna usar o console do Windows dá vontade de mudar para o Linux ;)


Felizmente não é necessário uma mudança tão radical (muito embora eu recomendo usar o Linux, ou qualquer outro S.O. sempre que possível). Por exemplo, a algum tempo eu vinha usando o console2 que é uma boa alternativa ao console do Windows. Recentemente eu passei a usar o ConEmu simplesmente porque o mesmo tem sido atualizado mais frequentemente que o console2 (de qualquer forma eu recomendo instalar ambos e experimentar para ver qual lhe agrada mais).

Entre outros recursos o ConEmu suporta múltiplas tabs, seleção de texto muito melhorado, uso de qualquer fonte, etc.

Quanto a mim, não pretendo voltar a usar o console do Windows (talvez, quem sabe, usar mais o power shell, mas isto já é assunto para outro post :).

(This post in English)

Sep 4, 2013

Blogging experiments....

Hi,

Even though in the beginning I used to post in portuguese (my native language) I decided to switch to english to force me to write more in this language.

Although I am still firm believer that anyone interested in information technology field do need to be able to read english I came to the conclusion that posting in portuguese is also valuable so, starting with this post I'll experiment posting in both english / portuguese.

What do you think? 

If I get no feedback then I may decide switching back to english only posts :).

(you can read this post in portuguese)

Happy coding!

Posts em português

Olá,

Quando eu comecei a postar em meu primeiro blog eu postava em português; contudo depois de algum tempo decidi postar em inglês. Meu objetivo era o de me forçar a escrever neste idioma e assim aperfeiçoar minhas habilidades com o mesmo.

Contudo após este tempo eu repensei a decisão e concluí que não postar em português estimularia esta tendência de adotar o inglês em detrimento do Português. Assim sendo, a partir deste post, pretendo seguir um modelo em que postarei nos dois idiomas (contudo o conteúdo dos posts não serão uma tradução literal de um idioma para o outro).

O que você acha? Após alguns posts vou reavaliar e decidir se continuo neste modelo, se volto a postar apenas em inglês, se passo a postar apenas em português ou, quem sabe, se paro de postar :)

PS: Aqui esta a versão em inglês deste post.

Happy coding!

Aug 24, 2013

Looking for a new Job: the experience

Hi.

On this post I've said that I was joining a great team and that I was really excited about it; I did meant that but unfortunately this journey came to an end on Feb/1/2013 when my contract was not renewed after the latest corporate acquisitions round.

In this post I'll describe the process I took to find a new job, but first lets make things as clear as possible:
  1. I am not an HR expert (far from it, I'd rather say I am a complete newbie on the subject), so take every world with a whole mountain of salt ;)
  2. yes, I did follow most, if not all, of the presented advice.
Perhaps the most important advice (and probably the hardest to follow) is: don't panic! I know that it is easier to say than to do (I've been there, remember ?), but try to keep calm and review your options carefully.

The first thing you need is to realize that 
Looking for a new job is a full time job!

It may look like restating the obvious but I haven't realized how much time it may take! So, be prepared to dedicate a lot of time to this phase (fortunately, job wise I hadn't much else to do :).

My first step was to create a list of requirements/constraints for the new job, sorted by importance; you should take into account aspects such as compensation package, relocation, type of work, etc. Depending on your constraints it'll take longer to find your new dream job.

In my case the list looked something like:
  1. It had to be fun and challenge.
  2. The company  I'd work for should at least recognize and be committed to implement/use good development practices (TDD, continuous building, pair programming, etc).
  3. Compensation should be closer to or higher than what I was earning before.
  4. Work from home if possible.
  5. Avoid relocation.
Soon after I come up with this list I started to suffer from the ROOR (Running out of resources ;) syndrome - for reasons that are not important to explain here I had almost no savings... :(.

At this point you really need to think about what you want, review your requirements list and refrain from accepting the first (or second, third, whatever) job offer you may get only because you are running out of money. 

Of course there is a hard deadline and you can't wait indefinitely  in my case I strove to get at least 4 ~ 5 job offers before taking a decision. More importantly than the number, was the quality of the offers; there was one in particular that I was really interested in so I discussed with my wife and we decided we'd squeeze as much as possible from our small savings and would try to allow me 1 ~ 2 more months before taking the decision (while I was waiting for the interviews to come I took the time to experiment with something new, but related to my field of interest). 

After some time the interviews started to come and suddenly I had participated in 3 ~ 4 of them, some in the traditional sense of the word and some virtual interviews (through skype / phone).

Some notes from these interviews (process wise):
  • Never forget that interviews are a two lane road: you are not the only that is being interviewed! You should also be evaluating the company in question.
  • Don't be afraid of challenges! Instead, use them as a motivation to you to learn and improve.
  • Be humble but not shy. Do not put yourself in the position of someone that is reluctant to disagree because you are afraid of not getting an offer: be yourself.

  • Be prepared to face ridiculous, unrealistic job skill set requirements / compensation packs. Just keep the professionalism.

  • Show enthusiasm; would you hire a candidate that looks (and behaves) apathetic in an interview?

  • Even if, in the middle of the interview, you've already made your mind and you don't plan to accept a (possible) job offer, keep the professionalism.
Fun fact: there was 2 situations that I found very strange: in one of the interviews I was asked absolutely no technical questions (at least none that I think would be able to assess my ability to do the job) and in another one the interviewer sold the company in question as the best company in the world but said that they could not get good developers to join them, hum... (guess what? I discarded both of them). 

When you finally get a job don't forget to get back to any pending job offer and let them know you are not available anymore.
Hope this was helpful.

Aug 15, 2013

Did you know? Windows 7 Cool feature

Warning: I've started to write this post a long time ago (whence references to Windows 7 as the new kid on the block) but I refrained to posting it since I could not verify the behavior; now I decided to give it another try.... :).


A common complain on Windows platform is that whenever you try to use a file already being used by another process there is no easy way to find out which process is using that file. The canonical sample is trying to delete a file using Windows Explorer:

It happens that Windows Vista introduced a new COM interface named IFileIsInUse that could be used to allow other processes to figure out which process have the file open. Unfortunately, AFAIK (and based on the MSDN documentation), applications must be aware of this interface and actively do something with it if they want to play nicely with other applications, including the OS. 

This morning I was reading some blog posts and someone suggested that Windows 7 had finally fixed this misbehavior (bug?). Cool! Now I could not resist playing a little bit with it.
My first try was to run a C# application that just kept a file open until some key is pressed and try to delete the file; Wow! it worked perfectly! 
But now I was left wondering whenever this could have something to do with CLR 4.0 changes (since I was compiling with VS 2010). You know, maybe the FCL team decided to do the IFileIsInUse interface dance internally (when you open a FileStream for instance).


In order to solve this doubt I took 2 actions:
  1. Targeting CLR 2.0 (by changing VS configuration for the project)
  2. Write a native C++ application to do the same thing as the C# one (the code bellow).
  3. Compile the same native program (2) with VS 2010 on Windows XP box (which has no support for IFileIsInUse at all)
  4. Compile the same native program (2) with VS 2010 on Windows Vista box (which does has support for IFileIsInUse)
#include "stdio.h"

int main(int argc, char* argv[])
{
 const char *fileName = "Test.txt";
 FILE* p = fopen(fileName, "w+");
 if (p == NULL)
 {
  printf("Unable to create file...");
  return -1;
 }

 printf("[%s] Press any key to close the file ", fileName);

 getchar();

 fclose(p);

 return 0;
}
and in the first two cases (i and ii) the result was the same: Windows Explorer was able to detect which application had the file open (with no extra effort from my side :)! Really nice! (Ok, I agree, Windows should have been doing this for ages, but better late than never, don't you agree ? :)


By the other hand, in the last 2 cases (iii and iv) explorer failed to detect the application that had the file open (with exclusive rights).

To me looked like on Windows 7 (and 8 also BTW) Windows Explorer is falling back to NtQuerySystemInformation if it cannot find an IFileIsInUse entry in ROT. So I wrote a simple app (DumpROT.cpp) that searched the ROT for IFileIsInUse implementations and as I suspected when I run the app that keeps the "Test.txt" file open, RotDump fails to find any IFileIsInUse in ROT (it looks like even Libreoffice fails to register opened files in the ROT). Some other programs I've tested (including Visual Studio 2012) didn't registered open files either (see the output bellow):
The -verbose command line option instructs DumpROT to show all entries in the ROT irrespective to what these entries references.

As a last test I decided to run MS sample for this interface and voilá it does register an IFileIsInUse reference in the ROT for the chosen file!

This output was obtained by running DumpROT with the same set of opened files from the previous one (since I omitted the -verbose option the tool gave no feedback). Then I run it again, but this time with -verbose option; you can see in the output that no reference to IFileIsInUse was found in ROT.  Next step was to run FileIsInUseSample (the MSDN sample with some changes to accept a file path through the command line) and executed DumpROT again; this time you can see that DumpROT found an entry to "output.txt"  (the file passed to the sample app) in the ROT.

Unfortunately I don't have MS Office installed here to check whenever it takes advantage of this feature or not.

Happy coding!

Adriano

Aug 8, 2013

I love my job ;)

I am so proud of being part of the team behind Unity (even if my contributions so far are really a tinny part of it - almost nothing ;)


I've joined Unity team 5 months ago and everyday I get impressed by how much they have achieved already.

Sure, as any other job, it has its "this task sucks" moments but most of the time I'm having fun and learning new stuff (and the developers / team mates are really supportive).

Thanks all for the opportunity. I am really happy working with such great people.

Happy codding.

Aug 3, 2013

Interesting tricks with value types in .Net

A while back I was pairing with a team mate hunting a memory allocation that should not be happing (it was not a leak but it was in a method called thousands of times per second and we do believed it was not required (or at least we should try to avoid it at all costs).

After some code inspection we nailed it down to a foreach loop, something as simple as:

var list = new List<int>();

// the code bellow allocates memory. 
foreach(var item in list)
{
}
Interestingly enough, when compiled against C# 3.5 / 4.0 compilers we could not reproduce this behavior; it was only when compiling on Mono 2.6 (on mono 2.10 it didn't happened).

After some investigation (and head banging) we found the issue; for reasons that I'll not explain here (basically to avoid gc allocations) the enumerator returned by List is a value type but it happens that in order to fulfill the foreach contract it also implements IDisposable. On .Net (at least on 3.5) it happens that the compiler completely avoids boxing this enumerator but when compiled with gmcs (the mono cs compiler) 2.6.5.0 a box gets generated for the code that calls IDisposable.Dispose()! (see the code bellow):

finally
{
     IL_0048: ldloc.2
     IL_0049: box valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator< int32>
     IL_004e: callvirt instance void [mscorlib]System.IDisposable::Dispose()
     IL_0053: endfinally
}
Well, it happens that MS C# compiler (and newer mono ones also) emit different IL for that finally block:
finally
{
     IL_004b: ldloca.s 3
     IL_004d: constrained. valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator< int32>
     IL_0053: callvirt instance void [mscorlib]System.IDisposable::Dispose()
     IL_0058: nop
     IL_0059: endfinally
}
See, no box instruction. Instead of boxing, the compiler loads the value type address and then asks the runtime to handle that address as a reference to IDisposable.

Really interesting (at least IMHO)

Happy codding!

Aug 2, 2013

Getting Windows 8 on a Macbook Pro

I am typing this post on a new, shine Mac Book Pro with a retina display, a big SSD and lots of memory ;)

But instead of using Mac OS I decided to go through the bootcamp route and install Windows 8 (sorry, I cant't code in C# without Resharper anymore :)

Well, since this solution is an official solution (from Apple) I expected everything to go really smoothly and without any major issues (other than the Windows 8 ones... :). This was my first disappointment with Apple; first I tried 3 different flash disks (pendrive) but bootcamp just hangs without any information why (no one can blame Windows for this ;). Some times it just said "an error occurred while copying windows files to the flash disk" (or something like that). 

I even tried 2 different external hard drives with the same outcome. In the end I decide to do it the way the "pros" does, i.e, I manually created a bootable flash drive using a Windows 8 x64 image, used bootcamp to install it (but not to install the drivers) and as soon as Windows booted after the installation finished I downloaded and installed the bootcamp drivers manually.

Finally I had an working machine (hey, it is really fast) (moving from an old Q9400  to a new I7 machine makes a huge difference) and was happy... until trying to close the notebook lid (expecting to put Windows to a good sleep) and noticing it just turned the computer off. 

While googling trying to understand what went wrong I realized this is a relatively common issue with this setup (at least lots of people was asking similar questions in various online forums); the problem is that it looks like some device driver don't support sleeping. You can confirm this by running the following command in the command line:

powercfg -a

In my case I just got this:

The following sleep states are available on this system:
    Hibernate
    Fast Startup

The following sleep states are not available on this system:
    Standby (S1)
The system firmware does not support this standby state.

    Standby (S2)
The system firmware does not support this standby state.

    Standby (S3)
The system firmware does not support this standby state.

    Standby (Connected)
The system firmware does not support this standby state.

    Hybrid Sleep
Standby (S3) is not available.

Notice the line saying the system do not support S3 sleep state; this is exactly the state the machine should enter when its lid is closed.. 

Later I found this joy in a FAQ on Apple site:


23. My Macintosh running Windows 7 or 8 does not sleep when a Thunderbolt device is plugged in.  Is this normal?
Yes. Sleep is disabled in Windows 7 or 8 while a Thunderbolt device is plugged in.
Well done! Anyway, it looks like I do have an workaround; do not use thunderbolt devices. I'll try.

What do you think?

May 7, 2013

Once again

Hi

Well, I have been busy lately but I can't refrain myself from posting this; recently I have got tons of phishing emails claiming they are from local banks. In most of those financial institutions I'm not even a customer! Anyway, it doesn't hurt to try :)

Bellow you can see the original message, but pay attention to the email sender (xxxhrs@webxc31s05 and goes on). They don't even bothered to use something more realistic. There is only a single link at the bottom of the page pointing basically to www.djentachi.kz which definitively does not sound as a valid web address for this bank :)


The bottom line: as always be careful with everything coming into your email box.

Adriano

Mar 8, 2013

SSH: using specific keys with specific hosts

First of all, I have never thought I'd post something Unix related (not that I have anything against it; it just because I am more a Windows user :)

It just happens that for personal reasons I have some VMs running Ubuntu and from time to time I need to transfer files from my host computer to the guest, i.e, from my Windows machine to Ubuntu running on the VM. Since the virtualization solution I am using has some issues regarding file/folder sharing between host/guest OS, I am using scp to do the job.

Until today I used to have a single RSA key pair to authenticate me when connecting to my Ubuntu VM and also to github and bitbucket but this has proven to no be an optimal solution. You see, when I am copying files to Ubuntu I'd like to not be forced to type any password, after all this VM has no sensitive data and is off limits since it is not connected to the internet, but since I am using a single RSA key pair for most of my authentication  needs I don't want do leave it unprotected so every time I want to copy something to the guest OS (my Ubuntu running on the VM) I find myself typing a huge, complicated password - actually very often mistyping it :(.


Today I took the time and decided I'd find out how to setup multiple RSA key pairs and use one with no password at all to authenticate me with my VM and one with a strong password for each online service I use.


Actually it was easier than I thought ;). Basically the utilities I rely on (ssh and scp) allows one to specify which identity file (the RSA file containing your private key) (-i file_path) is to be used.


if you don't want to specify which file should be used every time or if the utility you use don't allow you to specify this file (but uses ssh behind the scenes) you can use ~/.ssh/config file!

Happy codding.

Mar 6, 2013

New types from .NET 4.5

Hi.

While experimenting with WPF programing I've just stumbled on a nice, new class in .Net 4.5 (thanks to Resharper) named CallerMemberNameAttribute.

The first thing you can figure out based on its name is that it is an attribute. It's only applicable to parameters and is meant to make developers live easier when it comes to find out the name of the caller method / property / event / etc :)

Basically you add this attribute to any parameter of type string with a default value and the compiler will do its magic.

Bellow you can see an example:

public partial class Form1 : Form
{
	public Form1()
	{
		InitializeComponent();
		
		button2.Click += delegate
		{
			Foo();
		};
	}

	private void Foo([CallerMemberName] string caller = null)
	{
		MessageBox.Show("Called from : " + caller);
	}
}

This is really useful for implementing INotifyPropertyChanged interface.

Note that this gives you only the name of the member calling the method, not the type in which this method is defined.

As any other feature developers should not abuse it. For instance, IMHO, using this feature with indexers should be avoided:

public partial class Form1 : Form
{
	public Form1()
	{
		InitializeComponent();
		
		button2.Click += delegate
		{
			MessageBox.Show( this[0] );
			MessageBox.Show( this[1] );
		};
	}

	private string this[int n, [CallerMemberName] string caller = null]
	{
		return n > 0 ? this[n-1] : caller + "(" + n + ")";
	}
}

For more information, look into the documentation.

Happy codding!

Jan 4, 2013

The end of the world is approaching...

Hi

First of all, Happy new year! :)

Last night I was surprised (upset?) for getting an offer (that I could not refuse) from a well know web site (which I like pretty much, by the way) claiming that that was my last chance to subscribe to their 1 month free premium plan.

I have absolutely no problem with the offer. What gets on my nerves is the fact that they have been sending  this very same offer for the past 6 ~ 9 months, saying each time that that was my last chance

Come on guys. You should already have noticed that I even went to your website and started the registration process.... you should ask yourselves why I did not finished it, instead of keeping bugging me ;)

See you!