Fico confuso com as funções min e max, em certos contextos.
Em um contexto, quando você está usando as funções para obter o maior ou o menor de dois valores, não há problema. Por exemplo,
//how many autographed CD's can I give out?
int howManyAutographs(int CDs, int Cases, int Pens)
{
//if no pens, then I cannot sign any autographs
if (Pens == 0)
return 0;
//I cannot give away a CD without a case or a case without a CD
return min(CDs, Cases);
}
Fácil. Mas em outro contexto, fico confuso. Se estou tentando definir um máximo ou um mínimo, entendo de trás para frente.
//return the sum, with a maximum of 255
int cappedSumWRONG(int x, int y)
{
return max(x + y, 255); //nope, this is wrong
}
//return the sum, with a maximum of 255
int cappedSumCORRECT(int x, int y)
{
return min(x + y, 255); //much better, but counter-intuitive to my mind
}
É desaconselhável fazer minhas próprias funções da seguinte maneira?
//return x, with a maximum of max
int maximize(int x, int max)
{
return min(x, max);
}
//return x, with a minimum of min
int minimize(int x, int min)
{
return max(x, min)
}
Obviamente, o uso dos componentes internos será mais rápido, mas isso me parece uma microoptimização desnecessária. Existe alguma outra razão pela qual isso seria desaconselhável? E em um projeto de grupo?
design
functions
readability
Devsman
fonte
fonte
std::clamp
função C ++ 11 ou algo semelhante.up_to
(paramin
) eat_least
(paramax
)? Eu acho que eles transmitem o significado melhor do queminimize
etc., embora possa levar um momento para entender por que eles são comutativos.min
eemax
tambémminimize
emaximize
são nomes totalmente errados para as funções que você deseja escrever. O padrãomin
emax
faz muito mais sentido. Você na verdade QUASE acertou os nomes das funções. Essa operação é chamada de fixação ou nivelamento e você escreveu duas funções de nivelamento. Eu sugirocapUpperBound
ecapLowBound
. Não preciso explicar a ninguém qual faz qual, é óbvio.Respostas:
Como outros já mencionaram: não crie uma função com um nome semelhante ao de uma função interna de biblioteca padrão ou de uso geral, mas mude seu comportamento. É possível se acostumar com uma convenção de nomenclatura, mesmo que não faça muito sentido para você à primeira vista, mas será impossível argumentar sobre o funcionamento do seu código depois de introduzir as outras funções que fazem a mesma coisa, mas que têm seus nomes trocados.
Em vez de "sobrecarregar" os nomes usados pela biblioteca padrão, use novos nomes que transmitam exatamente o que você quer dizer. No seu caso, você não está realmente interessado em um "mínimo". Em vez disso, você deseja limitar um valor. Matematicamente, esta é a mesma operação, mas semanticamente, não é bem. Então, por que não apenas uma função
isso faz o que é necessário e diz isso pelo nome. (Você também pode implementar
cap
em termos demin
como mostrado na timster de resposta ).Outro nome de função usado com freqüência é
clamp
. São necessários três argumentos e “prende” um valor fornecido no intervalo definido pelos outros dois valores.Se você estiver usando um nome de função geralmente conhecido, qualquer nova pessoa que se juntar à sua equipe (incluindo o futuro em que voltará ao código depois de um tempo) entenderá rapidamente o que está acontecendo, em vez de xingar você por tê-lo confundido, quebrando o expectativas sobre nomes de funções que eles pensavam que sabiam.
fonte
clamp
é usado extensivamente em todos os tipos de processamento de sinal e operações semelhantes (processamento de imagem etc.), então é definitivamente com isso que eu também iria. Embora eu não diria que isso exige limites superior e inferior: eu já o vi muitas vezes apenas por uma direção.clamp
Também ia mencionar . E se estiver escrito corretamente, você poderá usar apenas um limite de infinito / infinito negativo para quando você quiser apenas um limite. Por exemplo, para garantir que um número não seja maior que 255 (mas sem limite inferior), você usariaclamp(myNumber, -Infinity, 255)
.Se você criar uma função como aquela em que
minimize(4, 10)
retorna 10 , eu diria que isso é desaconselhável, porque seus colegas programadores podem estrangular você.(Ok, talvez eles não o estrangulem literalmente até a morte, mas sério ... Não faça isso.)
fonte
DO NOT
(fora de "NÃO fie, dobre ou mutile"). Alguém que implementasse algo assim receberia um cartão.Aliasing uma função é bom, mas não tente alterar o significado dos termos existentes
Não há problema em criar um alias da função - bibliotecas comuns fazem isso o tempo todo .
No entanto, é uma má idéia usar termos de maneira contrária ao uso comum, como o seu exemplo, onde você imagina que max e min devem ser invertidos. É confuso para outros programadores, e você fará um desserviço treinando a si mesmo para continuar interpretando esses termos de maneira não-padrão.
Portanto, no seu caso, abandone o jargão "mínimo / máximo" que achar confuso e crie seu próprio código fácil de entender.
Refatorando seu exemplo:
Como um bônus adicional, toda vez que você olhar esse código, estará se lembrando de como min e max são usados na sua linguagem de programação. Eventualmente, isso fará sentido em sua cabeça.
fonte
min
emax
que confunde o OP. É quandomin
é usado para definir um limite superior fixo em algum valor.get_lower_value
seria tão contra-intuitivo nesta aplicação. Se eu escolhesse um nome alternativo para esta operação, eu o chamaria supremo , embora não tenha certeza de quantos programadores entenderiam isso imediatamente.supremum
da funçãoget_lower_value
definida acima para chamar apenasmin
. Isso faz com que o próximo programador seja exatamente o mesmo problema que chamá-lomaximise
. Eu sugiro chamá-loapply_upper_bound
, mas não tenho certeza de que seja perfeito. Ainda é estranho porque funciona da mesma maneira que você coloca os parâmetros, mas o nome implica que um dos parâmetros é "o valor" e o outro é "o limite", e que de alguma forma são diferentes.Eu amo essa pergunta. Vamos acabar com isso.
1: Você deve agrupar uma única linha de código?
Sim, posso pensar em muitos exemplos em que você pode fazer isso. Talvez você esteja aplicando parâmetros digitados ou ocultando uma implementação concreta atrás de uma interface. No seu exemplo, você está essencialmente ocultando uma chamada de método estático.
Além disso, você pode fazer muitas coisas em uma única linha atualmente.
2: Os nomes 'Min' e 'Max' são confusos
Sim! Eles são totalmente! Um guru de codificação limpo os renomeia como "FunctionWhichReturnsTheLargestOfItsParameters" ou algo assim. Felizmente, temos documentação e (se você tiver sorte) IntelliSense e comentários para nos ajudar, para que qualquer pessoa que esteja confusa com os nomes possa ler o que deve fazer.
3: Você deve renomeá-los para outra coisa você mesmo.
Sim, vá em frente. Por exemplo, você poderia ter:
Acrescenta significado e o chamador não precisa ou deseja saber como calcular o valor.
4: você deve renomear "min" para "maximizar"
Não!! és maluco?! Mas sim, a pergunta sublinha o fato de que pessoas diferentes leem significados diferentes em nomes de funções e objetos. O que uma pessoa acha claro e convencional, a outra acha opaca e confusa. É por isso que temos comentários. Você deve escrever:
Então, quando alguém lê
eles sabem que você cometeu um erro.
fonte
FunctionWhichReturnsTheLargestOfItsParameters
são uma coisa boa, não quero fazer parte dele.FunctionWhichReturns
na frente de todas as funções (que não lançam uma exceção ou terminam). Você pode acabar comgetMinimum
,getLarger
(ougetLargest
com mais de 2 entradas), porém, seguindo o conselho real, ao longo das linhas de que (a) funções puras e / ou "getters" deve usar a verrugaget
, palavras (b) inglês não devem ser abreviados em nomes. Claramente, isso é muito detalhado para aqueles que decidem chamar essas funçõesmax
.Não . Não crie funções com nomes muito semelhantes às funções internas, mas que na verdade fazem o oposto . Pode parecer intuitivo para você, mas vai ser muito confuso para outros desenvolvedores e até para você mesmo em algum momento no futuro, quando você tiver mais experiência.
O significado de
max
é "o máximo de", mas seu entendimento "intuitivo" é algo como "o máximo de". Mas isso é simplesmente um entendimento errado da função, e alterar o nome demax
paramaximum
não comunica sua interpretação diferente. Mesmo que você acredite firmemente que os designers de idiomas cometeram um erro, não faça algo assim.Mas mudar o nome para dizer
cap(x, limit)
como foi sugerido seria bom, pois ele comunica claramente a intenção, mesmo que apenas envolvamin
.fonte
O que pode ser confuso é usar Capped no nome da sua função ou entender o que significa colocar uma tampa. É um limitador e não requer um máximo de nada.
Se lhe for pedido o menor, o menor ou o mais antigo, você acha que Max é a função apropriada?
Deixe min e max em paz. Faça testes para, pelo menos, corrigi-lo na segunda vez.
Se você precisar usar muito essas funções em seu projeto, terá uma dica para ajudá-lo a esclarecer qual delas usar. Mais ou menos como <ou>, a parte mais larga da boca está voltada para o valor maior.
fonte
max
função é mais apropriada, mas em termos de lógicamin
é o que ele está realmente procurando.Para responder à sua pergunta: Existe alguma outra razão pela qual isso seria desaconselhável? E em um projeto de grupo? Faz sentido que você queira suas próprias funções, o que não é problema. Apenas certifique-se de que eles estejam em sua própria classe auxiliar e não sejam facilmente chamados para outras pessoas, a menos que sejam importados. (Joes.Utilities.)
Mas, olhando novamente para o seu problema, basicamente eu estaria pensando:
Você está ficando confuso porque está tentando aplicar a lógica do seu cérebro a essas funções mín. / Máx. Em vez disso, basta falar em inglês.
if
o contrárioinput
é o .greater than or equal to 255
then
return 255
return
input
Qual é:
Minha opinião. Você está usando as funções max \ min pelas razões erradas, a velocidade dessas coisas é insignificante. Faça o que faz sentido.
fonte
Enquanto eu entender o seu problema, ficaria relutante em fazer isso. Seria melhor simplesmente perfurar seu crânio o que min () e max () fazem.
A maioria dos programadores sabe o que as funções min () e max () fazem - mesmo que, como você, às vezes eles lutem com sua intuição sobre a qual usar a qualquer momento. Se estou lendo um programa e vejo max (x, y), sei imediatamente o que ele faz. Se você criar sua própria função "alias", qualquer pessoa que esteja lendo seu código não saberá o que esse alias faz. Eles precisam encontrar sua função. Isso interrompe desnecessariamente o fluxo de leitura e força o leitor a pensar melhor para entender seu programa.
Se você tiver problemas para descobrir qual usar em algum momento, eu diria, adicione um comentário explicando isso. Então, se um futuro leitor estiver igualmente confuso, seu comentário deve esclarecer. Ou, se você fizer errado, mas o comentário explicar o que você estava tentando fazer, a pessoa que tentar depurá-lo terá uma pista.
Depois que você alias uma função, porque o nome entra em conflito com sua intuição ... esse é o único caso em que isso é um problema? Ou você vai alias outras funções? Talvez você esteja confuso com "ler" e ache mais fácil pensar nisso como "aceitar", altere "anexar" para "StringTogether", "arredondar" para "DropDecimals" etc. etc. Leve isso a um extremo ridículo e seus programas serão incompreensíveis.
De fato, anos atrás eu trabalhei com um programador que não gostou de toda a pontuação em C. Então ele escreveu várias macros para deixá-lo escrever "THEN" em vez de "{" e "END-IF" em vez de "}" e dezenas de outras substituições. Então, quando você tentou ler os programas dele, nem parecia mais C, era como ter que aprender um idioma totalmente novo. Não me lembro agora se "AND" foi traduzido para "&" ou "&&" - e esse é o ponto. Você prejudica o investimento que as pessoas fizeram para aprender o idioma e a biblioteca.
Dito isto, eu não diria que uma função que não faz nada além de chamar uma função de biblioteca padrão é necessariamente ruim. Se o objetivo da sua função não é criar um alias, mas encapsular um comportamento que por acaso é uma única função, isso pode ser bom e adequado. Quero dizer, se logicamente e inevitavelmente você precisar fazer um máximo nesse ponto do programa, basta ligar diretamente para max. Mas se você precisar executar algum cálculo que hoje exige um máximo, mas que possa ser modificado no futuro para fazer outra coisa, uma função intermediária será apropriada.
fonte
Não há problema em renomear funções internas, desde que os novos nomes tornem seu código muito claro e não serão esquecidos por ninguém. (Se você estiver usando C / C ++, não use um #define, pois fica difícil ver o que está acontecendo.) O nome de uma função deve funcionar como um comentário explicando o que o código de chamada está fazendo e por que está fazendo. .
Você não é a única pessoa que teve esse problema com min e max, no entanto, ainda estou vendo uma boa solução geral que funciona em todos os domínios. Eu acho que um problema com a nomeação dessas funções é que os dois argumentos têm significados lógicos diferentes, mas são apresentados como significando o mesmo.
Se o seu idioma permitir, você pode tentar
fonte
Não.
Você não escreve seus invólucros. Os nomes desses invólucros não são muito significativos.
O que você está tentando fazer é uma ofuscação de código gentil. Você está inventando uma camada extra que serve a dois propósitos:
Escondendo coisas com as quais você não se sente confortável, estará prejudicando seu código agora e a si mesmo no futuro. Você não pode crescer ficando na sua zona de conforto. O que você precisa é aprender como
min
emax
trabalhar.fonte
Tudo bem, e não é realmente contra-intuitivo usar Min, Max para controlar mais e menos. Isso também é feito usando:
No firmware, ele remonta à MMX, que antecede os modernos gráficos 3D que se baseiam nesse extensivo recurso.
Substituir uma função padrão da indústria, mesmo localmente, me preocuparia, um nome derivado pode ser melhor. Os alunos de C ++ podem sobrecarregar sua turma obscura, talvez.
fonte
É bom em alguns casos, mas não no seu exemplo, porque há maneiras muito melhores para a palavra-lo:
saturate
,clamp
,clip
, etc.fonte
Prefiro criar uma função genérica chamada 'bounded'
ou com o uso de 'min' e 'max'
fonte
Que tal chamar suas funções:
atmost(x,255)
: retorna o menor de x ou 255 no máximo.atleast(10,x)
: retorna o valor mais alto de x ou pelo menos 10.fonte
min(x+y, MAX_VALUE);
traria muito mais significado do quemyCustomFunction(x, y);
Portanto, a resposta é SIM, é desaconselhável . Serve apenas como um apelido para a linguagem do seu cérebro.
fonte