Question

As described here, a function can be said to be a query when it returns a value, and a command when it modifies a value. It also states that a function should not be both.

That a query should not be a command seems popularly enforced by functional programming, in that it is a pure function.

Does a language exist, where if and only if the function is non-void, it cannot change state?

Was it helpful?

Solution

Yes, SQL has distinct commands for querys (reads) and commands (updates).

SQL has different commands for DML (Data Manipulation Language) for performing INSERT, UPDATE, DELETE.

For reads, use DQL (Data Query Language) for performing SELECTs (reads).

Languages like C# are OO based. The best you can do with a language like C# is to put up guardrails.

For example a query interface:

public interface IQuery<in TIn, out TOut>
{
    TOut Execute(TIn queryInput);
}

A command interface:

public interface ICommand<in TIn>
{
    void Execute(TIn commandInput);
}

One can also make object(s) immutable to ensure that they can not be changed once instantiated.

But, developers can ignore the guardrails so if Command-Query is being implemented in a language like C#, probably new code that is added should be code reviewed to ensure the pattern is being followed as initially designed.

OTHER TIPS

As far as I know there isn’t such a language because in some instances there are specific cases where you do need to both modify a value and return a value at the same time.

For example, in c# there is a common pattern used called TryGet. In this case you output a modified value of some parameter using the “out” keyword, while returning a bool to store whether the modification was successful.

So something like this simple example. (Typed on phone so sorry if there are errors)

bool TryGetFifthCharacter(string origString, out char fifthChar) {
    bool itWorked;
    if (length < 5) {
        ItWorked = false;
    }
    else {
        fifthChar = origString[5];
        itWorked = true;
    }
    return itWorked;
}

Use the function like this:

string orig = “hello”;
char fifth;
if (TryGetFifthCharacter(orig, out fifth)) {
    print(fifth);
}
else {
    print(“failed”);
}

So there are some cases where you want to do both things! Although I think this should be used only in very specific cases.

Licensed under: CC-BY-SA with attribution
scroll top