A friend of mine introduced me to the concept of functional programming this weekend. As someone who's been writing procedural PHP since before PHP...
For further actions, you may consider blocking this person and/or reporting abuse
The concept of functional programming definitely helps with code maintainability. But, in my opinion, it's like TDD in PHP. We all talk about how great it would be to get to TDD, but don't have any practical experience in coding TDD.
I think sometimes we place too much focus on wanting to code everything "the right way" that we get caught up in paradigms that don't necessarily add any value to the code we are writing. PHP OOP is not on its way out, and I think we will be back to that as the primary paradigm when we find that coding in the functional paradigm is harder than coding in the OOP paradigm.
For the record though (and I've only really been doing this in JS so far).... TDD is really lovely. It sucks when you have to mock objects and deal with cluster effs like WordPress... but refactoring a system with good test coverage is a total joy.
... but oddly, I don't TDD so much with PHP because of the required mocking. So I guess what I'm thinking here is... if we use simple data and functions, it's easier for us to do TDD... and making the better path the easier path is probably not a bad thing.
I LOVED TDD when I first learned about it. I implemented it everywhere I could! Later, it got to the point where the amount of time I was taking to write code to test my code was more time than to write the actual code. I lost the value in doing the testing to begin with.
Think about it this way...time is something you can't buy back. At some point you have to evaluate how much time you are spending on the things you are doing. When you're spending more time to write tests than to write code, you have to compare that to the amount of time you would be debugging code to solve issues or add capabilities.
For me, going TDD, or even unit testing all together got to the point where it wasn't worth the value of effort I was putting in. That is why I went to automated functional testing.
I found that if you place your focus on testing your public facing capabilities, then you can catch more bugs with less amount of code. Which is the reason I spent time building out FireTest ua1.us/projects/firetest/
Now all of my efforts are focused on exercising the functionality and not on testing each individual piece of code that implements that functionality. And when a bug is reported, I write a test that will replicate that bug and include it in my test suite to ensure that bug never happens again.
I can see how that'd be the case. For me, the thing I like about TDD is that I can clearly outline my expectation of how code should work so that it feels logically sound. And then, if I need to refactor it, I can confirm that everything is still ok. I would never want to refactor a big project that was only tested from public facing stuff. I think that if you need to mock stuff TDD can be slow and a pain. Almost all of my tests are expect().toBe();... there's almost nothing to writing them. I keep it deliberately simple because if it's hard to test, I'm probably writing brittle code. (Not to say you are or were either. Just something that I noticed about my own coding practice).
Nice! Different stuff works for different people. I find no value in writing individual units. Never have I ever caught a bug because a unit test failed. I did catch a bug because my functional test failed though.
Even recently. My test was written in a way such that I expected that if the user tried to access a class that didn't exist within a DI container, that the code would throw an exception. Turns out that the code was written such that if the DI container didn't contain the class it would throw an exception in php 7.1, but not 7.3. That is a bug that I wouldn't have been able to catch if I mocked everything and spent time writing individual unit tests.
Totally agree. Different strokes.
And I hear ya about the need for other tests and assurances too. I wouldn't ever think, "I have unit tests, so everything is perfect."
And I've written loads of code that isn't tested at all and had zero problems.
I can say this much. I DEFINITELY dislike TDD when working with OOP. :)
You definitely can write PHP in a functional style. It’s missing some of the niceties in syntax of a functional language though.
Mostly you’re just writing code to minimize the amount that you mutate data.
If you’re writing in a functional style in PHP it can still be useful to use OO concepts like classes as, essentially, tiny namespaces where you can determine the level of privacy of methods. Interfaces and abstracts can also be pretty useful to define custom types.
Such as?
These are some nice to have features in functional programming languages.
Function can be passed to other functions and returned as values. In short functions should be treated as values.
closures the inner function can use the variables of outer function regardless of where it is running.
Map, filter, reduce like functions.
pipeline operator.
Unless I'm misunderstanding the terms, I believe PHP has all of these features except a pipeline operator.
It's a different language, but check out the ramda library for examples of really awesome functional programming. The documentation is great. Chris Okahravi has a superb video tutorial series on every single function in ramda too. —> youtube.com/playlist?list=PLrhzvIc...
If you REALLY want to get into it, check out Prof. Frisby's Mostly Adequate Guide to Functional Programming github.com/MostlyAdequate/mostly-a...
+1 for Frisby’s
I'm fascinated by FP and I maintain several PHP codebases. I'd love PHP to be more functional than it is.
What PHP has:
What PHP lacks:
require/includethe right file all presuppose you're going to do OOP)..... I was setting up a new project in PHP storm, and when setting the language level for the CLI interpreter I noticed the option to set PHP 7.4, which has "short closures" and arrow functions!!!!!!!!!!! :D :D :D :D :D
wiki.php.net/rfc/short_closures
"Variable binding
The position of this RFC is that the shorthand syntax is to allow anonymous functions to be used as easily as possible. Therefore, rather than requiring individual variables be bound to the closure through the use ($x) syntax, instead all variables used in the body of the anonymous function will automatically be bound to the anonymous function closure from the defining scope."
Oh happy day!!!
22 Yes, 30 No. I don't think this is happening?
I forgot to post the later one.
wiki.php.net/rfc/arrow_functions
The linked RFC was reissued as the above.
.... edit... turns out this one was also reissued as the following.
wiki.php.net/rfc/arrow_functions_v2
51 yes, 8 no
I've written about it, so instead of just copy and paste a whole article, I'll share this link, these are my thoughts about FP in PHP :
medium.com/swlh/functional-program...
:D I’m so happy to hear that you’re excited about this!!!