Live data from Hacker News

Fighting Complexity in Software Development

github.com

51–60 of 117 posts

Re: Fighting Complexity in Software Development

#51
post #38
post #31

Earlier quoted context omitted.

The problem is when you want validation errors which contains the field name, and a descriptive error message. Oh you want them localised as well? You then want each field to be validated individually. So you get an error for each field which is wrong. So you have if statements for each field creating a localised validation error object then placing in a list. You have 8 fields coming in on your request. It's startin…

> The problem is when you want validation errors which contains the field name, and a descriptive error message. Oh you want them localised as well? So the above example would become something like this: if (!string.IsNullOrEmpty(card.CardNumber) && CardNumberRegex.IsMatch(card.CardNumber)) validationContext.add("CardNumber", Localizer.MessageFor("InvalidCCNumber")); if (x.ExpirationMonth 12) validationContext.add("E…

Your starting to build your own validation library inside that validation context. Inside I presume it must be creating some kind of error object to a list.

Next problem, rename a field on the object using a refactoring tool. You now have to change validation code to change the field name. You may forget about the validation code if your not looking at it. You have good tests though so you would probably would catch it. But you want it to be automatic. Maybe nameof?

The class is getting a lot responsibility, and you want to seperate validation out into its own class responsible for that. Maybe extract to a validation object which operates on a request/command class?

Might point is you eventually you end up building something like fluent validation. With own set of default rules, validation classes etc. Maybe fluent validation is overly complicated but I'd rather get the speed boost of using a well tested library that I already know instead of gradually refactoring into something custom.

Re: Fighting Complexity in Software Development

#52
post #13

I feel like I’ve responded this before, but I feel like people often attribute their increased knowledge of how to develop systems without bugs to the new fancy language they switched to. Fact is they could build better software in the old language as well, assuming they started from scratch.

I strongly disagree. We use a strongly typed Lua-like language at my company and it has everything you need to build decent applications, but we hit so many bugs. It took me 12 hours over 5 days to make a simple modification to the business logic (half of that was figuring out and fixing bugs). It took me 4 hours to write something far more complex in Rust with virtually zero bugs; I attribute this almost entirely to…

> We use a strongly typed Lua-like language at my company [...]

Is this homegrown? In my experience this alone has a major impact in productivity because it is generally hard to create a good implementation and a new language and/or implementation only pays when the existing solution is too bad. (Source: I have made a Lua type checker at work. It worked, but fell into disuse as I moved on and the entire org abandoned Lua in spite of my work.)

Re: Fighting Complexity in Software Development

#53
post #13

I feel like I’ve responded this before, but I feel like people often attribute their increased knowledge of how to develop systems without bugs to the new fancy language they switched to. Fact is they could build better software in the old language as well, assuming they started from scratch.

In my opinion it's usually worse using a new framework or language as you don't know the ins and outs of it. Your first project is going to be a learning experience in that technology. I have seen plenty of Python code that was clearly written by Java developers wanting to try out something new.

Re: Fighting Complexity in Software Development

#54
post #21

I really love the concepts provided by Domain Driven Design (DDD), regardless if you choose OOP or FP to implement it with. It's fine if you want to choose C#, and there're better ways of addressing the approaches to validation in OOP than were provided in the examples. Value objects are a nice way to ensure strong immutable types like credit cards can be created and passed around without requiring separate validatio…

I find doing things like having types that flow through different stages -> UnvalidatedEmail, ValidatedEmail, VerifiedEmail is a lot better in f#. In c# you need to create a lot of value object classes for that. Or have some kind of property inside the value object which indicates current state of the email. Even then you won't be able to exhaustive pattern matching on it to guarantee each situation is handled.

Maybe I'm missing something, but what stops you from having Unvalidated etc wrapper classes in C#?

Re: Fighting Complexity in Software Development

#55
post #17
post #8

In mature OOP you have ways to write nice models and have good validations. https://guides.rubyonrails.org/active_record_validations.htm... I will argue that the complexity of software development is not because of OOP vs Functional. Tooling, documentation, quality of libraries and people are what matter most. Ruby was a massive success is largely attributed to above. We are humans, we can understand and deal with a…

but have you ever had to maintain a ruby project after the first year? The cost just goes up and up, and I think it’s because the language is so hostile to static analysis.

I would stay Dynamic languages like Ruby are inherently more flexible and powerful, which more easily leads to complexity in the system... (if left unchecked)

Re: Fighting Complexity in Software Development

#56
post #13

I feel like I’ve responded this before, but I feel like people often attribute their increased knowledge of how to develop systems without bugs to the new fancy language they switched to. Fact is they could build better software in the old language as well, assuming they started from scratch.

I strongly disagree. We use a strongly typed Lua-like language at my company and it has everything you need to build decent applications, but we hit so many bugs. It took me 12 hours over 5 days to make a simple modification to the business logic (half of that was figuring out and fixing bugs). It took me 4 hours to write something far more complex in Rust with virtually zero bugs; I attribute this almost entirely to…

I attribute this almost entirely to sum types (Rust enums), a better type system, an unforgiving compiler, async/await, a better module system, lifetime checking...

This seems like an example of a language effectively abstracting common complexities and pain points, which were probably discovered in earlier languages...

Re: Fighting Complexity in Software Development

#57

Earlier quoted context omitted.

"Started from Scratch". I have never seen any project where something has been started from scratch actually turn out well.

People are going to jump on the imprecise wording here but this is generally correct. People need to be very wary of "let's just throw this out and start over". There are cases where it makes sense, but 95% of the time it amounts to "the old code is complicated and it's a lot more fun to start over than it is to figure out the old stuff some other guy wrote". The old code is complex because it actually works and has…

Rebuilds are generally a bad idea, and I've never had a good experience doing that. Apart from what you've already stated, it's kind of an insult to the team before you, that you just deleted their code.

Replacing a system is also not really solving a problem that the business cares about. So this enevitably leads to feature creep, "If you're rebuilding it, can you add X, Y, Z...". This then leads raises the bar even higher...

The better alternative is to modularize the system somehow and replace seperate chunks... but that's easier said than done

Re: Fighting Complexity in Software Development

#58
post #28
post #8

In mature OOP you have ways to write nice models and have good validations. https://guides.rubyonrails.org/active_record_validations.htm... I will argue that the complexity of software development is not because of OOP vs Functional. Tooling, documentation, quality of libraries and people are what matter most. Ruby was a massive success is largely attributed to above. We are humans, we can understand and deal with a…

Agree. You can write terse, maintainable, well encapsulated, testable and readable code in most any language. The problem is about the humans not the language they select. But yes, complexity is also a major problem.

What I have learned is that what makes a language (or platform, or tool) "good" isn't how easy it is to write good code, but how hard it is to write bad code. Does a beginner following the path of least resistence, on a tight schedule, end up with maintainable code or not?

I'd argue that this is the weakness with (the traditional) OO languages. An experienced developer with plenty of time can write good software with almost any tool. But that's not what's interesting. I want to see tools that not just lets but rather guides inexperienced developers into making maintainable software.

Things like "no nulls" or "immutable by default" in Rust and most functional languages are two examples of such designs. OO itself doesn't necessarily mean the developers get trapped in poor code, but the traditional 3 (C++, Java, C#) sure do give developers lots of guns to shoot at their feet. Perhaps not mainly because they are OO, but because they inherited some poor fundamental decisions about mutability and nulls (from C) and about inheritance as a default method of abstraction (from C++) etc.

Re: Fighting Complexity in Software Development

#59

Earlier quoted context omitted.

> metaprogramming is rare In Java? Not really. Spring has been around since 2003 or so.

I guess he was referring not to metaprogramming in the common sense, but to the change of behaviour of built-in methods and classes.

Ah, I thought that's called "monkey patching".

Re: Fighting Complexity in Software Development

#60

I love F#, but using F# instead of (type|java)script would add a lot of complexity to my 'full stack'. Let's see I replaced my node.js backend with an F# one, the following issues would arise: 1. I now have two different languages for client and server, and can't share e.g. validation code. 2. Dealing with 2nd class linux support (no REPL) 3. No library that combines the maturity and simplicity of express.js. Yes I a…

As to the REPL: there is now a dotnet global tool for it:

    dotnet tool install -g dotnet-script
After installation, you simply run:

    dotnet script
to start the REPL.
Post reply on HN