How I want my command inputs, but nobody agrees

legolord208

jD91mZM2

Posted on August 13, 2017

How I want my command inputs, but nobody agrees
switch cmd {
case "help":
    search := strings.Join(args, " ")
    printHelp(search)
case "exit":
    closing = true
case "exec":
    if nargs < 1 {
        stdutil.PrintErr("exec <command>", nil)
        return
    }
    ...
Enter fullscreen mode Exit fullscreen mode

This is some source code from my old version of my crappy application DiscordConsole, written in Go. (A rewrite is being made.)
I chose it because it perfectly demonstrates how I want my command systems, and also how languages make this difficult.
Come on, I know you like your OOP, but isn't it damn overkill to

public interface CommandHandler {
    public String[] acceptCommands();
    public int minArg();
    public int maxArg();
    public void handleCommand(String, CommandArgs);
}
public class EchoCommand implements CommandHandler {
    public String[] acceptCommands() {
        return []String{"echo"};
    }
    public int minArg() { return 1; }
    public int maxArg() { return Integer.MAX_VALUE; }
    public void handleCommand(String cmd, CommandArgs args) {
        System.out.println(args.join());
    }
}
...
Enter fullscreen mode Exit fullscreen mode

To me that's just plain ugly. And oh god how inefficient.
Sorry for the mix of programming languages, I thought Java perfectly described OOP, and Go perfectly described how I want my command systems while still using the "switch" keyword and not "match" like Rust does.

But there is this one advantage with your system. It allows splitting commands in multiple files. And now you won't stop nagging on me and how horrible my command system is.
Yes, it's true I can't split mine into multiple files. It's true that's really a problem once you get more than 3 commands. But it's also the OOP way makes unecessary allocations and function calls, and is a pain to set up.

So let's think outside the rules of any programming language. What is a perfect command system to me?

match cmd {
    "echo" => {
        usage_min!(1, "No argument specified");
        println!("{}", args.join(" "));
    },
    "some_long_command" => include!("commands/some_long_command.rs"),
    ...
}
Enter fullscreen mode Exit fullscreen mode

This example was written in Rust. The match keyword is like switch but cooler. It perfectly demonstrates how macros are THE way to make a cheap application look good in code, and yes, that is saying all languages that don't have them suck. I love macros.
It also shows that it very nearly is possible to make a non-OOP command system look good, AND split it into multiple files. The only thing stopping us is that the include! keyword in Rust exists, but it doesn't see local variables and macros.
Still then, a lot more languages should have macros, and a lot more languages should be able to include a file's contents without any hygiene and stuff.

This whole post is essentially me hoping #32379 gets fixed...

💖 💪 🙅 🚩
legolord208
jD91mZM2

Posted on August 13, 2017

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related