Clojure - sintaxe básica
Para entender a sintaxe básica do Clojure, vamos primeiro examinar um programa simples Hello World.
Hello World como um programa completo
Escreva 'Olá, mundo' em um programa Clojure completo. A seguir está um exemplo.
Exemplo
(ns clojure.examples.hello
(:gen-class))
(defn hello-world []
(println "Hello World"))
(hello-world)
As seguintes coisas precisam ser observadas sobre o programa acima.
O programa será escrito em um arquivo chamado main.clj. A extensão 'clj' é o nome da extensão de um arquivo de código clojure. No exemplo acima, o nome do arquivo é main.clj.
A palavra-chave 'defn' é usada para definir uma função. Veremos as funções em detalhes em outro capítulo. Mas, por enquanto, saiba que estamos criando uma função chamada helloworld, que terá nosso código Clojure principal.
Em nosso código Clojure, estamos usando a instrução 'println' para imprimir “Hello World” na saída do console.
Em seguida, chamamos a função hello-world que, por sua vez, executa a instrução 'println'.
O programa acima produz a seguinte saída.
Resultado
Hello World
Forma Geral de uma Declaração
A forma geral de qualquer instrução precisa ser avaliada entre colchetes, conforme mostrado no exemplo a seguir.
(+ 1 2)
No exemplo acima, a expressão inteira está entre colchetes. A saída da declaração acima é 3. O operador + atua como uma função em Clojure, que é usado para a adição de numerais. Os valores de 1 e 2 são conhecidos como parameters to the function.
Vamos considerar outro exemplo. Neste exemplo, 'str' é o operador usado para concatenar duas strings. As strings “Hello” e “World” são usadas como parâmetros.
(str "Hello" "World")
Exemplo
Se combinarmos as duas instruções acima e escrevermos um programa, ele se parecerá com o seguinte.
(ns clojure.examples.hello
(:gen-class))
(defn Example []
(println (str "Hello World"))
(println (+ 1 2)))
(Example)
Resultado
O programa acima produz a seguinte saída.
Hello World
3
Namespaces
Um namespace é usado para definir um limite lógico entre os módulos definidos no Clojure.
Namespace atual
Isso define o namespace atual no qual o código Clojure atual reside.
Sintaxe
*ns*
Exemplo
Na janela de comando REPL, execute o seguinte comando.
*ns*
Resultado
Quando executamos o comando acima, a saída será adiada dependendo de qual é o namespace atual. A seguir está um exemplo de uma saída. O namespace do código Clojure é -
clojure.examples.hello
(ns clojure.examples.hello
(:gen-class))
(defn Example []
(println (str "Hello World"))
(println (+ 1 2)))
(Example)
Exigir declaração em Clojure
O código Clojure é empacotado em bibliotecas. Cada biblioteca Clojure pertence a um namespace, que é análogo a um pacote Java. Você pode carregar uma biblioteca Clojure com a instrução 'Require'.
Sintaxe
(require quoted-namespace-symbol)
Exemplo
A seguir está um exemplo do uso desta declaração.
(ns clojure.examples.hello
(:gen-class))
(require ‘clojure.java.io’)
(defn Example []
(.exists (file "Example.txt")))
(Example)
No código acima, estamos usando a palavra-chave 'require' para importar o namespace clojure.java.io que possui todas as funções necessárias para a funcionalidade de entrada / saída. Como não temos a biblioteca necessária, podemos usar a função 'arquivo' no código acima.
Comentários em Clojure
Os comentários são usados para documentar seu código. Os comentários de uma única linha são identificados usando ;; em qualquer posição na linha. A seguir está um exemplo.
Exemplo
(ns clojure.examples.hello
(:gen-class))
;; This program displays Hello World
(defn Example []
(println "Hello World"))
(Example)
Delimitadores
Em Clojure, as declarações podem ser divididas ou delimitadas usando colchetes ou colchetes.
Exemplo
A seguir estão dois exemplos.
(ns clojure.examples.hello
(:gen-class))
;; This program displays Hello World
(defn Example []
(println (+ 1 2 3)))
(Example)
Resultado
O programa acima produz a seguinte saída.
6
Exemplo
A seguir está outro exemplo.
(ns clojure.examples.hello
(:gen-class))
;; This program displays Hello World
(defn Example []
(println [+ 1 2 3]))
(Example)
Resultado
O programa acima produz a seguinte saída.
[#object[clojure.core$_PLUS_ 0x10f163b "clojure.core$_PLUS_@10f163b"] 1 2 3]
Espaços em branco
Os espaços em branco podem ser usados no Clojure para dividir os diferentes componentes de uma instrução para maior clareza. Isso pode ser feito com a ajuda do operador vírgula (,).
Por exemplo, as duas instruções a seguir são equivalentes e a saída de ambas as instruções será 15.
(+ 1 2 3 4 5)
(+ 1, 2, 3, 4, 5)
Embora Clojure ignore as vírgulas, às vezes as usa para tornar as coisas mais fáceis para o programador ler.
Por exemplo, se você tiver um mapa hash como o seguinte (def a-map {: a 1: b 2: c 3}) e solicitar seu valor na janela REPL, Clojure imprimirá a saída como {: a 1, : b 2,: c 3}.
Os resultados são mais fáceis de ler, especialmente se você estiver vendo uma grande quantidade de dados.
Símbolos
No Clojure, os símbolos são equivalentes aos identificadores em outras linguagens de programação. Mas, ao contrário de outras linguagens de programação, o compilador vê os símbolos como valores de string reais. Como um símbolo é um valor, um símbolo pode ser armazenado em uma coleção, passado como um argumento para uma função, etc., como qualquer outro objeto.
Um símbolo só pode conter caracteres alfanuméricos e '* +! /. : - _? ' mas não deve começar com um numeral ou dois pontos.
A seguir estão exemplos válidos de símbolos.
tutorial-point!
TUTORIAL
+tutorial+
Estrutura do Projeto Clojure
Finalmente, vamos falar sobre uma estrutura de projeto típica para um projeto Clojure. Como o código do Clojure é executado na máquina virtual Java, a maior parte da estrutura do projeto no Clojure é semelhante ao que você encontraria em um projeto Java. A seguir está o instantâneo de uma estrutura de projeto de amostra no Eclipse para um projeto Clojure.
As seguintes coisas importantes precisam ser observadas sobre a estrutura do programa acima.
demo_1 - Este é o pacote no qual o arquivo de código Clojure é colocado.
core.clj - Este é o arquivo de código principal do Clojure, que conterá o código para o aplicativo Clojure.
A pasta Leiningen contém arquivos como clojure-1.6.0.jar, necessários para executar qualquer aplicativo baseado em Clojure.
O arquivo pom.properties conterá informações como groupId, artifactId e versão do projeto Clojure.
O arquivo project.clj contém informações sobre o próprio aplicativo Clojure. A seguir está um exemplo do conteúdo do arquivo de projeto.
(defproject demo-1 "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {
:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"
}
:dependencies [[org.clojure/clojure "1.6.0"]])