Open KimBruce opened 7 years ago
This is very strange. list is definitely in prelude.methods
, when prelude is standardGrace:
import "mirrors" as m
def pm = prelude.methods
def methodList = list(m.reflect(pm).methodNames).sorted
print (methodList.asString.replace ", " with "\n")
This prints a long list of method names, including list
and list(_)
.
If you move the same program into the dialect minitest, which also inherits from prelude.methods
, where prelude
is standardGrace, it still works (although now the output is longer, since it includes the method defined by minitest).
@KimBruce, you didn't post the URL for your "dialectExample" in the issue. Is it written in another dialect? If it is, then when you inherit prelude.methods
, you are inheriting that dialect's methods
object, which evidently does not contain list(_)
.
You could change the dialect in which you are writing dialectExample, or you could import "standardGrace" explicitly, and inherit from an attribute of that.
DialectExample is one of the sample dialects in the repository. It does use dialect “dialect”. It is exactly those dialects that are causing the problem.
There seems to be a problem with the way that the compiler checks for the existence of methods. Notice that the error message you were seeing
Syntax error: there is no method list(_).
in "listTest" (line 3, column 15-28)
is from the compiler, which can't find a list(_)
method, not from the runtime. If you write outer.list
in your sample program, it will run fine, so the list(_)
method really is there; the compiler just isn't seeing it. (The same is true for List
.)
Everything works fine with a single level of dialect; this problem occurs only when you have a dialect written in another dialect. The gct file generated for the first dialect does not contain methods
as a fresh method, and thus the second dialect, although it inherits from first dialect's methods
, does not know what they are.
This is extremely puzzling. Why does it know about list and List through outer, but can't figure it out on its own. And yes, it only occurs within a dialect defined with dialect "dialect".
The compiler doesn't "know about" list
or List
. If you make an explicit request on outer.wombat
, then it just compiles code that will make the request, and hopes for the best. However, if you write just wombat
, then the compiler has to look around and try and find a definition of wombat
, either on the super chain, or on the outer chain. In these cases, definitions that are missing will cause bogus compilation errors.
There seem to be two problems here.
dialectExample
, even though it inherits prelude.methods
and actually does support all of these methods, does not put them in the list of public methods in `dialectExample.gct. One way to force these methods into the .gct is to redeclare them, for example:
dialect "dialect"
inherit prelude.methods alias myList(_) = list(_)
method list(x) { myList(x) } type List = collections.List
// This example implements most of the requireTypes dialect. // It must be compiled as a dynamic module to be used. ...
Then the _.gct_ file will contain
... public: List checker(1) list(1) myList(1) types: List
and the dialectical program will compile (but see below).
2. The second problem seems to be a phasing problem. Even though recompiling the dialectical program (here _#234.grace_) will force recompilation of the _dialectExample_, dialect, the _dialectExample.gct_ file that gets used to build the symbol table for _#234_ is the **old** one (if it exists).
Here is my work-around for this issue.
Ratter than writing dialect in standardGrace, I wrote it like this:
#pragma ExtendedLineups
dialect "none"
import "standardGrace" as sg
import "errormessages" as errormessages
import "ast" as ast
inherit sg.methods
method methods {
// This should be unnecessary, because it is inherited.
// But the compiler gets confised and does not find it statically.
prelude.clone(self)
}
Thus, it gets the declarations from the standardGrace dialect by inheritance rather than by using it as a dialect.
Similarly, I defined staticTypes like this:
#pragma noTypeChecks
#pragma ExtendedLineups
dialect "none"
import "dialect" as dia
import "ast" as ast
import "util" as util
inherit dia.methods
def TypeError is public = dia.CheckerFailure.refine "TypeError"
I then removed all of the qualifications by prelude
, since names (like List
) are no longer both inherited and available in an outer scope; they are just inherited.
Hi Andrew,
I tried getting this to work for a couple of days, but kept running into complications. One issue is that that “methods” didn’t seem to pick up public defs, causing lots of issues. I may try it again later, but for now I’m going back to working on variants.
[Sorry, I didn’t save enough of a record of what I’ve done to provide you with any meaningful feedback. I’ll try to get back to it later, but for now just decided to scrap it to move forward.]
Have a good vacation and let’s not worry about this until after you return.
Kim
On Mar 15, 2017, at 10:22 PM, Andrew Black notifications@github.com wrote:
Here is my work-around for this issue.
Ratter than writing dialect in standardGrace, I wrote it like this:
pragma ExtendedLineups
dialect "none" import "standardGrace" as sg import "errormessages" as errormessages import "ast" as ast
inherit sg.methods
method methods { // This should be unnecessary, because it is inherited. // But the compiler gets confised and does not find it statically. prelude.clone(self) } Thus, it gets the standardGrace dialect by inheritance rather than by using it as a dialect.
Similarly, I defined staticTypes like this:
pragma noTypeChecks
pragma ExtendedLineups
dialect "none" import "dialect" as dia import "ast" as ast import "util" as util
inherit dia.methods
def TypeError is public = dia.CheckerFailure.refine "TypeError" I then removed all of the qualifications by prelude, since names (like List) are no longer both inherited and available in an outer scope; they are just inherited.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/gracelang/minigrace/issues/234#issuecomment-286960964, or mute the thread https://github.com/notifications/unsubscribe-auth/ABuh-nTuLlF8NKD6Yq8xSdKDHNPCXwQgks5rmMcDgaJpZM4MS6fK.
One issue is that that “methods” didn’t seem to pick up public defs, causing lots of issues.
Yes, I saw that too. That should be another issue, I think. That's why TypeError
is defined in terms of dia.CheckerFailure
rather than plain CheckerFailure
.
If dialect "dialect" is used to build a new method, e.g., "myDialect", then list operations are not available in programs using that dialect. E.g., in the repository under sample/dialects is a simple dialect "dialectExample" that is written using dialect "dialect". The following program crashes:
with the message:
but runs fine if you erase the first line. The dialect "dialectExample" includes the line
which is supposed to make the prelude methods available. Does prelude.methods not include the collection classes?