hisham hm

A small practical example where Lua’s % behavior is better than C’s

These days I saw on Twitter a comment on how the behavior of the % (remainder) operator for negative numbers is weird in C.

I’ve seen this discussion come up numerous times in the Lua mailing list over the years. The reason being because Lua does it different, and most languages simply copy the behavior of C.

Today I saw Etiene’s cool demo of a mini JavaScript Duck Hunt clone that she presented at a “intro to programming” workshop for the Women in Leadership event in Bremen, Germany.

It’s a really nice demo of game behavior in a short span of code, and with the environment of Mozilla Thimble, it instantly enticed me to play around with the code and see what happened.

The first thing that came to my attention was that the ducks spawn at position x=0, and this made them “pop” into the screen. I thought that changing the initial value to something like x=-50 would be a small change to try and would produce a smoother effect (just change 0 to -50 in lines 56 and 116).

When I first tried that, the result was that they would show up, but wouldn’t start flapping their wings until they were at x=0. The reason is because the logic to switch sprites is made testing x % 30 for values 0, 10 and 20… and JavaScript’s % operator, like C’s, returns negative remainders for negative divisors.

My quick hack solution was to calculate

   var absx = Math.abs(this.x);

(which required me a visit to DuckDuckGo to figure out how to properly say “abs(x)” in JavaScript). This made the birds enter the screen flapping their wings. Yay!

Of course, this is not something you’d want to have to explain in an “intro to programming” workshop. It would be better if the animation “just worked” with that change…

But wait! If you have really sharp eyes, you’ll notice that from -50 to 0, the birds are flapping their wings upwards and from 0 on, they do it downwards. The animation is inverted!

The reason is because operating on abs(x) causes this:

Lua 5.3.0  Copyright (C) 1994-2015 Lua.org, PUC-Rio
> for i = -50, 100 do io.write(math.abs(i)%30, " ") end
20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 0 1 2 3 4 5 6 7 8 9 10

If I write a one-liner to simulate the sprite logic in Duck Hunt, I get this:

> for i = -50, 100 do r=math.abs(i)%30; io.write(r==0 and "1" or (r==10 and "2" or (r==20 and "3" or ".") ) ) end
3.........2.........1.........3.........2.........1.........2.........3.........1.........2.........3.........1.........2.........3.........1.........2

Indeed, it’s going 3,2,1, 3,2,1 at the negative numbers and then 1,2,3, 1,2,3 at the positive ones. But let’s just drop the math.abs in Lua and see what happens:

> for i = -50, 100 do r=i%30; io.write(r==0 and "1" or (r==10 and "2" or (r==20 and "3" or ".") ) ) end
2.........3.........1.........2.........3.........1.........2.........3.........1.........2.........3.........1.........2.........3.........1.........2

We get 1,2,3,1,2,3 all the way!

In my experience, the vast majority of times I used %, it was to tell something to “do this every X steps”, like Etiene does in her Duck Hunt. For this kind of purposes, I’m pretty convinced that Lua’s behavior for % is a lot better. It’s unfortunate that most other languages just decided to follow the example of C.

Of course, there are a million other ways to make the ducks flap their wings, with and without %, that’s not the point. But it intrigued me that, if JavaScript had Lua’s behavior for %, my initial tiny change would have “just worked”!


Sobre a fala dos estrangeiros

A reportagem abaixo me instigou a escrever esse post. Vejam o vídeo.

Em bom portunhol, D’Ale brinca com garrafa: “Se estava cheia, guardava”

A intolerância das pessoas com a fala dos estrangeiros me irrita. Se os repórteres do SporTV acham que o que o D’Alessandro fala é “portunhol”, então eles definitivamente não iam achar que o meu pai, que viveu quase 50 anos no Brasil, falava português.

O D’Alessandro mora no Brasil desde 2008 — acompanhei desde o início quando ele era acanhado para dar entrevistas até os dias de hoje quando ele é o capitão do time e sempre a referência na hora de falar. Eu sempre brinco que no RS os repórteres botam os jogadores de língua espanhola pra falar no rádio e não estão nem aí, e que a gente tem uma adaptação mais natural ao portunhol, mas sinceramente, a essa altura do campeonato chamar o português do cara de “portunhol” ainda, é dose.

Pra piorar, fizeram questão de expor o deslize gramatical dele no título, coisa que eu já cansei de ver corrigirem na transcrição quando entrevistam jogadores falantes nativos de português. E ainda aposto que quem escreveu essa matéria ainda achou que estava elogiando, ao chamar o “portunhol” dele de “bom”.


Velho Mundo e Novo Mundo

Às vezes as pessoas fazem uma cara engraçada quando estou falando de algum assunto — tipicamente cultura ou política — e eu uso as expressões Velho Mundo e Novo Mundo. Parece que eu falei algum anacronismo, ou que estou resgatando algum conceito empoeirado lá das aulas da sétima série.

Hoje vi um mapa que me relembrou dessa distinção, então acho que ajuda a pôr no concreto o quanto ela existe e ainda transparece nos dias de hoje.

Países onde a pessoa se torna um cidadã simplesmente por nascer dentro dele:

Legenda:

(Via esse post no Twitter)


Adeus, Galeano

A palestra dele na PUC-Rio está gravada na minha mente, que momento lindo foi aquele. Quando pessoas como ele se vão, eu sinto um peso de responsabilidade maior nas costas. Não é prepotência, pois não estou me comparando com ele. Mas dá uma sensação de que “agora é com a gente”, todos nós que ainda estamos por aqui, o dever de redobrar o envolvimento, não se omitir, trabalhar para abrir as cabeças e tornar esse mundo um lugar melhor. Nenhum de nós é um Galeano, mas juntos todos somos um pouquinho ele.