Jump to page: 1 24  
Page
Thread overview
Command–query separation principle [re: @mustuse as a function attribute]
Oct 19, 2022
mw
Oct 19, 2022
mw
Oct 19, 2022
zjh
Oct 19, 2022
mw
Oct 19, 2022
Mike Parker
Oct 19, 2022
mw
Oct 19, 2022
mw
Oct 19, 2022
Mike Parker
Oct 19, 2022
mw
Oct 19, 2022
mw
Oct 19, 2022
Paul Backus
Oct 19, 2022
mw
Oct 19, 2022
rikki cattermole
Oct 19, 2022
mw
Oct 19, 2022
rikki cattermole
Oct 19, 2022
mw
Oct 19, 2022
H. S. Teoh
Oct 19, 2022
mw
Oct 19, 2022
H. S. Teoh
Oct 19, 2022
mw
Oct 19, 2022
Paul Backus
Oct 19, 2022
mw
Oct 19, 2022
Paul Backus
Oct 19, 2022
H. S. Teoh
Oct 19, 2022
mw
Oct 19, 2022
Paul Backus
Oct 19, 2022
mw
Oct 19, 2022
Adam D Ruppe
Oct 19, 2022
Paul Backus
Oct 19, 2022
H. S. Teoh
Oct 19, 2022
Adam D Ruppe
Oct 19, 2022
Ali Çehreli
Oct 19, 2022
Paul Backus
Oct 19, 2022
mw
Oct 19, 2022
mw
Oct 19, 2022
Paul Backus
Oct 22, 2022
mw
Nov 02, 2022
mw
Oct 19, 2022
mw
October 19, 2022

Following the discussion from:

https://forum.dlang.org/post/kyonizwffgvpuvrwhoog@forum.dlang.org

On Wednesday, 19 October 2022 at 01:49:26 UTC, mw wrote:

>

On Wednesday, 19 October 2022 at 01:38:27 UTC, Adam D Ruppe wrote:

>

On Wednesday, 19 October 2022 at 01:34:54 UTC, mw wrote:

>

Is there any (design) doc about this?

scroll up, click the link from this very thread.

https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1038.md#design-goals-and-possible-alternatives

"""
Rather than make either sacrifice, this DIP proposes a design that allows both rigor and simplicity to be maintained, and reserves the possibility for a future DIP to allow @mustUse as a function attribute.
"""

Another future DIP? I think this DIP is flawed for not using "@mustUse as a function attribute"

@mustuse as a function attribute was in the original version of the DIP. It was vetoed by Walter. Thus, only the type attribute remains in the accepted version.

FWIW, this is the same path that #[must_use] took in Rust. It was added originally as a type attribute only, and later had its usage extended to functions.

In case anyone does not know, I'd like to refer to the following: command query separation principle

https://en.wikipedia.org/wiki/Command%E2%80%93query_separation#:~:text=Command-query%20separation%20(CQS),the%20caller%2C%20but%20not%20

"""
It states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both.
"""

For a query, its return value should never be disregarded, this is forced by the Eiffel compiler.

The kind of problem (wasting hours of development time, frustration and pain) the OP's author has experienced would have never happened if s/he is using Eiffel.

@Walter, you haven't study Eiffel well enough? although you said you have Meyer's book?

October 19, 2022

D does not strictly follow DbC, and has many legacy features from Java/C++ world, and many libraries does not follow command query separation principle at all. Also there is no compiler enforcement. That's the current status, we have to accept that.

In theory:

paths.remove(i); // is just a command, should not return anything, and the paths object itself should have been modified, which is the OP author's expectation.

However, for whatever reason (implementation performance concern maybe?) the remove() method right now returns(!) a new object, which actually is the new paths object with the updated state, so the current correct way to use it is:

paths = paths.remove(i); // works - what I erroneously thought the previous line was doing

So the DIP to add @mustuse as a function attribute is a remedy to D's not being strictly follow DbC and the command query separation principle. At least it forces the programmers do not ignore the important return value as in the above example.

I really cannot see why @mustuse as a function attribute got rejected.

DbC is a seemingly simple concept, but actually it's deeper than you often thought, it affects many details of language design.

October 19, 2022

On Wednesday, 19 October 2022 at 05:41:19 UTC, mw wrote:

>

I really cannot see why @mustuse as a function attribute got rejected.

DbC is a seemingly simple concept, but actually it's deeper than you often thought, it affects many details of language design.

There is also class level private.

October 19, 2022

On Wednesday, 19 October 2022 at 05:41:19 UTC, mw wrote:

>

DbC is a seemingly simple concept, but actually it's deeper than you often thought, it affects many details of language design.

OK, an informal exercise: derive command query separation principle from DbC.

The contract in DbC mostly exhibits as assertions in the code.

The programmer can insert assertions at any place of the code, without changing the code's original semantics (i.e the behavior when the assertions are turned-off, e.g. in release mode). In an OOP language, most of the time the assertions are checking some properties of an object, hence any method that can be called in an assertion must be a query (i.e a query can be called on an object for any number times without changing that object's internal state). So now we have query method.

But we do need to change an object's state in imperative programming, then those methods are classified as commands. After changing an object state, the command must NOT return any value. Why? because otherwise, the programmer may accidentally want to call that command and check the returned value in some assertions ... then you know what happens in the end: the program behaves differently when assertions are turn on in debug mode and off in release mode.

Therefore, we have this:
"""
every method should either be a command that performs an action, or a query that returns data to the caller, but not both.
"""

October 19, 2022

On Wednesday, 19 October 2022 at 04:52:31 UTC, mw wrote:

>

@mustuse as a function attribute was in the original version of the DIP. It was vetoed by Walter. Thus, only the type attribute remains in the accepted version.

Please include the entire context that I posted earliar from the summary of the formal assessment here:

https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1038.md#formal-assessment

Walter didn't just willy-nilly "veto" the attribute on functions. He accepted the proposal with three requests for enhancement, one of which I summarized as:

>

develop rules for handling covariance and contravariance when applied to functions.

Paul opted instead to punt on this and restrict the attribute to types, which was a perfectly reasonable thing to do. Note that the DIP was still accepted.

Walter doesn't not want the attribute to apply to functions. It's just that he wants it to be more fully specified. He and Paul had a series of emails on this and other aspects of the DIP.

If anyone is willing to take this and flesh it out further so that it meets Walter's criteria for applying to functions, please let me know. It's pretty much guaranteed to be approved.

October 19, 2022

On Wednesday, 19 October 2022 at 07:28:21 UTC, Mike Parker wrote:

>

On Wednesday, 19 October 2022 at 04:52:31 UTC, mw wrote:

>

@mustuse as a function attribute was in the original version of the DIP. It was vetoed by Walter. Thus, only the type attribute remains in the accepted version.

Please include the entire context that I posted earliar from the summary of the formal assessment here:

https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1038.md#formal-assessment

Walter didn't just willy-nilly "veto" the attribute on functions. He accepted the proposal with three requests for enhancement, one of which I summarized as:

>

develop rules for handling covariance and contravariance when applied to functions.

Covariance and contravariance is a big topic by itself.
But ..., what does it have anything to do here with @mustuse as a function attribute?

@mustuse here only enforces there must be a receiver of the function call result, and do not throw away the returned result.

I'd really like to see some examples what's this concern is about.

>

Paul opted instead to punt on this and restrict the attribute to types, which was a perfectly reasonable thing to do. Note that the DIP was still accepted.

Walter doesn't not want the attribute to apply to functions. It's just that he wants it to be more fully specified. He and Paul had a series of emails on this and other aspects of the DIP.

If anyone is willing to take this and flesh it out further so that it meets Walter's criteria for applying to functions, please let me know. It's pretty much guaranteed to be approved.

I wish I have more time, but I just have so many things to do these days.

October 19, 2022

On Wednesday, 19 October 2022 at 07:41:33 UTC, mw wrote:

> >

If anyone is willing to take this and flesh it out further so that it meets Walter's criteria for applying to functions, please let me know. It's pretty much guaranteed to be approved.

I wish I have more time, but I just have so many things to do these days.

But if anyone want to work on it, I'd happy to help.

October 19, 2022

On Wednesday, 19 October 2022 at 07:41:33 UTC, mw wrote:

>

Covariance and contravariance is a big topic by itself.
But ..., what does it have anything to do here with @mustuse as a function attribute?

@mustuse here only enforces there must be a receiver of the function call result, and do not throw away the returned result.

I'd really like to see some examples what's this concern is about.

Following are the examples Walter provided in his email discussions with Paul:

Covariance Ex. 1:

class C {
  T h();
}
class D : C {
  override @mustuse T h();
}

Ex. 2

class C {
  @mustuse T h();
}
class D : C {
  override T h();
}

Contravariance Ex. 1:

class C {
   void t(T function() @mustuse *);
}
class D {
   override void t(T function() *);
}

Ex 2:

class C {
   void t(T function() *);
}
class D {
   override void t(T function() @mustuse *);
}

The rules for what happens in each case need to be clearly defined. Walter proposed the following:

====
To establish the rule, just resolve this simple case:

T f();
@mustuse T g();

Can g be implicitly coerced into the type of f? No.
Can f be implicitly coerced into the type of g? Yes.

I.e. @mustuse can be added in an implicit type conversion, but it cannot be
subtracted. That's all we need to know, everything else follows inevitably.

In which case, both Examples 1 would fail, and both Examples 2 would pass.

There was more to their discussion beyond this, though, and I'm not the person to summarize it.

So again, if anyone wants to take a stab at fleshing it out, please let me know. I can ask Paul and Walter to provide their thoughts to help get started.

October 19, 2022

On Wednesday, 19 October 2022 at 07:41:33 UTC, mw wrote:

>

On Wednesday, 19 October 2022 at 07:28:21 UTC, Mike Parker wrote:

>

On Wednesday, 19 October 2022 at 04:52:31 UTC, mw wrote:

>

@mustuse as a function attribute was in the original version of the DIP. It was vetoed by Walter. Thus, only the type attribute remains in the accepted version.

Please include the entire context that I posted earliar from the summary of the formal assessment here:

https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1038.md#formal-assessment

Walter didn't just willy-nilly "veto" the attribute on functions. He accepted the proposal with three requests for enhancement, one of which I summarized as:

>

develop rules for handling covariance and contravariance when applied to functions.

Covariance and contravariance is a big topic by itself.
But ..., what does it have anything to do here with @mustuse as a function attribute?

@mustuse here only enforces there must be a receiver of the function call result, and do not throw away the returned result.

I'd really like to see some examples what's this concern is about.

I read the above link again, esp these:

  1. address issues that arise from the feature's interaction with inheritance when applied to classes.

  2. develop rules for handling covariance and contravariance when applied to functions.

And I think, 3) is talking about 2) about types!

In short: it's about the @mustuse annotation on types! -- the accepted half of the DIP!

Actually, it's the other half I.e @mustuse annotation on function should be accepted! since it has nothing to do with covariance and contravariance.

And the accepted half on types should be addressed with 3).

October 19, 2022

OK, I saw what they are talking about.

Basically, in Eiffel, all query @mustuse.

Here in D @mustuse is an remedy add-on, which can be specified by the programmers in the middle of the inheritance tree, the question is what if the pointers got casted either upwards or downwards?

(It's too late for me here today.)

On Wednesday, 19 October 2022 at 08:15:32 UTC, Mike Parker wrote:

>

On Wednesday, 19 October 2022 at 07:41:33 UTC, mw wrote:

>

Covariance and contravariance is a big topic by itself.
But ..., what does it have anything to do here with @mustuse as a function attribute?

@mustuse here only enforces there must be a receiver of the function call result, and do not throw away the returned result.

I'd really like to see some examples what's this concern is about.

Following are the examples Walter provided in his email discussions with Paul:

Covariance Ex. 1:

class C {
  T h();
}
class D : C {
  override @mustuse T h();
}

Ex. 2

class C {
  @mustuse T h();
}
class D : C {
  override T h();
}

Contravariance Ex. 1:

class C {
   void t(T function() @mustuse *);
}
class D {
   override void t(T function() *);
}

Ex 2:

class C {
   void t(T function() *);
}
class D {
   override void t(T function() @mustuse *);
}

The rules for what happens in each case need to be clearly defined. Walter proposed the following:

====
To establish the rule, just resolve this simple case:

T f();
@mustuse T g();

Can g be implicitly coerced into the type of f? No.
Can f be implicitly coerced into the type of g? Yes.

I.e. @mustuse can be added in an implicit type conversion, but it cannot be
subtracted. That's all we need to know, everything else follows inevitably.

In which case, both Examples 1 would fail, and both Examples 2 would pass.

There was more to their discussion beyond this, though, and I'm not the person to summarize it.

So again, if anyone wants to take a stab at fleshing it out, please let me know. I can ask Paul and Walter to provide their thoughts to help get started.

« First   ‹ Prev
1 2 3 4