O que não é Ciência da Computação


Considerações: Eu quero ser claro sobre a minha intenção neste post. Eu não estou argumentando que a programação, engenharia de software, testes, quantificação e outras tarefas práticas ou campos relacionados não são tão importantes quanto a CC (Ciência da Computação). Essas disciplinas altamente relacionadas são absolutamente tão importantes e úteis quanto Ciência da Computação. Em vez disso, o que estou tentando transmitir é que existe, em grande parte, como um produto da cultura popular e uma perpetuação de equívocos comuns, um mal-entendido generalizado sobre o que a Ciência da Computação abrange. Particularmente, há um núcleo profundamente teórico que constitui a base da CC que não pode e nem deve ser ignorado. Além disso, apesar do fato de que muitos estudantes (inclusive eu na época) não apreciam totalmente essa teoria quando a aprendem, ela é tão importante quanto outras considerações mais práticas.
Além disso, não pretendo sugerir que áreas da Ciência da Computação que não sejam teoria da computabilidade ou teoria da complexidade não são, de alguma forma, CC reais ou não são tão interessantes ou dignas de estudo. No entanto, gostaria de salientar que o trabalho realizado por pessoas em quase todos os ramos da Ciência da Computação consiste em certas coisas que são "Ciência da Computação propriamente dita" e outras coisas que residem em um domínio diferente. Isso não significa que essas pessoas não sejam verdadeiras cientistas da computação ou que as coisas em um domínio diferente sejam menos importantes. Por exemplo, eu pesquiso em Biologia Computacional. Parte do que faço diariamente é Ciência da Computação, parte dela é design e programação de software, parte dela é Biologia e muito dela é Estatística ou outros ramos da Matemática. Essas outras tarefas são tão interessantes, satisfatórias e importantes quanto o ciência da computação que faço, mas elas não são Ciência da Computação. Neste post, não pretendo ofender ninguém, mas sim ajudar a esclarecer algumas das percepções errôneas comuns do que a CC realmente é.

Eu estava pensando em colocar esse título "O que é Ciência da Computação?". No entanto, a ideia ligada a esse título tem mais probabilidade de ser um livro ou, pelo menos, um manifesto do que um post no blog. Em vez disso, imaginei que poderia escrever um post de tamanho razoável sobre as razões da Ciência da Computação não ser o que as pessoas acostumam atribuir incorretamente como sendo Ciência da Computação.
Existem duas práticas que muitas vezes as pessoas confundem com a Ciência da Computação que considero serem os dois equívocos mais comuns. O primeiro (e isso acontece se você for, você mesmo, um cientista da computação e tem membros da família que não são) é o "suporte técnico". Em particular, as pessoas acham que Ciência da Computação significa aprender como os computadores ou partes específicas de software funcionam e como consertá-los quando eles estragam. No entanto, é verdade que um típico cientista da computação possa ter mais sorte em instalar um driver de impressora do que um leigo, mas isso não tem nada a ver com seu treinamento formal em Ciência da Computação e mais com o fato de que os cientistas da computação (mas nem sempre) gastam muito mais tempo lidando com computadores.
No entanto, a combinação de suporte técnico com CC, embora muito comum, não é muito interessante. Em particular, as atribuições são tão diferentes que deveria ser fácil esclarecer essa confusão; potencialmente com a ajuda de algumas analogias. Aqui estão duas ótimas citações (muitas vezes atribuídas incorretamente a Edgar Dijkstra) que realmente tocam o cerne da questão:

“A ciência da computação não é sobre máquinas, da mesma forma que a astronomia não é sobre telescópios. Há uma unidade essencial de matemática e ciência da computação”
- Michael R. Fellows (1991)

igualmente

“O que gostaríamos que nossos filhos o público em geral do futuro aprendessem sobre Ciência da Computação nas escolas? Precisamos acabar com o mito de que a Ciência da Computação é sobre computadores. A Ciência da Computação não tem mais a ver com computadores do que a Astronomia, com telescópios; a Biologia, com microscópios; ou a Química, com os béqueres e os tubos de ensaio. A ciência não é sobre ferramentas, é sobre como as usamos e o que descobrimos quando fazemos isso.”
- Micheal R. Fellows, Ian Parberry (1993)

Ok, então a mensagem que deve ficar é que a Ciência da Computação não é sobre computadores ou “ferramentas” em geral da mesma maneira que a Astronomia (ou Astrofísica) não é sobre telescópios. Você pode esperar que um astrofísico saiba mais sobre um telescópio do que, digamos, um bibliotecário, simplesmente porque eles usam telescópios com muito mais frequência. No entanto, o coração do que eles fazem não tem nada a ver com o próprio telescópio. O mesmo acontece com os cientistas da computação e os computadores.
Outra coisa que as pessoas comumente confundem com CC, que requer uma distinção mais sutil, é a PC (programação de computadores). A razão pela qual esse equívoco é mais difícil de retificar é que a grande maioria dos cientistas da computação realmente programa. De fato, muitos deles programam muito. No entanto, a prática da programação em si não constitui Ciência da Computação. Deixe-me motivar essa distinção com uma anedota.
Meu orientador criou uma nova disciplina, que ele está ensinando neste semestre, chamada “Algoritmos e Estruturas de Dados (para Cientistas)”. O título da aula deve deixar o objetivo bastante claro; O objetivo do curso é ensinar aos cientistas (ou seja, estudantes da graduação que são tecnicamente competentes e matematicamente maduros) como entender, desenvolver e analisar algoritmos e estruturas de dados. À medida que as técnicas computacionais se tornam mais prevalentes em diferentes domínios científicos, a necessidade de especialistas em computação aumentará, mas também aumentará a necessidade de os cientistas do domínio adquirirem um nível básico de compreensão das técnicas que empregam. Então, houve muito interesse na turma e muitas pessoas se registraram.
Agora, cerca de 3/4 do percurso, meu amigo, que é um dos assistentes do professor, e eu estávamos conversando na hora do almoço e ele me explicou que alguns dos alunos do curso estavam preocupados ou confusos com a falta de atribuições de programação. Agora, o programa do curso era claro que a própria aula consistiria em muito pouca programação (~2 tarefas), mas ao invés disso, seria pesado em problemas de trabalhos de casa. Também ficou claro que a aula é principalmente sobre o design e a análise de algoritmos o objetivo é que, no final do curso, o aluno seja capaz de projetar algoritmos eficientes para lidar com os problemas que encontrarem e analisarem (ou seja, provar) correção desses algoritmos e caracterizar seus tempos de execução. No entanto, apesar do fato de que o conteúdo e os objetivos do curso foram claramente descritos, ainda é possível entender a confusão dos alunos. Em particular, entre aqueles que não são eles próprios cientistas da computação (por exemplo, cientistas de outras áreas), a ideia de que os cientistas da computação são programadores e de que a Ciência da Computação é programação é desenfreada.
Adendo: para não representar erroneamente a turma ou minha opinião, quero esclarecer o parágrafo acima com o seguinte: não estou argumentando que não se deva implementar os algoritmos que ele aprende em tal turma. Na verdade, ele deveria ser, e os alunos são encorajados a fazê-lo. O que estou argumentando é que, por causa de um equívoco fundamental sobre o que significa "design e análise de algoritmo", não é incomum ter pessoas inscrevendo-se em uma aula esperando algo diferente do que recebem (e diferente do projeto e análise de algoritmo). Implementar um algoritmo de caminho mais curto e verificar se ele calcula os caminhos mais curtos para um grande número de casos de teste é ótimo e, provavelmente, ajudará a entender melhor o algoritmo. No entanto, isso não constitui uma prova formal de correção e a prova de correção, assim como a implementação prática, também é importante. Isso é o que eu estou tentando chegar aqui; não que as coisas práticas não sejam importantes (elas são, na verdade, da maior importância), mas que as coisas teóricas não são apenas uma perda boba e pedante de tempo, mas são fundamentalmente importantes por si mesmas (e dignas de estudo). Além disso, a classe em si incorpora atribuições de programação. No entanto, elas são excedidos em número em frequência e foco por outros trabalhos de casa escritos.
No entanto, além de sua conexão com a base teórica da computação (ou seja, o cálculo Lambda), as linguagens de programação reais têm tão pouco a ver com a Ciência da Computação quanto, novamente, os telescópios têm a ver com a Astronomia. As linguagens de programação são extremamente importantes, e sua velocidade, expressividade e recursos fazem uma imensa diferença prática na construção de software eficiente e escalonável. Entretanto, do ponto de vista da Ciência da Computação, Haskell e BrainF* são equivalentes; Elas são linguagens Turing Completo o que significa que são capazes de realizar o mesmo conjunto de cálculos1. No entanto, o algoritmo é distinto como um objeto de design e estudo de qualquer implementação particular do mesmo. Essa percepção está na base da compreensão da diferença entre PC e CC. Ciência da Computação é matemática; é o estudo do que é computável e do que é eficientemente computável, e é sobre o projeto e a análise dos procedimentos que podem eficientemente computar as coisas. É possível projetar um algoritmo, provar sua exatidão e caracterizar seu tempo de execução sem inserir um caractere em um arquivo de código-fonte, e todas essas tarefas se encaixam perfeitamente no campo da Ciência da Computação, mas nenhuma delas requer (ou exige) um pouco de programação. Agora, para tornar o algoritmo projetado útil, seria necessário implementá-lo e levar em conta considerações não apenas teóricas, mas também práticas (por exemplo, o algoritmo é assintoticamente eficiente ou realmente eficiente? Quais decisões de design e engenharia precisam ser tomadas para que a implementação seja prática para dados do mundo real?
Portanto, embora a programação e a implementação que se seguem sejam de suma importância, e embora constituam devida diligência para a maioria das pesquisas em CC, essas tarefas não são, elas próprias, da própria Ciência da Computação. Talvez possamos traçar outra analogia aqui também. O projeto e a análise do algoritmo (CC) podem ser semelhantes à descoberta do princípio de Bernoulli (deixando de lado questões importantes, mas filosóficas, relativas à invenção versus descoberta), enquanto a engenharia e implementação eficiente do algoritmo (PC) pode ser semelhante a construção de um aerofólio que opera com base no princípio. Não é uma ótima analogia (certamente não tão boa quanto a que envolve o telescópio), mas relaciona a diferença substancial entre as disciplinas relacionadas, mas absolutamente distintas, da Ciência da Computação e da Programação de Computadores.
Infelizmente, não acho que essa confusão seja algo que irá desaparecer tão cedo, já que os próprios programas de Ciência da Computação continuam a misturar CC e PC mais intensamente em seus currículos. Não é que essa mistura seja ruim, por si só. Na verdade, sem a capacidade de projetar e construir software (uma tarefa de PC), os graduandos em ciências da computação seriam muito menos empregáveis do que atualmente, embora talvez muitos continuem a fazer trabalhos teóricos na pós-graduação. No entanto, essa fusão das duas disciplinas confunde ainda mais a distinção entre elas, e torna ainda mais difícil explicar às pessoas em outros campos o que é a Ciência da Computação (ou seja, não é sobre Python, ou Matlab ou até mesmo programação em geral). Eu não sei como resolver este problema, mas sei que existe e que não parece estar indo embora tão cedo.


Notas:

1. Como apontado por Gasche na postagem do Reddit que vincula esta entrada do blog, a frase original não transmite a minha intenção real. Enquanto Haskell e BrainF* são equivalentes de uma perspectiva da Teoria da Computabilidade, e ambos representam um modelo Turing Completo de Computação, existem diferenças teóricas reais entre elas que não podem ser varridos para debaixo do tapete. Note, no entanto, que dado um interpretador BrainF*, pode-se escrever um compilador Haskell (o inverso também pode ser feito e tem). Há também, obviamente, um mundo de diferença prática entre eles, mas esse foi o ponto de levantar esses dois exemplos em primeiro lugar. O que eu realmente queria entender na diferença entre o algoritmo e a implementação desse algoritmo é o que é comumente captado pela notação de Landau (big-O), e a idéia central é colocada bem pelo comentário de Gasche no Reddit:
Isso transmite a ideia de que, embora um determinado programa possa estar funcionando consistentemente dez vezes mais rápido nesta máquina diferente ou com esse compilador diferente, decidimos abstrair esses detalhes e observar a maneira como o desempenho evolui em grandes entradas, e isso permite tirar conclusões que resistem a um avanço rápido no poder da máquina ou outras tecnologias (mas, é claro, às vezes você quer fazer análises mais refinadas do que isso, fazendo menos aproximações de uma maneira ainda científica, como quando trabalha, por exemplo em algoritmos alheios ao cache com um modelo refinado de máquina abstrata).
Portanto, o argumento é que o algoritmo descreve um procedimento para realizar algum cálculo que é amplamente independente de qualquer linguagem particular (semântica formal) e que é aplicável em uma ampla gama de modelos de computação. O projeto e análise do algoritmo lida diretamente com questões sobre a computabilidade e computabilidade eficiente (assintoticamente) da solução. Obviamente, para aplicar o algoritmo para resolver problemas do mundo real, uma implementação específica e a qualidade desta implementação são da maior importância. No entanto, o projeto e a análise do algoritmo podem ser realizados independentemente de qualquer implementação específica. Embora a teoria e a prática sejam frequentemente estudadas em conjunto e atuem sinergicamente, elas geralmente têm objetivos distintos e algumas vezes respondem a questões distintas.

Comentários

Postagens mais visitadas deste blog

Usando a Complexidade de Kolmogorov para resolver o Problema da Parada

Explicado: P vs. NP

O Vocabulista: Qual é a raiz da palavra computador?