Live data from Hacker News

In Defense of Simple Architectures (2022)

danluu.com

421–430 of 447 posts

Re: In Defense of Simple Architectures (2022)

#421

Earlier quoted context omitted.

We have services in Python and C# at $dayjob, and my experience is that Python has mostly left C# behind here - what is something you can express in the C# type system that MyPy cannot statically check? Conversely, I find myself constrained by C#'s typesystem not having features now widely popular from Rust and Typescript and available in modern Python: const generics / literals, protocols/structural interfaces and m…

Was bewildered when reading this message. How come? Python and TypeScript by definition don't have a concept of const generics the way it applies to C++ templates or Rust. Nor "matching over algebraic datatypes" made any sense - sure sounds slightly below average fancy but comes down to just using C# pattern matching effectively, which the author may have never done. But then it struck me "structural interfaces sure…

Sorry - can you put the snark aside and answer the question then, it seems given my lack of understanding here as a mere Go simpleton it should be trivial for you.

The question I responded to said: "Better static analysis, for one."

I asked: "What is something you can express in the C# type system that MyPy cannot statically check?"

Can you provide some examples where C#'s type system can express something that modern well-typed Python cannot type-check?

Re: In Defense of Simple Architectures (2022)

#422

Earlier quoted context omitted.

We have services in Python and C# at $dayjob, and my experience is that Python has mostly left C# behind here - what is something you can express in the C# type system that MyPy cannot statically check? Conversely, I find myself constrained by C#'s typesystem not having features now widely popular from Rust and Typescript and available in modern Python: const generics / literals, protocols/structural interfaces and m…

Was bewildered when reading this message. How come? Python and TypeScript by definition don't have a concept of const generics the way it applies to C++ templates or Rust. Nor "matching over algebraic datatypes" made any sense - sure sounds slightly below average fancy but comes down to just using C# pattern matching effectively, which the author may have never done. But then it struck me "structural interfaces sure…

> Python and TypeScript by definition don't have a concept of const generics the way it applies to C++ templates or Rust.

Can you help guide me where I'm misunderstanding the type system aspect of const generics that's missing in Python? What I meant was that in Python I can say something like this:

    import typing as t

    class FooEater[NUM_FOOS: int]:
        def eat_foo(self, num_foos: NUM_FOOS):
            print("nomnom")
    
    one_foo = FooEater[t.Literal[1]]()
    one_foo.eat_foo(2)  # type error, NUM_FOOs for one_foo only allows literal '1'

And a PEP695-compatible typechecker will error at build time, saying I can't call `eat_foo` with `2`, because it's constrained to only allow the value `1`.

I admit to not being a type system specialist, but at least as I understand Rust's "const generics" the type system feature is: "Things can be generic over constant values". Isn't that the same as what Python supports?

Re: In Defense of Simple Architectures (2022)

#423

Earlier quoted context omitted.

if the pride of a good job done isn't enough motivation for you then you'll never understand because you simply don't have the ability to.

Unless you're working pro bono, the "pride of a good job done" isn't enough motivation for you either. Your employer may wish it was, though. Point is, there is more to the equation. Employees don't exist in isolation, and when jobs actively refuse to take into account that the workers are real, living human beings, with needs and plans and dependents to feed, then resume-driven work will continue.

> Unless you're working pro bono, the "pride of a good job done" isn't enough motivation for you either. Your employer may wish it was, though.

wait, let me guess, if I truly loved my wife I'd also never play a video game by myself.

Watch as my eyes roll out of my head, onto the floor, and out the door.

Re: In Defense of Simple Architectures (2022)

#424
post #417
post #407

Earlier quoted context omitted.

I envy that position. Feels like because I didn’t work in go or python at my most recent job, I’m having trouble landing anything. (I have 5 years of golang prior to my most recent job) My experience working in devops doesn’t seem to matter for SE positions either.

I do freelance gigs. And I charge what's "enough" for me, so price may play a role. And so I have several gigs a year. I'm on my third for 2024. I give talks on meetups and conferences, so my insights are seen. I prefer to work in start- or scale ups, so there's a real need for some "know it all".

How did you get started doing that?

It might just be the area I live in, but I wouldn’t even know how to start looking for freelance roles that aren’t just poorly paid 3mo junior contracts.

Re: In Defense of Simple Architectures (2022)

#425
post #121

Earlier quoted context omitted.

Python will let you use float division on integers. Compiled type languages won't do that. This would be solved by using a double data type. But python doesn't have it.

You'd almost certainly just use a library dedicated to mitigating this problem though, of which there are many.

Or you could just use a language with a static type system and avoid a whole class of bugs automatically.

Re: In Defense of Simple Architectures (2022)

#426
post #391

Earlier quoted context omitted.

Here's the thing: You're right. And also you're not. Sometimes, often, feedback is about timing. The time to talk about how better to architect a thing is when it's being architected, not 2 months later. Instead of "This is crap" try "Hey I know this works for now, but there's room for improvement here. Next time we're talking about a system like this can I help with design? I have a few ideas what we might improve".…

I wish I could have that good timing, but I'm rarely hired early enough.

Hey 3 years from now the mistakes you’re making today will look like “Wow I wish I was there, that loup-vaillant guy sucked” to some new hotshot :)

That is to say: You can start now. There’s always plenty of new mistakes to make.

Re: In Defense of Simple Architectures (2022)

#427
post #416

Earlier quoted context omitted.

> Hurfbaz This made me chuckle. :) It's HarfBuzz. Yours sounds like a goblin.

I could't recall the correct name but originally, it is in Persian حرف باز and in that باز would be transliterated as Baz. But yes, you're right.

I wasn't even aware that this came from Persian! Thanks for educating me.

Re: In Defense of Simple Architectures (2022)

#428

Earlier quoted context omitted.

It took a decade to find the data to show that this decision we made 10 years ago was bad - for those entire 10 years we all thought it was good until we we looking at a performance issue and realized the roots case what a decision made in the early days had an unexpected side effect.

Congratulations on your success. Legacy code is never easy to work with, but it's a good problem to have because it means you survived where hardly anyone does.

10 years ago this was a greenfield project that was just getting the first release. Today it is a legacy project that is bringing in a ton of $$$.

Re: In Defense of Simple Architectures (2022)

#429
post #182

Earlier quoted context omitted.

Starting today: Go, C#, Rust, possibly TypeScript (not my personal choice but probably acceptable), Java (which despite being poorly done in a lot of places does have the tooling necessary for this if used by decent programmers). C++ with a super-strong static analysis tool like Coverity used from day one. (I consider C or C++ plus something like Coverity to be essentially a different language than using just a C or…

In my experience writing software that performs financial calculations, it is easy to screw up in any language. I'm not sure that any of those languages provide a great enough advantage specific to financial calculations, considering all of the other baggage. To state the obvious, most apps that perform financial calculations are not performing financial calculations in 99% of the code.

Well, I was as broad as "statically typed" versus "dynamically typed" for a reason. Dynamically typed languages have a hard time enforcing much of anything. Statically-typed languages can do things like "type Pennies int", or create a structure with a value and attached currency type, or create a structure with a value, currency type, and attached timestamp, or even have all of those at once, while making it practical to have functions that never mix any of them up.

I'm writing a lot of email-related code right now, porting something out of Perl into Go, and because this code supports Google-style "+" addressing, where "anemail+something@gmail.com" and "anemail+other@gmail.com" need to be tracked as separate recipients (as defined by the SMTP protocol) but I also have a slate of functions that need to operate on the mailbox, as identified by "anemail@gmail.com", using some types to keep the two things straight has greatly cleaned up the translated Go code, whereas in Perl it was all just strings and there are constant repeated snippets of code trying to (inconsistently!) translate between the two on demand and with no compiler support as to whether it is being done correctly. I wouldn't be surprised this fixes longstanding and hard-to-diagnose bugs simply by the act of imposing a static type system on top of the mass of dynamically-typed goo. I'm fairly sure I've identified at least one place in the old code that it failed to do the conversion, but in dynamically-typed languages it's hard to even be sure about that.

Statically typed languages do not automatically or magically make dealing with currency easier and safer than dynamically type languages. A static language's compiler will not peep as you pass around an "integer" that represents US pennies, or maybe Euro pennies, or maybe Yen, or maybe Italian Lira as of March 23, 1981. But if you have a need to do so, and a need to do it safely, static languages give you much more rigid and safe tools to do it with.

(You can create a "currency" type in dynamically-typed languages that is a lot smarter than an int, certainly, but you can't use the interpreter to rigidly enforce that it is used correctly, and the various incremental or progressive typing options I've seen generally fail to impress me. The cultural temptation in a dynamically-typed language to allow functions to also just take an int and then "guess" the rest will be overwhelming based on my experience and it takes a strong developer lead to push back against people sneaking that in.)

While you're right that only small bits of the code may be doing calculations, a lot of the app may be dealing with money in some sense. In a statically-typed language used correctly, the money values can at least pass through those parts of the system unambiguously, carrying exactly what they are, and the parts of the system doing the calculation doesn't need to do a lot of defensive programming to ensure that the currency values are actually of the expected type. Code pulling these values out of the database should put them into the correct type, code displaying them to users should be using this information correctly. Not just things "calculating" with the money but anything that touches money values, passes them along, serializes or deserializes them, all of it is cleaned up by having a precise specification of what it is that is maintained all the way through the app.

Re: In Defense of Simple Architectures (2022)

#430
post #425

Earlier quoted context omitted.

You'd almost certainly just use a library dedicated to mitigating this problem though, of which there are many.

Or you could just use a language with a static type system and avoid a whole class of bugs automatically.

Look, I like static type systems, but not all type systems are created equal, and some(with the easiest example being Go) are downright awful for helping encode business logic, forcing you to write immense amounts of code just to work around their awful type system decisions, code that often introduces bugs because of those issues.
Post reply on HN