Class name too long error
zonyitoo opened this issue · 20 comments
Once the lines of code hits 1000+, the compiler will generate inner classes which makes javac
generates the file name of .class
too long.
Can be possibly solved with: http://en.wikipedia.org/wiki/Lambda_lifting
Inner classes are generated because of multiple argument functions (one argument one inner class as per the formalization), I don't think lambda lifting can help much.
there would the same number of inner classes, but their names would be shorter after lifting, no? may not work with applyopt though
@tomtau I don't think lambda lifting will solve this problem.
In practice, I saw dozens of Let
s nested into other Let
s, and also some data
s nested in Let
s, which should be an error in generating module. Because no one will write so much nested let
s in one let
. And I am sure that I haven't write any data
s nested in let
s.
@bixuanzju Also, if inner classes will be generated because of multiple argument functions, then why it generates a inner class in level 10+?
For example:
./F2j_parser$.java:15069: 错误: 写入Fun12500时出错: ./F2j_parser$$1Let181$1Let214$1Let275$1Let519$1Let570$1Let653$1Let704$1Let776$1Let837$1Let952$1Let1119$1Let1148$1Let2667$1Let2938$1Let4231$1Let5025$1Let5106$1Datatype15368$1Let5344$1Let6291$1Let8384$1Let8647$1Let9144$1Fun12312$1Fun12399$1Fun12494$1Fun12500.class (File name too long)
class Fun12500 extends f2j.Closure
^
1 个错误
错误: 找不到或无法加载主类 F2j_parser$
@zhiyuanshi A simple example:
let rec fun1 (a : Int) (b : Int) : Int = a + 1;
let rec fun2 (a : Int) (b: Int): Int = a + 2;
fun1 1 4
would generate
Test$$1Let1$1Fun11$1Fun14.class
Test$$1Let1$1Fun11.class
Test$$1Let1$1Let18$1Fun28$1Fun31.class
Test$$1Let1$1Let18$1Fun28.class
Test$$1Let1$1Let18.class
Test$$1Let1.class
Test$.class
Those long nested Let
classes are generated because we transform all recursive functions to LetRec
instead of Fix
in the front-end. Could you revert that change?
@bixuanzju I don't think that'll solve the problem. Besides, if I revert that change, a more serious bug will arise.
@zhiyuanshi So now Fix
constructor will never be used, right? BTW, in the backend, LetRec
will be translated to Let classes, initially designed for mutually recursive functions. But now, self recursive function would also be wrapped into Let classes. If you insist this is needed in the front-end, I could add a transformation in the partial evaluator, that if a letrec has only one binding, change it to fix.
@bixuanzju I think the fix will work but won't solve the very issue once and for all. In the end, people will write very large programs with letrec
holding a great many of bindings.
This has nothing to do with how many bindings. Nested classes are generated only for multiple argument functions (if you write a function with 10+ arguments, it would of course has 10+ nested classes, we can do nothing about that). However, the problem now is the way backend deals with LetRec
:
- Using
Letrec
for every recursive functions:
let rec fun1 = ... fun1 ...;
let rec fun2 = ... fun2 ...;
generates
class Let1 {
class Fun1 {
...
}
class Let2 {
class Fun2 {
...
}
}
}
Notice Fun2
are embedded inside two Let
classes.
- However,
fun1
andfun2
could useFix
(they only recur on themselves), then
class Fun1 {
...
}
class Fun2 {
...
}
No unnecessary Let
classes.
- If you write
let rec fun1 = ... fun2 ...
and fun2 = ... fun1...;
generates
class Let1 {
Obejct fun1;
Object fun2;
class Fun1 {
...
}
class Fun2 {
...
}
}
As seen, Let
classes are there for mutual recursive functions.
@tomtau Tomas may have some thoughts on this?
@bixuanzju The second one make senses!!
@bixuanzju looks good
@zonyitoo the names that cause you problems are generally dominated by the nested Lets?
@tomtau It seems yes. Actually I have already mentioned that in Slack with you.
I don't know much detail about the backend. If you need my co-operation, please contact me. ;)
f2j: lib/PartialEvaluator.hs:(36,17)-(38,19): Irrefutable pattern failed for pattern Core.Lam _ _ body
@bixuanzju It is hard to give you an example. I just want to compile my parser, and it crash. I don't know where and why this problem happens.