Controle de fluxo

  • if
  • cond
  • Lógica booleana

if

Em Clojure, a ferramenta mais básica que temos para controle de fluxo é o operador if. Veja este exemplo de como você poderia escrever um código no cenário de validação de dados.

Um exemplo. Se somarmos 40 a y e ele ainda for menor que 150, então devolva (+ y 40); caso contrário, devolva -150. (No aplicativo da tartaruga a tela tem a parte superior 150 em y e a inferior em -150 em y.)

Referência: Condicional if

(if (< (+ y 40) 150)
  (+ y 40)
  -150))

Forma geral do operador if

(if expressao-condicional
  expressao-para-avaliar-quando-verdadeiro
  expressao-para-avaliar-quando-falso)

Exemplos de if

(if (> 3 1)
  "3 é maior que 1"
  "3 não é maior que 1")
;=> "3 é maior que 1"

(if (> 1 3)
  "1 é maior que 3"
  "1 não é maior que 3")
  ;=> "1 não é maior que 3"

Veracidade

Quando testamos a veracidade de uma expressão, o Clojure considera que valores nil e false são falsos e todo o resto é verdadeiro. Estes são alguns exemplos:

Referência: Veracidade

(if "tudo que não for false e nil é considerado verdadeiro"
  "Uma string é considerada verdadeira"
  "Uma string não é considerada verdadeira")
;=> "Uma string é considerada verdadeira"

(if nil
  "nil é considerado verdadeiro"
  "nil não é considerado verdadeiro")
;=> "nil não é considerado verdadeiro"

(if (get {:a 1} :b)
  "expressões que valem nil são consideradas verdadeiras"
  "expressões que valem nil não são consideradas verdadeiras")
;=> "expressões que valem nil não são consideradas verdadeiras"

cond

O operador if aceita apenas um predicado. Quando queremos usar múltiplos predicados if não é uma boa opção. Teríamos que escrever vários ifs, um dentro do outro, para conseguir isso. Para decidirmos entre múltiplas situações, o operador cond funciona melhor.

Por exemplo, se somarmos 40 a y e passar de 150, avalie a primeira expressão, que no caso devolve -150. Se somarmos 40 a y e for menos de -150, avalie a segunda expressão, que no caso devolve 150. Se ambos os predicados forem falsos, avalie a expressão do :else. Nesse caso, retorne y mais 40. Se usarmos esta função na app da tartaruga, podemos manter a tartaruga sempre entre a parte de cima e a de baixo da tela.

Referência: Condicional cond

(cond
  (> (+ y 40) 150) -150
  (< (+ y 40) -150) 150
  :else (+ y 40)))

Forma geral do operador cond

(cond
  predicado1 expressao-para-avaliar-se-o-predicado1-for-verdadeiro
  predicate2 expressao-para-avaliar-se-o-predicado2-for-verdadeiro
  ...
  :else expressao-para-avaliar-se-nenhum-dos-predicados-anteriores-forem-verdadeiros)

Lógica booleana com and, or e not

ifs não são limitados a testar apenas uma coisa. Você pode testar múltiplas condições usando lógica booleana. Lógica booleana s if statements are not limited to testing only one thing. You can test multiple conditions using boolean logic. Boolean logic é o que chamamos de combinar e mudar o resultado de predicados usando and (e), or (ou) e not (não). to combining and changing the results of predicates using and, or, and not.

Se você nunca viu esse conceito em programação, lembre-se que é bem parecido com o nosso senso comum do jeito que você olha para as coisas normalmente. Seria isso e aquilo verdade? Só se os dois forem verdade. Seria isso ou aquilo verdade? Sim, se um dos dois for verdade. A diferença pro ou do português é que se os dois forem verdade, também consideramos a expressão toda como verdade. Isto não é verdade? Sim, se for falso.

Combinando and, or, e not

and, or, e not podem ser combinados. O que pode ficar um pouco difícil de ler. Eis um exemplo:

(defn ano-bissexto?
  "A cada quatro anos, exceto em anos divisíveis por 100, mas sim se for divisível por 400."
  [ano]
  (and (zero? (mod ano 4))
       (or (zero? (mod ano 400))
           (not (zero? (mod ano 100))))))

[Bônus] cond, and, or, e not combinados

Aprendemos sobre cond, and , or e not. Vamos pensar em que funções podemos escrever combinando eles. Vamos ao exemplo:

(defn verdadeiro-ou-falso?
  "Dada uma operacao, devolve true ou false"
  [operacao]
  (let [x true
        y false]
    (cond
      (= operacao :and) (and x y)
      :else false)))

(defn correto?
  "Dados uma operacao e uma resposta, devolve um mensagem se a resposta está certa ou não"
  [operacao resposta]
  (if (= resposta (verdadeiro-ou-falso? operacao))
      "Você venceu!"
      "Você perdeu ='("))

Voltar ao primeiro slide, ou ir para o índice do currículo.