I have basically the same workflow. Planning mode has been the game changer for me. One thing I always wonder is how do people work in parallel? Do you work in different modules? Or maybe you split it between frontend and backend? Would love to hear your experience.
I plan out N features at a time, then have it create N git worktrees and spawn N subagents. It does a decent job. I find doing proper reviews on each worktree kind of annoying, though, so I tend to pull them in one at a time and do a review, code, test, feedback loop until it’s good, commit it, pull in the next worktree and repeat the process.
I literally have 3 folders, each on their own branch. But lately I use 1 folder a lot but work on different features (that won't introduce "merge conflicts" in a sense). Or I do readonly explorations (code auditing is fun!) and another one makes edits on a different feature, and maybe another one does something else in the Flutter app folder. So fairly easy to parallelize things like this. Next step is to install .net sdk + claude on some vm's and just trigger workflows from there, so no ide involved..
You won't be able to parallelize things if you just use the IDE's and their plugins. I do mine in the terminal with extra tabs, outside of the IDE.
I use GitHub Copilot in Intellij with Claude Sonnet and the plan mode to implement complete features without me having to code anything.
I see it as a competent software developer but one that doesn't know the code base.
I will break down the tasks to the same size as if I was implementing it. But instead of doing it myself, I roughly describe the task on a technical level (and add relevant classes to the context) and it will ask me clarifying questions. After 2-3 rounds the plan usually looks good and I let it implement the task.
This method works exceptionally well and usually I don't have to change anything.
For me this method allows me to focus on the architecture and overall structure and delegate the plumbing to Copilot.
It is usually faster than if I had to implement it and the code is of good quality.
The game changer for me was plan mode. Before it, with agent mode it was hit or miss because it forced me to one shot the prompt or get inaccurate results.
> I see it as a competent software developer but one that doesn't know the code base.
I know what you mean, but the thing I find windsurf (which we moved to from copilot) most useful (except writing opeanapi spec files) is asking it questions about the codebase. Just random minutiae that I could find by grepping or following the code, but would take me more than the 30s-1m it takes it. For reference, this is a monorepo of a bit over 1M LoC (and 800k YAML files, because, did I mention I hate API specs?), so not really a small code base either.
> I will break down the tasks to the same size as if I was implementing it. But instead of doing it myself, I roughly describe the task on a technical level (and add relevant classes to the context) and it will ask me clarifying questions. After 2-3 rounds the plan usually looks good and I let it implement the task.
Here I disagree, sort of. I almost never ask it to do complex tasks, the most time consuming and hardest part is not actually typing out the code, describing it to an AI takes me almost as much time as implementing for most things. One thing I did find very useful is the supertab feature of windsurf, which, at a high level, looks at the changes you started making and starts suggesting the next change. And it's not only limited to repetitive things (like . in vi), if you start adding a parameter to a function, it starts adding it to the docs, to the functions you need below, and starts implementing it.
> For me this method allows me to focus on the architecture and overall structure and delegate the plumbing to Copilot.
Yeah, a coworker said this best, I give it the boring work, I keep the fun stuff for myself.
Ah yes of course. But no one asked for the code really. Just show us the app. Or is it some kinda super-duper secret military stuff you are not even supposed to discuss, let alone show.
It is neither of these. It's an application that processes data and is not accessible outside of the companies network. Not everything is an app.
I described my workflow that has been a game changer for me, hoping it might be useful to another person because I have struggled to use LLMs for more than a Google replacement.
As an example, one task of the feature was to add metrics for observability when the new action was executed. Another when it failed.
My prompt: Create a new metric "foo.bar" in MyMetrics when MyService.action was successful and "foo.bar.failed" when it failed.
I review the plan and let it implement it.
As you can see it's a small task and after it is done I review the changes and commit them. Rinse and repeat.
I think the biggest issue is that people try to one shot big features or applications. But it is much more efficient to me to treat Copilot as a smart pair programming partner. There you also think about and implement one task after the other.
I've been writing an experimental pipeline-based web app DSL with Claude Code for the last little while in my spare time. Sort of bash-like with middleware for lua, jq, graphql, handlebars, postgres, etc.
How much experience do you have working in Java? This statement really surprises me because Java has some of the best in class tools to debug and troubleshoot issues.
Explain them the concepts of loot boxes and pay to win. My son, who was 8 at that time, understood quiet fast that these games don't require skill and are just trying to steal money from him. He doesn't like that and now avoids games that contain these dark patterns and has become quiet good at spotting them.
Also, buy a Nintendo console. It solves 99% of all problems. I haven't seen these dark patterns in any Nintendo title and personally I think it's the best gaming environment for kids.
Looking forward to this JEP. This is, IMO, how Streams should have been implemented from the get go. All intermediate operations can now be expressed with Gatherers rather than having dedicated methods that can never cover all intermediate operations people come up with.
And as a companion piece I really enjoyed Paul Sandoz's 'Code Reflection' talk https://www.youtube.com/watch?v=xbk9_6XA_IY, which considers how java code might understand java code. The sort of thing that enable pushing functions to SQL or GPUs for example.
Interesting, but I don't see how operating on the code model is going to be any easier than working on the AST. It seems much more hard to reason about many transformations as compared to manipulating the AST. I do hope they take inspiration from scala and rust macros
Well currently you can't get at the AST, only (with some hairy code) bytecode. (The use cases are post-compilation)
But suppose this work did enable that. What Paul is saying is that there are intermediate representations between bytecode and AST that are more helpful for these GPU / SQL / whatever runtime compilers. Representations that capture dataflows, for example. Chance are these compilers would transform an AST to something like this anyway.
Thanks, that makes sense. I think I approached more from the perspective of a library writer that doesn't want to delve into the depth of language to implement transformations/macros. However it does seem reasonable to have a variety of abstractions to be able to express these transformations in a way closer to the target language
Why ironic? Java is a multi paradigm language (though obviously not at the same level as say C++). It has been getting "functional" features for a while now, including streaming libraries, pattern matching, immutable records, etc.
Because they have in the past declared "Java is not a functional language" and were hostile to the use of monads in the standard library. They are adding nice features, but the language will never be as clean and unified as Scala.
Monads don’t go by the name, they must satisfy the axioms. How many people do it right? Even in Haskell lots of folks forget to check the axioms. Also, monads are hard to compose. I think there’s no reason to be like Cats or Arrow. It’s all already there, the mental shift is minimal in my opinion.
"Monads don't compose" just means you should choose a single monad for most of your functions; in Scala that is usually Future, Either, Try, IO or ZIO. There are conversion methods between the most common monads.
Scala monads are fantastic IMO; Either-based programming is simple and eliminates tons of boilerplate. So is Cats, although the learning curve is steep.
We got one in 2020 and we use it daily. Chicken, french fries, sausages, fish and bread is what we use it for most of the time. Some things like spring rolls are better fried with oil but overall we love it and it is a real time saver and of course less oil is used.
My partner is vegetarian and I’ve found that tofu and soy curls are near life changing good in the air fryer.
Cube the tofu, cook for 75% of the total time, pull out and dress in liquid seasoning, return for the last bit and the outside gets crisp while the inside remains juicy!
We don't make bread. We just make bread from the previous day hot and crunchy again. It just takes a few minutes. We used to do this with the oven but that takes quite some time more.