Por que os blocos if / while / loop / when padrão do Raku têm todos o mesmo valor de identidade (.WHICH)?

9

Exceto pelo bloco em que declarei uma assinatura, todos os blocos têm o mesmo valor de identidade e afirmam ser declarados na linha 1, independentemente de onde ocorram. Alguém poderia lançar alguma luz sobre por que esse é o caso?

say 「Let's look at some blocks…」;

if True {
  &?BLOCK.say;
}

while True {
  &?BLOCK.say;
  last;
}

loop {
  &?BLOCK.say;
  last;
}

if True -> | {
  「I'm different!」.say;
  &?BLOCK.say;
}

when ?True {
  &?BLOCK.say;
}
Daniel Mita
fonte

Respostas:

6

Primeiro de tudo: .sayse não dar-lhe o valor de identidade, pois que chama o .gistmétodo na expressão dada. Para o valor da identidade, você precisa chamar o .WHICHmétodo Felizmente, o Block.gistmétodo faz incluir o valor de identidade em sua stringification. Mas isso não é garantido para todos os objetos.

O que você vê lá é o otimizador estático em funcionamento: como nada está acontecendo dentro do bloco, ele pode ser descartado. No caso em que é diferente (onde você especificou uma assinatura alternativa), é diferente. Se você executar esse script com --optimize=0ou --optimize=1, todos os blocos terão valores de identidade diferentes.

Eu acho que você poderia chamá-lo de um problema que mencionar &?BLOCKnão inibe o otimizador estático de achatar o escopo. Por outro lado, você também pode chamar isso de DIHWIDT (Doutor, dói quando eu faço isso). Então não faça isso :-)

ATUALIZAÇÃO: é a assinatura diferente que fez a diferença. Daniel Mita ++

Elizabeth Mattijsen
fonte
2
Obrigado pela informação, embora não tenha certeza de seguir o segundo parágrafo. A criação da string não é o que faz a diferença, é a assinatura do bloco (ela tem o mesmo valor de identidade se eu remover a assinatura, mas manter a string).
Daniel Mita