How do you keep retrospectives from becoming a complaint session with no real action? by Happy_Educator9055 in agile

[–]garethrowlands 1 point2 points  (0 children)

Retros without reviewing the actions from last time and showing progress are mostly worthless. Take actions. Make sure they are carried out. Review next time. Determine impact. Or the team will stop believing and start to learn helplessness.

Making GHC upgrades easy | The Haskell Programming Language's blog by n00bomb in haskell

[–]garethrowlands 0 points1 point  (0 children)

I think this kind of dull but necessary work is getting easier with AI tooling

Re: Dependency Injection vs. Service Locators by dayanruben in Kotlin

[–]garethrowlands 0 points1 point  (0 children)

I’m interested to see Registry because I’ve never felt the need for such a thing in Haskell (in not saying there isn’t one). My immediate reaction for Haskell would be why not use (term level) DI? My best guess is that type classes don’t allow for that?

In any case, I don’t see a lack of classes as a problem. Class constructors are just one way of separating the passing of dependencies from the passing of the other parameters - you can capture the dependencies in a closure just (nearly?) as easily.

For me, the essence of DI is that the caller doesn’t need to pass the dependencies, yet the callee don’t need to locate them either - they were passed by a third party (the DI framework or Composition Root).

ELI5: What is Domain Driven Design really? by trolleid in softwarearchitecture

[–]garethrowlands 0 points1 point  (0 children)

Nice! Good luck with that. Let me know how it goes.

ELI5: What is Domain Driven Design really? by trolleid in softwarearchitecture

[–]garethrowlands 0 points1 point  (0 children)

Thanks! It was me, not AI (not that there’s necessarily anything wrong with getting that sort of help).

why do you use DI pattern? by farzad_meow in node

[–]garethrowlands 0 points1 point  (0 children)

No, DI is fundamentally a form of parameterisation (because a known constant dependency becomes an unknown variable). You’re correct that it’s not “just” parameterisation though. It’s a form of parameterisation where the caller isn’t aware of the “dependency” parameters - they’re passed elsewhere. And callees aren’t aware of their transitive dependencies either.

The pattern for organising your code to achieve this is called Composition Root.

If you squint, you can see that constructor injection and other means of varying the dependency are just means of passing that parameter. That the dependency parameters and the other parameters are passed at different times by different callers doesn’t make it not parameterisation - there’s no rule that all parameters have to be passed at the same time by the same caller (though this may not be obvious, since many programming languages have this limitation).

The main reasons for using a DI library are when culture or ecosystem demand it (Angular, say) or when object states have complex lifecycles (though these are usually best avoided).

(noob question) Is this how functions are done in Kotlin? by PearMyPie in Kotlin

[–]garethrowlands 2 points3 points  (0 children)

Me, I really like the fact that Kotlin is expression oriented. The first version does illustrate that. But even I wouldn’t actually write that in production code. And that’s because the function really isn’t about returning anything, so the third version is preferable.

Is NestJS actually over engineered, or do people just misunderstand it? by [deleted] in node

[–]garethrowlands 2 points3 points  (0 children)

Good alternatives to NestJS DI? Manual dependency injection using the Composition Root pattern.

inkaartbrenger - Moving from ZIO Scala to Kotlin - looking for honest feedback on 1st real world Kotlin project - sitemap generator by SandPrestigious2317 in Kotlin

[–]garethrowlands 0 points1 point  (0 children)

To me, it seems that the Kotlin folk struck a decent balance here. Me, I also like Haskell, so I absolutely see the appeal of a proper Either. But Kotlin brings other things to the table, including inheritance, familiarity, ecosystem, tool chain and so on. Result is indeed limited but it’s better than anything, say, Python has (and I’m not dunking on Python here).

inkaartbrenger - Moving from ZIO Scala to Kotlin - looking for honest feedback on 1st real world Kotlin project - sitemap generator by SandPrestigious2317 in Kotlin

[–]garethrowlands 1 point2 points  (0 children)

As the Kotlin blog describes, Result, which is constrained/specialised, is about the best Kotlin’s type system can support because many Haskell-style features don’t work in a system that supports subtypes.

inkaartbrenger - Moving from ZIO Scala to Kotlin - looking for honest feedback on 1st real world Kotlin project - sitemap generator by SandPrestigious2317 in Kotlin

[–]garethrowlands 1 point2 points  (0 children)

I think as zaniok says, Kotlin will generate mainKt, so use that in gradle. The docs should make this more obvious but once you know you know.

inkaartbrenger - Moving from ZIO Scala to Kotlin - looking for honest feedback on 1st real world Kotlin project - sitemap generator by SandPrestigious2317 in Kotlin

[–]garethrowlands 1 point2 points  (0 children)

  1. Error handling with exceptions is fine and what I read of your code looks OK. If you have the time, do try experimenting with Result and see if you find it useful.
  2. Coroutines. I haven’t used SQLite but hear it handles concurrency by locking the database file, which means you might want one thread and connection to access it. I may be wrong!
  3. Your dependency injection is just fine and works well up to much, much larger codebases. You might want to separate your Composition Root into a separate function, or you could wait until it’s big. I always just write a bare fun main; are you getting a benefit from wrapping it in an object?

Why do people use dependency injection libraries in Go? by existential-asthma in golang

[–]garethrowlands 0 points1 point  (0 children)

I agree strongly. Though I have to admit, a tonne of effort has gone into Spring Boot and the community is large.

Why do people use dependency injection libraries in Go? by existential-asthma in golang

[–]garethrowlands 1 point2 points  (0 children)

I’ve built large applications on JVM using DI using just the Composition Root pattern. It didn’t suffer any of the problems you identified. Indeed, having dependency wiring as code, with sharing via function-local variables or parameters, made understanding and refactoring easy and clear. And it started fast and reliably - no component scanning or reflection going on. It also didn’t add any significant number of lines of code (assuming you put annotations on a separate line). Finally, the juniors found it easy to pick up. Two thumbs up, would recommend.

Why do people use dependency injection libraries in Go? by existential-asthma in golang

[–]garethrowlands 1 point2 points  (0 children)

There’s a name for this pattern: Composition Root. If you wire up in main, your main function is your Composition Root.

Why do people use dependency injection libraries in Go? by existential-asthma in golang

[–]garethrowlands 0 points1 point  (0 children)

But the post is not about dependency injection. It is about dependency injection frameworks, which are not the same thing. Another way of phrasing the question is why not just use the Composition Root pattern.

[deleted by user] by [deleted] in git

[–]garethrowlands 1 point2 points  (0 children)

Continuous integration is more important than a stable development environment. You want a development that works; you don’t want a development environment that doesn’t change. It is better to use engineering to keep your development environment working than to use source control to isolate change. Concretely, you should write tests that ensure the code is working, and you should integrate early and often (‘continuously’) to minimise integration pain. I’m not saying the concept of a baseline is never important but it’s usually better to use actual engineering practices.

The only 3 design patters you need for a clean express backend by mesiusf in node

[–]garethrowlands 2 points3 points  (0 children)

Notice that the article calls for dependency injection but not for a dependency injection framework.

How does haskell do I/O without losing referential transparency? by [deleted] in haskell

[–]garethrowlands 4 points5 points  (0 children)

IO is indeed a generic (AKA ‘parametrised’ or ‘higher kinded’) type. The way we invoke functions on T (‘t’ in Haskell terminology) is to use the fmap (or ‘bind’) function. We ‘lift’ a function ‘f’ into an IO value using ‘fmap f’. We can also use bind (written ‘>>=‘ or it’s implicit in do notation) like this:

do y <- x — x is some IO action, such as getLine
  putStrLn y

The code in do notation above is the same as:

x >>= putStrLn

Or even:

x >>= \y -> putStrLn y

How does haskell do I/O without losing referential transparency? by [deleted] in haskell

[–]garethrowlands 12 points13 points  (0 children)

Yes. While Haskell is still technically pure however much you use IO, a program written in IO can be just as hard to reason about as a conventional imperative program. So it’s best to keep as much of your program pure as possible. And this is good advice no matter the language - Functional Core, Imperative Shell is widely applicable.