2
$\begingroup$

A common issue in app development is avoiding over-fetching of data, such as in this naive (pseudocode) example:

get_user(id) {
  return sql_query("SELECT * FROM users WHERE id=$1", id);
}

render_some_webpage() {
  // ...
  print get_user(session.user_id).username;
  // ...
}

While this would work, it requires the database to send back a bunch of user fields when only the username is used (it's not a big deal in this trivial example, but gets much worse when associations/joins are involved). This problem is normally solved via adding an additional argument to get_user with a list of required fields, but that's far from a perfect solution. It seems the language could infer which fields of the user were actually used and allow get_user to act on this information (by only fetching the username).

Is this a known concept? Are there languages that implement this idea?

$\endgroup$
  • $\begingroup$ Note that programming is offtopic here, so both the problem and your request for languages are unsuited for this site. I'll leave it as borderline since you are also asking for concepts. Community votes, please! $\endgroup$ – Raphael Sep 28 '17 at 14:10
  • $\begingroup$ The boring answer may be, "sure, simple data analysis can do that, nothing to see here from a CS perspective". Since you'd require a tighlty integrated compiler and framework/runtime to implement it in practice, though, there may be no implementation for entirely technical reasons (which are all offtopic here). $\endgroup$ – Raphael Sep 28 '17 at 14:12
1
$\begingroup$

Few otherwise general-purpose languages bother to deeply integrate with (relational) databases. Most languages I've seen that do do some integration (though fairly shallowly) are bolt-on abominations. Links is quite a bit more principled, and I believe can actually more or less do what you want. It's a statically typed functional language whose goal was to collapse multi-tier web applications into one coherent (source) program.

In Haskell, a general-purpose, statically typed, purely functional language with no database integration, you can use the type class system and type inference to propagate information about the used fields back to the query site. The simplest approach to this will not actually know what columns are on the table, and so will lead to queries that may access columns that don't exist. Part of the reason I think Links can do what you want is that the type systems of Haskell and Links have some relation, and Phil Wadler, one of the primary designers of Links, is also the creator of type classes. (The mechanism is different though, using row types rather than type classes. Indeed, the approach in Haskell would be more like a poor man's row types.)

That said, it's not clear how desirable this actually is, especially when given a clean, modular syntax for making queries e.g. something like C#'s Linq. Using Linq is like your solution of passing in the list of required fields except you have the full flexibility of, at least, Linq's query syntax and so you aren't just slinging strings about and thus can't typo one of the fields. You're still required to change the query to return the appropriate fields, but often you do want some awareness and control over the query. (This is especially true if the code isn't validated against the schema and so typoing a field name can lead to non-existent column names in the query.)

$\endgroup$
  • $\begingroup$ This is an Stack Overflow, not a Computer Science answer. $\endgroup$ – Raphael Sep 28 '17 at 15:38
  • $\begingroup$ The Haskell answer refutes your statement in your comment on the question that "you'd require a tightly integrated compiler and framework/runtime to implement it in practice". $\endgroup$ – Derek Elkins Sep 28 '17 at 15:43
  • $\begingroup$ Thanks for the link (no pun intended). That looks really cool! $\endgroup$ – Gaelan Sep 28 '17 at 16:28
0
$\begingroup$

I know that this is probably not relevant to you, but the general problem is undecidable.

Consider this:

render_some_webpage() {
  ...
  user = get_user(session.user_id)
  ...
  if some_function(x) == 0
      print user.name
  else
      print user.email
  end
  ...
}

Now, the properties of user that get_user has to retrieve depend on the return value of an arbitrary function, determining which is (in general) not computable.

Of course, easier problems can be solved: here, we could just get name and email and be happy about all the properties we saved regardless. We can make the compiler as smart as possible, and apply the optimisation if it can figure something out.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.