- 176
- 154 102
Pairing with Duncan
United Kingdom
เข้าร่วมเมื่อ 16 เม.ย. 2013
Let's pair program in (mainly) Kotlin!
I've been programming since 1981, and a professional software developer for more than 30 years. I've been lucky enough to have some excellent teachers over the years, but I remember what it was like to work in an organisation where people didn't share my passion or expand my skills. So, now that I'm retired, it's time to give back. Subscribe to get a weekly fix of pair programming with an experienced engineer. Learn how I approach coding, problem solving, debugging and project management. Watch me try to figure out AI. Marvel at how often things fail the first time, but quickly get better.
Advanced Kotlin with Extreme Programming (XP), covering Java to Kotlin, Test Driven Development (TDD), Refactoring, Object Oriented (OOP) and Functional Programming (FP). Co-author with Nat Pryce of the O'Reilly book Java to Kotlin - A Refactoring Guidebook.
Show your appreciation though the medium of PayPal - www.paypal.com/paypalme/DuncanMcGregor
I've been programming since 1981, and a professional software developer for more than 30 years. I've been lucky enough to have some excellent teachers over the years, but I remember what it was like to work in an organisation where people didn't share my passion or expand my skills. So, now that I'm retired, it's time to give back. Subscribe to get a weekly fix of pair programming with an experienced engineer. Learn how I approach coding, problem solving, debugging and project management. Watch me try to figure out AI. Marvel at how often things fail the first time, but quickly get better.
Advanced Kotlin with Extreme Programming (XP), covering Java to Kotlin, Test Driven Development (TDD), Refactoring, Object Oriented (OOP) and Functional Programming (FP). Co-author with Nat Pryce of the O'Reilly book Java to Kotlin - A Refactoring Guidebook.
Show your appreciation though the medium of PayPal - www.paypal.com/paypalme/DuncanMcGregor
Tidy First Kotlin - Removing Redundant Code
To me, coding feels more like gardening than building. Instead of erecting permanent structures, we are planting things that grow, and occasionally die.
Sometimes we need to move code from one place to another where it is better suited. Sometimes a class is alive but just cluttering things up. If so, then we can dig it out and spend the time that we would have spent weeding and feeding on more productive tasks.
Today then we’re going to remove code from our Gilded Rose codebase, leaving it with the same features for our customers, but easier to work with for developers.
In this episode
* 00:00:36 We are currently loading stock data from a TSV file
* 00:01:22 and from Postgres
* 00:02:25 The unnecessary code is a bit of a burden
* 00:03:20 Remove DualItems from the production code
* 00:04:29 Now remove its tests
* 00:05:57 We had a test to remind us that we had some work to do when DualItems is obsolete!
* 00:06:45 Now we can delete that test and the DualItems
* 00:07:51 Remove StockFileItems test-first
* 00:08:47 and its configuration
* 00:09:19 Review and commit
* 00:10:24 Can we tidy up DbItems now that we are in the area?
* 00:10:49 IntelliJ inline is really broken
* 00:11:55 Undo when things get too bad and try another tack
* 00:13:19 Are we doing enough in the database?
* 00:13:42 We get a warning either way we call isEmpty!
* 00:14:16 Manually test because we don't have acceptance test coverage
There is a playlist of TDD Gilded Rose episodes - th-cam.com/play/PL1ssMPpyqocg2D_8mgIbcnQGxCPI2_fpA.html
The codebase is available on GitHub github.com/dmcg/gilded-rose-tdd
If you are going to be at KotlinConf 2025, or even just in Copenhagen in May, then you should totally be signing up for the workshop that Nat Pryce and I are running. It’s called Refactoring to Functional Kotlin, and will give you hands-on experience of taking legacy code and safely migrating it to a functional style. Places are limited, so buy now at kotlinconf.com/workhops
If you like this video, you’ll probably like my book Java to Kotlin, A Refactoring Guidebook (java-to-kotlin.dev). It's about far more than just the syntax differences between the languages - it shows how to upgrade your thinking to a more functional style
Sometimes we need to move code from one place to another where it is better suited. Sometimes a class is alive but just cluttering things up. If so, then we can dig it out and spend the time that we would have spent weeding and feeding on more productive tasks.
Today then we’re going to remove code from our Gilded Rose codebase, leaving it with the same features for our customers, but easier to work with for developers.
In this episode
* 00:00:36 We are currently loading stock data from a TSV file
* 00:01:22 and from Postgres
* 00:02:25 The unnecessary code is a bit of a burden
* 00:03:20 Remove DualItems from the production code
* 00:04:29 Now remove its tests
* 00:05:57 We had a test to remind us that we had some work to do when DualItems is obsolete!
* 00:06:45 Now we can delete that test and the DualItems
* 00:07:51 Remove StockFileItems test-first
* 00:08:47 and its configuration
* 00:09:19 Review and commit
* 00:10:24 Can we tidy up DbItems now that we are in the area?
* 00:10:49 IntelliJ inline is really broken
* 00:11:55 Undo when things get too bad and try another tack
* 00:13:19 Are we doing enough in the database?
* 00:13:42 We get a warning either way we call isEmpty!
* 00:14:16 Manually test because we don't have acceptance test coverage
There is a playlist of TDD Gilded Rose episodes - th-cam.com/play/PL1ssMPpyqocg2D_8mgIbcnQGxCPI2_fpA.html
The codebase is available on GitHub github.com/dmcg/gilded-rose-tdd
If you are going to be at KotlinConf 2025, or even just in Copenhagen in May, then you should totally be signing up for the workshop that Nat Pryce and I are running. It’s called Refactoring to Functional Kotlin, and will give you hands-on experience of taking legacy code and safely migrating it to a functional style. Places are limited, so buy now at kotlinconf.com/workhops
If you like this video, you’ll probably like my book Java to Kotlin, A Refactoring Guidebook (java-to-kotlin.dev). It's about far more than just the syntax differences between the languages - it shows how to upgrade your thinking to a more functional style
มุมมอง: 492
วีดีโอ
Understanding Gradle
มุมมอง 1.4Kวันที่ผ่านมา
It’s been 6 months since I had a major and public sense of humour failure with Gradle, but it’s still the build tool I know, and to be honest has been relatively painless in the Gilded Rose codebase. I do find that it helps to periodically refresh my mental model of how build tasks relate to each other, and how Gradle decides what gets run when. So today, instead of arguing with our build, let’...
Taming Dependencies with Gradle Version Catalogs
มุมมอง 46214 วันที่ผ่านมา
It’s a sad truth of modern software development that maintaining our build and deployment systems is taking more and more of the time that we could be using to write our own bugs. After my recent video on upgrading Gradle dependencies (th-cam.com/video/J8Pi9XvHkxg/w-d-xo.html), viewers recommended that I invest some more time in version catalogs (docs.gradle.org/current/userguide/platforms.html...
Groovy to Kotlin - Migrating a Gradle Build
มุมมอง 59021 วันที่ผ่านมา
I created the TDD Gilded Rose codebase in 2021, when the default for Gradle build scripts was the Groovy language. Since then I’ve tried to convert to the Kotlin DSL at least 3 times, and every time I’ve been beaten by some difficulty that just made the conversion uneconomic. Whatever you think about them, LLMs are certainly changing software economics at a rapid pace, so let’s have another go,...
Upgrading Dependencies for No Fun and No Profit
มุมมอง 525หลายเดือนก่อน
My aim was to show every significant edit to our Test Driven Gilded Rose codebase, but in practice there is a whole category of changes that I haven’t shown you - upgrading dependencies. As many of our dependencies have new versions I thought that now would be a good time to show my thought processes in deciding when, how and whether to keep up to date. It’s a bit tedious to be honest! As you w...
Replacing Handlebars - kotlinx.html for HTMX
มุมมอง 1Kหลายเดือนก่อน
Extreme Programming introduced the idea of a Spike Solution - a small experiment to that goes deep into a topic to explore and solve potential issues before we commit to changes that would be hard to reverse. In our Gilded Rose codebase we are using HTMX (htmx.org) to implement partial page updates. We have found that using Handlebars templates (handlebarsjs.com) to render these HTML fragments ...
Migrating Kotlin Context Receivers
มุมมอง 976หลายเดือนก่อน
Last week’s refactoring (th-cam.com/video/W_Hd1O3_XUk/w-d-xo.html) to remove our IO context receiver was relatively easy because the receiver was never actually referenced, it was just a marker. Our transaction context receiver may carry state though, so to remove its use we are going to have to convert from function contexts to function parameters. This is the widest-ranging refactor that we h...
Abolishing Kotlin Context Receivers
มุมมอง 988หลายเดือนก่อน
They say that no good deed goes unpunished, and it is a curse to live in interesting times. Welcome to life as a professional software developer. 18 months ago, I thought that Context Receivers were going to be a useful addition to the Kotlin language. So I published a series of episodes where I used them in the Gilded Rose stock control system, firstly just as a marker to show where code perfo...
Back to Basics Kotlin Refactoring - Man vs Machine
มุมมอง 6822 หลายเดือนก่อน
This week we’re back in our test-driven Gilded Rose codebase. For those who have only started watching recently - this is an implementation of a stock control system for a magical goods store, using Kotlin in a largely functional style, and developed iteratively over 100 episodes so far. Key technologies are Postgres via JOOQ and HTMX via http4k. It’s been a year since we added any core functio...
The Future of Source Code with Stephan Janssen
มุมมอง 4902 หลายเดือนก่อน
This is the final part of my conversation with Stephan Janssen. Whilst we do look at how to upload a whole project to an LLM’s web interface, and in particular Antropic’s context cache, most of the chat is between the two humans in the room. We discuss the difference between an LLM and a junior developer, what AI is good at now and where it should get better, and one of my favourite topics, the...
Mastering Chat-Oriented Programming with Stephan Janssen
มุมมอง 6222 หลายเดือนก่อน
In this episode I’m continuing my chat and pairing with Stephan Janssen, founder of the Devoxx conference empire and author of the Devoxx Genie AI plugin for IntelliJ github.com/devoxx/DevoxxGenieIDEAPlugin Last week (th-cam.com/video/NRAe4d7n6_4/w-d-xo.html) Stephan helped me understand how chatting with a large language model is implemented. Armed with this knowledge, this week we open up the...
Devoxx Genie AI Deep Dive with Stephan Janssen
มุมมอง 5922 หลายเดือนก่อน
This week I’ve been lucky enough to talk with Stephan Janssen, founder of the Devoxx conference empire and author of the Devoxx Genie github.com/devoxx/DevoxxGenieIDEAPlugin AI plugin for IntelliJ that we looked at last episode. My experience of what people are now calling Chat Oriented Programming - conversing with a large language model to help us write code - is mixed. I have had some impres...
Introducing the Devoxx Genie AI Plugin for IntelliJ
มุมมอง 9212 หลายเดือนก่อน
I have to confess that I’m really confused by AI tools for software development. I have found them very useful when asked to do simple tasks that I don’t know how to do - writing Bash loops or FFMPEG command lines - that sort of thing. But for real codebases they can be frustrating, either requiring repeated cajoling to get things right, or just missing the point completely. Mostly I think that...
Pairing with Duncan - the rebrand
มุมมอง 8623 หลายเดือนก่อน
Hello it’s Duncan I’ve been a professional developer for more than 30 years. Some of what I’ve learned in that time is written in books, but much much more is transmitted by working with people in teams, often whilst pair programming. Pair programming is a fantastic technique for spreading knowledge; but I know that we can’t all work in an environment where that is possible, or when it is, with...
AI-Generated Property-Based Fizz-BuzzWords - Now with Dark Mode
มุมมอง 4373 หลายเดือนก่อน
It was only while I was editing the first video in this series that I realised that the code could overflow its integer counter (after two billion or so rounds) and start counting up with negative numbers. Whilst its unlikely that FizzBuzz overflow could blow up a rocket, the point of kata is to practice our skills in a safe environment, so I’m not going to just shrug this off - we should learn...
This one’s important - Refactoring to Functional Kotlin
มุมมอง 9493 หลายเดือนก่อน
This one’s important - Refactoring to Functional Kotlin
Science with Servers - Benchmarking http4k and ktor
มุมมอง 4514 หลายเดือนก่อน
Science with Servers - Benchmarking http4k and ktor
Implementing Interfaces with Method Maps
มุมมอง 7454 หลายเดือนก่อน
Implementing Interfaces with Method Maps
Hunt the method - Advanced Kotlin Proxy Magic
มุมมอง 4454 หลายเดือนก่อน
Hunt the method - Advanced Kotlin Proxy Magic
Supercharge your Kotlin with Java Dynamic Proxies
มุมมอง 8884 หลายเดือนก่อน
Supercharge your Kotlin with Java Dynamic Proxies
Refactoring to the Repository Pattern
มุมมอง 1.4K4 หลายเดือนก่อน
Refactoring to the Repository Pattern
Advanced techniques for Kotlin Power Assert
มุมมอง 4825 หลายเดือนก่อน
Advanced techniques for Kotlin Power Assert
Generalising all the things - Expert Kotlin Refactoring
มุมมอง 6146 หลายเดือนก่อน
Generalising all the things - Expert Kotlin Refactoring
But turns out the program is irrelevant, so we can just delete the whole program. It's now much easier to maintain, and takes much less time to compile.
Luckily Alison has re-upped our contract, so we know she wants the functionality we have delivered.
That failing test about “remember to close DbItems” was nothing short of wonderful. What a delightfully empathic thing of Past Duncan to have done, in order to help out Future Duncan. ❤
Thank you. As I hadn’t rehearsed this session, my surprise at the failing test was genuine. To be honest though, I doubt whether the time spent writing that test was actually worthwhile. The consequences of leaving a class open are hardly severe, and it’s telling that the name of the test got out of sync because it was an identifier that wasn’t updated in a refactoring. So maybe the takeaway should be - you can use tests to maintain code structure invariants, and you can set up tests to let you know when an event has occurred.
This is the best refactoring video I have ever seen! Thanks for sharing ❤
Thank you. I think some of my later work is better, or at least better (video) edited, so please look around.
If `flywayMigrate` defines the task outputs, can you set the `generateJooq` inputs to be the `flywayMigrate` outputs? If you map them in the special gradle way, gradle knows about the task dependency without explicitly stating it. By explicitly depending on `flywayMigrate` and also setting the inputs to the path that `flywayMigrate` writes to, I think you're accomplishing the same thing -- but in a less flexible way. I'm not familiar with either plugin, so it seems quite likely that you can't use this approach.
I think this is the same question as @dom asked? This would be a better solution, marred only by my not knowing how to make it work! At this point having something that does the job allows me to get on with actual programming, but, as you say, with a bit of an unsatisfactory feeling.
@@eatthepi if the flywayMigrate task output returns if new migrations have been applied, yes you could. But if we are looking at two tasks that need to always run together the declarative approach stops making sense and it's better/easier to just use "doLast{}" on flywayMigrate.
Took me forever to get around to watching this. I had hoped for some examples on how to make HTMX apps that work more like React or Flutter and less like jQuery. I don't know why I had hoped for that, but I see it was way out of scope! Question: what plugin do you have that gives you the button to approve the actual files?
That’s it, hold my feet to the fire! I have plans to look at click to edit, but one thing at a time. The fabulous Ivan wrote plugins.jetbrains.com/plugin/9424-okey-doke-support
Wouldn't make more sense to put input.files("src/main/resources/db/migration") into the flywayMigrate task? (If it's not by default like that)
Good question, thank you. I did wonder while I was filming. We would still have to make the jooq task depend on migrate in order to have the migrate happen, but jooq would run, with its delays, whether or not the migrate actually did anything. I suppose it is possible to run one task only if another actually ran? But this works, and seems the least complicated, if not the best expression of the actual task dependencies.
@@PairingWithDuncan Yes, apparently this can be achieved using outputs.upToDateWhen { false } on the flywayMigrate task (I haven't personally tested it).
The fact that Gradle even exists (I claim) is a symptom of a pretty sick attitude towards complexity and, ultimately, quality. It is a tool born of laziness and arrogance (and, to be fair, Java weirdness).
I think I know what you mean by the attitude towards complexity, but like democracy, Gradle is the worst solution except for all the others
@@PairingWithDuncan This is true, sadly. Here's hoping Amper can rescue us from the madness. I'm in the middle of some KMP fun and games myself, and I find I spend more time fiddling with Gradle than I do actually developing features.
There's also Declarative Gradle that's being worked on, which might make the builds for most projects (that don't need extra logic) more simple to understand, eventually?
Unstoppable force (Duncan) meets immovable object (comprehending Gradle)
:-) I figure that at least I’m aiming at a relatively stationary part of Gradle, so stand a chance of hitting.
I recommend using „-rerun-tasks“ over clean.
Oh wow, I’ve been using Gradle for, what, 10 years now, and no one has ever told me about that. Must investigate thank you.
We've set up a "Renovate" bot at our workplace taking care of dependency updates by opening pull requests. That helped us keeping on track with dependency updates immensely. Its highly customizable in regards of what to update, when to to run and even supports merging automatically once CI tests were successful. It supports both dependency declarations in the build.gradle.kts as well as the .toml file. And it can even update the Gradle wrapper itself. However, it's not written or configurable using Kotlin, so it's most likely not a fit for a video on this channel. Just wanted to let others know who might be struggling with dependency updates as well.
Not sure which version this was added but at least in Android Studio, IDE shows a warning if update is available in toml
I had heard that there was editor support, but haven’t seen it in IntelliJ. There is a warning (at least in the build.gradle) if there is a CVE against a library, but I didn’t see support for other version updates.
I got into Kotlin sometimes back, it's horrible having to upgrade every 3 months. no wonder Java won. I pity my team for putting them through this
Do you need to talk about it ;-? I do feel that Kotlin is going through a bit of a lull at the moment. We have to put up with constant tooling change for not perceived progress on the language front. The changes, Gradle aside, are rarely breaking though, so I tolerate them. Java is also evolving, but I don’t think we can say either won, and I still prefer Kotlin to Java or Scala for team productivity and fun.
Do either of dependency tasks you used allow you to specify via flags or config to ignore alpha/beta/RC and/or only show patch, minor or major updates?
Good question thank you. They do! Gradle-versions-plugin has something complicated, but I’m told that refreshVersions can be configured with refreshVersions { enableBuildSrcLibs() rejectVersionIf { candidate.stabilityLevel.isLessStableThan(current.stabilityLevel) } }
Hilarious intro 😂
@TimSchraepen thank you. It’s the only bit I script, so it’s good to know my efforts aren’t wasted
I don't know if the Kotlin DLS is any "better" than the original Groovy DSL. They say you're supposed to take advantage of the autocomplete to inspect available properties, but as you've seen, the script doesn't even get syntax highlighting until it's fully correct, so I rarely actually get to use it. This doesn't make the Kotlin DLS any worse though; I think both are about the same amount of pain to work with. But for consistency, I might as well use the Kotlin DSL in my Kotlin project. And since I don't even know Groovy, at least I know what my copy-pasta is doing.
I think this sums up my view. Neither is good enough, Kotlin is a bit better.
In my opinion is a lot better, the problem with groovy gradle files is that people at some point tend to write scripts that works by accident, they dont declare plugins but declare extensions for them and the plugin is applied in different file etc. This leads to IDE being completly useless, hovewer in kotlin due to type safety it forces you to write better code, and IDE is actually helpful.
Version Catalog should probably be your next hurdle, it really does make updating dependencies MUCH easier (and less error prone) one large multi-module project and I like that the catalog is reusable between projects, a little fiddley to get strings and such, but honestly makes everything so much nicer once done.
At the risk of flogging a dead elephant, this is on my list for next week!
Welcome to the party! Perhaps just in time for the new declarative DSL to drop!
All the more content to thrill you with
You jest, but Jetbrains are working on a new build system...
No, not even. Gradle is working on a new declarative DSL. As for Amper, so far, there's been conflicting information on whether it's a layer on top of gradle or not. If it is, then I fear it will add too many new failure points to be worthwhile.
@oharaandrew314 Isn’t Amper both? The problem is that we want a JFDI build, where we can also customise everything when we have specialist requirements
Who cares about removing the apply? If it works I would leave it.
I suppose my thought was that if I had other builds to convert, the extension would save a bunch of manual work.
Why didn't you use the AI to help fix the issues?
To be honest, because when I tried that in a run-through (I prefer the term to rehearsal ;-) it just dug me in to a deeper hole.
The latest release of kotlinx.html is visible at 5:37 at the right column of the github page.
The AI assistant is impressive. We're not allowed to use this feature at work, so I appreciate seeing it in action.
Thanks for the feedback. I’m slowly learning where I expect it to be faster than doing things by hand. At the moment these bulk transformations seem to be a good bet.
The versions gradle plugin you used can be configured with "RejectVersionsIf and componentSelection" to filter out those beta version update suggestions. It would be nice if it worked a bit better out of the box, but for my projects where I do a bit of configuration, the plugin would have suggested the Kotlin 2.0.0 -> 2.0.21 update. Gradle version catalogs extract all the dependency versions into a "libs.versions.toml"-file. In that file, the IDE does give me quick actions to update dependency version strings, although it doesn't work 100% of the time.
Thank you for the info. I’ve been thinking of introducing a version catalog, although yet another file format!
The flyway issue seems to be that your testdb only created a db named postgres and your connection string wanted a db guilded_rose, my guess is flyway 9 falls back to postgres (default name).
I did wonder about the name, thank you. It’s surprisingly hard to record and RTFS at the same time.
Like it, would check changelogs and compiler output in addition. Doing updates at least once a week in our team.
Thank you. I think I have accumulated a bit of compiler warning debt - the Playwright deprecation in particular, but that should be fixable when I next see it. I have to confess that I don't tend to check library changelogs unless something goes wrong. Which is a bit of a risk, but with good integration tests hasn't yet bitten me (that I remember ;-).
Since FlyWay 10 they've moved specific database support to separate modules instead of bundling them all in their core module. I suspect you'll need to add their postgres database module dependency org.flywaydb:flyway-database-postgresql
FWIW From my experience LLM’s are quite good in helping out with kotlinx.html.
That's good to know thanks. I may try to see if they can add some style!
if an attribute is common enough you can simply define an "extension property" for example /** * The hx-post attribute will cause an element to issue a POST to the specified URL and swap the HTML into the DOM * using a swap strategy. * * @see hxSwap * */ internal var HTMLTag.hxPost: String get() = attributes.getValue("hx-post") set(value) { attributes["hx-post"] = value }
this is really useful, specially if you're gonna use htmx all over the place
For attributes that have a predefined set of possible values one can create an enum containing the posibilities, to take advantage of typesafety enum class HxSwap { /** * Replace the inner html of the target element. * */ innerHTML, /** * Replace the entire target element with the response * */ outerHTML, .... and so on } /** * The hx-swap attribute allows you to specify how the response will be swapped in relative to the [hxTarget] of an * AJAX request. If you do not specify the option, the default is htmx.config.defaultSwapStyle (innerHTML). * * @see hxSwapOob * */ internal var HTMLTag.hxSwap: HxSwap get() = HxSwap.valueOf(attributes.getValue("hx-swap")) set(value) { attributes["hx-swap"] = value.name }
I also did this but I never implemented the get()’s. Do you happen to know when they’re used?
@@TimSchraepen actually we never use the getter, atleast i havent found a situation where it's useful to read the value of an attribute, it's actually better to define extension functions, that way we can do it in a more semántic way hxSwap(HxSwap.outerHTML, "from:body") // or whatever fun HTMLTag.hxSwap(value: HxSwap, vararg modifier: String = emptyArray()) { attributes["hx-swap"] = value.name + modifier.joinToString(prefix = " ", separator = " ") }
That's a good tip thank you.
Thanks Duncan. It was very interesting to follow your reasoning. I also really like your plugin that tracks the progress of the tests and the shortcuts used. Which plugin is it, please?
Glad it was helpful! The shortcuts are shown with plugins.jetbrains.com/plugin/7345-presentation-assistant-for-2023-2, although I note that the IDE now has that built in (in a more in-your-face way). I get lots of questions about the test progress bar. It was written by the inimitable @dmitrykandalov. To use it install his Liveplugin (plugins.jetbrains.com/plugin/7282-liveplugin) and then this gist gist.github.com/dmcg/1f56ac398ef033c6b62c82824a15894b
12:37 Wunderbar ✨ Love your refactoring videos. I appreciate your very structured approach on refactoring. I've used to get stuck trying to refactor to much at the same time. I've been watching your videos for a long time now and have read the book a while ago, both of which helped me in improving my own refactorings over the years. Thank you for that. Even though we had some areas of code where context receivers deemed a great fit over the last years, we refrained from using them as they were still experimental. While the refactoring does not look to bad, I'm still glad we opted for that approach, as some of the contexts might've span almost the whole application, which in turn would've resulted in refactorings affecting a lot of places in the code. Of course a flexible startup like Gilded Rose can take some of those risks associated with adopting experimental technologies. 😉 Have a great weekend.
Thank you for your kind words. As you say, contexts are solving multi-layer propagation, and so require intervention at each layer. I’m thinking of reverting most of this refactor in order to redo it when context parameters are finally available (skipping a compiler version).
Late this week as I was having so much fun at SoCraTes Belgium that I forgot it was Friday!
TL;DR: context receivers and context parameters aren't really 2 separate features, but more so an evolution of a feature. Context parameters will end up fulfilling almost everything that we wanted from context receivers Haven't finished the video fully yet, but in terms of elegance, context parameters will actually be pretty alright. The only downside is that you'll have to make contextual "bridge" functions to members. Skipping a (minor) compiler version isn't so bad as well. I think the context receivers to context params hasn't been communicated well enough. My understanding is that the differences are very tiny, and in a way context params are just a natural evolution of context receivers (but with names, and without propagating member/extension functions, only context functions). The same core idea is still absolutely there, and the migration should actually be pretty simple once context params are out (just adding a name or _ for every context, creating bridge methods, and that's it) Oh and having contexts on classes is getting removed too, but that feature wasn't fleshed out fully anyway.
Maybe it’s a bit clickbait, but yes, it hasn’t been communicated well! And context(_:IO) is just a shame!
@@PairingWithDuncan I don't even think your video is clickbait. There's been somewhat of a "panic" (for lack of a better word) in the context-using community, and it's unfortunate because the reality isn't that bad at all. `context(_: IO)` is annoying, but that's a minor change that can be easily added in the future. I think right now they don't want to add `context(IO)` because there's an idea to have different semantics for that (which would basically match the current CR semantics) but that idea hasn't been explored fully.
With all due respect, you could probably wait 10 years and you would have a 50% chance of getting something useful out of this ai code generation
For me the infuriating thing about AI is that it can and does give useful results, but, at present, not reliably enough to be economical in my day to day work.
Great feedback honest, but without ranting and without giving up that the tool could be able to provide the service one day. Only minor remark, you ask to like the video for less of that content "more human coding" 😅 I liked anyway, because it's a great demo. But personally I would be more interested in more of those 😂
I really appreciate you taking the time to comment. The last few videos have had more downvotes than usual, so I’m wondering what people want to see, so thanks for letting me know.
Happy birthday Duncan! Thanks for your time spent on your videos.
Thank you. I hadn’t realised that I would be publishing this on my birthday, so it’s a nice bonus to share it with viewers.
Thanks for going back to this series.
It’s my happy place! I’m thinking of organising a Gilded Rose Con next year.
Great video Duncan! I've been playing with AI assistants in established codebases and this video was a great example of the current limitations, especially when compared with an experienced human doing the same refactoring loop. I'm wondering if a tool could be built that allowed a human to ask the AI assistant to start the refactoring and then fed the failed test messages back into the AI assistant automatically and have it continue to iterate on the refactoring until the test suite was green? Any interest in collaborating on that?
🤔 I think that it has legs, especially as I know two people who know how to write IntelliJ plugins! Have you seen this th-cam.com/video/HsAdTP8T5Ao/w-d-xo.html
@@PairingWithDuncan oh that’s interesting! Thanks for sharing!
Hello sir I am fresher I am looking for jobs but every company asking only dsa they are not focusing on developement , I getting bored when I start learning dsa or solving leetcode problems can please how can get job or internship without dsa
Well you seem to be way better at getting TH-cam subscribers than I am! My advice would be to build contacts in the industry by meeting other developers, and build a portfolio of work that you can show off on GitHub
It turns out that context receivers are going to be replaced with context parameters, but no release will support both to allow us to migrate. So don't do this!
AI is useful but I'm getting tired of hearing about it. Good videos 👍🏼
I’m pleased we managed to produce something interesting enough!
Allen Laura Taylor Richard Davis Betty
Erm?
Thank you Stephan!
Very knowledgeable and generous with his time
I don't really want PHD's working in my team, though. I'd much prefer great problem solvers who have converted years worth of mistakes into sharp instincts and high standards. I'm yet to be convinced that current gen AI in any form can fulfill those requirements.
This is an interesting point. PhD knowledge may be good when we want an answer to a factual question, or a summary on a topic. No one has a PhD in my codebase though, so here we want good inference, not knowledge. Plus ‘clever’ people sometimes make bad developers. Was it Joel Spolsky who wanted to hire “smart, and gets things done”?
I don't know if this AI is really usefull. Removing that property was a relatively simple example, just grep for the name of the properties to get the files, then open the file and remove the text. Seems easy enough.
My experience has been that for tasks that I know how to do, AI is a bit frustrating. And I know how to do the majority of tasks in my projects. But others are reporting significant productivity gains, and frustration is often a function of lack of experience, so I’m trying to work through to find the sweet spot.
I say please to LLMs too. It's because we are British and were brought up proper.
Enjoyed it 🎉
Thank you! More interesting chat about chat to come.
Thank you for an informative and entertaining video! I really enjoyed having Dmitry as a co-presenter because it feels like participating in a real-life conversation
I appreciate the feedback. I’m trying to feature more actual pairing on the channel, but in the meantime there are quite a few with Dmitry to enjoy
Socrates mentioned! Hype!
I'll put details in the shownotes too
What! You tease...
I did warn you in the introduction!
@@PairingWithDuncan You did.
Great tool for IJ. Thanks for promoting.
It's certainly nice to have options, and I've learned a lot by using it.
Important finding, copying with the small clipboard button keeps the formatting. If you disable the "streaming mode (beta)", some of my code is in code blocks that have their own clipboard button. If that is not the case, you can copy the whole message and remove what you don't need. Either way, the formatting stays. Thanks for the video!
That’s really useful to know, thank you
This made me laugh (at the underwhelming experience) and glad to see I've not been missing much in the AI coding assistant world
So many people I respect report having such good results that I think I must be doing something wrong. Maybe my coding style, choice of language and libraries is just not conducive to AI assistance, or maybe I’m just not patient enough. I hope Stephan will help me work out which.