Juniors on side projects say the darndest things...



  • A few years ago, with one of the company's projects prospering, management decided to let one of the developers on said project work on a side project during less busy times in the hopes that this side project could also become something revenue-generating.

    The side project would be some sort of simulation engine built in Unity, to run on mobile devices. The developer, Lenny, had been in the industry a bit under a year, but he had been doing decent work, so why not give him a chance? It would also represent a great opportunity for him to pick up some greenfield experience in a new framework, which is something a lot of juniors don't get to do.

    Now, while Lenny did not report to me, he often shared anecdotes of challenges he faced and overcame in working on this project, possibly because I tend to be a very approachable person in the workplace that people consult for advice and/or rant to about their latest frustrations. Perhaps he also looked up to me. Either way, one day, he was lamenting how MonoDevelop (which is what ships with Unity) behaves differently from Visual Studio:

    "One thing that's really frustrating about MonoDevelop is that the code completion doesn't fill in the parameters the same way that Visual Studio does, so I have to type a lot more. I mean, I have this method that takes 33 parameters..."

    "Wait a minute," I objected. "33 parameters? Does your method handle all the possible permutations? Did you ever think, for even a moment, that 'there has to be an easier way,' when you were adding, say, the 20th parameter? Do you have any idea of how much more irritating this is going to become for you as the method grows?"

    "But that's not the point," he countered. "Visual Studio does it for me when I'm using Visual Studio! I shouldn't have to do all that typing!"

    Figuring that one can lead a junior to water, but cannot make them learn maintainable practices, I'd figure I'd let him learn the hard way. I wouldn't be touching his codebase, so the outcome wasn't really my problem, anyhow. Fast forward a day or two to another conversation:

    "Sounds like you're making a lot of progress," I complimented. "What are you using for source control?"

    "Oh, that? I've heard about it," he said, sheepishly. "The code's on my computer. Right now, I do a build maybe once a week and throw the ZIP on a share folder on the server."

    "You really should put that into some form of source control," I suggested. "The benefits are enormous - your entire project is backed up, you can isolate local code differences down to individual lines, and if you mess up one file, you can download the last good copy of any file from any point in time. I'll show you how to set up SVN, Mercurial, or TFS if you'd like."

    "No thanks," he said. "I'm learning a lot right now, and I don't want to try to learn too much too quickly."

    Murphy's Law kicked in a few days later. Unity, being the gigantic turd that it is, occasionally corrupts your project files when it crashes for whatever reason. If you don't have your project files backed up, you will then have to go through the tedium of reassembling and reassociating your assets. This lovely feature had now graced Lenny's project. "Ugh, my project file won't open! It's gonna take me a while to get this all set up again!"

    At that point, a coworker sitting in the cubicle next to mine, who had been quietly savoring the schadenfreude of the events up to this point, finally spoke up. "You know, Lenny, if you'd like, I can show you how to make a backup of your important files by copying and pasting folders in Windows Explorer."



  • @Groaner Sounds like your company is TRWTF for giving a potentially real project to a junior and then not giving him any guidance or mentor.

    The best possible outcome would be that the project fails. You get to throw away the junior's code, hopefully after using it as a teaching moment to point out all the mistakes he made and unlearn the bad habits he picked up.

    If the project succeeds, however, now you have a huge pile you have to maintain, and a junior whose bad practices just got validated by the management. Fail all around.


  • Notification Spam Recipient

    @Groaner said in Juniors on side projects say the darndest things...:

    "One thing that's really frustrating about MonoDevelop is that the code completion doesn't fill in the parameters the same way that Visual Studio does, so I have to type a lot more. I mean, I have this method that takes 33 parameters..."

    Fuck me I almost fell off my ball when I read that.

    Literally

    0_1464947771746_giphy.gif

    Reading the last paragraph I feel maybe lessons can be learned and somethings can be thrown away.



  • While I agree that the autocomplete in MonoDevelop can be irritating but it should not be an excuse for the shit. I turn off the auto-complete when possible, because pressing spacebar causes it to input what MonoDevelop thinks is right when all I wanted to input is a space.



  • @WPT Is there any IDE with decent parameter completion for C++ other than Visual Studio? Something that runs on Linux or free. All I have tested is much inferior to VC++.


  • BINNED

    @fbmac said in Juniors on side projects say the darndest things...:

    @WPT Is there any IDE with decent parameter completion for C++ other than Visual Studio? Something that runs on Linux or free. All I have tested is much inferior to VC++.

    Eclipse CDT is fine, but Eclipse is shite. I recently tried CLion but will wait to see if it improves, also it is not free.


  • area_pol

    @fbmac said in Juniors on side projects say the darndest things...:

    IDE with decent parameter completion for C++

    Codelite - I was impressed that its autocomplete manages with the huge Unreal Engine 4
    Qt Creator - especially useful if you work with the Qt library



  • @Adynathos do you claim any of these is comparable to MSVC in code completion?



  • We have a Junior who had a "man bun" and claimed to know Java and PHP.

    At the time we were working in a Microsoft only shop. There were some apps that were PHP / Python (I tended to look after these) but everything else was the standard Microsoft ASP.NET Stack.

    • Two days into the job he says "I don't really like Microsoft" ... Tried promoting Linux at every opportunity.
    • I was explaining how to do proper exception handling in C#, he wasn't checking for nulls and just caught a generic exception when NullReference Exception was thrown. After telling him to fix it (i.e. check for null and deal with it accordingly), he just dismissed this advice because "I didn't like Exceptions" (whatever that meant).
    • I rewrote some of our legacy PHP forms that were vunerable to SQL Injection. I rewrote these using Python (this was my only other choice) as this was when PHP still had a horrific security record. The guy refused to use Python because it didn't use a C style syntax ...

    He got shitcanned ...


  • area_pol

    @fbmac Hard to say, I only use VS for Unreal Engine, and because its a huge engine with crazy templates, VS spends most time "parsing" the files after any changes, so I rarely wait to see the autocomplete.

    On Linux I used Codelite and one impressive thing was that - after initial parsing on project creation - the autocomplete was very fast, without VS's long waits after changes.

    Qt Creator will do good autocompletion on the Qt library, though I have seen it having problems with other libraries, maybe it needs some way of specifying where to look for the headers.


  • area_pol

    @lucas1 said in Juniors on side projects say the darndest things...:

    claimed to know Java

    I didn't like Exceptions

    Somehow the claim is hard to believe.



  • @Adynathos That could very well be causality. Having learned Java I now hate exceptions.


  • Winner of the 2016 Presidential Election

    @lucas1 said in Juniors on side projects say the darndest things...:

    He got shitcanned ...

    So… no WTF, then? I am disappoint.

    @Dragoon said in Juniors on side projects say the darndest things...:

    Having learned Java I now hate exceptions.

    Yeah, I don't like checked exceptions either. From a programmer's point of view, the advantage of exceptions is that you can ignore them until you're at the correct level in the call stack. Especially in combination with RAII (in C++), that can save you quite a lot of typing and make your code cleaner. With checked exceptions, OTOH, you're forced to explicitly ignore the error conditions by writing code, so there's not much difference to signaling errors via return values (as in Rust or Go) anymore.



  • @Groaner said in Juniors on side projects say the darndest things...:

    "You really should put that into some form of source control," I suggested. "The benefits are enormous - your entire project is backed up, you can isolate local code differences down to individual lines, and if you mess up one file, you can download the last good copy of any file from any point in time. I'll show you how to set up SVN, Mercurial, or TFS if you'd like."

    "No thanks," he said. "I'm learning a lot right now, and I don't want to try to learn too much too quickly."

    And, goshdarnit, he's right! For instance, he's just about to learn what happens when you don't have source control.


  • ♿ (Parody)

    @asdf said in Juniors on side projects say the darndest things...:

    With checked exceptions, OTOH, you're forced to explicitly ignore the error conditions by writing code, so there's not much difference to signaling errors via return values (as in Rust or Go) anymore.

    Which could be as easy as signaling up-level that an exception could be coming their way, so you can handle it at the correct level. I mean, I'm with you the lazy inconvenience, but I don't like eating my vegetables either.


  • Notification Spam Recipient

    @fbmac said in Juniors on side projects say the darndest things...:

    @WPT Is there any IDE with decent parameter completion for C++ other than Visual Studio? Something that runs on Linux or free. All I have tested is much inferior to VC++.

    eclipse. Beware the void! Beware!



  • Not everything has to be fucked. I was the most annoyed with the chap and my co-workers complained about his lack of work ethic before I complained about the fact he was an idiot.

    On Exceptions: I use Exceptions in my code where appropriate or at least try to. Using them to catch NullReference exception which is much more expensive than checking whether a value isn't null.

    if (myObject == null) return;
    
    //snip some code using myObject
    

    or

    if(myObject != null) {
        //snip some code
    }
    

    (Depending on your preference. I prefer the former so you don't end with with if statement pyramids).

    instead of:

    try {
        myObject.doStuff()
    } catch (Exception e) {
        //do nothing
    }
    

    Which was his preferred method.


  • Winner of the 2016 Presidential Election

    @lucas1 said in Juniors on side projects say the darndest things...:

    Using them to catch NullReference exception

    If that exception ever gets thrown in your code, that's a bug. Simple as that. Catching that exception type is just plain wrong.



  • @Groaner said in Juniors on side projects say the darndest things...:

    I mean, I have this method that takes 33 parameters..."

    I have a coworker who likes to take a class that's nothing but a holder for a couple of dozen pieces of data and give it a constructor that takes every single one of those fields. Then he writes code calling it and when I have to work with that code I waste hours deciphering which of the ten different parameters with the same datatype is which.

    Then we need to include another piece of data in this object and he updates the constructor to include it, and everything he's written breaks.

    Yes, I know it takes a bit more typing and quite a few more lines to call object.setFoo(); object.setBar(); object.setWhatjamacallit() a couple of dozen times, but I promise you'll like it if you try.



  • @cartman82 said in Juniors on side projects say the darndest things...:

    @Groaner Sounds like your company is TRWTF for giving a potentially real project to a junior and then not giving him any guidance or mentor.

    We were small. His boss was a C-suiter and barely had time to help mentor with their core business. Notwithstanding that Lenny was probably the Unity expert at the company at that point.

    The best possible outcome would be that the project fails.

    This is what eventually happened, but not necessarily because of the junior. He quit in an amusing fit of rage several months later for unrelated reasons.



  • @CarrieVS It depends. In C++ is is highly discouraged to create an instance of an object in an invalid or incomplete state, whether or not you place it into a valid state later. If constructing the object leaves it in a valid state, then calling setters like that afterward is fine. I think this can apply to most other languages too (maybe even C).

    In the rare event you need a lot of variables to be passed to the constructor, I think this is why chain builders were made. But I'd say it's a code smell to have enormous objects that need many variables in order to be constructed in a valid state.



  • This post is deleted!

  • BINNED

    @lucas1 said in Juniors on side projects say the darndest things...:

    Not everything has to be fucked. I was the most annoyed with the chap and my co-workers complained about his lack of work ethic before I complained about the fact he was an idiot.

    On Exceptions: I use Exceptions in my code where appropriate or at least try to. Using them to catch NullReference exception which is much more expensive than checking whether a value isn't null.

    if (myObject == null) return;
    

    Ok so you plain ignore it

    //snip some code using myObject

    
    or
    
    

    if(myObject != null) {
    //snip some code
    }

    
    (Depending on your preference. I prefer the former so you don't end with with if statement pyramids).
    
    

    Are you afraid of if-statements? as well as throwing exceptions? Ok, welcome to C, use goto

    instead of:

    try {
        myObject.doStuff()
    } catch (Exception e) {
        //do nothing
    }
    

    Which was his preferred method.

    My preferred method is

    myObject.doStuff()
    

    If it is null let the program crash and the world end with a nice stack trace



  • @dse said in Juniors on side projects say the darndest things...:

    My preferred method is

    myObject.doStuff() //myObject can't be null
    

    FTFY.

    Wishful Error Handling pattern: every call is accompanied with its preconditions stated in a comment.



  • @Maciejasjmj I suppose you would also write xpos += xvel; //neither xpos nor xvel can be NaN?


  • BINNED

    @Maciejasjmj Documentation is good, it shows you are senior.
    I prefer if it goes to the method's documentation for doxygen, but for something like can't be null? No, it should be perhaps documented at the module or project-level because otherwise all of my methods will need to mention this rather obvious requirement.


  • :belt_onion:

    @asdf said in Juniors on side projects say the darndest things...:

    @lucas1 said in Juniors on side projects say the darndest things...:

    Using them to catch NullReference exception

    If that exception ever gets thrown in your code, that's a bug. Simple as that. Catching that exception type is just plain wrong.

    I..... may have consciously written that line of code to avoid like 30 if(var==null) return false; checks on variables......

    (Null was unrecoverable but didn't deserve to bring down the whole call stack if it happened...)

    My only excuse is that I was surrounded by :wtf: and had little time. And I did go back and fix it later!


  • :belt_onion:

    @dse said in Juniors on side projects say the darndest things...:

    can't be null

    @NotNull works nicely for that. And @Nullable. And if you've got a good IDE, it'll scream if you mix the two (pass a @Nullable into a @NotNull)



  • @dse said in Juniors on side projects say the darndest things...:

    Are you afraid of if-statements? as well as throwing exceptions?

    No, I have no idea how you came to that conclusion.



  • @LB_ said in Juniors on side projects say the darndest things...:

    It depends. In C++ is is highly discouraged to create an instance of an object in an invalid or incomplete state, whether or not you place it into a valid state later. If constructing the object leaves it in a valid state, then calling setters like that afterward is fine. I think this can apply to most other languages too (maybe even C).
    In the rare event you need a lot of variables to be passed to the constructor, I think this is why chain builders were made. But I'd say it's a code smell to have enormous objects that need many variables in order to be constructed in a valid state.

    The object I'm thinking of doesn't need all its variables set to be in a valid state. In fact it will almost never have all variables non-null. This makes his constructor calls even harder to decipher as half the parameters are null and don't even have a datatype to indicate which set of things they might be.

    (He also seems to have an allergy to primitives, and always uses the wrapper classes regardless of whether there's a need. I may have caused this as in a previous project we needed to distinguish between zero and not set for a lot of things so I suggested we use wrappers. In this case it happens that the only things that we need to make that distinction for are strings.)


  • Banned

    @CarrieVS said in Juniors on side projects say the darndest things...:

    The object I'm thinking of doesn't need all its variables set to be in a valid state. In fact it will almost never have all variables non-null.

    Sounds like the 30-parameter constructor is the least of your design problems.



  • @Gąska Well I was intending to make two classes for a couple of different combinations of values, but the other guy decided otherwise and I had too much else to worry about to fight him on that.

    Basically it represents a thing which we may have a couple of dozen bits of data about, but won't necessarily have all of them. In some cases we'll know which ones we might have and definitely won't have for different contexts, in others they're fields we definitely want if they're present in the database for that record, but they're optional fields that may or may not be empty.



  • @dse said in Juniors on side projects say the darndest things...:

    Ok so you plain ignore it

    No, in Sitecore for example they have the concept of a pipeline a pipeline is a class that is intialised on web request in a particular order, think middle-wares but more complicated.

    So I may have many pipelines run on HttpRequest, all pipelines are put in a queue. Each class must have a Process method that is called when the pipeline is run. If I want to exit execution I just return out of the method and it will run the

    So I may have code like something like this:

    protected void Process(HttpRequestArgs args) {
        if(string.IsNullOrEmpty(args.Context.Request.QueryString["myQueryStringVar"])) return;
        
        //do some other stuff if myQueryStringVar isn't null. 
    }
    

  • Grade A Premium Asshole

    @Groaner said in Juniors on side projects say the darndest things...:

    It would also represent a great opportunity for him to pick up some greenfield experience in a new framework, which is something a lot of juniors don't get to do.

    There are good reasons why juniors don't usually get such projects. You guys just figured out a few of them.


  • Discourse touched me in a no-no place

    @LB_ said in Juniors on side projects say the darndest things...:

    In C++ is is highly discouraged to create an instance of an object in an invalid or incomplete state, whether or not you place it into a valid state later. If constructing the object leaves it in a valid state, then calling setters like that afterward is fine. I think this can apply to most other languages too (maybe even C).

    It depends on the lifecycle model that you're using. With Java, it's quite common when working with Spring or EJB to use a model that says that an object might be constructed in an initially-incomplete state, have a bunch of property setters called to make the object complete in terms of property configuration, and then undergo a state transition to where it is “in service”. There's even a callback you can get so that you find out when this happens; it's done via a @PostConstruct-annotated method, which can be private, so it doesn't disturb the external contract of the object. (There are equivalents on the destruction side of things.)

    Doing it this way, instead of via the constructor, makes constructing general graphs of objects much easier; you don't have to force everything into a construction DAG. (In fact, solving all of this stuff is the core of what Spring does, along with management of configurations and proxy objects. Everything else is built on top.)

    It's actually easy to use and convenient. And long-winded. Java's always long-winded.



  • @dkf said in Juniors on side projects say the darndest things...:

    With Java, it's quite common when working with Spring or EJB to use a model that says that an object might be constructed in an initially-incomplete state, have a bunch of property setters called to make the object complete in terms of property configuration, and then undergo a state transition to where it is “in service”.

    I don't know about the rest of the EJB objects, but JPA @Entity objects will get their non-Lazy fields populated before the EntityManager hands them back to you, so your code never sees the incomplete state. Then again, @Entity objects are meant to be "dumb" so you'd better not be doing any processing logic in them.


  • Discourse touched me in a no-no place

    @powerlord said in Juniors on side projects say the darndest things...:

    I don't know about the rest of the EJB objects, but JPA @Entity objects will get their non-Lazy fields populated before the EntityManager hands them back to you, so your code never sees the incomplete state. Then again, @Entity objects are meant to be "dumb" so you'd better not be doing any processing logic in them.

    They've got a somewhat simpler lifecycle than EJB, since entities are supposed to behave a lot like POJOs. The full EJB spec is a heck of a lot more complicated, but it's nice to just say “plug things together for me, and give me a callback when I'm supposed to finish setting up”. It's a lot simpler in practice than trying to do it all in constructors, and the lifecycle doesn't need to be the same as the application (e.g., Spring Web makes a lot of use of a session-level lifecycle, which is nice). Once you've not got explicit configuration and lifecycle in your code, you really don't need to write so much.

    The techniques should be applicable to many other languages, though I'd guess that most scripting languages would tend to ignore it (as it's what they can do easily already).



  • @powerlord said in Juniors on side projects say the darndest things...:

    Then again, @Entity objects are meant to be "dumb" so you'd better not be doing any processing logic in them.

    We use them to implement a rich domain model, so ours are wired with repositories to fetch or occasionally update other objects, web services, all sorts of good stuff. We use AspectJ and the @Configurable and @Resources annotations to make the repositories and other Spring configured objects inject like magic.

    We have a reasonably complex application of maybe half a million lines of code and this architecture is working really well for us so far.

    Are we bad people?



  • @cartman82 said in Juniors on side projects say the darndest things...:

    @Groaner Sounds like your company is TRWTF for giving a potentially real project to a junior and then not giving him any guidance or mentor.

    The best possible outcome would be that the project fails. You get to throw away the junior's code, hopefully after using it as a teaching moment to point out all the mistakes he made and unlearn the bad habits he picked up.

    If the project succeeds, however, now you have a huge pile you have to maintain, and a junior whose bad practices just got validated by the management. Fail all around.

    Or you could end up like me, took over the junior's project and rewrite the modules one-by-one.

    The current project I'm working on had the "functions" and "reporting" modules all replaced... Literally everything except designer generated code is replaced. One year have passed and I'm still not gone to the administration related functions yet. (Partly because I only have time working on this project occasionally)



  • @CarrieVS said in Juniors on side projects say the darndest things...:

    I have a coworker who likes to take a class that's nothing but a holder for a couple of dozen pieces of data and give it a constructor that takes every single one of those fields.

    Try tell him/her take a look at this, at least it'll say him/her some typing on creating new constructors.

    If the class is just container for parameters this should work.



  • @CarrieVS said in Juniors on side projects say the darndest things...:

    @Groaner said in Juniors on side projects say the darndest things...:

    I mean, I have this method that takes 33 parameters..."

    I have a coworker who likes to take a class that's nothing but a holder for a couple of dozen pieces of data and give it a constructor that takes every single one of those fields. Then he writes code calling it and when I have to work with that code I waste hours deciphering which of the ten different parameters with the same datatype is which.

    Then we need to include another piece of data in this object and he updates the constructor to include it, and everything he's written breaks.

    Yes, I know it takes a bit more typing and quite a few more lines to call object.setFoo(); object.setBar(); object.setWhatjamacallit() a couple of dozen times, but I promise you'll like it if you try.

    Which is why I love C# 3.0 and above, this is one of the features I miss the most when I go back to my old .Net 2.0 project on Visual 2005.


Log in to reply