Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem Nesting blocks from static method #109

Closed
bmulvihill opened this issue Dec 31, 2017 · 3 comments
Closed

Problem Nesting blocks from static method #109

bmulvihill opened this issue Dec 31, 2017 · 3 comments
Labels
bug.interpreter A bug specifically relating to the interpreter source code bug Generic label for bugs. Every bug should have this tag in addition to the more specific bug tag
Milestone

Comments

@bmulvihill
Copy link
Contributor

bmulvihill commented Dec 31, 2017

The follow code raises an error that seems to stem from a scope issue:

deftype Test
  defstatic hello(&block)
    block()
  end
end

i = 0

Test.hello do
  10.times do
    i += 1
  end
end

Uncaught Exception: No variable or method i for Test:Test

@faultyserver faultyserver added bug Generic label for bugs. Every bug should have this tag in addition to the more specific bug tag bug.interpreter A bug specifically relating to the interpreter source code labels Dec 31, 2017
@faultyserver
Copy link
Member

Very interesting. I don't really have any idea what would be causing this. You mentioned in discord that it works when the method is an instance method rather than a static method, which pretty much rules out my initial thought of doubly-nested blocks just having issues with closures over the root scope.

I'll try to look more into this tomorrow afternoon.

@faultyserver faultyserver added this to the Next milestone Dec 31, 2017
@faultyserver
Copy link
Member

I wonder if this could be an issue with scope vs instance_scope on Types. See this code:

scope =
case {type = current_self, node.static?}
when {TType, true}
type.scope
when {TType, false}
type.instance_scope
when {Value, true}
# Any other kind of value is not allowed to define static methods.
raise "Cannot define static method on #{__typeof(current_self).name}"
else
current_scope
end

Maybe scope doesn't have the same parent as instance_scope, and so it loses lexical context? That shouldn't be an issue though, because block should close over the lexical scope, not the semantic one.

@faultyserver
Copy link
Member

My suspicion that this has something to do with static vs instance scopes has been furthered by the fact that this works when Test is a module instead of a type:

defmodule Test
  def hello(&block)
    block()
  end
end

i = 0

Test.hello do
  10.times do
    i += 1
  end
end

IO.puts(i) #=> 10

Going to properly start looking into this now.

faultyserver added a commit to faultyserver/myst that referenced this issue Jan 27, 2018
…r blocks on static methods.

`Invocation` was incorrectly determining the value of `self` to use when calling a function. Before myst-lang#131, it was only checking if the Call had a receiver, and would use that value if it did. After myst-lang#131, if the Call did _not_ have a receiver, it would then check if the functor was a closure, and use the closed value of `self` if it was.

Now, Invocations _always_ perform both checks, with closures taking higher precedence than Call receivers (though, both will be pushed to the stack if the conditions are met).

Before this commit, I was very confused why static methods weren't working while non-static methods were. I assumed it was an issue with `scope` vs `instance_scope` on Types or something like that, but had no idea.

Now, though, I'm even more confused how _any_ case was working previously, as the Call receiver was _always_ being pushed as the value of `self`. At least with this version of the code, the value of `self` that will be present is more explicit and well-specified. ¯\_(ツ)_/¯
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug.interpreter A bug specifically relating to the interpreter source code bug Generic label for bugs. Every bug should have this tag in addition to the more specific bug tag
Projects
None yet
Development

No branches or pull requests

2 participants