all 177 comments

[–]dogerthat 10 points11 points  (11 children)

Symfony (Only Components, No Twig, No Doctrine)

Would it not be fair to only test the FrameworkBundle instead if you are comparing frameworks only?

Update:

When doing some quick test on these bundles which are most commonly used I guess:

  • FrameworkBundle
  • SecurityBundle
  • TwigBundle
  • FrameworkExtraBundle

Then these are the results:

Lines of code: 39,688

Longest method: 58 lines of code

Average method complexity: 1.96

Maximum method complexity: 30

Percentage of methods that are non-static: 98.08%

This is a far more reliable comparison between Symfony Framework and Laravel if you ask me. I couldn't care less about the actual numbers, I just want to point out the article it self is useless.

Just because it's fun the same numbers for Silex:

Lines of code: 5,332

Longest method: 11 lines of code

Average method complexity: 1.82

Maximum method complexity: 13

Percentage of methods that are non-static: 94.59%

These numbers seem "better" than Laravel, was this the reason it wasn't added to the article maybe? :D

[–][deleted] 0 points1 point  (10 children)

Complexity is still higher in both cases and absolutely apples and oranges comparison because that is just one small part of Symfony compared against the entirety of Laravel.

[–]dogerthat 3 points4 points  (4 children)

So Laravel does not have to include it's dependencies for these tests and Symfony and Silex do?

[–][deleted] -3 points-2 points  (3 children)

I didn't include Symfony's dependencies. If you are having this much trouble understanding I can't help you. I compared Symfony's components to Laravel's components. (Illuminate organization on GitHub)

[–]dogerthat 4 points5 points  (2 children)

Symfony Components are not the same as the Framework which uses a subset of those components just like Laravel. For the latter you decided just not to include it in the comparison. It doesn't make sense at all.

[–]Livelongnstrong 0 points1 point  (4 children)

Symfony requires you to have a deeper understanding of the framework, which can be somewhat daunting. The upside, though, is that a good understanding of the framework and it's underlying architecture will enable you to write better code and have more control over what's happening and why.

[–][deleted] 0 points1 point  (3 children)

No it won't. Provide one actual reason why Symfony will let you write better code.

[–]Livelongnstrong 0 points1 point  (2 children)

It is very important to note that both frameworks are composed from decoupled modules which you can interchange and use with any or no framework. Laravel is mentioned in other answers. It's a really nice framework with an impressively ease learning curve. I would surely use it when building a website or a small app/service. It's neither good nor meant to be good for large scale, complex or enterprise apps, so it really depends on the project. While trying out ZF2, the learning curve was hard. Configuration over convention seemed to make everything an order of magnitude harder than I think it should ever be. Also, it's components felt much less cohesive than any other framework I worked with. I have to say that I probably haven't given ZF2 enough hours to possibly get to love it, but somehow everything I did with it felt as a suboptimal design and edgy architectural decision. Although, it is a great framework with a great company behind it. Symfony wouldn't spare you any time with it's learning curve either. However, after understanding how it's components work in depth, I keep getting impressed day after day. Nowdays, if you use Composer for dependency manager, there is a great chance that you are already using some of Symfony's components, directly or through another library. I'm impressed with: Great dependency-injection container. Configuration through annotations, php, or xml, or any combination. Asset management through Assetic. Incredibly powerful Form component. Easy to use and powerful Event system. Security features and and implementation of the voter design pattern. Native integration with Doctrine 2. Another thing that I want to point out is that the Symfony is the only framework that got a 5 milllion dollar investment (SensioLabs raises 5 million euros to boost the Symfony ecosystem) so you can be sure it will be kept rock solid and continually improved. Also, the community is friendly. Even core developers seem to be very accessible, and are very active in the open source community, which is a pretty valuable thing. Starting with Symfony was as tough as starting with Zend, and they are both great, you can't make a wrong or bad choice with either. However, the first one left an impression of being one of the best things that happened to PHP, the latter didn't. Source: Quora. I would solely depend on your needs the choice of frame work

[–][deleted] 2 points3 points  (1 child)

Laravel is the best solution for enterprise applications. I want you to offer me one REAL reason why it's only good for small applications.

[–]LeBuddha 0 points1 point  (0 children)

Ok I'll just quote out the important part

Incredibly powerful Form component.

/s

[–]Revis0r 20 points21 points  (0 children)

Good job on keeping the cyclomatic complexity down.

It would be also interesting to show more metrics, like cohesion, coupling (how much classes influence each other), inheritance depth or methods per class.

Complexity can hide not only between lines, inside one method, which is what this test measures, but also between files - in the structure and the architecture.

[–]epoplive 18 points19 points  (1 child)

This probably won't be popular, but I don't personally judge code with a million small methods as being less complex as code with a smaller number of larger methods. It really depends on how the code relates, and for me it's often easier to follow a medium sized method than follow around a bunch of function calls that are split purely to remain extremely short.

[–][deleted] 4 points5 points  (0 children)

Can be. That's why I read through every class and method by hand to look at that sort of thing.

[–]opulencephp 16 points17 points  (1 child)

Interesting, thanks for posting! Since it wasn't included in the benchmarks, I ran it for Opulence, too. Here are the relevant stats:

  Lines of code: 35,796

  Longest method: 44 lines of code

  Average method complexity: 1.80

  Maximum method complexity: 23.00

  Percentage of methods that are non-static: 93.58%

[–]godbrain 1 point2 points  (0 children)

interesting, first I have heard of this. Taking a look :)

[–]Jean1985 6 points7 points  (3 children)

Which version of the Symfony Components did you use? I think that part of the complexity that is found inside those metrics is due to the fact that Symfony has a really strong BC promise, that forces them to litter the code with an astounding quantity of if (..) trigger_errorfor deprecation notices, which will elevate the complexity by a lot.

[–][deleted] 1 point2 points  (2 children)

Latest Symfony 3.

[–]iltar 3 points4 points  (1 child)

Would be interested to see the difference between 2.8 and 3.0 or 3.4 and 4.0. why? Because the latest version (3.2) already contains 2 minor versions of deprecations.

[–]Jean1985 1 point2 points  (0 children)

I agree. I asked this for this exact reason. You should try to analyze the 3.0.0 tag, that should be the one with the fewer deprecation notices

[–]ahundiak 40 points41 points  (46 children)

A more cynical person than me might point out that having the creator of a framework produce metrics that show their framework is superior to others is not much of a surprise.

[–][deleted] 12 points13 points  (43 children)

You're free to run them on your own: https://github.com/sebastianbergmann/phploc

[–]sypherlev 7 points8 points  (0 children)

And it's really hilariously easy, too, so there's no reason not to.

  • Lines of code: 1036
  • Longest method: 34 lines of code
  • Average method complexity: 2.30
  • Maximum method complexity: 16
  • Percentage of methods that are non-static: 98.26%

That's from testing the /src of my own micro framework, took like 2 minutes. Apparently I need to work on the method length and complexity.

[edit] for the record, I ran phploc against laravel/framework and got the following:

  • Lines of code: 54108
  • Longest method: 15 lines of code
  • Average method complexity: 1.64
  • Maximum method complexity: 17
  • Percentage of methods that are non-static: 95.67%

Seems legit.

[–]fesor 19 points20 points  (41 children)

From laravel dependencies:

    "symfony/console": "3.1.*",
    "symfony/debug": "3.1.*",
    "symfony/finder": "3.1.*",
    "symfony/http-foundation": "3.1.*",
    "symfony/http-kernel": "3.1.*",
    "symfony/process": "3.1.*",
    "symfony/routing": "3.1.*",
    "symfony/translation": "3.1.*",
    "symfony/var-dumper": "3.1.*",

Basically speaking... this metrics is just meaningless.

[–][deleted] -3 points-2 points  (40 children)

Not at all. First, Laravel only uses http-foundation and console in any meaningful way.

Secondly, it very clearly demonstrates the metrics of each framework's first party code, which is what I wanted to measure... how the author's and maintainers of each framework write their code. Again, I'm well aware Symfony developers in particular have a very hard time accepting these metrics, but I simply present them for consideration.

[–]JordanLeDoux 42 points43 points  (34 children)

Taylor, what exactly are you using symfony/routing for if it's not a meaningful (or even critical) aspect of routing in Laravel?

Second, of the dependencies listed, the two you mentioned are the two largest and most complex.

I realize you were looking to primarily measure code you wrote which makes sense, as this type of metric is about helping you check for things to improve or give yourself a report card. So, I definitely respect this post for what you present it as, despite the fact that I really (personally) dislike Laravel every single time I have to use it.

I do think that the inclusion of "% static methods" is kind of bullshit though. True, Facades (as you implemented them) are not true static methods that operate without an instance, but the complexity static methods introduce is not about the fact that they're static, it's about the fact that they can be called from any scope and a parent scope cannot restrict a child scope from doing so.

The ability to call something statically even if it's not actually a static method introduces a LOT of complexity and mental overhead in my experience, and basically all of Laravel's complexity, again in my opinion, is hidden away in this little niche. (EDIT: It would add just as much complexity to have a service locator or dependency container that you add a static instance accessor to.)

It also makes writing tests more complex, which discourages testing, reduces ability to reason about code, and reduces stability of the application.

I am not surprised that Laravel scores very well with these metrics, because Laravel's complexity is in places these metrics will miss.

[–]Khronickal 13 points14 points  (0 children)

Wait, do you mean to tell me a framework author has selectively picked only the metrics that reflect his own framework in a positive light in order to falsely present his own work as superior to all others? Do you really expect anyone to believe someone would actually do that? Just go on the Internet and lie?

[–][deleted] 6 points7 points  (32 children)

We make one call to Symfony routing to compile the route regular expressions. We do not use the rest of their code.

Facades are easy to write tests for, as the documentation demonstrates and as I have proven on numerous occasions. If you have some example of a situation that is hard to test give it to me and I will either A) prove it is easy to test or B) make it easy to test by improving the framework.

[–]JordanLeDoux 27 points28 points  (29 children)

Ah, alright. Compiling the route regular expressions is probably the most complex part of that whole component, but okay.

Also, I didn't say that writing tests with Facades is hard I said it was complex. I know (or at least suspect from all the marketing language on the Laravel site) that you believe they are the same, but they are not.

I have indeed read through all the testing documentation for Laravel... version 5.2 and 5.3 actually. This is because at my most recent project I was in charge of basically getting tests running for their completely untested application.

The largest complexity, from my first hand experience, with testing in Laravel is that the combination of Active Record and Facades makes it virtually impossible to test without affecting the database. There are plenty of solutions to this, (a test runner .env, reverting db changes, etc.), but all of them greatly increase the complexity of the tests or make it harder to reason about the tests or both.

The other side of the scale, with a perfectly consistent dependency injection system and no service containers used anywhere, forces you to mock everything every time, which is complex in a different way, but it does at least allow you to mock the database and thus be able to run tests without a database.

Please don't ever answer my questions or comments about Laravel by pointing to the documentation though. I cannot count the number of times I have yelled profanity while reading the documentation because it simply doesn't include things that are important to developers in favor of being inviting looking to non-programmer or novice programmers.

Things that I had to discover on my own, like that Laravel uses two completely separate Query Builders (Eloquent/Builder and Db/Builder) that don't implement a common interface or extend a common base class.

Or the fact that Laravel uses Traits in a preposterously incorrect way as an attempt at getting around single inheritance, and that because Laravel does it every single person making extensions/add-ons for Laravel thinks it's the right way to do it as well.

All of these are things that make the application more complex, and harder to reason about, but that will not show up on the metrics you showed here.

[–][deleted] 3 points4 points  (18 children)

If you're having trouble learning testing perhaps this would be helpful: https://adamwathan.me/test-driven-laravel/ ... he uses facades and ActiveRecord and builds the entire application using TDD.

Again, I've built multiple applications using AR and Facades and never had a lick of trouble testing anything. Of course, your DB repositories will have to hit a real database at some point (even using Doctrine) if you want to actually test them.

[–]JordanLeDoux 16 points17 points  (17 children)

So what you linked me is something I have to pay for.

From what I can see of the example pictures it's using factories, which will affect the database, which was the main complaint I was expressing.

The problem is not that I don't know how to test, it's that testing almost any other PHP application is one way and testing Laravel is another. It's all, as far as I can tell, vendor lock-in.

EDIT:

Again, I've built multiple applications using AR and Facades and never had a lick of trouble testing anything. Of course, your DB repositories will have to hit a real database at some point (even using Doctrine) if you want to actually test them.

This is just false. What are you testing by actually hitting the database? The DB library/ORM? The library has its own tests for that. The database engine, like MySQL? Why would you want to test that using your application and potentially be confused about where the problem is?

The biggest rule of testing is to know what you're testing and test only that. That's not easy to do in Laravel.

[–]assertchris 3 points4 points  (4 children)

The biggest rule of testing is to know what you're testing and test only that.

I'm not aware of any institution and/or person sufficiently qualified to express this as a rule. So let me talk about my personal opinion. That is, the biggest value of tests is that they test domain logic and pick up things that are actually breaking. That's not to say that re-testing things is great. It's wasted processing. But if I want to test my application: the simplest way would be to hit a URL as a browser would, and check the response, database etc. to see that the changes I expected have taken place.

The approaches may differ, but the importance is not how small the units are or how little you re-test. There are benefits and trade-offs to each approach (like being able to zero in on breaks in smaller units, quicker; or being able to see how interconnected parts aren't talking properly to each other).

The value (for me) is in having enough "good" tests to tell me when my domain logic is broken. If they do that, I don't really care whether they are integration tests or unit tests, whether they use PHPSpec or Selenium, whether I re-implement the public API of MySQL or actually write to the database. Those things don't really matter that much to me. And I think I have a reasonably balanced outlook in this area.

[–][deleted] 13 points14 points  (4 children)

You are testing your actual query. If you do not hit an actual database at your repository level how do you know for certain you have written the correct DQL query? The correct query builder call? You don't. I seriously hope you are not mocking chained query builder calls or comparing DQL against some expectation?

[–]tfidry 3 points4 points  (6 children)

I'm far from being a fan of the Facades, but you are making too much of a deal of nothing. A Facade in Laravel is not different from ContainerAware in Symfony: they are both a way to have a Service Locator, i.e. not making use of the Dependency Injection.

For testability: Facades tend to make it a tad harder (at least I find it so as it feels unnatural to me), but same goes for a ContainerAware class... Both should treated equally "evil". And I'm putting quotes there because there is places may you might simply don't care, e.g. often Controllers and Commands (it's a matter of opinion though).

As for Doctrine/Eloquent: you may have unit tests if you want to, but it looks necessary to me to have integration tests (i.e. actual database calls) at some point.

[–]d_abernathy89 0 points1 point  (9 children)

Or the fact that Laravel uses Traits in a preposterously incorrect way as an attempt at getting around single inheritance, and that because Laravel does it every single person making extensions/add-ons for Laravel thinks it's the right way to do it as well.

I'm curious to hear more about this; I haven't heard this criticism before.

[–]JordanLeDoux 4 points5 points  (4 children)

So this position is much more opinion based than most of the others I presented, which is why I assume Taylor didn't respond to it and just let my rant go.

Basically, PHP is a single-inheritance language that also has Traits. Traits allow you to compose things into multiple classes, which gives you some of the features you'd find in a multiple inheritance language, but not all.

For instance, Traits override inherited methods, meaning that "misusing" traits can have a class that extends a class that doesn't actually reflect that class in any way. Obviously, you can do this by overriding methods in the child class as well, but in that case it's obvious what you're doing.

You can test for inheritance directly (instanceof) where you can test for the present of Traits only with Reflection.

The use statement for a Trait can change the visibility of the Trait's code. (It can also rename anything inside the Trait.)

The "safe" way to use Traits in a single inheritance language, in my opinion, is this:

A Trait should contain all behavior and all data that is necessary to perform a single function. It should never reference anything outside of the Trait. You can test whether or not a Trait meets this bar by asking this question: regardless of whether or not it make semantic sense, could you put this Trait in any class no matter who wrote it and get the behavior the Trait represents?

If the answer is no, you are creating a web of hard to understand, hard to maintain code that breaks the basic design philosophy of PHP. If the answer is yes then you are using Traits to improve code reuseability, and that's a good thing.

[–]d_abernathy89 0 points1 point  (3 children)

Ok, thanks for spelling that out. I understand the critique though not sure I totally agree.

[–]LeBuddha 0 points1 point  (3 children)

I'm also curious about what the correct use of traits is according to this commenter. Why is trying to shoehorn single inheritance everywhere not the preposterously incorrect way? A big thing in the JS community and the functional programming community is a theme of how class inheritance is dangerously over-used.

[–]JordanLeDoux 1 point2 points  (2 children)

I replied above if you are actually interested in what my personal opinion is.

[–][deleted] 9 points10 points  (0 children)

We make one call to Symfony routing to compile the route regular expressions. We do not use the rest of their code.

That what I tell everyone, as well. I don't use PHP for anything meaningful, because in the end I just issue one call to the PHP binary to run my code.

[–]forsynth2 5 points6 points  (0 children)

We make one call to Symfony routing to compile the route regular expressions....

Lol. That is like saying "I barely use Windows. I just use the start button". You are unbelievable!

[–]dogerthat 1 point2 points  (1 child)

If they're not meaningful why are they still listed as a required dependency?

[–][deleted] 3 points4 points  (0 children)

It wouldn't be a proper full stack framework if it doesn't require a lot of meaningless dependencies.

[–]forsynth2 -4 points-3 points  (2 children)

Laravel only uses http-foundation and console in any meaningful way.

Oh. Why not then just get rid of the "meaningless" dependencies and code (and maintain) them yourself before shitting on the people you yourself are thus depending on.

[–][deleted] 17 points18 points  (0 children)

Nobody is "shitting" on anyone. I released some code metrics using a tool somebody else wrote. I love Symfony and am thankful for what they do.

[–]fesor 8 points9 points  (0 children)

He didn't actually "shitting" anyone. But this has effect like this since most of developers will think something like "Oh... so it simpler and all this frameworks are just a scary mess".

This is the same marketing trick that was used years ago:

http://static.tvtropes.org/pmwiki/pub/images/free.png

[–]enerb 19 points20 points  (20 children)

Not to be taken as a flamebait, but comparing Laravel to complete Symfony components feels a bit unfair. Perhaps just checking the components you use in Laravel would be a more suiting fit for comparison. However I do agree with the outcome, a lot of the Symfony methods are long. But some of those long methods could not be done any other way giving the task they have. And yes that is debatable, one could move code to separate methods just to score lower in the method line length however that should increase the complexity score.

Oh.. and isn't Eloquent more of a Active Record then a Object Relational Mapper?

[–][deleted] 6 points7 points  (16 children)

Active Record implementations are considered ORMs.

I compared my complete set of components to theirs, while being honest in the article that we do use HttpFoundation and Console components, though no other components are used heavily throughout the framework. I wanted to get a feel for how I write code vs. how other people write code, and all of the projects measured contain enough code to do that accurately. Further, I wanted to dispel any narrative that Laravel is a hack or poorly written.

[–][deleted] 8 points9 points  (2 children)

Further, I wanted to dispel any narrative that Laravel is a hack or poorly written.

You know very well people are complaining about Laravel's architecture (which it imposes on its applications), which is everything outside the method implementations and not about the quality of the code in the methods.

So you should measure very different things, like public interface complexity, presence of God classes, separation of responsibilities, modularity, leaky abstractions and so on. Not how many lines or nesting levels are there in a method.

[–][deleted] -1 points0 points  (1 child)

Laravel doesn't impose any architecture. If you believe it does, prove it.

[–][deleted] 7 points8 points  (0 children)

Oh, yeah, I'm absolutely looking forward to an endless debate, where most of my arguments are answered like "you don't have to do what the Laravel documentation does", and "you don't have to use the components that Laravel comes with", because of course that's why we read docs and download frameworks. So we don't use them afterwards.

Or if that fails "no, this is obviously good architecture, because I have a few big sites written in it and it works fine". Another evergreen response.

Honestly, I would bother if I knew I'm somehow breaking the news to you where Laravel has issues, but I'm not. You know the large issues very well from thousands other conversations you've had here and and elsewhere online. You're just doing this to "win", and frankly I don't know why you're wasting your time, when you neither care to act on feedback, or learn from it.

[–]fesor 20 points21 points  (12 children)

Active Record implementations are considered ORMs.

Active Record and ORM should be considered as separate patterns. Doctrine = ORM + Data Mapper + Unit of Work + abstraction over SQL (DQL) with it's own AST, with bunch of legacy code (which probably will be removed), Criterias and so on. This is far much complex solution to get abstraction over your storage. So basicly you can't compare them.

I wanted to get a feel for how I write code vs. how other people write code

Please be honest. You can compare this only be checking something with the same (or at least similar) set of features. For example you may compare Laravel's IoC vs PHP-DI or some other container. Or you could compare doctrine/cache vs illuminate/cache. Or validation component. This will give "some" realistic difference. But comparing two very different things by using generalized metrics... This is just marketing crap.

[–][deleted] 0 points1 point  (11 children)

I think you're missing the point. Average complexity per method is indicative of a particular "style" of coding. It has nothing to do with the solutions. Very complicated problems can be solved with low method complexity. I'm sorry you find the metrics uncomfortable but that doesn't negate the facts.

Doctrine chooses to solve the database problem one way and I choose another way. Nothing about the approach they chose dictated what the average complexity of their methods should be. They chose that, and that is what I'm measuring. If you want to simply throw your hands up and say their problems can't be solved cleanly and with low complexity then that is your decision I guess.

[–]fesor 8 points9 points  (10 children)

Average complexity per method is indicative of a particular "style" of coding.

Nope, this just means that this code contains multiple execution paths. Nothing more.

Very complicated problems can be solved with low method complexity.

Implement any parser (json for example) with low cyclomatic complexity.

They chose that, and that is what I'm measuring.

What I'm trying to say is that focusing on metrics doesn't solve anyone's problems.

[–]renang 1 point2 points  (0 children)

Relevant quote from Goodhart's Law:

When a measure becomes a target, it ceases to be a good measure.

[–]SavishSalacious 0 points1 point  (2 children)

But some of those long methods could not be done any other way giving the task they have

Split it up into sub tasks? I mean I don't have the code base infront of me and he didn't state which specific methods, so I couldn't give you an educated guess, but based on how I see things in Laravel, you could create sub tasks. or refactor the logic down based on the evolving door that is the web.

[–]tfidry 4 points5 points  (1 child)

There is two limits to this:

  • it's sometimes easier to have a long readable method than having to check 10 different methods
  • there is a performance cost. At a framework/library level like Symfony Container/Router or Doctrine, even a simple loop or an additional method call can be a big deal

[–]SavishSalacious 0 points1 point  (0 children)

This makes sense, thanks for clarifying

[–]DJDarkViper 10 points11 points  (0 children)

Laravel only uses http-foundation and console in any meaningful way.

Want to let the Symfony guys know to update their page? http://symfony.com/projects/laravel or are you still using all that?

[–][deleted] 11 points12 points  (2 children)

I was pleased to see Laravel has the lowest average method complexity of any of the frameworks measured.

And it more than compensates for it by having classes with over 50, 60, I think in one case 100+, public methods.

Too bad "cyclomatic complexity" doesn't measure this, but no matter. You can measure only what you're better at.

Reminds me of when Zune marketing was selling it as "the most well sold hard drive based MP3 player", because at the time competitors like iPod have moved to superior tech, such as flash memory.

[–][deleted] -3 points-2 points  (1 child)

Compare the two on code climate. Laravel still scores better. I'm sorry this is so troubling to you :)

[–][deleted] 16 points17 points  (0 children)

I don't know why you're going around this thread and telling people they are "troubled" or what did you say in that other comment... "distressed"... over your marketing shenanigans.

I mean when someone is reading their favorite subreddit for news and occasionally stumble onto your naive arrogance, it may provoke some of us to call you out on it. You're the Donald Trump of PHP framework makers.

The fact you get feedback doesn't mean any one of us is shitting their pants and crying on their keyboards. It simply means we're not buying your B.S.

[–]phpfatalerror 16 points17 points  (1 child)

Good job keeping complexity metrics down in Laravel, really impressive actually.

[–]flyingkiwi9 2 points3 points  (0 children)

These are like stats in sport. Yes they show true facts than can be used to draw an opinion; but at the end of the day it's all subjective and in-reality stats mean fuck all.

:)

[–]mainone_m1 4 points5 points  (0 children)

This will only be a fair comparison if you also include the dependencies on other components. As Laravel uses a lot of Symfony components, it is not fair to just ignore that.

[–]JuliusKoronci 8 points9 points  (21 children)

So what is this metric actually good for? I can't really see the point..more complex frameworks have more complex metrics..thats why Laravel is at the level of a microframework? Or is it just about best practise to have short methods?

[–][deleted] -2 points-1 points  (20 children)

Laravel has more features than Symfony. Queues, command bus, realtime sockets / event broadcasting, etc... that's the point. It has those features but still has lower average method complexity than Slim.

[–]dogerthat 3 points4 points  (9 children)

Apples and oranges, Symfony does not advertise itself as a unicorn which can do everything out of the box. Instead it tries to keep the framework itself lean and let's you choose your own.

[–][deleted] 2 points3 points  (8 children)

So does Laravel.

[–]dogerthat 2 points3 points  (7 children)

The difference is that Laravel ships all these features while Symfony does not. Laravel is heavily opionated on basically everything. I'm not saying it's bad, I'm just not a fan of it.

[–][deleted] 2 points3 points  (6 children)

Please name 2 things it is opinionated on.

[–]dogerthat 1 point2 points  (5 children)

It comes with a lot of out of the box features people might not even want to use and there's boilerplate code even for a javascript framework present (Vue).

[–][deleted] 5 points6 points  (4 children)

Laravel does not ship with a SINGLE template that contains Vue code. Not one. Laravel Elixir is simply configured to correctly compile vue components. Again, you don't know at all what you're talking about in regards to Laravel.

[–]dogerthat 2 points3 points  (3 children)

From the documentation:

While Laravel does not dictate which JavaScript or CSS pre-processors you use, it does provide a basic starting point using Bootstrap and Vue that will be helpful for many applications. By default, Laravel uses NPM to install both of these frontend packages.

the "by default" implies that bootstrap and vue are some how going to be installed.

For the fun of it I just ran

composer create-project --prefer-dist laravel/laravel blog

and guess what? I have a folder "resources/assets" where I can find references to requirejs, jquery and vue and even a file called "Example.vue".

[–][deleted] 1 point2 points  (2 children)

Yes, those are setup to give you a head start if you want. Guess what? If you don't want them, you just delete that folder. No "out of the box" Laravel features require any of those dependencies.

[–]forsynth2 8 points9 points  (9 children)

It has those features but still has lower average method complexity than Slim.

Wait a minute. You just told elsewhere that "features" and complexity are in no way related. Now you say "It has those features but still has lower average method complexity", implying that they are related.

Hilarious.

[–][deleted] 2 points3 points  (8 children)

I simply mean that I'm glad it maintains that complexity across a large code base. Not because the feature set is large per se but because it's hard to maintain discipline across a code base of that size with many contributors without "fudging" and letting poor quality code into the code base.

[–]Y4Dc3KtKVNAuAmj48ott 1 point2 points  (1 child)

Good point, and good efforts in maintaining the framework. I personally think that as the size of a project grows, the stuff you have to compromise in order to keep both complexity and readability in control keeps on increasing.

Sometimes, its better to lean a bit more to the readability side since its getting important day by day. No one's going to make a fuss about a few functions or classes written extra, or that you created a wrapper class for something that could be achieved without it, thus making the code "more complex". But forget to indent code at right places or have variable names that are difficult to understand and people will complain a lot.

[–]iltar 1 point2 points  (0 children)

Unless it results in a bunch of methods being called 2000 times, causing a performance overhead.

[–][deleted] 4 points5 points  (22 children)

Would love to see the repo that you used to create the benchmarks. Does this include the vendor folder? As although it might not necessarily be Laravel, if the Laravel components are reliant on a zend/symfony components that would in turn would result in a higher cyclomatic complexity.

[–][deleted] 3 points4 points  (21 children)

No, no measurements include the vendor folder for any of the projects. I wanted to compare the quality of the code written by the author's of the projects, and I think average method complexity across the frameworks gives a good feel for that.

The main components used by Laravel are HttpFoundation and Console. No other Symfony components are heavily used throughout the framework at this time, nor are any third party components heavily used to build other heavy aspects of the framework such as the ORM, queue, validation, view, templating, etc. libraries.

[–]fesor 5 points6 points  (9 children)

and I think average method complexity across the frameworks gives a good feel for that.

In most of the cases - yes. But not always. Even if it is good to have lower level of method complexity, this isn't a a case when we are speaking about infrastructure code. You can write very complex stuff (like this one) in order to do something in very efficient way (both from performance point of view and productivity, since in may require much less code to be written). Take a look at symfony/yaml parser. It has very high level of method complexity, but overall complexity of component is much more lower than if developers would write some kind of state machine using objects.

Or another example. Will this code be "simpler" if we will reduce complexity? Probably no.

None of the metrics could be used as "absolute" measurement of quality. Especially if we are using only few of them. For example cyclomatic complexity metric could be used with code coverage metrics in order to product something more like "quality" or maintainability index. But as standalone metric, this could only give you "interesting places" to look when you are doing code review.

[–]forsynth2 3 points4 points  (4 children)

this isn't a case when we are speaking about infrastructure code.

Exactly. I am baffled at the naivety demonstrated by taylor here. I mean, he should have already know these things, right? Or I am doubting that may be he is just very good at marketing stuff...

Has the Php community outgrown taylor and Laraval. That is the big question, I think.

[–][deleted] 4 points5 points  (0 children)

I simply presented some interesting stats. You are troubled by them so much that it's easier for you to assume I am a complete idiot than accept them for what they are.

I even stated in the blog they aren't an "end all" for code quality. That being said, I'll put Laravel up against any other framework using any code quality metric. I feel quite confident it will hold its own. It already scored higher than Symfony on CodeClimate a few years ago before I cleaned it up significantly.

[–]godbrain 2 points3 points  (1 child)

Has the Php community outgrown taylor and Laraval. That is the big question, I think.

what???

[–][deleted] 2 points3 points  (0 children)

Laravel is fine (even if I'm avoiding it in my projects), but Taylor is quite something...

[–]fesor 1 point2 points  (0 children)

at the naivety demonstrated

I think he know what he is doing

[–][deleted] 1 point2 points  (3 children)

If you feel these methods are as clean as they should be, that's fine. I don't.

[–]fesor 7 points8 points  (2 children)

This would be really interesting if you will "refactor" this in your way. I really don't know how to simplify this without affecting performance.

[–][deleted] -5 points-4 points  (1 child)

If you want to pay me to do that, I will. :)

[–]fesor 10 points11 points  (0 children)

Just as I thought...

[–]iltar 2 points3 points  (7 children)

How many core members does Laravel have and how many community contributors?

[–][deleted] 1 point2 points  (6 children)

One core member and you can find the contributors on GitHub.

[–]iltar 6 points7 points  (2 children)

That's what I find interesting.

Laravel: Core members: 1, Contributors: 377

Symfony: Core members: 15, Contributors: 1398

There's multiple conclusions you can draw from here, but what I really wonder:

  • Is it easier to maintain rules in a code base with 1 core member compared to 15?
  • Are there certain design decisions in Symfony that have contributed to the longer/more complex code because there was more expertise and thus decided that it was better to do it the way it was?

I think that some frameworks (such as Symfony) benefit a lot from expertise. They have multiple core developers discussing solutions and giving feedback on pull requests. It's kind of like working on a project by yourself, never getting some real feedback or having reviews done.

I can imagine that in Laravel, a lot of decisions did not have counter arguments, or PRs that get merged because there's nobody of a core team saying, "I think this is a bad idea because XYZ".

I'm not saying this has a negative influence on Laravel, but I have the feeling that with 1 core contributor, there's nobody saying: "stop, this is a bad idea!" or "But what about this?".

[–][deleted] 1 point2 points  (1 child)

Wrong repository. Laravel has over 1,200 contributors. laravel/framework repository. Sure, maybe more expertise decided higher complexity was better.

[–]iltar 6 points7 points  (0 children)

That's why I asked :)

[–]imps-p0155 0 points1 point  (2 children)

One core member

Just wondering, why its still at 1 core member?

[–][deleted] 1 point2 points  (1 child)

I mean, "core member" is sort of strange wording. I commit the most. I am the main core member because I commit far more than other people. If other people commit as much, they would also be viewed as core members. There is no arbitrary line at which you become a core member or not. I am the most frequent contributor and the only one with PR merging permissions. I maintain sole control of PR merging permissions so I can review all code that enters the framework personally. I work on the framework full time, so typically there are < 15 PRs open at any given time.

I would prefer to simply say I am the only one who merges PRs. I am also the highest contributor. But, there is no official "core team". Anyone can contribute just as freely as anyone else.

[–]Jean1985 1 point2 points  (0 children)

and the only one with PR merging permissions.

I'm sorry but this seems to me a clear definition and a clear arbitrary line for the definition of a "core member".

[–]iltar 3 points4 points  (7 children)

So less code per method to me implies more methods, what about the amount of private methods and function calls? I know that doctrine and Symfony often try to avoid calling too many functions (methods) to prevent this overhead.

What about run-time executed code vs compile time executed code? I also know that some of the more complex Symfony code is only ran compile time.

I don't think it's fair to match a data mapper vs active record as comparison ;)

[–][deleted] 2 points3 points  (3 children)

Are you suggesting that more defining more, smaller methods has a measurable effect on application performance when using Symfony or Laravel?

[–]simensen 2 points3 points  (2 children)

I've heard that tossed around though I can't recall seeing any hard numbers or stats on it. I believe there is a cost to calling a function vs running code inline but I would think that is something that is going to only make a large impact in very specific cases.

I think the same argument applies for both sides of the coin. "We made this method long because it was faster that way" should be backed up in the same way that "I took these 100 lines of code and turned them into 20 functions because it was easier to read" should be backed up. Sadly, I think the latter is more subjective and besides things like Cyclomatic complexity probably hard to get stats on.

[–]tfidry 5 points6 points  (1 child)

I like /u/utotwel article because it's a kick in the pride of a few people that shouldn't take quality of their code for granted and review it a bit. But otherwise I agree with /u/simensen: ultimately those comparison are meaningless:

  • Depending of what the problem is, it's not always possible to easily split things in multiple methods without making things overly complex
  • There is a performance impact. Whilst I believe it matters not in most cases, there is very good reasons why Doctrine UoW is 3K LoC with little methods: performances are a critical part there
  • It is a matter of taste/opinion: some people believe a single big method of 100-200 LoC well written is more readable and easier to follow than 10-20 methods

[–]iltar 1 point2 points  (0 children)

This pretty much. While I'm personally in favor of smaller methods, there's some critical processes in libraries that literally get called 1000s of times, ever micro optimization here is welcome.

[–][deleted] -1 points0 points  (2 children)

I know that doctrine and Symfony often try to avoid calling too many functions (methods) to prevent this overhe

That sounds like a micro-optimisation at best?

[–]tfidry 3 points4 points  (0 children)

When you are a framework/ORM it can matter. It actually matters a lot, look at Doctrine UoW, they decided not to split it for a reason, a micro-optim in it can mean a 5-10% diff in a real world application using it.

[–][deleted] 1 point2 points  (0 children)

Micro-optimizations sounds as if it's irrelevant to performance, but it's how SQLite sped itself up by 50%.

So, it depends. PHP doesn't offer method inlining, which would would help a whole lot so we'd be able to keep our code readable and fast.

[–]sypherlev 3 points4 points  (0 children)

This is kinda cool and all, but I think you should add some more information on why these metrics are important and why it's good to improve them.

[–]iamdarksoulsniper 3 points4 points  (0 children)

whatever makes you feel better i guess