Live data from Hacker News

Why static languages suffer from complexity

hirrolot.github.io

41–50 of 306 posts

Re: Why static languages suffer from complexity

#41

So whenever I have to study someone else's 'dynamic' python I encounter this sort of thing: def foo(bar, baz): bar(baz) ... What the heck is 'bar' and 'baz'? I deduce no more than 'bar' can be called with a single 'baz'. I can't use my editor/IDE to "go to definition" of bar/baz to figure out what is going on because everything is dynamically determined at runtime, and even grep -ri '\(foo\|bar\|baz\)' --include \*.p…

In Clojure, I tend to put pre and post assertions on most of my functions, which is useful for checking errors in the schema of runtime data (very useful when dealing with 3rd party APIs) but it also offers the documentation that you are seeking: (defn advisories [config] {:pre [ (map? config) (:download-advisories-dir config) ] :post [ (map? %) ] } (let [ dir (:download-advisories-dir config) ] ;; more code here

And now imagine the compiler would actually enforce that practice, and you have static typing, with less boilerplate.

Re: Why static languages suffer from complexity

#42

So whenever I have to study someone else's 'dynamic' python I encounter this sort of thing: def foo(bar, baz): bar(baz) ... What the heck is 'bar' and 'baz'? I deduce no more than 'bar' can be called with a single 'baz'. I can't use my editor/IDE to "go to definition" of bar/baz to figure out what is going on because everything is dynamically determined at runtime, and even grep -ri '\(foo\|bar\|baz\)' --include \*.p…

Static languages unfortunately don't save you from that. You find automatically inferred types, or types that refer to some abstract interface or template-class-mess but you have no idea where the actual implementation lives until you compile with RTTI and run it under a debugger... and as tfa posits, people working with the limitations of static languages often end up reinventing a dynamic structure.

Is this somehow supposed to relevant to the posted article or did you just want to start a tangentially related dynamic-vs-static flame war here in the comments section?

Re: Why static languages suffer from complexity

#43

So whenever I have to study someone else's 'dynamic' python I encounter this sort of thing: def foo(bar, baz): bar(baz) ... What the heck is 'bar' and 'baz'? I deduce no more than 'bar' can be called with a single 'baz'. I can't use my editor/IDE to "go to definition" of bar/baz to figure out what is going on because everything is dynamically determined at runtime, and even grep -ri '\(foo\|bar\|baz\)' --include \*.p…

The real power of dynamic languages is being able to do: const foo = JSON.parse(arbitraryJsonString); and not having to worry about the structure up front.

There's something to this. I love featurefull type systems, but I've seen engineers try to parse JSON the "right" way in Scala, get frustrated, and blame the entire concept of statically typed languages. Elm manages to make this user friendly so perhaps it's "only" a matter of compiler messages and API design?

Re: Why static languages suffer from complexity

#44

So whenever I have to study someone else's 'dynamic' python I encounter this sort of thing: def foo(bar, baz): bar(baz) ... What the heck is 'bar' and 'baz'? I deduce no more than 'bar' can be called with a single 'baz'. I can't use my editor/IDE to "go to definition" of bar/baz to figure out what is going on because everything is dynamically determined at runtime, and even grep -ri '\(foo\|bar\|baz\)' --include \*.p…

What the heck is 'bar' and 'baz'?

So there's no docstring? And the actual variables are that random and indecipherable?

Sounds like the problem is that you're tasked with looking at code written by someone who is either inexperienced or fundamentally careless. When dealing with reasonably maintained codebases, this kind of situation would seem pretty rare. In modern python we now have type hints of course, which have helped quite a lot.

Re: Why static languages suffer from complexity

#45
post #25

Earlier quoted context omitted.

You can do that in static languages too by just parsing into a map

What's the type definition of the map out of interest?

  const Json = union(enum) {
      null,
      number: f64,
      bool: bool,
      string: []const u8,
      array: []const Json,
      object: HashMap([]const u8, Json),
  };

Usually it's a tagged union of the base JSON types which can easily be consumed by most statically typed languages or a variant of it.

EDIT: added "tagged"

Re: Why static languages suffer from complexity

#46

So whenever I have to study someone else's 'dynamic' python I encounter this sort of thing: def foo(bar, baz): bar(baz) ... What the heck is 'bar' and 'baz'? I deduce no more than 'bar' can be called with a single 'baz'. I can't use my editor/IDE to "go to definition" of bar/baz to figure out what is going on because everything is dynamically determined at runtime, and even grep -ri '\(foo\|bar\|baz\)' --include \*.p…

Yup, I find this completely insane behavior to think that you somehow benefit from types not being there. You just make it way harder for people to understand your code and contribute to it.

To be fair, in recent years I've worked on a number of Typescript projects and it was common for developers to use `any`, `Object`, `() -> Promise`, etc. Not super helpful.

Though in my experience, sane code structure and informative comments trump everything else when it comes to understanding big and unknown codebase. I still shudder when I think about working years ago on various Java codebases (mostly business IT systems). What a convoluted mess of n-levels deep interface hierarchies. Types? Yeah, but good luck unraveling what exactly is happening in the runtime.

Re: Why static languages suffer from complexity

#47
post #37

Earlier quoted context omitted.

Yup, I find this completely insane behavior to think that you somehow benefit from types not being there. You just make it way harder for people to understand your code and contribute to it.

Oh yeah the easiest code in the world to read is some contorted type system and function signatures that look like hieroglyphics that you need a PHd in CS to comprehend. Python is easy to grok, and if you have programmers writing code like bar(foo,baz) then the problem is not Python. You can write crap in any language. Unit tests do much of what typing checks anyway ... and here's the thing ... you NEED unit tests no…

Yeah, I always say that python is an amazing language to prototype and terrible language to scale precisely because it lets people write the usual terrible code and then gives you the freedom to make it even worse.

Re: Why static languages suffer from complexity

#48

So whenever I have to study someone else's 'dynamic' python I encounter this sort of thing: def foo(bar, baz): bar(baz) ... What the heck is 'bar' and 'baz'? I deduce no more than 'bar' can be called with a single 'baz'. I can't use my editor/IDE to "go to definition" of bar/baz to figure out what is going on because everything is dynamically determined at runtime, and even grep -ri '\(foo\|bar\|baz\)' --include \*.p…

[deleted]

Re: Why static languages suffer from complexity

#49

So whenever I have to study someone else's 'dynamic' python I encounter this sort of thing: def foo(bar, baz): bar(baz) ... What the heck is 'bar' and 'baz'? I deduce no more than 'bar' can be called with a single 'baz'. I can't use my editor/IDE to "go to definition" of bar/baz to figure out what is going on because everything is dynamically determined at runtime, and even grep -ri '\(foo\|bar\|baz\)' --include \*.p…

In Clojure, I tend to put pre and post assertions on most of my functions, which is useful for checking errors in the schema of runtime data (very useful when dealing with 3rd party APIs) but it also offers the documentation that you are seeking: (defn advisories [config] {:pre [ (map? config) (:download-advisories-dir config) ] :post [ (map? %) ] } (let [ dir (:download-advisories-dir config) ] ;; more code here

How is this any better than static types?

Re: Why static languages suffer from complexity

#50

So whenever I have to study someone else's 'dynamic' python I encounter this sort of thing: def foo(bar, baz): bar(baz) ... What the heck is 'bar' and 'baz'? I deduce no more than 'bar' can be called with a single 'baz'. I can't use my editor/IDE to "go to definition" of bar/baz to figure out what is going on because everything is dynamically determined at runtime, and even grep -ri '\(foo\|bar\|baz\)' --include \*.p…

Well, you could put the types on these days.

But also, there’s nothing stopping the code from being much clearer about its intention than this weirdly contrived example (I have a lot of code and most the function names are pretty unique). And surely you want to search for ‘foo(‘ to find invocations.

Post reply on HN