Question

Dynamic typing newbie here, hoping for some wizened words of wisdom.

I'm curious if there is a set of best practices out there for dealing with function arguments (and let's be honest, variables in general) in dynamically typed languages such as Javascript. The issue I often run into is with regards to readability of code: I'm looking at a function I wrote a while ago and I have no clue what the structure of the argument variables actually is. It's usually ok at the moment of development of new code: everything's fresh in my head, every variable and parameter makes sense because I just wrote them. A week later? Not so much.

For example, say I'm trying to crunch a bunch of data about user sessions on a website and get something useful out of it:

var crunchSomeSessionData = function(sessionsMap, options) {
    [...]
}

Disregarding the fact that the function name isn't helpful - that obviously is a huge deal - I actually don't know anything at all about what the structure of sessionsMap or options is. Ok.. I have k/v pairs the sessionsMap object, since it's called Map, but are the value a primitive, an array, another hash of stuff? What is options? An array? A whitespace separated string?

I have a few options:

  • clarify the structure exactly in the comment header for the function. The problem is that now I have to maintain the code in two places.
  • have as useful of a name as possible. e.g. userIdToArrayOfTimestampsMap or even have some kind of pseudo-Hungarian dialect for variable naming that only I speak that explains what the types are and how they're nested. This leads to really verbose code, and I'm a fan of keeping stuff under 80 col.
  • break functions down until I'm only ever passing around primitives or collections of primitives. I imagine it might work, but then I'd likely end up with micro-functions that have one or two lines at most, functions that exist only for the purpose of readability. Now I have to jump all over the file and recompose the function in my head, which just made readability worse.
  • some languages offer destructuring, which to some extent can almost be thought of as extra documentation for what the argument type is going to contain.
  • could create a "class" for the specific type of object, even though it'd not make a huge difference in a prototypal language like JS, and would probably add more maintenance overhead than necessary. Alternatively, if available, one can try to use protocols, maybe something along the lines of Clojure's deftype/defrecord etc.

In the statically typed world this is not nearly as much of an issue. In C# for example you get a:

public void DoStuff(Dictionary<string, string> foo) {[...]};

Ok, easy peasy, I know exactly what I'm getting, no need to read the function header, or go back to the caller and figure out what it's concocting etc.

What's the solution here? Are all people developing in dynamically typed languages continuously boggled by what types their subroutines are getting? Are there mitigation strategies?

No correct solution

Licensed under: CC-BY-SA with attribution
scroll top