You missed the point. And you're also completely wrong. Copilot is extremely useful and in general a huge timesaver.
Yes if you tell it to write an entire program it will get it wrong and you'll spend some time verifying things. But that's not a sane way to use it. As a very clever auto-complete it's fantastic. It's also pretty great at getting past "blank page syndrome". Even if what it spits out is wrong it's still helpful to get you started.
I don't know if I'm doing something wrong, and admittedly I have only tried the free version of ChatGPT (3.5), but it basically never works for me. Not even for relatively simple things.
From my past history:
"Is "192.168.1.4" included in the subnet "192.168.0.0/16"?" -> No
"Check whether a widget overflows in flutter" -> returns a function that cannot be made to works even with a lot of massaging (uses stuff that does not exist)
"Write a parser for this multiline format in C++ (describe format)" -> parser only read first line
Admittedly a trick one: "Can you give me a C++ function to merge 2 uint32_t and one uint16_t into a unique uint64_t?" -> happily gives an answer
Sometimes it is salvageable, and sometimes it can provide ways I did not consider to solve a problem (though the proposed solution is usually broken), but usually I would have been faster to do it myself than to try to fix whatever it gives me.
I have basically given up on it, except for some generic "how would you solve problem X?", and when I see people talking about it, it feels like a totally different world.
> "Is "192.168.1.4" included in the subnet "192.168.0.0/16"?" -> No
ChatGPT is not good at numbers or complex maths like this.
> Check whether a widget overflows in flutter
I mean this would be closed as unclear on StackOverflow, but again, this is basically asking ChatGPT to write an entire function. It can do a good stab but it's not going to get it correct.
Copilot isn't for that sort of thing. Let me give you a more realistic autocomplete example from my code:
It completes `, cpp).expect("error writing main.cpp");` which is actually exactly what I had. I may have used Copilot to write that; I don't remember. The point is it is 100% correct and saved me writing all that. Traditional autocomplete can't compete with that.
However even for "do it all for me" queries it can still be useful. For example I asked:
> I have a C++ process paused in a debugger (lldb). It is consuming a lot of memory. Is there any way I can see what is using the memory? E.g. a heap profiler that can attach to the process?
It got it wrong and told me to run the process under Valgrind. I said:
> Those instructions aren't for attaching to an existing process.
And it told me about the Heaptrack project with can do exactly what I want. I can see why search engines are integrating this asap. Even though it hallucinates, it does that infrequently enough that it's still really useful. I mean it hallucinates frequently but even so it is very useful.
Perhaps a better example is this:
> Write a C++ program to run a child process and send data to its stdin and stdout while it is running.
After 2 more prompts I got it to output the code below. This code is not correct. But the fixes to make it work are relatively minor, and EASILY less work than writing it all from scratch.
In a few years we will look on people that don't use Copilot (or similar) like people that don't use IDEs. They're hurting their own productivity out of principal.
-------
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <vector>
class ChildProcess {
public:
ChildProcess() : pid(-1), pipefd{-1, -1} {}
~ChildProcess() {
if (pid != -1) {
close(pipefd[1]); // Close write end of the pipe
waitpid(pid, nullptr, 0);
}
}
bool create(const std::string& command, const std::vector<std::string>& arguments) {
if (pipe(pipefd) == -1) {
std::cerr << "Failed to create pipe." << std::endl;
return false;
}
pid = fork();
if (pid < 0) {
std::cerr << "Failed to fork process." << std::endl;
return false;
} else if (pid == 0) {
// Child process
close(pipefd[0]); // Close unused read end of the pipe
// Redirect stdin and stdout to the pipe
if (dup2(pipefd[1], STDIN_FILENO) == -1) {
std::cerr << "Failed to redirect stdin." << std::endl;
return false;
}
if (dup2(pipefd[1], STDOUT_FILENO) == -1) {
std::cerr << "Failed to redirect stdout." << std::endl;
return false;
}
// Convert arguments to a C-style array
std::vector<char*> args;
args.reserve(arguments.size() + 2);
args.push_back(const_cast<char*>(command.c_str()));
for (const std::string& arg : arguments) {
args.push_back(const_cast<char*>(arg.c_str()));
}
args.push_back(nullptr);
// Execute the child process
execvp(command.c_str(), args.data());
// execvp() only returns if there's an error
std::cerr << "Failed to execute child process." << std::endl;
return false;
} else {
// Parent process
close(pipefd[1]); // Close unused write end of the pipe
}
return true;
}
void write(const std::string& data) {
if (pid != -1) {
::write(pipefd[1], data.c_str(), data.size());
}
}
std::string read(size_t numBytes) {
std::string output;
if (pid != -1) {
char buffer[numBytes + 1];
ssize_t bytesRead = ::read(pipefd[0], buffer, numBytes);
if (bytesRead > 0) {
buffer[bytesRead] = '\0';
output = buffer;
}
}
return output;
}
std::string readLine() {
std::string output;
if (pid != -1) {
char buffer;
ssize_t bytesRead;
while ((bytesRead = ::read(pipefd[0], &buffer, 1)) > 0) {
output.push_back(buffer);
if (buffer == '\n') {
break;
}
}
}
return output;
}
private:
pid_t pid;
int pipefd[2];
};
int main() {
ChildProcess childProcess;
std::vector<std::string> arguments = {"arg1", "arg2"};
if (childProcess.create("child_process", arguments)) {
childProcess.write("Hello, child process!");
std::string output = childProcess.read(1024);
std::cout << "Child process output: " << output << std::endl;
std::string line = childProcess.readLine();
std::cout << "Child process line: " << line << std::endl;
}
return 0;
}
No I didn't miss the point, not even slightly. You didn't read mine and are blinded by the insane virtues.
Do you really think it's fine blowing 400 watts because you can't be arsed to think or do not have the creative intelligence to get over the blank page syndrome and have to lean on a crutch?
> Do you really think it's fine blowing 400 watts because you can't be arsed to think or do not have the creative intelligence to get over the blank page syndrome and have to lean on a crutch?
Yes if you tell it to write an entire program it will get it wrong and you'll spend some time verifying things. But that's not a sane way to use it. As a very clever auto-complete it's fantastic. It's also pretty great at getting past "blank page syndrome". Even if what it spits out is wrong it's still helpful to get you started.