Controle de fluxo
Avance em um fluxo contínuo de decisões que devem ser tomadas.
Fallback
As operações padrão ou de coalescência nula são definidas com dois pontos de interrogação ??
e funcionam da seguinte maneira:
<talvezNullOuError> ?? <valorFallback>
Caso o lado esquerdo não seja null
nem Error
, então ele é usado; caso contrário, fallbackValue
é retornado.
de forma semelhante, você pode usar o operador de atribuição por coalescência nula
??=
If
Declarações If
são definidas com um ponto de interrogação ?
, como abaixo:
<condição> ? <resposta>
como não há alternativa,
null
é retornado se a condição não for atendida
If-Else
Declarações If-Else
são definidas com um ponto de interrogação ?
seguido de dois pontos :
, como abaixo:
<condição> ? <resposta> : <alternativa>
Para usar declarações If-Else
multilinhas, envolva a resposta em chaves {...}
assim:
<condição> ? {
<resposta>
} : {
<alternativa>
}
Cases
Cases
são definidos com a seta espessa =>
e são automaticamente encadeados, criando uma sintaxe intuitiva e simplificada, semelhante a uma declaração switch, sem a possibilidade de queda (fall-through). Isso permite que condições não relacionadas sejam misturadas, resultando em uma estrutura "if-else-if-else" mais concisa:
<condição1> => <respostaPara1>
<condição2> => <respostaPara2>
<condição3> => <respostaPara3>
...
Exemplo:
escolha = (x) -> {
x == 1 => 'a'
x == 2 => 'b'
x == 3 => 'c'
}
escolha(2) # 'b'
escolha(8) # null
Para fornecer um valor padrão para seu método, você pode adicionar um caso pega-tudo usando um sublinhado _
no final da sequência:
escolha = (x) -> {
x == 1 => 'a'
x == 2 => 'b'
x == 3 => 'c'
_ => 'd'
}
escolha(2) # 'b'
escolha(8) # 'd'
Para cenários mais complexos, você pode usar blocos como resultados para cada caso:
...
condição => {
# faça algo
'foo'
}
_ => {
# faça outra coisa
'bar'
}
...
Cases
devem terminar em um caso pega-tudo _
ou final do bloco. O uso mais efetivo de Cases
é dentro de métodos na parte inferior do corpo do método.
Embora seja possível adicionar Cases
aninhados, é melhor evitar construções excessivamente complexas. Isso torna o código mais difícil de seguir e provavelmente perde o objetivo de usar esse recurso.
Pode ser mais apropriado extrair essa lógica para um método separado. O FatScript incentiva os desenvolvedores a dividir a lógica em métodos distintos, ajudando a evitar código spaghetti.
Switch
O operador Switch
é denotado pelo símbolo de seta dupla para a direita >>
, que guia o fluxo de controle baseado na correspondência do valor com uma série de casos:
Sintaxe:
<valor> >> {
<valorCaso1> => <respostaPara1>
<valorCaso2> => <respostaPara2>
...
_ => <respostaPadrão>
}
Cada caso no bloco Switch
é avaliado em ordem até que uma correspondência seja encontrada e o resultado do caso correspondente é retornado:
escolher = -> _ >> {
1 => 'um'
2 => 'dois'
3 => 'três'
_ => 'outro'
}
escolher(2) # 'dois'
escolher(4) # 'outro'
Os casos do Switch
também podem envolver expressões, permitindo correspondências dinâmicas:
avaliar = (x, y) -> x >> {
y + 1 => 'logo acima de y'
y - 1 => 'logo abaixo de y'
_ => 'não diretamente ao redor de y'
}
avaliar(5, 4) # 'logo acima de y'
avaliar(3, 4) # 'logo abaixo de y'
avaliar(7, 4) # 'não diretamente ao redor de y'
Tap
O operador Tap
é representado pelo símbolo de duas setas para a esquerda <<
, que facilita a execução de efeitos colaterais sem alterar o resultado principal de uma expressão. Ele é projetado para processar valores por meio de métodos especificados (taps) que podem executar efeitos colaterais, mas ainda retornando o valor original da expressão.
Sintaxe:
<resultado> << <métodoTap>
o lado direito de um
tap
deve sempre ser um método
Nesta estrutura, <resultado>
é uma expressão cujo valor é passado para <métodoTap>
, que executa usando <resultado>
como sua entrada, mas não afeta o valor final da expressão. Em vez disso, <métodoTap>
é usado puramente por seus efeitos colaterais.
Veja como o operador tap
pode ser usado:
console <- fat.console
increment = x -> x + 1
resultado = increment(4) << console.log
Neste exemplo, increment(4)
calcula para 5
, que é então passado para console.log
e, embora console.log
retorne null
, o resultado final atribuído a resultado
é 5
.
Vários efeitos colaterais podem ser encadeados sequencialmente, cada um recebendo o mesmo resultado inicial:
val = pure(in) << fx1 << fx2 << fx3