I wrote this blog post, which I think will be relevant to many of the readers of this forum.
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.
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.
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.
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.
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.
If anything, the fact that you consider someone elseâs use of the word âjust plain wrongâ proves @withoutboatsâs point.
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.
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."
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.
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.
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.
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.
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.