6 ms·
I'm not sure it is that concise. Just look at the code that you've given. What is it actually doing? How much of it is the juicy part and how much is the lang
by dchichkov 12y ago
I'm not sure it is that concise. Just look at the code that you've given. What is it actually doing? How much of it is the juicy part and how much is the language clutter? To me, it feels like in terms of the actual functionality this code does not do that much. Skips the text before first "+++". In more concise languages that whole piece would look like a single line:
env.lines = [line for line in env.lines if not line.startswith("+++")]
And just look at this:
when String.length line > 4 && String.sub line 0 3 = "+++"
Really? Specifying numbers like that in the code? And are we really going to alloc an object here? Wow. Wouldn't anyone prefer to use something like:
line.startswith("+++") ?
edit: my code doesn't implement the exact same functionality. I've only attempted to give a feel/look of the code, not rewrite it. it looks like the original code returns the lines after the '+++' lines, but I can not tell for sure, as the header/modified function implementations are not given.
- dragonwriter 12y ago> In more concise languages that whole piece would look like a single line: --- env.lines = [line for line in env.lines if not line.startswith("+++")] --- I don't think that's what its actually doing. I think its actually return all the lines after the first line that starts with "+++". Or maybe all those lines but the first. (I don't think its a good example of clear FP code, either.)
- codygman 12y agoTo this Haskeller it appears to be keeping state as well.
- dllthomas 12y agoCertainly some information is moving behind the scenes, given the "header ... ; modified ..."
- dllthomas 12y agoYeah, in Haskell I'd probably have done something like dropWhile (not . T.isPrefixOf "+++") >>> \case [] -> return () (line:lines) -> do header env line modified env 0 lines edited to add: code above assumes LambdaCase and OverloadedStrings extensions, and that you've imported Data.Text qualified as T
- thinkpad20 12y agolambdacase is one of my favorite extensions :D
- dllthomas 12y agoI really like ScopedTypeVariables
- codygman 12y agoI'm pretty sure the Ocaml code is doing more than the Python code you posted. Hopefully someone who knows Ocaml can explain it to us and then we can write the actual python equivalent.
- dchichkov 12y agoErr. Ok. Just look at this. Is that concise? when String.length line > 4 && String.sub line 0 3 = "+++" Specifying numbers like that in the code? Allocating an object? Wow. I don't understand why anyone wouldn't prefer to use something like: line.startswith("+++")
- magnusjonsson 12y agoThe ocaml standard library is minimal to a fault. It's just enough to implement the compiler itself. For higher level operations like starts_with, you use libraries. The Batteries library for example provides what you want: String.starts_with line "+++"
- dchichkov 12y agoNote, that the original code reads: when String.length line > 4 && String.sub line 0 3 = "+++" And the Batteries library is not being used in the original code. If that doesn't tell you anything, I'm sorry. And good luck.
- magnusjonsson 12y agoIt's a problem. Until people have standardized on which 'better standard library' to use, programs will keep building from these too low level building blocks.
- dchichkov 12y agoIt is a style, not a problem. OCaml had been there a long long time. I've brushed with it a couple of times over the years, and every time the same thing. You look at some random OCaml code, and it looks like this: when String.length line > 4 && String.sub line 0 3 = "+++" I'm looking at it, and I'm not even sure - is it a bug there? Should it be '>=3' or they've really wanted to say '> 4'. Numbers all other the place? Ten different variants of equal signs?
- sampo 12y ago> looks like the original code returns the lines after the '+++' lines, but I can not tell for sure, as the header/modified function implementations are not given Actually from the line | [] -> () we know that the function `start`returns nothing (well, returns a special value 'unit' which is OCaml's way to say nothing), so also the functions `header` and `modified` inside must return nothing, so they are called for their side effects only.
- dragonwriter 12y ago> we know that the function `start`returns nothing Which is cool, but start is a (recursive) helper function for the go function (and if you look at the source file, there are a number more that are defined along with it, this is kind of a weird excerpt to just show the main go function and the first of several helpers), which is be the main public interface being defined in the code presented. I wasn't trying to describe what it looked like start did when called, but what it seemed like go was trying to do. (And, I was doing so looking just at the excerpt and going a bit off the cuff; its clearly, looking at the source file, doing a lot more.)
- Dn_Ab 12y agoYour code is not doing the same thing. A few minor bits; env has no 'lines' in its definition and String.sub does not allocate objects: it's better to think of String.sub, String.length, etc. as functions packaged in a module of helpful combinators. OCaml is a language with currying and higher order functions, all that power is wasted if instead of composition you `.Objected` into everything. The advantages of piping, currying and composition on first class functions simply cannot be overstated. Okay, so the next thing, from String.sub line 0 3 it's clear that you need to know the string length, hence the > 4 can't be avoided. You could pack it away into a function but why waste time if you're not going to write this 3 or more times? The function `start` takes an env, a string list and returns unit. It's a procedure. The function looks for a string that starts with "+++" and either fails to find and returning () else passes to `modified` (also a procedure, tail recursive) which goes through the list (line :: lines returns the head and the tail of the list) applying modifications to env by tracking which lines were modified. `Lines` is an integer list and `result` is an integer pair list, so hopefully it's clearer now why your code is doing something completely different.