Not Explicit

I wrote this blog post, which I think will be relevant to many of the readers of this forum.

21 Likes

Summary of my views on IRC:

I really like the conclusion. We should be more explicit about what explicit means by using different words.

For a bit of PR, I think that we should say that Rust has a balanced amount of explicitness, or that Rust is explicit where it matters.

1 Like

In the discussion about heap-allocated strings in Rust some people have suggested a syntax like:

"hello"s

It’s explicit and I like it enough, but some people have argued that it’s not long enough (I guess they mean it’s not salty enough).

I strongly disagree with this post, especially with

To me, Rust is explicit because you can figure out a lot about your program from the source of it.

This is a nice property of Rust, but all the examples that you list are really implicit, not explicit.

Implicitness does not mean, that you cannot tell anything about the code. It just means that you have to use additional knowledge to figure it out.

In my understanding, "explicit" is what you call "manual" in your post. And what you mean by "explicit" is really "deterministic".

IMO you are trying to redefine those words and give them a new meaning.

1 Like

The blog post is an exploration in how we can better our communication with each other, not a declaration on the meaning of certain words.

2 Likes

The blog post explains that some words don’t have specific-enough meaning to be helpful in a conversation. Your understanding of the word “explicit” is distinctly unhelpful if it’s not the same as what everyone else in the discussion means. You can either choose to argue what you think “explicit” should mean, or you can try to pick words whose meaning is less ambiguous in the context. The latter is more helpful.

2 Likes

What I wanted to say is that I find “explicit” a very descriptive and specific word.

For example if you take “manual” vs “explicit”: I don’t really care for the fact, that someone has to manually write the function call. I care about that the call is explicitly present in the source code. Using the word “manual” does not express this exactly, while “explicit” does IMO.

The second point is, that I don’t agree at all with how @withoutboats uses the word “explicit”. E.g. calling a destructor call “explicit” because it happens deterministically is IMO just plain wrong. Such a misuse of the word should not be a reason not to use it.

2 Likes

If anything, the fact that you consider someone else’s use of the word “just plain wrong” proves @withoutboats’s point.

5 Likes

When talking in a common language, one has to agree about the meaning of the words, at least roughly. If we decide to use "manual" instead of "explicit", how does that solve the problem? Someone else will misunderstand that too.

The example with the destructor call and all the examples with the struct fields/layout in the original post are basically examples of the definition of implicitness, which is the contrary of explicitness. From Implicit Definition & Meaning - Merriam-Webster

a: capable of being understood from something else though unexpressed

I admit that the example with constructor is perhaps a bit confusing. Maybe it stretches the concept, and requires a fair bit of squinting. However, that doesn’t detract from the main point. “explicit” can be used to mean “manual”, but it also means each of the other concepts, in some cases. “manual” is, in a sense, more specific. You can’t use it to mean “locally visible”. “explicit” can be and has been used to mean that. That’s the main benefit of having more words to express ourselves. “explicit” is on the table because it’s being used in arguments inappropriately often enough to catch attention. That doesn’t mean we should stop using the word, but it does mean we should think twice whether some other phrasing is a better choice.

1 Like

Time for me to play devil's advocate.

From Implicit Definition & Meaning - Merriam-Webster

a: capable of being understood from something else though unexpressed

Normally I have a pretty strong knee-jerk reaction to seeing "arguments by Merriam Webster," but as I thought about it some more, I figured that perhaps this is worth discussion.

I guess @troplin's argument can be thought of as basically the English-language equivalent of bikeshedding? The point is, even if we do try to agree upon common language for discourse, not all choices of lexicon are equal. Certain choices for a term may have the potential to cause more confusion than other choices, and many people involved in e.g. RFC discussions will not be in the loop about our choice of lexicon. Thus it is prudent to choose something that feels natural to many people.

I too feel that the meaning ascribed by @withoutboats to the term "explicit" seems unusual. I agree with @troplin that my intuitive reading of the word "explicit" has a meaning very close to what boats calls "manual." As for the concept that boats calls "explicit", I might call that "deterministic" or "inferrable."

But on the flip side...

Even though I would define the word "explicit" in the manner I just described, that is not ultimately how I use it. "Explicit" is a word that I tend to reach for even when I probably shouldn't, sometimes leading to silly strawman debates, and I believe this is true for many other people, too. Therein lies the problem.

I care about that the call is explicitly present in the source code. Using the word “manual” does not express this exactly, while “explicit” does IMO.

I do not feel that this use of the term "manual" is problematic. Even if it is not strictly correct, it is unambiguous, which is far more important than correctness. There is nothing else that the term "manual" could possibly refer to in the context of source code that is already written, and that is why it is a better term to use than "explicit."

4 Likes

To me "manual" has a connotation of "laborious", "burdensome" or even "not enforced by the compiler" or "error-prone" as in manual memory management, and that's definitely not what I want to express. I'm not a native speaker though.

But probably you are right and this is bikeshedding. People should just explain what they mean a bit more in detail and everyone will understand.

OT Rant: I just have that knee-jerk reaction to such topics. It's like the recurring discussion (at least where I live) to abolish the DST switch in favor of having DST (instead of normal time) the whole year through. I mean, people could just get up an hour earlier but no, changing time is easier than changing habits...

Speaking as an American: "manual" has no such negative connotations to me, especially not the first two. For the second two, I can kind of see where you're coming from, though I would probably use a phrase like "by hand" instead.

(ironically, I am aware that "by hand" is more or less exactly what the word "manual" used to mean, but to me it invokes none of the same imagery. To me, "manual" is nothing more than the opposite of "automatic," in the same way that "analog" is nothing more than the opposite of "digital.")

I don’t think we should litigate about the exact meaning of specific words, but rather that we should present our concerns in more detailed, explained and “thought through” expressions. When someone says that a design is bad because it is “implicit” or “magic” (or “ugly” or “unergonomic”) with no further elaboration, it is exceptionally unpersuasive. I often am not even sure what specifically they mean by this.

We all take different connotations from the words we use. We all have different beetles in our boxes.

8 Likes

I often am not even sure what specifically they mean by this.

I would say, that when you can't express something clearly, then you don't really understand your own feelings, the origin of them.

If you have feelings regarding a new language feature, then these feelings are to some degree a speculation of how you will feel in the future using this feature.

There might be some truth in the feelings, because of former experiences, but the origin might also be unfamilarity and when getting used to some feature, really experiencing the effect of the feature, then your feelings might completely change.

To me, “explicit” in the PL context always meant “has an own visual representation in the code”, so drops in Rust are implicit in my book (which is very much fine). As such, I agree with @troplin, and I’m also very sympathatic to @withoutboats blog post in that I’m often confused when people argue from an “expliciteness” POV and mean something else, and I think communication could be improved quite a bit if people used narrower meanings for their words or (preferably “and”) people elaborated their point just in this way.

I tend to use ‘this isn’t explicit and explicit is good’, so I feel compelled to explain what I mean by explicit, since it’s not represented in the post. Note, I can’t think of another word which makes my notion more clear.

My notion of implicit vs explicit is mostly influenced by things in C++ which are implicit vs explicit, like coersions and conversions. For example, single argument constructors can be marked as explicit, which means that they aren’t considered in contexts where implicit conversions are allowed but explicit ones are.

So, how does one apply this to Rust?

As an example, constructors in C++ both ‘construct’ and ‘convert’, unless the user types the keyword ‘explicit’ with the declaration. The relevant take away here is that a choice is being made (i.e. to ‘convert’ or not) but the choice is defaulted without the user needing to acknowledge that a choice has been made. Another example is const in method declarations (struct S { void foo() const; };. Note, lambdas are similarly implicit but change the default, so you need [a]() mutable { a = 10; } if you want to capture a by value and then change it (note, this won’t change the original value of a).

So, when I say, ‘this syntax isn’t explicit’, what I really mean is that a choice is being made (because it’s defaulted) and the programmer is not required to type or read something which acknowledges this choice.

So, as an example in Rust, if I type mod s { struct S; }, then S is not public and I may not even know that Rust has a public vs private distinction. In this case, even though this syntax is implicit, it is mostly fine because users will eventually get an error when trying to use S and will learn the syntax anyways.

Rust mostly gets this right and implicit features have defaults which are more restrictive and therefore, users only need to type more and learn more about various choices when they need to.

Anyways, this is the most useful definition of explicit/implicit I’ve encountered, because it allows reasoning about whether code (as read, after the fact) was written to intentionally do something or not.

3 Likes

This definition is useful, but not enough on its own to make a judgment call on a feature. There are an awful lot of places where a choice is made without any indication from the user.

The examples that do fit your “more restrictive” criteria (e.g. private/pub, shared/mut, move/Copy, various common #[derive]s) don’t necessary have single canonical dimensions they’re “more restrictive” in. For instance, shared references are less restrictive about where they can be sent.

Further, there are a plenty of examples that don’t fit: Send and Sync are automatically applied, lifetime variance is automatically determined, HRTBs are automatically inferred, lifetimes are automatically elided, auto(de)ref and other coercions are automatically used.

In the end I think the point is that, for any particular issue, when you’re about to call something “not explicit” or “explicit,” instead take the time to expand on which choice is being made and why you think it should have a different (or no) default.

1 Like

I was just adding to the taxonomy of different definitions of explicit. Discussing how it applies to every feature in the language is possible but not really useful at this point.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.