Pairing with Duncan
Pairing with Duncan
  • 176
  • 154 102
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
มุมมอง: 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
Ultimate Kotlin TDD FizzBuzz
มุมมอง 7923 หลายเดือนก่อน
Ultimate Kotlin TDD FizzBuzz
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
Benchmarking Ktor and http4k
มุมมอง 7695 หลายเดือนก่อน
Benchmarking Ktor and http4k
Advanced techniques for Kotlin Power Assert
มุมมอง 4825 หลายเดือนก่อน
Advanced techniques for Kotlin Power Assert
Kotlin Power Assert
มุมมอง 9145 หลายเดือนก่อน
Kotlin Power Assert
Was Betteridge right?
มุมมอง 8265 หลายเดือนก่อน
Was Betteridge right?
Duncan is away
มุมมอง 4046 หลายเดือนก่อน
Duncan is away
We need to talk about Gradle
มุมมอง 2.1K6 หลายเดือนก่อน
We need to talk about Gradle
Generalising all the things - Expert Kotlin Refactoring
มุมมอง 6146 หลายเดือนก่อน
Generalising all the things - Expert Kotlin Refactoring
Ktor vs http4k
มุมมอง 1.4K6 หลายเดือนก่อน
Ktor vs http4k

ความคิดเห็น

  • @user-yf1ml8jt3i
    @user-yf1ml8jt3i 4 วันที่ผ่านมา

    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.

    • @PairingWithDuncan
      @PairingWithDuncan 4 วันที่ผ่านมา

      Luckily Alison has re-upped our contract, so we know she wants the functionality we have delivered.

  • @TimSchraepen
    @TimSchraepen 5 วันที่ผ่านมา

    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. ❤

    • @PairingWithDuncan
      @PairingWithDuncan 5 วันที่ผ่านมา

      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.

  • @mytubekt
    @mytubekt 8 วันที่ผ่านมา

    This is the best refactoring video I have ever seen! Thanks for sharing ❤

    • @PairingWithDuncan
      @PairingWithDuncan 8 วันที่ผ่านมา

      Thank you. I think some of my later work is better, or at least better (video) edited, so please look around.

  • @eatthepi
    @eatthepi 12 วันที่ผ่านมา

    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.

    • @PairingWithDuncan
      @PairingWithDuncan 12 วันที่ผ่านมา

      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.

    • @dom-
      @dom- 8 วันที่ผ่านมา

      @@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.

  • @oharaandrew314
    @oharaandrew314 12 วันที่ผ่านมา

    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?

    • @PairingWithDuncan
      @PairingWithDuncan 12 วันที่ผ่านมา

      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

  • @dom-
    @dom- 12 วันที่ผ่านมา

    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)

    • @PairingWithDuncan
      @PairingWithDuncan 12 วันที่ผ่านมา

      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.

    • @dom-
      @dom- 12 วันที่ผ่านมา

      @@PairingWithDuncan Yes, apparently this can be achieved using outputs.upToDateWhen { false } on the flywayMigrate task (I haven't personally tested it).

  • @upbeatsarcastic8217
    @upbeatsarcastic8217 12 วันที่ผ่านมา

    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).

    • @PairingWithDuncan
      @PairingWithDuncan 12 วันที่ผ่านมา

      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

    • @upbeatsarcastic8217
      @upbeatsarcastic8217 12 วันที่ผ่านมา

      @@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.

    • @Blacklands
      @Blacklands 11 วันที่ผ่านมา

      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?

  • @kyay10
    @kyay10 13 วันที่ผ่านมา

    Unstoppable force (Duncan) meets immovable object (comprehending Gradle)

    • @PairingWithDuncan
      @PairingWithDuncan 13 วันที่ผ่านมา

      :-) I figure that at least I’m aiming at a relatively stationary part of Gradle, so stand a chance of hitting.

  • @IPad-gf8mv
    @IPad-gf8mv 13 วันที่ผ่านมา

    I recommend using „-rerun-tasks“ over clean.

    • @PairingWithDuncan
      @PairingWithDuncan 13 วันที่ผ่านมา

      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.

  • @JentaroYusong
    @JentaroYusong 15 วันที่ผ่านมา

    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.

  • @zeusalmighty6740
    @zeusalmighty6740 18 วันที่ผ่านมา

    Not sure which version this was added but at least in Android Studio, IDE shows a warning if update is available in toml

    • @PairingWithDuncan
      @PairingWithDuncan 18 วันที่ผ่านมา

      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.

  • @nixoncode
    @nixoncode 18 วันที่ผ่านมา

    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

    • @PairingWithDuncan
      @PairingWithDuncan 18 วันที่ผ่านมา

      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.

  • @Alivezombie16
    @Alivezombie16 18 วันที่ผ่านมา

    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?

    • @PairingWithDuncan
      @PairingWithDuncan 18 วันที่ผ่านมา

      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) } }

    • @TimSchraepen
      @TimSchraepen 18 วันที่ผ่านมา

      Hilarious intro 😂

    • @PairingWithDuncan
      @PairingWithDuncan 18 วันที่ผ่านมา

      @TimSchraepen thank you. It’s the only bit I script, so it’s good to know my efforts aren’t wasted

  • @oharaandrew314
    @oharaandrew314 26 วันที่ผ่านมา

    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.

    • @PairingWithDuncan
      @PairingWithDuncan 26 วันที่ผ่านมา

      I think this sums up my view. Neither is good enough, Kotlin is a bit better.

    • @xozzy7809
      @xozzy7809 26 วันที่ผ่านมา

      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.

  • @righteouscoder
    @righteouscoder 26 วันที่ผ่านมา

    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.

    • @PairingWithDuncan
      @PairingWithDuncan 26 วันที่ผ่านมา

      At the risk of flogging a dead elephant, this is on my list for next week!

  • @oharaandrew314
    @oharaandrew314 26 วันที่ผ่านมา

    Welcome to the party! Perhaps just in time for the new declarative DSL to drop!

    • @PairingWithDuncan
      @PairingWithDuncan 26 วันที่ผ่านมา

      All the more content to thrill you with

    • @vlogan79
      @vlogan79 26 วันที่ผ่านมา

      You jest, but Jetbrains are working on a new build system...

    • @oharaandrew314
      @oharaandrew314 26 วันที่ผ่านมา

      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.

    • @PairingWithDuncan
      @PairingWithDuncan 25 วันที่ผ่านมา

      @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

  • @sandrodelacruz8125
    @sandrodelacruz8125 26 วันที่ผ่านมา

    Who cares about removing the apply? If it works I would leave it.

    • @PairingWithDuncan
      @PairingWithDuncan 26 วันที่ผ่านมา

      I suppose my thought was that if I had other builds to convert, the extension would save a bunch of manual work.

  • @sandrodelacruz8125
    @sandrodelacruz8125 26 วันที่ผ่านมา

    Why didn't you use the AI to help fix the issues?

    • @PairingWithDuncan
      @PairingWithDuncan 26 วันที่ผ่านมา

      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.

  • @gekylafas
    @gekylafas หลายเดือนก่อน

    The latest release of kotlinx.html is visible at 5:37 at the right column of the github page.

  • @eatthepi
    @eatthepi หลายเดือนก่อน

    The AI assistant is impressive. We're not allowed to use this feature at work, so I appreciate seeing it in action.

    • @PairingWithDuncan
      @PairingWithDuncan หลายเดือนก่อน

      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.

  • @eatthepi
    @eatthepi หลายเดือนก่อน

    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.

    • @PairingWithDuncan
      @PairingWithDuncan หลายเดือนก่อน

      Thank you for the info. I’ve been thinking of introducing a version catalog, although yet another file format!

  • @jonathankolberg2706
    @jonathankolberg2706 หลายเดือนก่อน

    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).

    • @PairingWithDuncan
      @PairingWithDuncan หลายเดือนก่อน

      I did wonder about the name, thank you. It’s surprisingly hard to record and RTFS at the same time.

  • @IPad-gf8mv
    @IPad-gf8mv หลายเดือนก่อน

    Like it, would check changelogs and compiler output in addition. Doing updates at least once a week in our team.

    • @PairingWithDuncan
      @PairingWithDuncan หลายเดือนก่อน

      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 ;-).

  • @TimSchraepen
    @TimSchraepen หลายเดือนก่อน

    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

  • @TimSchraepen
    @TimSchraepen หลายเดือนก่อน

    FWIW From my experience LLM’s are quite good in helping out with kotlinx.html.

    • @PairingWithDuncan
      @PairingWithDuncan หลายเดือนก่อน

      That's good to know thanks. I may try to see if they can add some style!

  • @juanherrera9521
    @juanherrera9521 หลายเดือนก่อน

    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 }

    • @juanherrera9521
      @juanherrera9521 หลายเดือนก่อน

      this is really useful, specially if you're gonna use htmx all over the place

    • @juanherrera9521
      @juanherrera9521 หลายเดือนก่อน

      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 }

    • @TimSchraepen
      @TimSchraepen หลายเดือนก่อน

      I also did this but I never implemented the get()’s. Do you happen to know when they’re used?

    • @juanherrera9521
      @juanherrera9521 หลายเดือนก่อน

      @@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 = " ") }

    • @PairingWithDuncan
      @PairingWithDuncan หลายเดือนก่อน

      That's a good tip thank you.

  • @OlivierCatteau
    @OlivierCatteau หลายเดือนก่อน

    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?

    • @PairingWithDuncan
      @PairingWithDuncan หลายเดือนก่อน

      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

  • @JentaroYusong
    @JentaroYusong หลายเดือนก่อน

    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.

    • @PairingWithDuncan
      @PairingWithDuncan หลายเดือนก่อน

      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).

  • @PairingWithDuncan
    @PairingWithDuncan หลายเดือนก่อน

    Late this week as I was having so much fun at SoCraTes Belgium that I forgot it was Friday!

  • @kyay10
    @kyay10 หลายเดือนก่อน

    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.

    • @PairingWithDuncan
      @PairingWithDuncan หลายเดือนก่อน

      Maybe it’s a bit clickbait, but yes, it hasn’t been communicated well! And context(_:IO) is just a shame!

    • @kyay10
      @kyay10 หลายเดือนก่อน

      @@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.

  • @razvanfilip3735
    @razvanfilip3735 หลายเดือนก่อน

    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

    • @PairingWithDuncan
      @PairingWithDuncan หลายเดือนก่อน

      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.

  • @brunolannoo5452
    @brunolannoo5452 2 หลายเดือนก่อน

    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 😂

    • @PairingWithDuncan
      @PairingWithDuncan 2 หลายเดือนก่อน

      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.

  • @lmoalves
    @lmoalves 2 หลายเดือนก่อน

    Happy birthday Duncan! Thanks for your time spent on your videos.

    • @PairingWithDuncan
      @PairingWithDuncan 2 หลายเดือนก่อน

      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.

  • @oltiondoda7639
    @oltiondoda7639 2 หลายเดือนก่อน

    Thanks for going back to this series.

    • @PairingWithDuncan
      @PairingWithDuncan 2 หลายเดือนก่อน

      It’s my happy place! I’m thinking of organising a Gilded Rose Con next year.

  • @mikegehard6402
    @mikegehard6402 2 หลายเดือนก่อน

    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?

    • @PairingWithDuncan
      @PairingWithDuncan 2 หลายเดือนก่อน

      🤔 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

    • @mikegehard6402
      @mikegehard6402 2 หลายเดือนก่อน

      @@PairingWithDuncan oh that’s interesting! Thanks for sharing!

  • @ShortBits786
    @ShortBits786 2 หลายเดือนก่อน

    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

    • @PairingWithDuncan
      @PairingWithDuncan 2 หลายเดือนก่อน

      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

  • @PairingWithDuncan
    @PairingWithDuncan 2 หลายเดือนก่อน

    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!

  • @dmartls1
    @dmartls1 2 หลายเดือนก่อน

    AI is useful but I'm getting tired of hearing about it. Good videos 👍🏼

    • @PairingWithDuncan
      @PairingWithDuncan 2 หลายเดือนก่อน

      I’m pleased we managed to produce something interesting enough!

  • @RichardGonzalez-v6y
    @RichardGonzalez-v6y 2 หลายเดือนก่อน

    Allen Laura Taylor Richard Davis Betty

  • @JamesJosephFinn
    @JamesJosephFinn 2 หลายเดือนก่อน

    Thank you Stephan!

    • @PairingWithDuncan
      @PairingWithDuncan 2 หลายเดือนก่อน

      Very knowledgeable and generous with his time

  • @upbeatsarcastic8217
    @upbeatsarcastic8217 2 หลายเดือนก่อน

    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.

    • @PairingWithDuncan
      @PairingWithDuncan 2 หลายเดือนก่อน

      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”?

  • @camilotorresf1
    @camilotorresf1 2 หลายเดือนก่อน

    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.

    • @PairingWithDuncan
      @PairingWithDuncan 2 หลายเดือนก่อน

      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.

  • @Onlinepmcourses
    @Onlinepmcourses 2 หลายเดือนก่อน

    I say please to LLMs too. It's because we are British and were brought up proper.

  • @IPad-gf8mv
    @IPad-gf8mv 2 หลายเดือนก่อน

    Enjoyed it 🎉

    • @PairingWithDuncan
      @PairingWithDuncan 2 หลายเดือนก่อน

      Thank you! More interesting chat about chat to come.

  • @vanyazkv
    @vanyazkv 2 หลายเดือนก่อน

    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

    • @PairingWithDuncan
      @PairingWithDuncan 2 หลายเดือนก่อน

      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

  • @TimSchraepen
    @TimSchraepen 2 หลายเดือนก่อน

    Socrates mentioned! Hype!

    • @PairingWithDuncan
      @PairingWithDuncan 2 หลายเดือนก่อน

      I'll put details in the shownotes too

  • @Onlinepmcourses
    @Onlinepmcourses 2 หลายเดือนก่อน

    What! You tease...

    • @PairingWithDuncan
      @PairingWithDuncan 2 หลายเดือนก่อน

      I did warn you in the introduction!

    • @Onlinepmcourses
      @Onlinepmcourses 2 หลายเดือนก่อน

      @@PairingWithDuncan You did.

  • @Talaria.School
    @Talaria.School 2 หลายเดือนก่อน

    Great tool for IJ. Thanks for promoting.

    • @PairingWithDuncan
      @PairingWithDuncan 2 หลายเดือนก่อน

      It's certainly nice to have options, and I've learned a lot by using it.

  • @ulicqueldromal
    @ulicqueldromal 2 หลายเดือนก่อน

    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!

    • @PairingWithDuncan
      @PairingWithDuncan 2 หลายเดือนก่อน

      That’s really useful to know, thank you

  • @nickbw
    @nickbw 2 หลายเดือนก่อน

    This made me laugh (at the underwhelming experience) and glad to see I've not been missing much in the AI coding assistant world

    • @PairingWithDuncan
      @PairingWithDuncan 2 หลายเดือนก่อน

      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.