Author here. A few have mentioned already, but this is to practice, to force you to understand what FP brings to the table, and lead you in path of discovery. When it comes to production code, you apply what you have learned, and make the decisions that you think more convenient. As an example, if you want certain performance gains on F# you do go to mutable state (Phil Trelford did a talk about it). Doesn't matter how pretty/OO/pure is the code if your application doesn't do what is supposed to ;-)
The people that talked about the rules at Codurance was none of the people that defined the original rules. We had to "reverse engineer" the thinking, find reasons and then discard, change or let as they were (one of the objectives of the write up was to put down those reasons). Explicit recursion did take a while. The reasoning we came with is to learn to use map/reduce functions (do take into account that our group has an ecletic knowdledge of FP and hybrid languages: Clojure, Haskel, Elixir, Scala, F#, ...). Can that binary search tree be converted into a linear search if you rearrange the tree into a list? Yes. Now you can use map /reduce. Is it performant? Most probably not. Are there other ways? Time to discover. Interestingly, most of the katas/exercises on which we are practicing these rules are not heavily algorithmic in nature. Maybe we do need to add some to understand better and modify the "rules" with the new knowledge.
In fact, a colleague that is reading SICP at the moment is the one that basically put the idea forward, as he was going through the whole idea of fold/map/unfold on the book exercises
You are right. If you don't follow most of those rules, you are not doing pure FP. My interest on them was because I was writing production code that felt procedural. The rules are there so you can practice with purpose. Once you go into production code, you can discard them, but with knowledge that it will not be because your OOP skills take over, but conscious decisions.
SOLD!!!!! I will have to add this to my kata collection. That also reminds me of the 8-queen problem. The last solution that I created (C#) years ago did use recursion.
Furthermore to Klathmon, there is an opportunity cost. Because you don't have the test, changing that method in the future becomes problematic. Is not the bug reappearing, is the refactoring that cannot longer take place.
The same that that structural test creates unnecessary coupling there will be other tests that create that coupling as well. It is a learning phase. You will realize that there are things that you can do and things that you can't do while testing.
Once I learned how to test properly, TDD has been helpful, never a hindrance.
In case you haven't read them `Test Driven Development By Example` by Kent Beck and `Growing Object-Oriented Software Guided by Tests` by Steve Freeman and Nat Pryce are great books
Wait, that says it took around 0.3 billion years, and when there was only single cell life, we have no clue about the biodiversity at that point in time. It cannot compare in time scale, and we have no clue if it can compare on biodiversity scale.
>> more direct mapping onto manipulating a DAG of commits
That would be a leaky abstraction. The fact that is using DAG should be irrelevant. If they find a better way of doing the work, that shouldn't really affect the ux.
>Humans SHOULD be able to easily read and construct URLs.
>This facilitates discovery and eases adoption on platforms >without a well-supported client library.
The URL is ephemeral on REST. That is because you create the documents on the fly. They can be linked or not to things that you store on the datastore. Allows you to easily change around as needed because the URL is not the API. The hyperlinks are the API. The URL is like a memory pointer. You shouldn't care about it.
I only like doing exercise where my brain is active all the time. So sports where there is competition (I play squash), or where i need to keep thinking about it (swimming so I don't drown), or one that doubles as social activity (like partner dancing)
Pair programming is quite intensive when done correctly. You build stamina with time. But even so, using the Pomodoro technique is the way forward. Someone driving for 20/25 minutes, then 5/10 rest, and switch the driver.
Even so, I will still not do it 8 hours a day. Probably 6, to give you time to do other stuff, like investigations, admin, ...
That last example, as you recognise at the end, was an agile flow, as per the Manifesto, they found what worked for them well. However they wanted to call it.
Any other flow in which management wants to standarized the process, fails at agility. I don't consider those Agile. Just because I call the fruit Orange Blue, doesn't make it so.
Separate deployment from release (Feature flags). Then you can do QA and show to stakeholders whenever in whichever environment. You can even use it for Code Review, though I prefer pair/ensemble programming to CR (better to correct things as you go than after the fact)
Rebranding wouldn't help. The same people doing Fauxagile will be doing FauxX after. The underlying issues of why Fauxagile exists don't get removed because of rebranding
Being in the bench is not unusual for Consultancy companies, where there is no necessarily alignment between finishing with a client and starting with the next one. Or even starting directly on a client when you join them.
I just want to point about that sentence of "goal posts get shifted". In his book Test Driven Development by Example (2003), Kent Beck, on the preface, page X says: "Red-Write a little test that doesn't work, and perhaps doesn't even compile at first"
There is no goal post moving.
More likely, as we transmit information, we don't do it correctly, and knowledge/data gets lost. I found quite enlightening to always go back to the source.
I like that write up on [2]. I have not really been exposed to C in a very long time, and that has been quite informative.
I also like that Set of Unit Testing Rules. That is basically correct, external systems are a no-no on unit testing.
Usually, you deal with mocks through indirections, default arguments, and other stuff like that so you can exclusively test the logic of the function, which is more difficult in C, from what I've seen on your write up, than in other languages. But if you care about not having that on your code for performance reasons, then more likely than not, you will not be able to unit test. And that is fine. You have an integration test (because you are using outside systems). You can still do integration test first, as long as they help you on capturing the logic and flow. The issue is that they tend to be far more involved, and far more brittle (as they depend on those outside systems).
Release integration branches bring the behaviour of big releases. The bigger the release, the bigger the risk, therefore the less you want to do it.
With release integration branches you not only integrate for release (which the bigger the release, the more difficult it is), but also now you have to integrate back from release into main (because bug fixes and what not). The longer that you have had that integration branch, the more likely that you have move forward the main code and the more difficult then becomes the back integration. So you end duplicating the effort.
So the problem is not the feature flags. If the code/system doesn't get improved bit by bit (is ok to have technical debt), then, whatever the technique, you are going to end in a bad place.
The Agile manifesto was created by devs, for the benefit of creating software. Everyone gets the benefits.
After having used release and feature branches, and trunk based development, as a developer I see mostly benefits (there are some drawbacks, there is no perfect technique) with trunk based development.
Sadly that is the case with most ideas/techniques, because we misinterpret them or we hear about them 10 reinterpretations down from the original. Nothing like going back to the source.
Is even easier with a small team to do TBD. Because the amount of integration is reduced the possible need of branches (or their TBD equivalents dark launch/branch by abstraction/feature flags) is greatly reduced. So the branches add ceremony where none is needed.
Though those branches could be needed if you are doing mobile, desktop or library/framework development.
Point two:
Alternatives to source control branches are dark launches, branch by abstraction and feature flags.
Point three:
The best results that I have had on developing systems were doing exactly that. You need more discipline (like make sure that you run test and linters locally), but my experience is that makes the whole process easier.
CI is continuous integration, there is nothing continuous to coding on your branch and merging after a few days.
I love TBD. But it has its places. For mobile apps I've used (and would use) release branches. You have a hard requirement on the way that app stores work.
You can still do TBD for most of the development of new features, though.
> as a code-input robot while developers around him bark commands at him is actually productive.
Nothing to do with mob/ensemble programming. At the end, is a discussion that a) make code easy to understand b) create shared knowledge c) avoid unnecessary work.
> This might be unusual but I would prefer to read someone's mental model of how the code works than the code itself.
The hypothesis under Peter Naur's (the N on BNF) "Programming as Theory Building" paper is that transmitting (by talking) the mental model is far more important than other format of documentation to understand a system.
Also, inconsistency. The example that they put is SHOWLN and showln, and they use all over the place showln, but then they write ReadLN. Driving me cranky :-)
Bulk, for a mail delivery company, refers exclusively to volume. You get discount on volume. Creating massive volumes of customized mails has been trivial for years.
I've used quite extensively Pair Programming, and at its best is better when both people tend to be senior, as you can bounce design ideas out of each other much easier, and is more likely that a bad decision (or test, or ...) gets caught earlier.
With junior devs is too easy to become something in which the senior dominates the conversation.
Regarding checklist people like Hollnagel, Wears, Braithwaite, Dekker, ... have done a bit on investigation (Hollnagel mostly on Healthcare, Dekker started on air industry but spread from there). Read the "Safety-I vs Safety-II" paper or the "When a checklist is not enough: How to improve them and what else is needed" paper
That's interesting. Whenever I have an issue with a flag it gets picked up on dev/test/uat environments (all gets tested, especially around the code behaving the same as before with the flag off). The code change never reaches production. And if for some reason the code under the flag is wrong, and it has reached production (something unexpected, unseen), undoing the change is whatever long it takes to switch the flag back (and the cache to update if you have a cache).