• 5 Posts
  • 14 Comments
Joined 2 years ago
cake
Cake day: July 29th, 2023

help-circle
  • I often felt that current ML speeds up newbie devs by effectively teaching them the language and libraries — but slows down experts that already know the stack well from memory.

    It depends. You don’t need LLMs to write stuff for you that you already know. You use them to take.care of the drudge work or explore things you are not familiar with. Things like Copilot’s /explain can speed up onboarding even for seasoned developers, and Copilot can also help you speed up iterations on proofs of concept. For example, I’ve been using Copilot to experiment with some changes to the software architecture of some projects I own, and it’s fantastic at generating code following specific design patterns. It’s also fantastic to get it to iterate designs in near-real.time by prompting it with directives such as “repeat the last example but implementing X with design pattern Y and moving the implementation to Z”. You are presented with examples that you can browse through and get a taste of what you’d get, but with a fraction of the time. To top things off, you can prompt Copilot to present pros and cons and even propose optimizations.

    Like any tool, it has its purposes. You just need to learn how to use it.


  • I don’t use chat, it’s usually useless.

    I think Chat is the most useful feature of Copilot. Prompts like /docs work impeccably, but /explain and /optimize is also pretty good. /tests is hit-and-miss if you have zero tests and require too much context if you already have them. More often than not /fix is a waste of time.

    Where I found Copilot to be quite useful is something unexpected: naming things. You can prompt it to give suggestions, you can ask it to refactor things for you. Quite nice.

    I think that Claude is far better at generating code, and explore new stuff, but Claude is also down and broken extremely often,not to mention it’s annoying limit of 10 questions per half a day.


  • I use chat the most. It’s pretty good once you understand the importance of building context, set up personas, and feed it workable prompts. The biggest mistake I see people do is presume that you can expect it to output gold when inputting garbage.

    Once you build up an understanding of what personas work for your personal tastes and what context you need to have, it can output impressive results. The most success I’ve been having is with somewhat complex refactorizations. Stuff like “refactor X so that Y and Y” can save you a lot of time.

    The most disappointing experience has been with writing unit tests. copilot has this infuriating tendency to remove old tests when you’re prompting it to add new ones. You need to explicitly request it to append tests to file X without overwriting existing tests for it not to mess up, and even then results are sketchy. For unit tests it’s also important to setup good contexts otherwise whatever time you save by prompting copilot to write them will be wasted refactoring code to use specific frameworks and follow specific styles.


  • Like most have already said, the auto complete is top tier (…)

    My experience is the exact opposite. Even though it has its moments, more often than not it just hallucinates and proposes a lot of stuff that neither matches definitions nor could possibly compile. I guess that this might reflect the impact of having classes with similar names in multiple namespaces but it’s bad to the point I prefer to rely exclusively on plain old autocorrelation.





  • It’s usually easier imo to separate them into different processes (…)

    I don’t think your comment applies to the discussion. One of the thread pools mentioned is for IO-bound applications, which means things like sending HTTP requests.

    Even if somehow you think it’s a good idea to move this class of tasks to a separate process, you will still have a very specific thread pool that can easily overcommit because most tasks end up idling while waiting for data to arrive.

    The main take is that there are at least two classes of background tasks that have very distinct requirements and usage patterns. It’s important to handle both in separate thread pools which act differently. Some frameworks already do that for you out of the box. Nevertheless it’s important to be mindful of how distinct their usage is.





  • What features do you use often And what features are not that useful in an IDE and can be considered bloat?

    Being able to build projects and debug them is a given. Why would anyone use an IDE that did not supported building or running a project?

    Developers spend most/practically all their time navigating through a project. Therefore, features such as opening files, searching for symbols, going to definitions, navigating back to points you were in, end up being the ones everyone uses the most. Also, code bookmarks are also of critical importance to work on specific tasks.

    Support for refactoring primitives is also of critical importance. It’s extremely convenient to extract/inline functions, rename symbols across the whole project, automatically generate code such as classes and their unit tests, etc. Nowadays, if an IDE does not support basic refactoring features such as extract/inline function/variable then I’d argue that it’s not worth bothering with.

    Finally, source code formatting. It’s surprising the impact on team dynamics and productivity that we get by having an entire team on the same page with regards to where a space is expected to show and not show up.

    I’m sure that there are plenty of spectacular features that should be must-haves but I’m oblivious to. Not using them doesn’t mean they are bloat.






  • Focusing on code coverage (which doesn’t distinguish between more and less important parts of the code) seems like the opposite of your very good (IMO) recommendation in another comment to focus on specific high-value use-cases.

    The usefulness of code coverage ratios is to drive the conversation on the need to track invariants and avoid regressions. I agree it’s very easy to interpret a metric as a target to optimize, but in this context coverage ratios is primarily used to raise the question on why wasn’t a unit test added.

    It’s counterproductive to aim for ~100% but without this indicator any question or concern regarding missing tests will feel arbitrary. With coverage ratios being tracked, this topic becomes systematic and helps build up a team culture that is test-driven or at least test-aware.

    Code coverage is an OK metric and I agree with tracking it, but I wouldn’t recommend making it a target. It might force developers to write tests, but it probably won’t convince them.

    True. Coverage ratios are an indicator, and they should never be an optimizable target. Hence the need to keep minimum coverage ratios low, so that the team has flexibility to manage them. Also important, have CICD pipelines export the full coverage report to track which parts of the code are not covered.

    The goal is to have meaningful tests and mitigate risks, and have a system in place to develop a test-minded culture and help the team be mindful of the need to track specific invariants. Tests need to mean something and deliver value, and maximizing ratios is not it.



  • Here’s a way to convince a team to write unit tests:

    • setup a CICD pipeline,
    • add a unit test stage,
    • add code coverage calculation,
    • add a rule where unit tests fail if a code coverage metric drops.
    • if your project is modularized, add pipeline stages to build and test and track code coverage per module.

    Now, don’t set the threshold to, say, 95 %. Keep it somewhat low. Also, be consistent but not a fundamentalist.

    Also, make test coverage a part of your daily communication. Create refactoring tickets whose definition of done specifies code coverage gains. Always give a status report on the project’s code coverage, and publicly praise those who did work to increase code coverage.