Tipos
Tendo em vista o nosso domínio de aplicação, cujos programas consistem primariamente em aplicações de álgebra linear sobre o espaço euclidiano, listamos abaixo os recursos da linguagem:
Tipos de dados primitivos
- int
- bool
- float
- string
- vec2 (vetor 1x2)
- vec3 (vetor 1x3)
- vec4 (vetor 1x4)
- mat2 (matriz 2x2)
- mat3 (matriz 3x3)
- mat4 (matriz 4x4)
Tipos de dados compostos
Tipagem
Todos os tipos podem ser verificados em tempo de compilação, por serem estáticos, à exceção das matrizes de tamanho arbitrário que por terem tamanho definido em tempo de execução precisam ser checadas dinamicamente - isto é, precisamos analisar a compatibilidade das dimensões das matrizes para fazer as operações. Por ser uma simples verificação de tamanhos (checar 4 valores), essa checagem não oferecerá muito prejuízo à performance.
Junto com o fato de não haver conversões implícitas nem unions (um tipo de natureza muito insegura), é possível dizer que PIG será fortemente tipada.
Conversões
Conversões podem ser implícitas(coerção - tempo de compilação) ou explícitas (pelo programador). Também podem ser de alargamento ou estreitamento, sendo a primeira mais segura, porém até ela pode resultar em perda de de precisão.
Em PIG, apenas conversões explicitas são permitidas focando desta forma na segurança e perdendo pontos no quesito redigibilidade. Dentre as conversões válidas para a linguagem, temos:
Conversão em expressões do tipo misto
É necessário reforçar que todas as conversões feitas no programa devem ser feitas explicitamente pelo programador; não são realizadas conversões implícitas.
O exemplo abaixo mostra um erro que será verificado em tempo de compilação:
def a : float = 3.0;
def b : int = 2;
def c : float;
c = a + b; # nao é aceito, os operandos não possuem o mesmo tipo.
a = 3; #outro erro, não é aceito dado que a é um float.
Agora um exemplo com conversão explícita (como se deve fazer):
def a : float = 3.0;
def b : int = 2;
def c : float;
c = a + toFloat(b);
Compatibilidade de tipos
PIG possui equivalência de nomes (dois tipos são equivalentes se eles têm o mesmo nome) por ser mais fácil de implementar e por ser também uma regra de equivalência fácil de entender para um usuário. Além disso, a equivalência por nome reforça a segurança (que já tínhamos introduzido ao retirar mecanismos de coerção), pois tipos com nomes diferentes não podem ser "misturados" no código, aumentando a legibilidade.