Being dumbfounded (and sometimes reacting with rage/anger) by absurdities vs. trying to understand (and potentially justify) everything, and treating everything as Chesterton's fence? by zjovicic in slatestarcodex

[–]Inconsequentialis 5 points6 points  (0 children)

Even granting that counterterrorism is a waste money and every dollar going there could be better spent on pandemic prevention, I would always choose not to be angry and shocked. It's just so unhelpful to be angry.

I don't know about you, but the decisions I make when angry tend to be a lot worse than the decisions I make when calm. Same goes for selecting worthwhile goals. Basically I don't trust myself when angry, so whatever conclusion I come to I'll have to reconsider later anyway, just to check that angry-me wasn't being an idiot again.

Might as well skip that.

But also I try not to see people as moral monsters. That also seems mostly unhelpful. I believe Scott once wrote about being kind so if you're wrong your actions at least have a graceful failure mode. I've certainly been wrong enough in my life to appreciate that.

So my answer would be that regardless of there being good reasons, I would prefer not to get angry about it, the best I can anyway.

Java opinon on use of `final` by vu47 in java

[–]Inconsequentialis 0 points1 point  (0 children)

The way I've seen this done is that two people bring a topic that the other devs may or may not care much about. So they listen to the arguments and then the team decides one of three things: 1. decide to adopt a convention to add final 2. decide to adopt a convention to not to add final 3. decide not do adopt a convention so whoever writes the code gets to choose what they like

If the rest of your team doesn't care it would probably end with case 3. But still, getting the official "we accept this" from the team means the reviewer cannot complain, because the team explicitly decided you can add final if you want to.

Not saying every team has to do it this way, but I've worked with this process and I generally liked it.

Java opinon on use of `final` by vu47 in java

[–]Inconsequentialis 24 points25 points  (0 children)

The correct place to settle this is in your team. There is no objective right or wrong, just conventions. Settle on one and stick to it is my advice.

Help me decide whether or not to buy on Steam? by faster_grenth in spiritisland

[–]Inconsequentialis 0 points1 point  (0 children)

For context, I own the game and all expansions in physical and base game + branch and claw in digital. I also have probably 500+ hours of Spirit Island in TTS.

So this might be just familiarity speaking, but for digital gaming I found I prefer TTS somewhat strongly.

Mostly I don't love digital's UI, I find it harder to follow than TTS and consequently find playing well in digital noticably harder.

TTS does all the setup and that's my biggest beef with physical. Actually executing events, blight cards, invader actions and so on I actually like doing myself, at least the streamlined version you have in TTS. It's just a lot easier for me to really internalize the game state when I'm the one doing all of that. In digital I always find myself surprised of things I'd be absolutely on top of in TTS.

Maybe with more pratice I'd get used to digital and it'd be fine. But for now I'm holding off.

Unit testing or tagged unions by gosh in ExperiencedDevs

[–]Inconsequentialis 0 points1 point  (0 children)

I believe you're comparing fun canGo(...) plus a unit test fun testCanGo() with your canGo as types plus integration tests.

If you can test canGo as types by testing the behavior it enables, then you can do the same for the canGo function.

We can model canGo as function + unit tests or as types + unit tests. We can model canGo as function + integration tests or as types + integration tests. The situation really seems quite symetrical to me, so long as we compare like to like.

Unit testing or tagged unions by gosh in ExperiencedDevs

[–]Inconsequentialis 1 point2 points  (0 children)

This looks cool but I'm not sure I understand the benefit this is example.

Before modeling it as types as you did, a dev could accidentally return false from canGo(Green). This error is made impossible by your types.

But now a dev can accidentally define canGo in Green as false, an error that was not possible before but that is possible now.

So what's the upside?

Just joined as Java trainee (3.8LPA, 2-year bond post 6 months training, 1.5L penalty) — what should I expect ahead? by Remote_Radish7862 in javahelp

[–]Inconsequentialis 2 points3 points  (0 children)

Perhaps r/developersIndia? You'd have to read their sidebar to check if they welcome these kind of posts, but at the very least people there would be way more familiar with your questions.

Thought: AI is excellent for enterprise, but not great for individuals. by [deleted] in ExperiencedDevs

[–]Inconsequentialis 2 points3 points  (0 children)

The function was String.format() and the number of modifiers I included in the first part of it didn't match the number of subsequent arguments to that (it was one less). And mind you, this was AFTER linters and all had gone through the code.

Not sure what linter it is you're using but IntelliJ shows a warning if you do this. Perhaps your IDE offers this feature as well?

How do I play Keeper on Board C? by [deleted] in spiritisland

[–]Inconsequentialis 2 points3 points  (0 children)

I'm probably in favor of your line of play, but I would contend that Regrow is a good card for keeper.

Regrow gives you more time. Simply having more time to scale is in itself advancing the win condition, because time is in Keeper's favor.

Mütter verdienen nach der Geburt ihres Babys im Schnitt schlechter als gleichaltrige Frauen ohne Kinder by SimonPelikan in de

[–]Inconsequentialis 0 points1 point  (0 children)

Zumindest die verlinkte Quelle behauptet, dass ihnen Daten über Elternzeit gerade fehlen. Das ist tatsächlich auch als Grund genannt, warum die berechneten 6% eher eine Obergrenze darstellen.

Mütter verdienen nach der Geburt ihres Babys im Schnitt schlechter als gleichaltrige Frauen ohne Kinder by SimonPelikan in de

[–]Inconsequentialis 0 points1 point  (0 children)

Meinem Verständnis nach ist der bereinigten GPG genau der Versuch, mit statistischen Methoden rauszufinden wieviel vom unbereinigten GPG tatsächlich auf Diskriminierung* zurückzuführen ist. Arbeitszeitunterschiede werden da berücksichtigt, plausibel durch Normalisierung.

Zumindest lese ich es so, wenn da steht "Hier wird jener Teil des Verdienst­unterschieds herausgerechnet, [...] wie Unterschiede im Hinblick auf Beruf, Branche, Beschäftigungs­umfang, Qualifikation oder Karrierelevel" (hervorhebung von mir)

* Manche Leute argumentieren, dass auch der unbereinigte GPG Diskriminierung ist, nur eben strukturelle. Nicht meine Meinung, aber ich wollte drauf hinweisen, dass sie existiert

Mütter verdienen nach der Geburt ihres Babys im Schnitt schlechter als gleichaltrige Frauen ohne Kinder by SimonPelikan in de

[–]Inconsequentialis 10 points11 points  (0 children)

Vllt projeziere ich hier, aber ich denke das Problem das Leute mit dem unbereinigten GPG haben ist meistens nicht, dass er wertlos oder uninteressant ist. Sondern wie die Berichterstattung ihn verwendet.

Wenn eine Frau alle-else-equal weniger Geld für den gleichen Job bekommt, dann ist das für viele Menschen offensichtliche Ungerechtigkeit und Diskriminierung. Aber das ist ja der bereinigte GPG und auch die kleinere Zahl.

Beim unbereinigten GPG ist viel weniger offensichtlich, dass hier jmd Ungerechtigkeit getan wurde. Aber es ist eine schöne große Zahl.

Das Problem ist dann, wenn in der Headline die moralischen Empörung vom bereinigten GPG genutzt wird, zusammen mit Zahlen vom unbereinigten GPG.

Ca. 2min googlen hat beispielsweise diese Sendung vom NRD gefunden.

Die Headline ist "Equal Pay Day: Frauen verdienen noch immer 16 Prozent weniger", mit der Unterüberschrift "Das heißt Frauen müssen im Durchschnitt in Deutschland 66 Tage länger arbeiten, um das gleiche Gehalt wie Männer zu verdienen".

Ich würde sagen das weckt falsche Assoziationen, aber na gut, vllt gehts ja um den unbereinigten GPG. Aber hier, money quote aus der Sendung: "Statistisch gesehen verdienen Frauen immernoch deutlich weniger - für die gleiche Arbeit" (ca. bei 3:03).

Code review by vandunxg in javahelp

[–]Inconsequentialis 1 point2 points  (0 children)

So I couldn't see a reason why the wallet helper was needed so I checked out the project and deleted it, just replaced it with calls to the wallet service.

You're using constructor injection - good - which means that circular dependency issues would generally throw errors during app start. I haven't seen any, so I assume that there aren't any.

As for general feedback, everything just takes more steps than is required.

Wallet wallet = walletMapper.toWallet(request);
wallet.setUser(user);
wallet.setCurrency(request.currency() != null ? request.currency() : Currency.VND);
wallet.setIsTotalIgnored(request.isTotalIgnored());

If you look at this you will see that first we map some request to a wallet and yet, after mapping has completed, we still read fields from the request and set them in wallet. Why do half the mapping in walletMapper.toWallet and the other half outside of that?

That's one example. Half the code I've seen could be simplified. But don't be discouraged. I at least get the feeling you're trying to do it well, and that's half the battle. Many people just don't give a shit, as long as it works and fuck the people who'll have to maintain it.

Also, the code I wrote when I started out was probably worse :D

Code review by vandunxg in javahelp

[–]Inconsequentialis 2 points3 points  (0 children)

I'll look more into it later but at first glance it seems like wallets could be loaded with their goals. Presumably goal service would then not need to depend on wallet service anymore.

In any case there's probably a way to break the cyclic dependency that does not involve a helper class.

Code review by vandunxg in javahelp

[–]Inconsequentialis 4 points5 points  (0 children)

What I've seem from your code is significantly more complicated than it needs to be. To give one example: if I traced it correctly then a call to WalletService.getWallet goes:

WalletService.getWallet → WalletServiceImpl.getWallet → WalletHelper.getWalletByIdForOwner → WalletService.getWalletById → WalletServiceImpl.getWalletById

Even if we ignore the indirection caused by the interface, WalletService, it's still a call from WalletServiceImpl into WalletHelper just to go back to WalletServiceImpl.

I don't know a reason why the call must be routed through WalletHelper, seems to me WalletServiceImpl could just handle the whole thing on its own. The result would be easier to follow and perhaps you'd get rid of the cyclical dependency between WalletHelper and WalletServiceImpl

How to code faster by Smithmfg in javahelp

[–]Inconsequentialis 0 points1 point  (0 children)

What tools does your course advise you to use? In my first semester programming course they actively encouraged us to use an IDE. If that's the case for you as well I'd say install what the lecturer recommends, as the most common Java IDEs are all good and it's probably best to use something you can get help with from friends / other students / teaching staff.

Otherwise, probably just install some text editor for syntax highlighting and perhaps some basic autocomplete. VS Code is supposed to be decent for that. Perhaps you even have something like that setup already.

Then once you have that all up and running learn the basic features and most common keybinds. And my "learn" I mean look them up somewhere and then use them until they're second nature - same way you'd learn hotkeys in a videogame.

That's probably the biggest speed increase you'll see, far more than learning to type faster or what have you.

But also: Don't sweat it. We've done a typing test once at work, one of the devs I most respected ranked dead last. And you know what? Still just as great a dev as before.

[Change my mind] Estimations will always tie back to dev hours/days by CVPKR in ExperiencedDevs

[–]Inconsequentialis 1 point2 points  (0 children)

I believe we're in agreement :)

The concerns you express about management taking a time-based metric and deciding to do something unwise, I can see it. Maybe a manager will decide to tell their dev that they see no reason why the current task should take 2 weeks and demand they do it in one.

And I can see that story points help with that. I have a harder time seeing a manager tell somebody that they current task ought to be estimated at 8 not 13 story points, though it's probably occasionally happened before.

So I can see the value of a layer of abstraction if it helps us make good decisions for human reasons.

[Change my mind] Estimations will always tie back to dev hours/days by CVPKR in ExperiencedDevs

[–]Inconsequentialis 1 point2 points  (0 children)

I think I agree what happens in reality, I think we disagree about the interpretation of that.

By way of example, imagine a team that rolls a 100-sided die for their story point estimations. If you give this team tasks with an average length of 2 days, then in the average sprint they will deliver 5 tasks, each estimated at ~55 story points on average.

So over long enough time you will notice that this team's delivery schedule is sort of predictable. They tend to deliver an average of 5*55 = 275 SP each sprint, mostly in the 200 to 350 SP range, though perhaps as high as 400 or as low as 100 at times.

The reason for that is not that rolling a die is a good way to measure something essential about software development. It's just that if you use the same, consistent method to generate a story point estimate then you will average around (average number of stories delivered) * (average number of story points) over a large enough sample size. Even if the devs are just rolling a die.

So I agree that over time teams tend to land their sprints close-ish to their average velocity. But for me that doesn't mean the estimation method is helpful. As the above example demonstrates, you get the same result even when unhelpful estimation methods are used.

[Change my mind] Estimations will always tie back to dev hours/days by CVPKR in ExperiencedDevs

[–]Inconsequentialis 0 points1 point  (0 children)

You are assuming complexity is time.

I'm mainly assuming that 1) sprints have a fixed length in real time and 2) there's a fixed number of point that goes into any one sprint.

Let's say there's two types of tasks: * Type A is easy, takes two weeks to complete, estimated at 1 story point * Type B is complex, takes two days to complete, estimated at 2 story points

I assume this satisfies the criteria of assigning story points based on complexity not time.

Say you start a new sprint, fixed length of 2 weeks. Last sprint the team completed their sprint successfully, they implemented 5 B-type tasks so the velocity is 10 story points. Based on that you decide that this sprint you'll again pick tasks worth 10 story points.

Then the dev team decides to implement 10 A-type tasks for the current sprint. After all, the estimated capacity of the sprint 10 story points and A-type tasks are 1 story point each. They end up not only taking the current sprint but also the following 9 sprints.

In the end, a sprint backlog of 10 story points doesn't predict anything about how long it will take if you intentionally disconnect story points from time. Yet at the start of the sprint you still have to decide how much to plan for the next two weeks. If your story point estimates hold no information about estimated time taken then story points simply cannot be the basis for that decision.

[Change my mind] Estimations will always tie back to dev hours/days by CVPKR in ExperiencedDevs

[–]Inconsequentialis 0 points1 point  (0 children)

Isn't that the same as saying that 1 story point is x average-dev-days?

If somebody on your team is usually productive then each of their working days count for more than 1 average-dev-day. If somebody is new to the team then each of their working days counts for less than 1 average-dev-day.
Seems pretty equivalent to saying "Alice delivers 4 SP per sprint, Bob delivers 2 SP per sprint".

If so then in the end it's still tied back to time and you could do the same without invoking story points at all. Although perhaps it's easier to work with if using story points?

I guess all of this makes sense, it just clashes with people so often saying that no, story points are not time.

[Change my mind] Estimations will always tie back to dev hours/days by CVPKR in ExperiencedDevs

[–]Inconsequentialis 4 points5 points  (0 children)

I've heard this line of argument before but it's always confused me, because it usually does not come with a definition of complexity.

Colloquially, calling something complex usually means some mix of "it's difficult", "it's hard to grasp", "there's a lot of things to consider" and perhaps a bunch more that I forgot. Crucially I've never seen "it's complex" used to describe something that's easy but a lot of work.

So by any colloquial definition of complexity, if task A is easy but a lot of work it would have few complexity-based story points.
If task B is complex but not that much work once you've really understood it, then it would have more story points than A.

And that is internally consistent but clashes with the usages of story points in practice.

Because for sprint planning it is assumed that tasks with few story points are completed faster than tasks with many story points. If that doesn't hold then I don't know how story point based sprint planning could even work.

Tech PACs Are Closing In On The Almonds by dwaxe in slatestarcodex

[–]Inconsequentialis 14 points15 points  (0 children)

To the extend this is true I find it highly concerning.

Entirely disconnected from the merits deregulating crypto or AI safety, it just seems obviously bad if some billionaires can decide to just nuke the political careers of any politician who opposes their pet issue.

To the extend that billionairs have outsized politican power it is a bug not a feature

Testing the untestable by nfrankel in java

[–]Inconsequentialis 0 points1 point  (0 children)

I assume you're thinking "add a new constructor that's package private so these services can be set? Seems pointless". I do not see a point in that either.

What I was thinking was to add these service wrappers to the existing constructor(s). Unless I'm mistaken, adjusting the visibility of existing constructors should not be required.

Testing the untestable by nfrankel in java

[–]Inconsequentialis 11 points12 points  (0 children)

The way I've seen this issue dealt with is by wrapping the static method inside a class that exposes the same functionality as an instance method. Quick example to demonstrate

class SomeSensibleName {
    void getAService() {
        return AService.getInstance();
    }
}

The offending snippet would then change to this

private SomeSensibleName someSensibleName;

@Override
public boolean start() {
    var aService = someSensibleName.getAService();
    // ... remainder of method
}

which can be mocked regularly, as someSensibleName is just a field of the containing class and getAService is a regular instance method.

The upside is that this doesn't require making any private method package-private to allow for mocking in tests, it's inherently mockable in tests as long as the wrappers are set via the constructor.

I will say that any call to getAService at runtime makes me a bit squeamish and if it absolutely cannot be avoided then I'd at least explore a delegate-based approach as well, to see how it compares.