0
proc myproc(T: typedesc): string =
  when T is bool:
    return "bool"
  when T is float:
    return "float"

echo myproc(bool)

Error: statement not allowed after 'return', 'break', 'raise', 'continue' or proc call with noreturn pragma

using elif works, but is it not unreasonable to require a linked when/else statement ?

v.oddou
  • 6,476
  • 3
  • 32
  • 63

1 Answers1

2

The real question is: What would anyone gain from allowing this code to compile, when all you have to do is to write

when T is bool:
  return "bool"
elif T is float:
  return "float"

Your code does not get shorter, nor can you do things that would not be possible otherwise. So, allowing your code to compile would only place an additional burden on the compiler without any return of investment. My code also makes the intention clearer: Either do one thing or the other, while your code says Maybe do this, and maybe do that.

I don't know the implementation details, but I would assume that it is not trivial for the compiler to prove that T is bool and T is float are disjoint.

Edit: Proof that there is no benefit

Assume our body starts with

when T is bool: return "bool"

Obviously, if T is bool evaluates to true at compile time, an unconditional return statement gets compiled and there may not be statements after it. That is to say, all statements coming after the when block must be swallowed at compile time unless the above condition is false.

I believe there are basically two different statements that may be swallowed at compile time: other when statements and calls to templates or macros (they may return an empty AST node). I already showed that a succeeding when may be replaced by an elif without any loss of expressiveness. Now let's look at a macro or template call:

when T is bool: return "bool"
call(T)

This can easily be fixed by rewriting it as:

when T is bool: return "bool"
else: call(T)

I admit that we have more code here, but I do not see any real gain we would get from leaving out the else:.

If you are still not convinced, I invite you to give example code where you think you would have an actual benefit, so that we can discuss it.

flyx
  • 35,506
  • 7
  • 89
  • 126
  • you lack imagination. also C compilers emit warning (or not) for cases like this with incomplete disjoint ifs; if the static analyzer finds a potential flow or a path with possibly no return reached. the C# compiler does it so perfectly it's an error. and it doesn't impose this idiot restriction. – v.oddou Apr 04 '18 at 08:43
  • 2
    @v.oddou `when` is something different than `if`. If your goal is to just complain that the language does not work exactly as you want it to, this is not the right platform to do that (use the [forum](https://forum.nim-lang.org/)). If your question is whether it's possible: Sure, it is. If your question is why it isn't implemented although it's possible, the most probable answer remains *because there is no benefit*. – flyx Apr 04 '18 at 13:50
  • good comment, but you haven't proven _because there is no benefit_ and in fact, I state the opposite. because some expressions with nested levels of `when` get easier to understand when written as disconnected series. Or when the conditions have nothing in common. example: the Fowler guard clause. e.g. `when sizeof(int) > 4 return` LFLF `when T is bool...` I see a benefit to separate the clauses. – v.oddou Apr 04 '18 at 14:05
  • Oh and yes, all my questions come with a grain of rant, because this language is a catastrophe for my nerves. It's rough and unwelcoming. – v.oddou Apr 04 '18 at 14:07
  • @v.oddou added *proof* fwiw; you may want to add actual code to your question where you think there is benefit. – flyx Apr 04 '18 at 18:36