A notação húngara é uma solução alternativa para idiomas com digitação estática insuficientemente expressiva? [fechadas]

28

No artigo de Eric Lippert What's Up With notation húngaro? , ele afirma que o objetivo da notação húngara (o tipo bom) é

estenda o conceito de "tipo" para incluir informações semânticas, além de informações de representação de armazenamento.

Um exemplo simples seria o prefixo de uma variável que representa uma coordenada X com "x" e uma variável que representa uma coordenada Y com "y", independentemente de essas variáveis ​​serem números inteiros ou flutuantes ou qualquer outra coisa, para que quando você escrever acidentalmente xFoo + yBar, o código parece claramente errado.

Mas eu também tenho lido sobre o sistema de tipos de Haskell, e parece que em Haskell, é possível realizar a mesma coisa (por exemplo, "estender o conceito de tipo para incluir informações semânticas") usando tipos reais que o compilador verificará por você. Portanto, no exemplo acima, o xFoo + yBarHaskell falharia na compilação se você projetasse seu programa corretamente, pois eles seriam declarados como tipos incompatíveis. Em outras palavras, parece que o sistema de tipos de Haskell suporta efetivamente a verificação em tempo de compilação equivalente à notação húngara

Então, a Notação Húngara é apenas um band-aid para linguagens de programação cujos sistemas de tipos não podem codificar informações semânticas? Ou a notação húngara oferece algo além do que um sistema de tipo estático como o de Haskell pode oferecer?

(Claro, estou usando Haskell como exemplo. Tenho certeza de que há outras linguagens com sistemas do tipo similarmente expressivo (rico? Forte?), Embora não tenha encontrado nenhum.)


Para ser claro, eu estou não falar de anotar os nomes das variáveis com o dados tipo, mas sim com informações sobre o significado da variável no contexto do programa. Por exemplo, uma variável pode ser um número inteiro ou flutuante ou duplo ou longo ou o que for, mas talvez o significado da variável seja que seja uma coordenada x relativa medida em polegadas. Este é o tipo de informação que estou falando sobre codificação via notação húngara (e via tipos Haskell).

Ryan C. Thompson
fonte
Pascal - embora se você tentar e adicione um XCood e YCoord tipo você definido no Pascal você só vai conseguir um compilador aviso IIRC
mcottle
11
blog.moertel.com/articles/2006/10/18/… é um artigo sobre como fazer algo muito semelhante a "apps hungarian" no sistema de tipos em Haskell.
Logan Capaldo
11
O F # também possui esse recurso de estilo.
Rangoric 11/11
Esse é um link muito bom para o artigo (o moertel.com) mostrando exatamente o tipo de coisa em que eu estava pensando: usar o sistema de tipos para transformar vulnerabilidades de segurança de interpolação de cadeias de caracteres em erros de compilação. Obrigado pelo link.
Ryan C. Thompson
Eu acho que durante muito tempo o OO alcançou a notação húngara para semântica, porque hoje você provavelmente escreveria: Foo.Position.X + Bar.Position.Y.
Pieter B

Respostas:

27

Eu diria "sim".

Como você diz, o objetivo da notação húngara é codificar informações no nome que não podem ser codificadas no tipo. No entanto, existem basicamente dois casos:

  1. Essa informação é importante.
  2. Essa informação não é importante.

Vamos começar com o caso 2 primeiro: se essa informação não é importante, a notação húngara é simplesmente ruído supérfluo.

O caso mais interessante é o número 1, mas eu argumentaria que se a informação é importante, ela deve ser verificada, ou seja, deve fazer parte do tipo , não do nome .

O que nos leva de volta à citação de Eric Lippert:

estenda o conceito de "tipo" para incluir informações semânticas, além de informações de representação de armazenamento.

Na verdade, isso não é "estender o conceito de tipo", é o conceito de tipo! O verdadeiro propósito de tipos (como uma ferramenta de design) é codificar informação semântica! Representação de armazenamento é um detalhe de implementação que, normalmente, não pertencem ao tipo em tudo . (E, especificamente, em um idioma OO não pode pertencer ao tipo, pois a independência de representação é um dos principais pré-requisitos para OO.)

Jörg W Mittag
fonte
C, onde a notação húngara foi mais usada pelo AFAIK, não é uma linguagem OO.
Péter Török 11/11
4
@ PéterTörök: OO é um padrão de design, não um recurso de um idioma, embora os idiomas modernos sejam projetados para facilitar, enquanto C não é.
Jan Hudec 11/11
3
@ PéterTörök: Eu escrevi bastante código orientado a objetos na linguagem C. Eu sei do que estou falando.
Jan Hudec 11/11
11
Embora possa ser verdade que informações importantes devem ser incorporadas ao tipo de uma variável e não ao nome, há muitas coisas importantes a serem ditas, mas quais sistemas de tipos não podem expressar. Por exemplo, se S1é a única referência em qualquer lugar do universo a um char[], cujo detentor pode e irá alterá-lo sempre que desejado, mas nunca deve expor a códigos externos, e S2é uma referência a uma char[]que ninguém jamais deve mudar, mas que pode ser compartilhada com objetos que prometem não mudar, deve S1e deve S2ser considerado semanticamente como o mesmo "tipo de coisa"?
Supercat
11
@ supercat - Você está descrevendo tipos de exclusividade.
21416 Jack
9

Todo o objetivo dos tipos (como uma ferramenta de design) é codificar informações semânticas!

Gostei desta resposta e queria acompanhá-la ...

Não sei nada sobre Haskell, mas você pode realizar algo como o exemplo de xFoo + yBarqualquer linguagem que suporte alguma forma de segurança de tipo, como C, C ++ ou Java. No C ++, você pode definir as classes XDir e YDir com operadores '+' sobrecarregados que apenas recebem objetos de seu próprio tipo. Em C ou Java, você precisaria fazer sua adição usando uma função / método add () em vez do operador '+'.

Eu sempre vi a notação húngara usada para informações de tipo, não semântica (exceto na medida em que a semântica pode ser representada por tipo). Uma maneira conveniente de lembrar o tipo de uma variável nos dias anteriores aos editores de programação "inteligentes" que exibem o tipo para você de uma maneira ou de outra diretamente no editor.

BHS
fonte
Ser orientado a objetos não é necessário nem suficiente para uma linguagem permitir xFoo + yBartipos definidos pelo usuário, nem o aspecto OO do C ++ é necessário para que esse exemplo funcione.
Luc Danton
Você está certo, não é OO, é tipo segurança. Eu editei minha resposta.
BHS
Hmm. É um bom ponto que você pode cometer xFoo + yBarum erro de compilação (ou pelo menos um erro de tempo de execução) em praticamente qualquer idioma. No entanto, a matemática com as classes XDir e YDir em, digamos, Java ou C ++ seria mais lenta que a matemática com números brutos? Meu entendimento é que, em Haskell, os tipos são verificados no tempo de compilação e, em tempo de execução, seria apenas matemática bruta sem verificação de tipo e, portanto, não é mais lento do que adicionar números regulares.
Ryan C. Thompson
No C ++, a verificação de tipo também seria feita em tempo de compilação, e a conversão e isso serão otimizadas na maioria dos casos. O Java também não faz isso, porque não permite a sobrecarga do operador e tal - portanto, você não pode tratar um XCoordinatecomo um int regular, por exemplo.
cHao 12/10
5

Percebo que a frase "Notação Húngara" passou a significar algo diferente do original , mas responderei "não" à pergunta. Nomear variáveis ​​com o tipo semântico ou computacional não faz o mesmo que a digitação no estilo SML ou Haskell. Não é nem um bandaid. Tomando C como exemplo, você pode nomear uma variável gpszTitle, mas essa variável pode não ter escopo global, pode até não constituir um ponto para uma cadeia terminada por nulo.

Penso que as notações húngaras mais modernas têm divergência ainda maior em relação a um sistema de dedução de tipo forte, porque misturam informações "semânticas" (como "g" para global ou "f" para bandeira) com o tipo computacional ("p" ponteiro ", i "número inteiro, etc etc.) Isso acaba sendo uma bagunça profana, onde os nomes de variáveis ​​têm apenas uma vaga semelhança com o tipo computacional (que muda com o tempo) e todos parecem tão semelhantes que você não pode usar a" próxima correspondência "para encontre uma variável em uma função específica - são todos iguais.

Bruce Ediger
fonte
4

A notação húngara foi inventada para o BCPL, uma linguagem que não possuía nenhum tipo. Ou melhor, tinha exatamente um tipo de dado, a palavra. Uma palavra pode ser um ponteiro ou um caractere ou um número inteiro booleano ou simples, dependendo de como você a usou. Obviamente, isso tornou muito fácil cometer erros horríveis, como desreferenciar um personagem. Assim, a notação húngara foi inventada para que o programador pudesse pelo menos executar a verificação manual do tipo, observando o código.

C, um descendente de BCPL, tem tipos distintos para números inteiros, ponteiros, caracteres etc. Isso fez com que a notação húngara básica fosse supérflua até certo ponto (você não precisou codificar no nome da variável se era um int ou um ponteiro), mas a semântica além desse nível ainda não pode ser expressa como tipos. Isso levou à distinção entre o que foi chamado de "sistemas" e "aplicativos" húngaro. Você não precisava expressar que uma variável era int, mas poderia usar letras de código para indicar se o int era uma coordenada digamos x ou y ou um índice.

Linguagens mais modernas permitem definições de tipos personalizados, o que significa que você pode codificar as restrições semânticas nos tipos, e não nos nomes das variáveis. Por exemplo, uma linguagem OO típica terá tipos específicos para pares de coordenadas e áreas, para evitar adicionar uma coordenada x a uma coordenada y.

Por exemplo, no famoso artigo de Joels elogiando o Apps Hungarian, ele usa o exemplo do prefixo uspara uma string insegura e spara uma string segura (codificada em html), para impedir a injeção de HTML. O desenvolvedor pode evitar erros de injeção de HTML, basta inspecionar cuidadosamente o código e garantir que os prefixos das variáveis ​​correspondam. Seu exemplo está no VBScript, uma linguagem agora obsoleta que inicialmente não permitia classes personalizadas. Em uma linguagem moderna, o problema pode ser corrigido com um tipo personalizado e, de fato, é isso que o Asp.net faz com a HtmlStringclasse. Dessa forma, o compilador encontrará automaticamente o erro, o que é muito mais seguro do que confiar nos olhos humanos. Então, claramente, um idioma com tipos personalizados elimina a necessidade de "Apps Hungarian" nesse caso.

JacquesB
fonte
2

Sim, embora muitos idiomas que possuem sistemas de tipos suficientemente fortes ainda tenham um problema - expressibilidade de novos tipos baseados em / semelhantes aos tipos existentes.

ou seja, em muitas línguas em que poderíamos usar mais o sistema de tipos, não o fazemos, porque a sobrecarga de criar um novo tipo que é basicamente o mesmo que um tipo existente que não seja o nome e algumas funções de conversão é muito grande.

Essencialmente, precisamos de algum tipo de typedefs fortemente tipados para eliminar a notação húngara completa nesses idiomas (a UoM no estilo F # também pode fazê-lo)

jk.
fonte
2

Lembre-se, houve um tempo em que os IDEs não tinham dicas de pop-up dizendo o que eles digitam de uma variável. Houve um tempo em que os IDEs não entendiam o código que estavam editando, então você não podia pular do uso para a declaração facilmente. Houve também um tempo em que você não podia refatorar um nome de variável sem passar manualmente por toda a base de código, fazendo a alteração manualmente e esperando que não perdesse uma. Você não pôde usar a pesquisa e a substituição, porque pesquisar pelo Cliente também o leva a CustomerName ...

Naqueles dias sombrios, era útil saber que tipo de variável estava onde estava sendo usada. Se mantido adequadamente (um GRANDE se por causa da falta de ferramentas de refatoração), a notação húngara forneceu isso.

Atualmente, o custo dos nomes horríveis que produz é muito alto, mas isso é relativamente recente. Ainda existe muito código que antecede os desenvolvimentos do IDE que descrevi.

mcottle
fonte
11
Se não me engano, essa é outra resposta que aborda um tipo diferente de notação húngara daquela que o OP está perguntando.
MatrixFrog
2
Esta resposta descreve o que foi chamado de "Sistemas Húngaro", em que o prefixo indica o "tipo" no nível do idioma. A pergunta é sobre "Apps Hungarian", onde a palavra "type" não foi mal interpretada e significa o tipo semântico . Atualmente, o sistema húngaro é quase universalmente condenado (e com razão; é uma bastardização do real objetivo da observação húngara). Aplicativos húngaros, no entanto, podem ser uma coisa boa.
Chao
Os editores capazes de pesquisar pelo sCustomer sem selecionar o sCustomerName (vi e emacs são 2 exemplos) existem desde os anos 70.
Larry Coleman
@ Larry, talvez, mas você não podia fazê-los rodar nos sistemas que eu estava programando nos anos 80
mcottle
@cHAo, não, não - meu argumento foi tentar explicar por que as pessoas colocam as informações extras em nomes de variáveis ​​em geral. Eu evitei mencionar estudiosamente qualquer versão da notação húngara. Talvez o exemplo que eu dei na seção "por que pesquisar e substituir não funcione no código fonte" pareça a você como "Systems Hungarian", mas não foi feito para isso. Eu apaguei os "s" principais para evitar a confusão.
Mcottle
0

Corrigir!

Fora de idiomas totalmente não tipados, como o Assembler, a notação húngara é supérflua e irritante. Duplamente, quando você considera que a maioria dos IDEs verifica o tipo de segurança à medida que você er.

Os extras "i" "d" e "?" os prefixos tornam o código menos legível e podem ser realmente enganosos - como quando um "cow-orker" altera o tipo de iaSumsItems de Inteiro para Longo, mas não se incomoda em refatorar o nome do campo.

James Anderson
fonte
9
Sua resposta sugere que você não entende a diferença entre o "Apps" húngaro original e inteligente e a bastardização idiota chamada "Systems" Hungarian. Leia joelonsoftware.com/articles/Wrong.html
Ryan Culpepper