gracelang / minigrace

Self-hosting compiler for the Grace programming language
39 stars 22 forks source link

Return statements inside object constructors behave inconsistently #325

Open IsaacOscar opened 4 years ago

IsaacOscar commented 4 years ago

Consider the following four methods:

method foo1 {
  object { return "Hello" }
  "Goodbye" }

method foo2 {
  object { {return "Hello"}.apply }
  "Goodbye" }

method foo3 {
  object { return "Hello" }}

method foo4 {
  object { {return "Hello"}.apply }}

I would expect all 4 methods to return "Hello" when called, however this is not the case:

print(foo1) // prints "Goodbye"
print(foo2) // prints "hello"
print(foo3) // prints "a foo3"
print(foo4) // crashes with:
// RequestError: error on line 18 of module test: undefined
//  17: print(foo3)
//  18: print(foo4)
// minigrace: program test exited with code 3.
apblack commented 4 years ago

Is there any reason to permit return directly inside an object constructor?

Andrew

On Feb 17, 2020, at 20:08, IsaacOscar notifications@github.com wrote:

 Consider the following four methods:

method foo1 { object { return "Hello" } "Goodbye" }

method foo2 { object { {return "Hello"}.apply } "Goodbye" }

method foo3 { object { return "Hello" }}

method foo4 { object { {return "Hello"}.apply }} I would expect all 4 methods to return "Hello" when called, however this is not the case:

print(foo1) // prints "Goodbye" print(foo2) // prints "hello" print(foo3) // prints "a foo3" print(foo4) // crashes with: // RequestError: error on line 18 of module test: undefined // 17: print(foo3) // 18: print(foo4) // minigrace: program test exited with code 3. — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or unsubscribe.

IsaacOscar commented 4 years ago

Hmm good point, all the examples I can think of involve putting a return inside a block (e.g. if (object_construction_went_bad) then { return fallback_object }) but that's technically not directly within the object constructor.

In the same vain there's no real reason to support returns directly within methods, e.g.

foo
return bar
baz // unreachable

You could just delete the baz and return and get the same effect.

Really, there only use is inside blocks.

apblack commented 4 years ago

If we allow

(object_construction_went_bad) then { return fallback_object }

then it is hard to know (statically) the shape of the object returned from a class. I suppose that we could check that the fallback_object has the same shape as the object under construction ... but this seems a little baroque.

I would be inclined to say that either:

  1. The only exits allowed from an object constructor are executing it to completion, and raising an exception, or
  2. Returning from an object constructor by means of a return statement inside the object constructor's initialization code is permitted, but any method that contains such an object constructor is not fresh.

Either way, a compiler has to detect such a return statement.