4 ms·
To me this looks like perl golfing, but for some reason perl golfing is bad but writing extremely terse functional programs is not. Personally I like to combin
by yoz-y 7y ago
To me this looks like perl golfing, but for some reason perl golfing is bad but writing extremely terse functional programs is not.
Personally I like to combine both approaches. In swift I would write something like this:
let l = ["abc", "ab", "abcdef", "abcdefgh"]
width = l.reduce(0, { max($0, $1.count) })
let centered = l.map({
(line: String) -> String in
var padding = (width - line.count) / 2
return String(repeating:" ", count: padding) + line
})
- jimbokun 7y ago"To me this looks like perl golfing" I think that's preposterous and totally unfounded. The identifiers have names like "alignCenter", "replicate", "maximum" and "length". Those are all actual full English words, nothing remotely obfuscated about them. "map", "++" for concatenation, and "x/xs" for an arbitrary list of things are all idiomatic so can be kept short because they are used so often, like pronouns in English. Lastly, your program looks very similar (almost isomorphic) to the Haskell version, so I think it's just dumb you use it as an argument to criticize the Haskell version as "extremely terse".
- yoz-y 7y agoOk. My problem with functional programming written like this (I admit that this example is too short) is that once there are too many functions combining with other functions it is very easy to lose thread of what is happening. My comparison with perl is more to the point that these programs are way easier to write than read. Again, this example is too simplistic to illustrate my point, but what I like with combining imperative and functional programming is that it is easier to keep trace of what is happening by using intermediate variables that hold the state and thus break the chain of functions.
- nyberg 7y agoThat is why the importance of being terse but following the rule of not going too far with nesting and pointfree is so valuable. I don't share your difficulty to follow the flow of the program as usually the name of the function, type, and documentation say all you need to know about it. That said, I find it difficult to follow what is happening when using several variables as you're then likely doing something wrong in the complexity of the function. A function should say much with very little and control flow should be clear instantly. The only thing outside of this would be a procedure which do-notation allows one to express. Imperative programming is already within Haskell with do-notation an it's composition is that of imperative. Mixing functional with something else makes it much harder to make use of combinators and other forms which ends in more messy code (in my experience). If one could go pure functional without do-notation emulating the "C monoid" it would be rather nice.
- robocat 7y agoIt does look like APL or Perl without enough understanding of Haskell (which I know very little about). I am guessing you have some experience writing Haskell code, so it looks clear to you. The example used idiomatic one or two letter variable names (x, n, xs) which I found difficult to read. The rewritten example was much clearer to me because I could see the variables.
- Koshkin 7y ago> $0, $1
- deleted 7y ago[deleted]
- 0xcoffee 7y agoObligatory C#: var input = new string[] { "abc", "ab", "abcdef", "abcdefgh" }; var maxLength = input.Select(e => e.Length).Max(); var output = input.Select(e => { var padding = (maxLength - e.Length) / 2; return new String(' ', padding) + e; }); Most modern `oop` languages these days all support functional constructs and achieve the same thing in same amount of code & style. Language and oop/functional style are not mutually exclusive anymore, which this article seems to overlook by comparing both languages and styles at the same time.
- rienbdj 7y agoSadly C# is still missing a few important ML features that making functional programming more difficult than in a true ML.
- n4r9 7y agoIt would be interesting if you could mention which feature/s you think it most sorely lacks. Some of the recent syntax additions have made it really easy to write concise functional code. I don't even use curly braces much anymore. What about f#?
- fnord123 7y agoThis looks like the Java if the Java was written by someone who knows Java: List<String> alignText(List<String> texts) { int maxLength = texts.stream().mapToInt(String::length).max().orElse(0); return texts.stream().map(text -> { var spaceCount = (maxLength - text.length()) / 2; return " ".repeat(spaceCount) + text; }).collect(Collectors.toList()); }
- saagarjha 7y agoPersonally, I’d replace width = l.reduce(0, { max($0, $1.count) }) with l.map { $0.count }.max()
- yoz-y 7y agoMuch better indeed!
- sorokod 7y agoand in Kotlin fun alignLines(lines: List<String>): List<String> { val maxLength = lines.map { it.length }.max()!! return lines.map { " ".repeat((maxLength - it.length) / 2) + it } }
- tome 7y ago> for some reason perl golfing is bad but writing extremely terse functional programs is not Because the Haskell has types checking that you're not doing anything completely stupid.