13
\$\begingroup\$

When we define a function that needs an import, we have to add it to the byte count. So far, so good. What about cases where the definition itself doesn't need the import, but when you want to call/execute the function you need it, for example to construct parameters?

Examples can be found here and here.

In both examples we have polymorphic functions that work for many different number types. The definition doesn't require any import. However, to run the function and get the result requested by the challenge you need to provide parameters of the number type Ratio which can only be constructed with the Data.Ratio module imported.

Do we need to add the import to the byte count in such cases?

\$\endgroup\$
3
  • \$\begingroup\$ Would it be possible to receive a Ratio value from another function that doesn't require importing the module? \$\endgroup\$ Sep 14, 2016 at 21:54
  • \$\begingroup\$ @MartinEnder: Not that I know of. \$\endgroup\$
    – nimi
    Sep 14, 2016 at 21:57
  • \$\begingroup\$ I think you should not count it since function definition is correct. It should be allowed to expect the input as a list of integer ratios [Ratio Integer]. Is there a meta for input format? \$\endgroup\$
    – Damien
    Sep 15, 2016 at 8:35

2 Answers 2

20
\$\begingroup\$

If your function is syntactically valid without the import (or similar mechanism), then it's not necessary to include the bytes for the import in your byte count, even if the import is needed to construct objects of the type that your function expects. Explicitly referencing the imported thing requires the import being counted.

Here are a few examples:

Acceptable

  • Python: lambda a:a.tm_year (defines a function which expects a struct_time argument and returns its tm_year attribute - requires import time or similar to construct the struct_time object, but due to Python's duck typing, the type is not explicitly stated in the function definition, and thus doesn't require the import - any object with a tm_year attribute could be used)

Unacceptable

  • Python: lambda a,b:re.match(a,b) (the re module is explicitly referenced, and thus the import re must be counted)
  • C++: int f(std::string s){return s.length();} (because C++ is statically-typed, the std::string class and its public interface need to be declared before they can be used, and thus the #include <string> directive (or another means of declaring the class and its interface) needs to be included with the function definition)
\$\endgroup\$
5
  • 5
    \$\begingroup\$ Another example to highlight it - Python f=lambda x:re.match("hello",x). You can define it without import re but need it when running. Yet I find it unacceptable, because re is needed for the code itself, not constructing parameters. \$\endgroup\$
    – ugoren
    Sep 16, 2016 at 6:15
  • \$\begingroup\$ @ugoren In that case, because there is an explicit reference to the module, it should be included in the byte count. I was intending to say that implicit references through duck typing or operator overloading should not need the module counted. I'll clarify that in the answer when I have time. \$\endgroup\$
    – user45941
    Sep 16, 2016 at 13:48
  • 1
    \$\begingroup\$ Frankly, I do not see why dynamic typing should get the pass, but a forward-declared type shouldn't. With dynamically typed interpreted language, the promise is "when you'll read this value, it'll be there", and with statically typed compiled language it is "when you're linking these files, this type will be there". \$\endgroup\$
    – user77406
    Feb 3, 2019 at 22:54
  • \$\begingroup\$ @Rogem If you forward-declare a type in a statically-typed language such that the function is valid at the time of definition, then that's acceptable. My answer does not say that doing so is unacceptable (though the second "unacceptable" example is phrased poorly, and I can see how that conclusion could be derived from it). \$\endgroup\$
    – user45941
    Feb 4, 2019 at 2:47
  • \$\begingroup\$ There is some reasoning here, but the rule of allowing implicit types to save bytes still feels kinda cheaty and stretching flexible I/O too much \$\endgroup\$
    – qwr
    Jul 28, 2022 at 22:10
8
\$\begingroup\$

Count all imports

The rules for counting imports are vaguely spread across several meta posts, but the default and simplest rule is to count them:


When looking into this, I first came across Scoring Java with Imports. There's only one answer there (score them), but it was also marked as a duplicate, since as noted in comments, a lambda is a function.


So, following the dupe trail leads you to On Scoring Imported Functions. There's one answer present, which seems to say that if an import is required to call the function, then you must count the import.


Similarly, in Unnamed Functions in Code Golf, one of the bullets is:

Any imports/includes/requires/whatever may be imported/included/required/whatever outside of the function (import math;math.gcd).

So it's clear that it's not enough for a function to exist (you can't just say gcd is the entirety of your code), you must count the import so that you can call it.


More obliquely, in an answer to Do I need to use imports or can I call a class explicitly, an answer argues for counting imports that are necessary for it to run:

If you are using a function instead of a full program, you must include any necessary includes/imports so that you could copy and paste the entire submission into a full program, and it would successfully compile/run.

It's not a huge consensus (if you can even call it that), but there are no comments or answers challenging that there.


The only exception I see to the default rule of count all imports, is the other answer to this question. Carving out an exception for this doesn't make sense, and does nothing but make it more confusing for newcomers. No matter how advantageous it is to lowering the byte count, it doesn't make sense as a rule.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .