CQS Design Principle Problem: Implementing a Queue
up vote
1
down vote
favorite
I'm creating this question based upon a small discussion I had in the comments to the answer to this question: design a method returning a value or changing some data but not both
@Kata pointed out that the pattern that the OP was interested in is called Command–query separation and argued that this is a good model to structure your code by.
From wikipedia:
Command–query separation (CQS) is a principle of imperative computer programming. It was devised by Bertrand Meyer as part of his pioneering work on the Eiffel programming language.
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. In other words, Asking a question should not change the answer.1 More formally, methods should return a value only if they are referentially transparent and hence possess no side effects.
I questioned the soundness of this design principle, as in general it would appear to make your code far more tedious. For instance: you could not perform a simple statement like next = Queue.Dequeue(); You would need two instructions: one to modify the data structure and one to read the result.
@Kata found an alternative Stack implementation that at first glance appears to satisfy the best of both worlds: taking a page from functional programming, we define our Stack as an immutable data-structure. Whenever we push(x) we create a new Stack node that holds the value x and maintains a pointer to the old head Stack instance. Whenever we pop() we just return the pointer to the next Stack instance. Thus we can adhere to the Command-Query Separation Principle.
Example Stack Implementation: https://fsharpforfunandprofit.com/posts/stack-based-calculator/
However, one thing that is unclear in this case is how you would keep multiple references to the Stack in sync while still adhering to the Command-Query Separation Principle? I don't see an obvious solution to this. So as a point of curiosity I'm posing this problem to the community to see if we can't find a satisfactory solution :)
EDIT: Here is an example of the problem:
s = new Stack();
s2 = s
...
s = s.push(x);
assert(s == s2); // this will fail
design-patterns functional-programming
add a comment |
up vote
1
down vote
favorite
I'm creating this question based upon a small discussion I had in the comments to the answer to this question: design a method returning a value or changing some data but not both
@Kata pointed out that the pattern that the OP was interested in is called Command–query separation and argued that this is a good model to structure your code by.
From wikipedia:
Command–query separation (CQS) is a principle of imperative computer programming. It was devised by Bertrand Meyer as part of his pioneering work on the Eiffel programming language.
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. In other words, Asking a question should not change the answer.1 More formally, methods should return a value only if they are referentially transparent and hence possess no side effects.
I questioned the soundness of this design principle, as in general it would appear to make your code far more tedious. For instance: you could not perform a simple statement like next = Queue.Dequeue(); You would need two instructions: one to modify the data structure and one to read the result.
@Kata found an alternative Stack implementation that at first glance appears to satisfy the best of both worlds: taking a page from functional programming, we define our Stack as an immutable data-structure. Whenever we push(x) we create a new Stack node that holds the value x and maintains a pointer to the old head Stack instance. Whenever we pop() we just return the pointer to the next Stack instance. Thus we can adhere to the Command-Query Separation Principle.
Example Stack Implementation: https://fsharpforfunandprofit.com/posts/stack-based-calculator/
However, one thing that is unclear in this case is how you would keep multiple references to the Stack in sync while still adhering to the Command-Query Separation Principle? I don't see an obvious solution to this. So as a point of curiosity I'm posing this problem to the community to see if we can't find a satisfactory solution :)
EDIT: Here is an example of the problem:
s = new Stack();
s2 = s
...
s = s.push(x);
assert(s == s2); // this will fail
design-patterns functional-programming
Comments are not for extended discussion; this conversation has been moved to chat.
– Samuel Liew♦
Nov 10 at 20:37
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I'm creating this question based upon a small discussion I had in the comments to the answer to this question: design a method returning a value or changing some data but not both
@Kata pointed out that the pattern that the OP was interested in is called Command–query separation and argued that this is a good model to structure your code by.
From wikipedia:
Command–query separation (CQS) is a principle of imperative computer programming. It was devised by Bertrand Meyer as part of his pioneering work on the Eiffel programming language.
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. In other words, Asking a question should not change the answer.1 More formally, methods should return a value only if they are referentially transparent and hence possess no side effects.
I questioned the soundness of this design principle, as in general it would appear to make your code far more tedious. For instance: you could not perform a simple statement like next = Queue.Dequeue(); You would need two instructions: one to modify the data structure and one to read the result.
@Kata found an alternative Stack implementation that at first glance appears to satisfy the best of both worlds: taking a page from functional programming, we define our Stack as an immutable data-structure. Whenever we push(x) we create a new Stack node that holds the value x and maintains a pointer to the old head Stack instance. Whenever we pop() we just return the pointer to the next Stack instance. Thus we can adhere to the Command-Query Separation Principle.
Example Stack Implementation: https://fsharpforfunandprofit.com/posts/stack-based-calculator/
However, one thing that is unclear in this case is how you would keep multiple references to the Stack in sync while still adhering to the Command-Query Separation Principle? I don't see an obvious solution to this. So as a point of curiosity I'm posing this problem to the community to see if we can't find a satisfactory solution :)
EDIT: Here is an example of the problem:
s = new Stack();
s2 = s
...
s = s.push(x);
assert(s == s2); // this will fail
design-patterns functional-programming
I'm creating this question based upon a small discussion I had in the comments to the answer to this question: design a method returning a value or changing some data but not both
@Kata pointed out that the pattern that the OP was interested in is called Command–query separation and argued that this is a good model to structure your code by.
From wikipedia:
Command–query separation (CQS) is a principle of imperative computer programming. It was devised by Bertrand Meyer as part of his pioneering work on the Eiffel programming language.
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. In other words, Asking a question should not change the answer.1 More formally, methods should return a value only if they are referentially transparent and hence possess no side effects.
I questioned the soundness of this design principle, as in general it would appear to make your code far more tedious. For instance: you could not perform a simple statement like next = Queue.Dequeue(); You would need two instructions: one to modify the data structure and one to read the result.
@Kata found an alternative Stack implementation that at first glance appears to satisfy the best of both worlds: taking a page from functional programming, we define our Stack as an immutable data-structure. Whenever we push(x) we create a new Stack node that holds the value x and maintains a pointer to the old head Stack instance. Whenever we pop() we just return the pointer to the next Stack instance. Thus we can adhere to the Command-Query Separation Principle.
Example Stack Implementation: https://fsharpforfunandprofit.com/posts/stack-based-calculator/
However, one thing that is unclear in this case is how you would keep multiple references to the Stack in sync while still adhering to the Command-Query Separation Principle? I don't see an obvious solution to this. So as a point of curiosity I'm posing this problem to the community to see if we can't find a satisfactory solution :)
EDIT: Here is an example of the problem:
s = new Stack();
s2 = s
...
s = s.push(x);
assert(s == s2); // this will fail
design-patterns functional-programming
design-patterns functional-programming
edited Nov 10 at 14:45
asked Nov 10 at 10:22
Ryan Pierce Williams
43719
43719
Comments are not for extended discussion; this conversation has been moved to chat.
– Samuel Liew♦
Nov 10 at 20:37
add a comment |
Comments are not for extended discussion; this conversation has been moved to chat.
– Samuel Liew♦
Nov 10 at 20:37
Comments are not for extended discussion; this conversation has been moved to chat.
– Samuel Liew♦
Nov 10 at 20:37
Comments are not for extended discussion; this conversation has been moved to chat.
– Samuel Liew♦
Nov 10 at 20:37
add a comment |
2 Answers
2
active
oldest
votes
up vote
1
down vote
accepted
In Functional Programming (FP) style, we often design our functions so that we don't need to keep such those references in sync.
Consider this scenario: you create a stack s
, inject it into a Client
object, then push an item to s
and get a new stack s2
:
s = new Stack()
client = new Client(s)
s2 = s.push(...)
Because s
and s2
are not in sync (i.e., they are different stacks), inside the object client
, it still sees the old version of stack (s
) which is something you don't want. Here is the code of Client
:
class Client {
private Stack stack;
// other properties
public Client(Stack stack) { this.stack = stack; }
public SomeType foo(/*some parameters*/) {
// access this.stack
}
}
To solve this, the functional approach does not use such an implicit reference, but instead passes the reference into the function as an explicit parameter:
class Client {
// some properties
public SomeType foo(Stack stack, /*some parameters*/) {
// access stack
}
}
Of course, sometimes this would be painful as the function now has one extra parameter. Every caller of Client
must maintain a stack in order to call the foo
function. That's why in FP you tend to see functions with more parameters than in OOP.
But FP has a concept which can mitigate this pain: the so-called partial application. If you already have a stack s
, you can write client.foo(s)
to get an "upgraded" version of foo
which does not require a stack but only requires the other some parameters
. Then you can pass that upgraded foo
function to a receiver who does not maintain any stack.
Nevertheless, it's worth to mention that there are people who agure that this pain can be actually helpful. For example, Scott Wlaschin in his article Functional approaches to dependency injection:
The downside of course, is that there are now five extra parameters for the function, which looks painful. (Of course, the equivalent method in the OO version also had these five dependencies, but they were implicit).
In my opinion though, this pain is actually helpful! With OO style interfaces, there is a natural tendency for them to accrete crud over time. But with explicit parameters like this, there is a natural disincentive to have too many dependencies! The need for a guideline such as the Interface Segregation Principle is much diminished.
Also, Mark Seemann -- the author of the book Dependency Injection -- had an interesting series on Dependency Rejection.
In case you cannot suffer that pain, then just break the CQS and back to the traditional implementation of Stack. After all, if a function (like pop
/dequeue
) is well-known and well-aware that it both returns something and changes its internal data, a violation of CQS is not so bad.
Even in this case, some FP languages offer a message-passing mechanism so that you can implement a mutable Stack in a manner that you don't write code mutating data (e.g., code using assignment symbol). MailboxProcessor in F# is such a mechanism.
Hope this helps :)
1
I do need to make more use of partial applications; very powerful :) I still don't think CQS makes much sense as a general design principle to follow, however, because of the unnecessary added complexity. It maybe better to argue that it is beneficial for particular scenarios rather than as a general design principle.
– Ryan Pierce Williams
Nov 11 at 7:52
Yes, you are right!
– Nghia Bui
Nov 11 at 7:52
add a comment |
up vote
0
down vote
It is because of the design of the function, you need to return a state which reflects the context.
This allows you to differentiate between success and failure as well as potentially other information if you supplement bool with a DequeueResult in the following minimal party code.
Let Dequeue = function bool(Result)
If Head == Null return
...
Return true
Something more inline with CQS might be
Let Dequeue = function Node()
Return Head
But would require Head to have a special value of Node.Null to try my differentiate between failures and contention.
Returning a DequeueResult may be better where you can indicate in the result more about the failure.
This version of Dequeue does not return the element. You can work around this by peeking before dequeuing, but then you are right back to my original complaint about CQS: you have made your code far more tedious since you now require multiple operations to accomplish the same basic tasks that you could complete in one step by not following the CQS.
– Ryan Pierce Williams
Nov 10 at 14:23
Then you want Let Dequeue = function Node() Return Head you would have to have a special operator for Node or have a Node.Null
– Jay
Nov 10 at 14:25
But then how do you solve the problem of keeping multiple stack references in sync? See example code in the OP.
– Ryan Pierce Williams
Nov 10 at 14:35
You wouldn't be able to assign a Node to a Stack variable unless we are assuming JavaScript, in which case const is the solution
– Jay
Nov 10 at 14:58
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237990%2fcqs-design-principle-problem-implementing-a-queue%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
In Functional Programming (FP) style, we often design our functions so that we don't need to keep such those references in sync.
Consider this scenario: you create a stack s
, inject it into a Client
object, then push an item to s
and get a new stack s2
:
s = new Stack()
client = new Client(s)
s2 = s.push(...)
Because s
and s2
are not in sync (i.e., they are different stacks), inside the object client
, it still sees the old version of stack (s
) which is something you don't want. Here is the code of Client
:
class Client {
private Stack stack;
// other properties
public Client(Stack stack) { this.stack = stack; }
public SomeType foo(/*some parameters*/) {
// access this.stack
}
}
To solve this, the functional approach does not use such an implicit reference, but instead passes the reference into the function as an explicit parameter:
class Client {
// some properties
public SomeType foo(Stack stack, /*some parameters*/) {
// access stack
}
}
Of course, sometimes this would be painful as the function now has one extra parameter. Every caller of Client
must maintain a stack in order to call the foo
function. That's why in FP you tend to see functions with more parameters than in OOP.
But FP has a concept which can mitigate this pain: the so-called partial application. If you already have a stack s
, you can write client.foo(s)
to get an "upgraded" version of foo
which does not require a stack but only requires the other some parameters
. Then you can pass that upgraded foo
function to a receiver who does not maintain any stack.
Nevertheless, it's worth to mention that there are people who agure that this pain can be actually helpful. For example, Scott Wlaschin in his article Functional approaches to dependency injection:
The downside of course, is that there are now five extra parameters for the function, which looks painful. (Of course, the equivalent method in the OO version also had these five dependencies, but they were implicit).
In my opinion though, this pain is actually helpful! With OO style interfaces, there is a natural tendency for them to accrete crud over time. But with explicit parameters like this, there is a natural disincentive to have too many dependencies! The need for a guideline such as the Interface Segregation Principle is much diminished.
Also, Mark Seemann -- the author of the book Dependency Injection -- had an interesting series on Dependency Rejection.
In case you cannot suffer that pain, then just break the CQS and back to the traditional implementation of Stack. After all, if a function (like pop
/dequeue
) is well-known and well-aware that it both returns something and changes its internal data, a violation of CQS is not so bad.
Even in this case, some FP languages offer a message-passing mechanism so that you can implement a mutable Stack in a manner that you don't write code mutating data (e.g., code using assignment symbol). MailboxProcessor in F# is such a mechanism.
Hope this helps :)
1
I do need to make more use of partial applications; very powerful :) I still don't think CQS makes much sense as a general design principle to follow, however, because of the unnecessary added complexity. It maybe better to argue that it is beneficial for particular scenarios rather than as a general design principle.
– Ryan Pierce Williams
Nov 11 at 7:52
Yes, you are right!
– Nghia Bui
Nov 11 at 7:52
add a comment |
up vote
1
down vote
accepted
In Functional Programming (FP) style, we often design our functions so that we don't need to keep such those references in sync.
Consider this scenario: you create a stack s
, inject it into a Client
object, then push an item to s
and get a new stack s2
:
s = new Stack()
client = new Client(s)
s2 = s.push(...)
Because s
and s2
are not in sync (i.e., they are different stacks), inside the object client
, it still sees the old version of stack (s
) which is something you don't want. Here is the code of Client
:
class Client {
private Stack stack;
// other properties
public Client(Stack stack) { this.stack = stack; }
public SomeType foo(/*some parameters*/) {
// access this.stack
}
}
To solve this, the functional approach does not use such an implicit reference, but instead passes the reference into the function as an explicit parameter:
class Client {
// some properties
public SomeType foo(Stack stack, /*some parameters*/) {
// access stack
}
}
Of course, sometimes this would be painful as the function now has one extra parameter. Every caller of Client
must maintain a stack in order to call the foo
function. That's why in FP you tend to see functions with more parameters than in OOP.
But FP has a concept which can mitigate this pain: the so-called partial application. If you already have a stack s
, you can write client.foo(s)
to get an "upgraded" version of foo
which does not require a stack but only requires the other some parameters
. Then you can pass that upgraded foo
function to a receiver who does not maintain any stack.
Nevertheless, it's worth to mention that there are people who agure that this pain can be actually helpful. For example, Scott Wlaschin in his article Functional approaches to dependency injection:
The downside of course, is that there are now five extra parameters for the function, which looks painful. (Of course, the equivalent method in the OO version also had these five dependencies, but they were implicit).
In my opinion though, this pain is actually helpful! With OO style interfaces, there is a natural tendency for them to accrete crud over time. But with explicit parameters like this, there is a natural disincentive to have too many dependencies! The need for a guideline such as the Interface Segregation Principle is much diminished.
Also, Mark Seemann -- the author of the book Dependency Injection -- had an interesting series on Dependency Rejection.
In case you cannot suffer that pain, then just break the CQS and back to the traditional implementation of Stack. After all, if a function (like pop
/dequeue
) is well-known and well-aware that it both returns something and changes its internal data, a violation of CQS is not so bad.
Even in this case, some FP languages offer a message-passing mechanism so that you can implement a mutable Stack in a manner that you don't write code mutating data (e.g., code using assignment symbol). MailboxProcessor in F# is such a mechanism.
Hope this helps :)
1
I do need to make more use of partial applications; very powerful :) I still don't think CQS makes much sense as a general design principle to follow, however, because of the unnecessary added complexity. It maybe better to argue that it is beneficial for particular scenarios rather than as a general design principle.
– Ryan Pierce Williams
Nov 11 at 7:52
Yes, you are right!
– Nghia Bui
Nov 11 at 7:52
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
In Functional Programming (FP) style, we often design our functions so that we don't need to keep such those references in sync.
Consider this scenario: you create a stack s
, inject it into a Client
object, then push an item to s
and get a new stack s2
:
s = new Stack()
client = new Client(s)
s2 = s.push(...)
Because s
and s2
are not in sync (i.e., they are different stacks), inside the object client
, it still sees the old version of stack (s
) which is something you don't want. Here is the code of Client
:
class Client {
private Stack stack;
// other properties
public Client(Stack stack) { this.stack = stack; }
public SomeType foo(/*some parameters*/) {
// access this.stack
}
}
To solve this, the functional approach does not use such an implicit reference, but instead passes the reference into the function as an explicit parameter:
class Client {
// some properties
public SomeType foo(Stack stack, /*some parameters*/) {
// access stack
}
}
Of course, sometimes this would be painful as the function now has one extra parameter. Every caller of Client
must maintain a stack in order to call the foo
function. That's why in FP you tend to see functions with more parameters than in OOP.
But FP has a concept which can mitigate this pain: the so-called partial application. If you already have a stack s
, you can write client.foo(s)
to get an "upgraded" version of foo
which does not require a stack but only requires the other some parameters
. Then you can pass that upgraded foo
function to a receiver who does not maintain any stack.
Nevertheless, it's worth to mention that there are people who agure that this pain can be actually helpful. For example, Scott Wlaschin in his article Functional approaches to dependency injection:
The downside of course, is that there are now five extra parameters for the function, which looks painful. (Of course, the equivalent method in the OO version also had these five dependencies, but they were implicit).
In my opinion though, this pain is actually helpful! With OO style interfaces, there is a natural tendency for them to accrete crud over time. But with explicit parameters like this, there is a natural disincentive to have too many dependencies! The need for a guideline such as the Interface Segregation Principle is much diminished.
Also, Mark Seemann -- the author of the book Dependency Injection -- had an interesting series on Dependency Rejection.
In case you cannot suffer that pain, then just break the CQS and back to the traditional implementation of Stack. After all, if a function (like pop
/dequeue
) is well-known and well-aware that it both returns something and changes its internal data, a violation of CQS is not so bad.
Even in this case, some FP languages offer a message-passing mechanism so that you can implement a mutable Stack in a manner that you don't write code mutating data (e.g., code using assignment symbol). MailboxProcessor in F# is such a mechanism.
Hope this helps :)
In Functional Programming (FP) style, we often design our functions so that we don't need to keep such those references in sync.
Consider this scenario: you create a stack s
, inject it into a Client
object, then push an item to s
and get a new stack s2
:
s = new Stack()
client = new Client(s)
s2 = s.push(...)
Because s
and s2
are not in sync (i.e., they are different stacks), inside the object client
, it still sees the old version of stack (s
) which is something you don't want. Here is the code of Client
:
class Client {
private Stack stack;
// other properties
public Client(Stack stack) { this.stack = stack; }
public SomeType foo(/*some parameters*/) {
// access this.stack
}
}
To solve this, the functional approach does not use such an implicit reference, but instead passes the reference into the function as an explicit parameter:
class Client {
// some properties
public SomeType foo(Stack stack, /*some parameters*/) {
// access stack
}
}
Of course, sometimes this would be painful as the function now has one extra parameter. Every caller of Client
must maintain a stack in order to call the foo
function. That's why in FP you tend to see functions with more parameters than in OOP.
But FP has a concept which can mitigate this pain: the so-called partial application. If you already have a stack s
, you can write client.foo(s)
to get an "upgraded" version of foo
which does not require a stack but only requires the other some parameters
. Then you can pass that upgraded foo
function to a receiver who does not maintain any stack.
Nevertheless, it's worth to mention that there are people who agure that this pain can be actually helpful. For example, Scott Wlaschin in his article Functional approaches to dependency injection:
The downside of course, is that there are now five extra parameters for the function, which looks painful. (Of course, the equivalent method in the OO version also had these five dependencies, but they were implicit).
In my opinion though, this pain is actually helpful! With OO style interfaces, there is a natural tendency for them to accrete crud over time. But with explicit parameters like this, there is a natural disincentive to have too many dependencies! The need for a guideline such as the Interface Segregation Principle is much diminished.
Also, Mark Seemann -- the author of the book Dependency Injection -- had an interesting series on Dependency Rejection.
In case you cannot suffer that pain, then just break the CQS and back to the traditional implementation of Stack. After all, if a function (like pop
/dequeue
) is well-known and well-aware that it both returns something and changes its internal data, a violation of CQS is not so bad.
Even in this case, some FP languages offer a message-passing mechanism so that you can implement a mutable Stack in a manner that you don't write code mutating data (e.g., code using assignment symbol). MailboxProcessor in F# is such a mechanism.
Hope this helps :)
edited Nov 11 at 15:11
answered Nov 11 at 7:38
Nghia Bui
1,443812
1,443812
1
I do need to make more use of partial applications; very powerful :) I still don't think CQS makes much sense as a general design principle to follow, however, because of the unnecessary added complexity. It maybe better to argue that it is beneficial for particular scenarios rather than as a general design principle.
– Ryan Pierce Williams
Nov 11 at 7:52
Yes, you are right!
– Nghia Bui
Nov 11 at 7:52
add a comment |
1
I do need to make more use of partial applications; very powerful :) I still don't think CQS makes much sense as a general design principle to follow, however, because of the unnecessary added complexity. It maybe better to argue that it is beneficial for particular scenarios rather than as a general design principle.
– Ryan Pierce Williams
Nov 11 at 7:52
Yes, you are right!
– Nghia Bui
Nov 11 at 7:52
1
1
I do need to make more use of partial applications; very powerful :) I still don't think CQS makes much sense as a general design principle to follow, however, because of the unnecessary added complexity. It maybe better to argue that it is beneficial for particular scenarios rather than as a general design principle.
– Ryan Pierce Williams
Nov 11 at 7:52
I do need to make more use of partial applications; very powerful :) I still don't think CQS makes much sense as a general design principle to follow, however, because of the unnecessary added complexity. It maybe better to argue that it is beneficial for particular scenarios rather than as a general design principle.
– Ryan Pierce Williams
Nov 11 at 7:52
Yes, you are right!
– Nghia Bui
Nov 11 at 7:52
Yes, you are right!
– Nghia Bui
Nov 11 at 7:52
add a comment |
up vote
0
down vote
It is because of the design of the function, you need to return a state which reflects the context.
This allows you to differentiate between success and failure as well as potentially other information if you supplement bool with a DequeueResult in the following minimal party code.
Let Dequeue = function bool(Result)
If Head == Null return
...
Return true
Something more inline with CQS might be
Let Dequeue = function Node()
Return Head
But would require Head to have a special value of Node.Null to try my differentiate between failures and contention.
Returning a DequeueResult may be better where you can indicate in the result more about the failure.
This version of Dequeue does not return the element. You can work around this by peeking before dequeuing, but then you are right back to my original complaint about CQS: you have made your code far more tedious since you now require multiple operations to accomplish the same basic tasks that you could complete in one step by not following the CQS.
– Ryan Pierce Williams
Nov 10 at 14:23
Then you want Let Dequeue = function Node() Return Head you would have to have a special operator for Node or have a Node.Null
– Jay
Nov 10 at 14:25
But then how do you solve the problem of keeping multiple stack references in sync? See example code in the OP.
– Ryan Pierce Williams
Nov 10 at 14:35
You wouldn't be able to assign a Node to a Stack variable unless we are assuming JavaScript, in which case const is the solution
– Jay
Nov 10 at 14:58
add a comment |
up vote
0
down vote
It is because of the design of the function, you need to return a state which reflects the context.
This allows you to differentiate between success and failure as well as potentially other information if you supplement bool with a DequeueResult in the following minimal party code.
Let Dequeue = function bool(Result)
If Head == Null return
...
Return true
Something more inline with CQS might be
Let Dequeue = function Node()
Return Head
But would require Head to have a special value of Node.Null to try my differentiate between failures and contention.
Returning a DequeueResult may be better where you can indicate in the result more about the failure.
This version of Dequeue does not return the element. You can work around this by peeking before dequeuing, but then you are right back to my original complaint about CQS: you have made your code far more tedious since you now require multiple operations to accomplish the same basic tasks that you could complete in one step by not following the CQS.
– Ryan Pierce Williams
Nov 10 at 14:23
Then you want Let Dequeue = function Node() Return Head you would have to have a special operator for Node or have a Node.Null
– Jay
Nov 10 at 14:25
But then how do you solve the problem of keeping multiple stack references in sync? See example code in the OP.
– Ryan Pierce Williams
Nov 10 at 14:35
You wouldn't be able to assign a Node to a Stack variable unless we are assuming JavaScript, in which case const is the solution
– Jay
Nov 10 at 14:58
add a comment |
up vote
0
down vote
up vote
0
down vote
It is because of the design of the function, you need to return a state which reflects the context.
This allows you to differentiate between success and failure as well as potentially other information if you supplement bool with a DequeueResult in the following minimal party code.
Let Dequeue = function bool(Result)
If Head == Null return
...
Return true
Something more inline with CQS might be
Let Dequeue = function Node()
Return Head
But would require Head to have a special value of Node.Null to try my differentiate between failures and contention.
Returning a DequeueResult may be better where you can indicate in the result more about the failure.
It is because of the design of the function, you need to return a state which reflects the context.
This allows you to differentiate between success and failure as well as potentially other information if you supplement bool with a DequeueResult in the following minimal party code.
Let Dequeue = function bool(Result)
If Head == Null return
...
Return true
Something more inline with CQS might be
Let Dequeue = function Node()
Return Head
But would require Head to have a special value of Node.Null to try my differentiate between failures and contention.
Returning a DequeueResult may be better where you can indicate in the result more about the failure.
edited Nov 10 at 14:28
answered Nov 10 at 14:20
Jay
2,55611825
2,55611825
This version of Dequeue does not return the element. You can work around this by peeking before dequeuing, but then you are right back to my original complaint about CQS: you have made your code far more tedious since you now require multiple operations to accomplish the same basic tasks that you could complete in one step by not following the CQS.
– Ryan Pierce Williams
Nov 10 at 14:23
Then you want Let Dequeue = function Node() Return Head you would have to have a special operator for Node or have a Node.Null
– Jay
Nov 10 at 14:25
But then how do you solve the problem of keeping multiple stack references in sync? See example code in the OP.
– Ryan Pierce Williams
Nov 10 at 14:35
You wouldn't be able to assign a Node to a Stack variable unless we are assuming JavaScript, in which case const is the solution
– Jay
Nov 10 at 14:58
add a comment |
This version of Dequeue does not return the element. You can work around this by peeking before dequeuing, but then you are right back to my original complaint about CQS: you have made your code far more tedious since you now require multiple operations to accomplish the same basic tasks that you could complete in one step by not following the CQS.
– Ryan Pierce Williams
Nov 10 at 14:23
Then you want Let Dequeue = function Node() Return Head you would have to have a special operator for Node or have a Node.Null
– Jay
Nov 10 at 14:25
But then how do you solve the problem of keeping multiple stack references in sync? See example code in the OP.
– Ryan Pierce Williams
Nov 10 at 14:35
You wouldn't be able to assign a Node to a Stack variable unless we are assuming JavaScript, in which case const is the solution
– Jay
Nov 10 at 14:58
This version of Dequeue does not return the element. You can work around this by peeking before dequeuing, but then you are right back to my original complaint about CQS: you have made your code far more tedious since you now require multiple operations to accomplish the same basic tasks that you could complete in one step by not following the CQS.
– Ryan Pierce Williams
Nov 10 at 14:23
This version of Dequeue does not return the element. You can work around this by peeking before dequeuing, but then you are right back to my original complaint about CQS: you have made your code far more tedious since you now require multiple operations to accomplish the same basic tasks that you could complete in one step by not following the CQS.
– Ryan Pierce Williams
Nov 10 at 14:23
Then you want Let Dequeue = function Node() Return Head you would have to have a special operator for Node or have a Node.Null
– Jay
Nov 10 at 14:25
Then you want Let Dequeue = function Node() Return Head you would have to have a special operator for Node or have a Node.Null
– Jay
Nov 10 at 14:25
But then how do you solve the problem of keeping multiple stack references in sync? See example code in the OP.
– Ryan Pierce Williams
Nov 10 at 14:35
But then how do you solve the problem of keeping multiple stack references in sync? See example code in the OP.
– Ryan Pierce Williams
Nov 10 at 14:35
You wouldn't be able to assign a Node to a Stack variable unless we are assuming JavaScript, in which case const is the solution
– Jay
Nov 10 at 14:58
You wouldn't be able to assign a Node to a Stack variable unless we are assuming JavaScript, in which case const is the solution
– Jay
Nov 10 at 14:58
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237990%2fcqs-design-principle-problem-implementing-a-queue%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Comments are not for extended discussion; this conversation has been moved to chat.
– Samuel Liew♦
Nov 10 at 20:37