Trilhas
/
Common Lisp
Common Lisp
/
Exercícios
/
Apresentando-se para o serviço
Apresentando-se para o serviço

Apresentando-se para o serviço

Exercício de aprendizagem

Introdução

Formato - Noções básicas

O Common Lisp tem um conceito chamado Impressora, que inclui todas as funções para escrever representações textuais de dados Lisp. Uma dessas funções é format, que permite ao programador formatar os dados como quiser.

As capacidades de format e da Impressora do Lisp em geral são um assunto amplo; aqui vamos descrever o básico do uso de format.

A função FORMAT

A função format recebe pelo menos dois argumentos: um fluxo no qual imprimir e uma string de controle que define o que será impresso e como.

Os fluxos são um conceito à parte e serão descritos em outro lugar. Por enquanto, basta saber que a impressão é feita no fluxo, e que existem dois valores especiais para esse argumento: t e nil. O t significa imprimir na saída padrão (na verdade, o fluxo ao qual a variável *standard-output* está associada). E nil significa criar uma string e retorná-la.

Repare que format sempre avalia para nil, exceto nesse último caso, em que nil é especificado como o fluxo. Essa é uma forma comum de fazer simplesmente interpolação ou construção de strings.

(format nil "hello world") ; => "hello world"
(format t "hello world")   ; => NIL (but "hello world" is printed to standard output)

Diretivas de formato

A string de controle pode conter "diretivas de formato", que dão instruções ao format sobre o que imprimir e como interpretar os demais parâmetros passados a ele. De certo modo, a string de controle é um programa que o format interpreta e executa. Todas as diretivas começam com ~ e são seguidas de um caractere (por exemplo, ~A, ~D, ~&). Não importa se o caractere está em maiúscula ou minúscula.

A maioria das diretivas de formato simplesmente interpola na saída um argumento passado ao format. Diz-se que elas "consomem" o argumento. Algumas diretivas não consomem argumentos, ou consomem mais de um. Há até uma diretiva que permite pular de um ponto a outro da lista de argumentos ou ignorar argumentos.

Formatação básica

Uma diretiva de formato bastante versátil é ~A. Ela imprime uma versão "legível para humanos" dos dados.

(format nil "Value = ~a" 10)                ; => "10"
(format nil "hello ~a" "world")             ; => "hello world"
(format nil "The list is: ~A" (list 1 2 3)) ; => "The list is: (1 2 3)"

Outra diretiva de formato útil é ~S. Ela imprime uma versão "legível para máquinas" dos dados. Isso pode ser muito útil se você quiser conseguir interpretar a saída gerada como dados Lisp. Para muitas coisas ela vai parecer igual à ~A, mas repare que, no caso de strings, por exemplo, a saída vai incluir as aspas (escapadas quando incluídas em outra string) para que o valor possa ser lido de volta como o parâmetro de string.

(format nil "~s" 10)            ; => "10"
(format nil "~s" "hello world") ; => "\"hello world\""
(format nil "~s" (list 1 2 3))  ; => "(1 2 3)"

Mais duas diretivas muito úteis são ~% e ~&. A primeira gera um caractere de nova linha, enquanto a segunda gera uma "linha nova". A diferença é que ~% sempre gera uma nova linha, enquanto ~& só gera uma se o cursor não estiver no início de uma linha. Nenhuma delas consome um argumento.

(format nil "~%new~%lines") ; => "
                                  new
                                  lines"

(format nil "~&new~&lines"  ; => "new
                                  lines"

Por fim, ~~ é uma diretiva simples que gera um ~ literal.

Instruções

Como quase todo mundo que tem um trabalho, Layla, a alienígena de Lisp, às vezes precisa fazer relatórios para informar outras pessoas. Ela pede se você poderia ajudá-la a formatar os dados que tem para esses relatórios.

1. Formatando valores trimestrais

A primeira coisa de que Layla precisa é de uma função: format-quarter-value, que recebe dois parâmetros: o trimestre e o valor, e os formata para um relatório. Ela deve resultar em uma string.

(format-quarter-value "last" 3.14) ; => "The value last quarter: 3.14"
(format-quarter-value "this" 0) ; => "The value this quarter: 0"

2. O relatório de dois trimestres

Layla agradece pela função format-quarter-value e diz que ela vai ser muito útil na próxima função de que precisamos.

O próximo relatório precisa mostrar o trimestre e o valor de 2 trimestres, impressos em duas linhas.

Além disso, a saída precisa ir para o stream fornecido como primeiro argumento.

Por exemplo: (format-two-quarters t "last" 3.14 "this" 0) vai produzir o seguinte na saída padrão:


The value last quarter: 3.14
The value this quarter: 0

Repare nas linhas em branco em volta.

3. Legível para humanos vs. alienígenas de Lisp

Layla esqueceu de contar que os alienígenas de Lisp gostam de ver os valores de um jeito que seja legível como dados de Lisp. Então ela precisa de uma nova função que possa ser lida como dados de lisp (de novo, para o stream especificado):

(format-two-quarters-for-reading nil "last" 3.14 "this" 0) ; =>

"(\"The value last quarter: 3.14\" \"The value this quarter: 0\")"
Editar via GitHub O link abre em uma nova janela ou aba
Common Lisp Exercism

Tudo pronto para começar Apresentando-se para o serviço?

Crie sua conta no Exercism para aprender e dominar Common Lisp com 27 conceitos92 exercícios e mentoria humana de verdade, tudo de graça.