Re. GUIs for git, have you taken a look at GitKraken [1]? I haven't had the chance to put it through its paces, but it looks pretty good.
HN user
rakpol
Aah, sweet, someone else who uses Perforce! I've been wondering, do you use version control as:
1. a way to record logical changes to files (e.g. implement two features without making any commits, then when you're done, pick out the files/chunks that encode each feature and create commits out of them),
2. a record of history (e.g. just start writing code and make a commit every time you compile/run tests without unexpected failures),
3. something else?
I've found it very painful to apply my git-adapted workflow to Perforce: I _want_ to just start coding, testing out various possible design choices and implementations instead of only theorizing about them, but can't (e.g. "I wonder if I could factor out these methods + fields into a different class?" Perforce: oh well, I guess I should write it down somewhere to remember for later. Git: branch my current work, spend five minutes sketching an extraction, then realize it's insane and continue working). Am I crazy and just don't realize ow much better the Perforce model is?
Typo on your "R&D, Netizens" blurb: certyfication -> certification.
Thus the reason I know carpentry :3 but, having programmed for a while, it seems like the hardest problems are converting plain english requirements to source code. At the point that that becomes trivial (and doesn't fall into WYSIWYG editors or graphical languages, which already exist and haven't brought about the apocalypse), wouldn't you just ask the computer to make itself smarter over and over? Or ask it to automate any other profession with stupendous ease?
Isn't cyclomatic complexity just about the number of paths through code? It seems like (statically resolved) nested calls, as long as they don't loop or branch themselves, shouldn't increase cyclomatic complexity.
I was thinking about the issue of nested code the other day -- isn't it (mostly) an editing environment problem? I mean, if my IDE can detect that a method is pure, couldn't it do a little magic (e.g. provide a different coloured background, some dotted boxes, etc.) and show me the inlined code right there? It doesn't seem wise to architect your codebase around the deficiencies in your tools, since one is (hopefully) going to long outlive the other.
Related:
[1] https://dubroy.com/blog/method-length-are-short-methods-actu...
I agree to an extent ... this example is pretty contrived, but when you start getting around ten filter/map/groupby operations in, it gets a little difficult to follow what's supposed to be happening. So typically, my first step towards breaking it out into a method is separating out the individual streams like above. As is mentioned in a cousin comment, it also looks a lot nicer with type inferencing, but alas we are stuck with the verbosity of standard Java 8 for now.
Oh definitely, although I'll have to wait for it to be added to the JDK [1] in order to use that in anger :/ (outside of lombok)
Just to be clear, wouldn't the alternative with a monorepo still require that you go back and forth with multiple teams if the commit is not backwards compatible? It seems like the main complaint you have is that it's difficult to wrangle a number of related pull requests, so perhaps switching to something like gitcolony [1] for code reviews would help.
That's like the function composition operator [1] in Haskell, right? Very neat :D I wonder if there's an equivalent macro in Scala ...
[1] http://lambda.jstolarek.com/2012/03/function-composition-and...
From the perspective of a younger dev, this seems like excellent reading for older devs, who tend to enforce their personal style without deferring to the de facto language standards (or PEP 8 for those working in Python). In fact, perhaps everyone could do with downing a half dozen humble pills and optimize their code for harmonious human interoperability than anything to do with machines :)
As someone who could very easily be on the other side of that code review (and I'm preeeettty sure I'm not in this case?) I feel obliged to at least try to provide a counterpoint :).
So I agree that enormous blobs of unreadable crap are indeed unreadable, and that regardless of how neat and functional your code is, it can still be complete gibberish to most people. That being said, long chains of streams can be broken out quite nicely by using intermediate names:
e.g.
Comparator<Transaction> descendingTransactionsByValue = comparing(Transaction::getValue).reversed();
Stream<Transaction> groceries = transactions.filter(t -> t.getType() == Transaction.GROCERY);
Stream<Transaction> sortedGroceries = groceries.sorted(descendingTransactionsByValue);
Stream<Transaction> transactionids = sortedGroceries.map(Transaction::getId).collect(toList());
vs. the first code block under "Figure 1" in the linked article.For me at least, it helps keep code from getting too unruly: you only have one 'thing' you can do in a filter, map or sorted call, unlike in a foreach loop where anything can go. So my thesis is this: using streams I can quickly scan over the function/stream names to get the gist of what it's doing, but using foreach loops I need to closely examine each line to have any idea of what's happening :3 (e.g. people love abusing labeled breaks [1] in our codebase, as well as excessively modifying input parameters w/o documentation, so I might be a bit biased against for loops)
[1] https://stackoverflow.com/questions/14960419/is-using-a-labe...
Your original post mentioned that you thought the author was inappropriately associating low prices with low quality ... that's not prejudice, though, right? That's a bog-standard standard heuristic people in my culture use to establish value (see: putting weights in electronics to make them feel more 'premium'). IMHO, it is genuinely terrifying that melamine made it into so many chinese dairy products. Perhaps the media sensationalized it too much, making the event stand out in my memory over similar local events? Who knows.
I guess what I'm getting at is rushing to the conclusion that xenophobia is the only deciding factor here seems a bit premature, and that the problem itself is likely multifaceted.
Perhaps there's more to it than snobbery? Take, as an anecdote, this list of food safety incidents in China [1]. Whether or not that's comparable to the issues in the North American food supply chain, someone felt that there was enough concern surrounding the quality Chinese food to write an article about it. Food for thought.
[1] https://en.wikipedia.org/wiki/Food_safety_incidents_in_China
Super biased, layman thoughts incoming.
Re. countries vs corporations: countries in isolation make laws for themselves (consumer protection, long-term economic protection, etc.), whereas corporations must abide by the laws of their host countries (hence tax evasion via incorporation in accommodating countries). If two countries start to compete, there isn't really anything that stops them from annihilating one another in disturbing fashions (e.g. erecting walls, slinging propaganda, blockading, etc.) other than treaties. Get enough treaties together and you get the EU.
Yes, but I have ... reservations. Same as with OCaml, I took on a small project with Scala and enjoyed the language, but only after carving out a subset of it that was palatable. Although it fits the bill, I'd be worried that enforcing conventions would become a large burden.
Unlike Frege where I (might? Frege's the only language of the three that I haven't investigated thoroughly) can point learners to essentially any Haskell tutorial and have them vaguely do 'the right thing', there exists a subset of Scala developers who use the language like Java with type inference. With Frege I could, for example, merely enforce the minimal usage of IO or State, but doing so with Scala is more complicated (maybe force the usage of cats/scalaz and their equivalent monads? It's still very easy to not use them, however). If there were an equivalent to F# on the JVM I'd settle on it in a heartbeat, but the dearth of well supported, pure functional languages makes this a tough choice. All in all, I'll probably go with pure4j, but it would be nice to stop writing Java at some point in my career.
Aah, fair point, it is pretty niche. Still, merely going off of their comparative contribution graphs [1] [2] and issue trackers [3] [4], it seems like Frege has a fair bit more throughput: for better or for worse, it seems like more _things_ are happening. Although I'll be the first to admit it's a misleading metric for determining the maturity of a project, it's still something. Imagine finding a bug in Frege: it seems like they merge even small patches from contributors, whereas ocamljava is essentially a one man show. Adopting ocamljava would probably mean forking and maintaining it too, whereas there's a possibility of just contributing to Frege.
That's all just my opinion, of course, and I hardly have enough industry experience to back up its validity! 'Just sanity checking my reasoning :)
[1] https://github.com/Frege/frege/graphs/contributors
[2] https://github.com/xclerc/ocamljava/graphs/contributors
Fair point, but it might almost be worth it just to suggest it just to see what the opposition is like -- if there isn't much, or any, go with Frege; otherwise, fall back to pure4j. I'd imagine framing the decision as picking from two choices would improve the odds of at least one being selected.
The idea behind both would be to introduce it incrementally, carving out parts of the codebase to be rewritten one section at a time.
You're right, though; pure4j offers an immediate and easily obtainable win, so it'd definitely be an easier pill to swallow. Thanks :)
That definitely made the short list! I picked up ocaml for a side project and enjoyed the language quite a bit. However, ocamljava is either dead or dormant at this point (last commit to master in June of last year) and it seemed to only have had one major contributor -- it would seem irresponsible to adopt such a solution in light of that.
Hoping for a little advice: I'm trying to push for some development culture changes at work, one of which is doing more local, incremental refactors rather than large, all-at-once changes (i.e. the sort of thing for which one books 'architecture meetings'). Since we'll hopefully be massaging large parts of the codebase, there's an opportunity to jump into something new with both feet.
Question: what do you think of the thesis of pure4j [1] vis. frege [2]? Namely, are the advantages gained by switching to a haskell-like language far above those attained by simply forcing effects into a small part of the codebase?