Olá pessoal. Tudo certo?!
No meu último snippet, propus o seguinte código:
var result = string.Join(@"\", that.Split('\\', '/')
.Reverse()
.SkipWhile(s => s == String.Empty)
.Skip(1)
.Reverse().ToArray()
);
O que ele faz? Ele “remove” o último segmento de um caminho (ex: se that = “c:\Program Files\MyProgram\” [ou , “c:\Program Files\MyProgram”], result será “c:\Program Files”).
Abaixo, uma implementação alternativa proposta pelo Alexandre Choffi.
var tmp = that.Trim().Replace('/', '\\');
if (tmp.Substring(tmp.Length - 1, 1) == @"\")
tmp = tmp.Substring(0, tmp.Length - 1);
int index = tmp.LastIndexOf('\\');
var result = tmp.Substring(0, index);
Trata-se de uma abordadegem imperativa.
A segunda é realmente mais fácil que a primeira? Seria apenas questão de hábito?
A favor da versão imperativa pode-se dizer que é mais próxima de como o computador funciona e facilita a depuração. Isso vai ser útil para entender porque ela gera ArgumentOutOfRangeException quando “that” é “C:\”.
Concordo com você.
Entretanto, a versão funcional se aproxima da forma como matemáticos veem a solução. Além disso, não tem side-effects.
O modo imperativo é mais fácil de entender para a maioria, porém, o código funcional, para este caso, ficou mais enxuto e elegante, o que em minha opinião o torna um mais simples para quem já conhece este paradigma.
Preciso comentar? Não há comparação.
Respondendo pelo Choffi (que não conseguiu postar por alguma “treta” do meu wordpress)
“Vidal, discordo!
Fiz um teste aqui e no pior caso a abordagem funcional teve uma performance 8 vezes pior do que a imperativa. Utilizei exatamente os códigos mostrados no post do Elemar. Claro que a imperativa não esta completa, fácilmente ocorrerá uma exception, mas acredito ser o suficiente para uma comparação de performance.
Na abordagem funcional o código é mais simples em termos de comandos, mas a imperativa é mais clara para um “programador leigo”.
Me corrijam se eu estiver viajando muito, mas não são todas as faculdades de computação (ciência, engenharia ou sistemas) que mostram a abordagem funcional profundamente. A abordagem funcional é menos manutenível(palavra bonita) por menos pessoas conhecerem este paradigma.
E performance deve ser levada em consideração!”
Eu acho que há lugar para os dois, a abstração do modelo funcional fica muito mais fácil a leitura e interpretação, portanto no fim tudo é bem imperativo. Depende do contexto onde os códigos estão pra saber qual ficaria mais fácil ou não.
Vidal, discordo!
Fiz um teste aqui e no pior caso a abordagem funcional teve uma performance 8 vezes pior do que a imperativa. Utilizei exatamente os códigos mostrados no post do Elemar. Claro que a imperativa não esta completa, fácilmente ocorrerá uma exception, mas acredito ser o suficiente para uma comparação de performance.
Na abordagem funcional o código é mais simples em termos de comandos, mas a imperativa é mais clara para um “programador leigo”.
Me corrijam se eu estiver viajando muito, mas não são todas as faculdades de computação (ciência, engenharia ou sistemas) que mostram a abordagem funcional profundamente. A abordagem funcional é menos manutenível(palavra bonita) por menos pessoas conhecerem este paradigma.
E performance deve ser levada em consideração!
Alexandre, interessante seu pensamento sobre o conhecimento que vem da faculdade e o conhecimento da engenharia de software em si.
Apesar do termo funcional usado no post, de fato não estamos falando de desenvolvimento funcional, só de um “padrão de projeto”, que na minha opinião é muito melhor para se trabalhar com listas. Padrões de projetos se aprendem num catalogo, facin facin, sou mais você ou qualquer um que goste de programar.
Eu acredito que se um código é mais fácil de ler, ele é mais manutenível (talvez ele não seja tão “debugável”, mas você pode quebrar essa operação em várias operações atômicas até ter formado o seu conceito e depois reuni-la em apenas uma).
Trabalhar com strings normalmente exige muitos ifs e checagens que tem uma GRANDE chance de trazer erros junto com elas. Tudo isso é abstraído nessa versão “monádica” da solução.