Rekursiver Aufruf von Attributen Y.jav #36

Open
opened 2018-11-01 07:56:34 +00:00 by pl · 3 comments
Owner

Im folgenden Programm wird das Attribut y im Konstruktor rekursiv aufgerufen.
Dies entspricht einen rekurisiven Aufruf bei der Initialisierung, was in Java zwar explizt verboten ist, aber nur durch das Frontend als Fehler abgefagen wird.
Untenstehendes Prgramm ist allerdings korrekt.

Dies wird derzeit nicht richtig in Bytecode übersetzt.

import java.util.function.*;

class Y<T,R> {
Function<Function<Function<T, R>, Function<T,R>>,Function<T,R>> y;

Y() {
y =  f -> t -> f.apply(y.apply(f)).apply(t);
}

public static void main(String args[]) {
Y<Integer,Integer> yObj = new Y<Integer,Integer>();
Function<Integer, Integer> factorial
    = yObj.y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
System.out.println(factorial.apply(3));
}

}

Im folgenden Programm wird das Attribut y im Konstruktor rekursiv aufgerufen. Dies entspricht einen rekurisiven Aufruf bei der Initialisierung, was in Java zwar explizt verboten ist, aber nur durch das Frontend als Fehler abgefagen wird. Untenstehendes Prgramm ist allerdings korrekt. Dies wird derzeit nicht richtig in Bytecode übersetzt. import java.util.function.*; class Y<T,R> { Function<Function<Function<T, R>, Function<T,R>>,Function<T,R>> y; Y() { y = f -> t -> f.apply(y.apply(f)).apply(t); } public static void main(String args[]) { Y<Integer,Integer> yObj = new Y<Integer,Integer>(); Function<Integer, Integer> factorial = yObj.y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); }); System.out.println(factorial.apply(3)); } }
Author
Owner

branch: bytecode2
commit: 5ddc9201f7

Y.jav und Testfile geaddet.

Mit diesem commit müsste der Typinferenz-Algorithmus die richtigen Ergebnisse ausgeben

class Y<te extends mm,
fg,
fq,
ds extends fg,
//ds extends vc,
mm extends fq
//vc extends fg
> {
Function<Function<Function<? super te, ? extends fg>,
Function<fq,ds>>,
Function<mm,ds/vc/>> y;

Y() {
y =  f -> t -> f.apply(y.apply(f)).apply(t);
}

}

Wenn man die Trasitivität anwendet bekommt man

te extends mm,
ds extends fg,
ds extends vc,
mm extends fq
vc extends fg

nun muss man ds und vc gleichsetzen, da Mehrfachvererbung nicht möglich ist.

branch: bytecode2 commit: 5ddc9201f7296ff28ca0c1c6b2d790082a122682 Y.jav und Testfile geaddet. Mit diesem commit müsste der Typinferenz-Algorithmus die richtigen Ergebnisse ausgeben class Y<te extends mm, fg, fq, ds extends fg, //ds extends vc, mm extends fq //vc extends fg > { Function<Function<Function<? super te, ? extends fg>, Function<fq,ds>>, Function<mm,ds/*vc*/>> y; Y() { y = f -> t -> f.apply(y.apply(f)).apply(t); } } Wenn man die Trasitivität anwendet bekommt man te extends mm, ds extends fg, ds extends vc, mm extends fq vc extends fg nun muss man ds und vc gleichsetzen, da Mehrfachvererbung nicht möglich ist.
Author
Owner

branch: bytecode2
commit: 37f8f2e1e0

de.dhbwstuttgart.exceptions.TypeinferenceException: Unresolved constraints: (Y<java.lang.Integer,java.lang.Integer,java.lang.Integer,java.lang.Integer,java.lang.Integer> <. Y, )
at de.dhbwstuttgart.typeinference.unify.TypeUnifyTask.compute(TypeUnifyTask.java:261)
at de.dhbwstuttgart.typeinference.unify.TypeUnifyTask.compute(TypeUnifyTask.java:1)
at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:94)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

branch: bytecode2 commit: 37f8f2e1e09736c9e018d062c8efaa09a1c69953 de.dhbwstuttgart.exceptions.TypeinferenceException: Unresolved constraints: [[(Y<java.lang.Integer,java.lang.Integer,java.lang.Integer,java.lang.Integer,java.lang.Integer> <. Y, )]] at de.dhbwstuttgart.typeinference.unify.TypeUnifyTask.compute(TypeUnifyTask.java:261) at de.dhbwstuttgart.typeinference.unify.TypeUnifyTask.compute(TypeUnifyTask.java:1) at java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:94) at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056) at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Author
Owner

import java.lang.Integer;
class Y {
y;
//factorial;

Y() {
	y =  f -> t -> f.apply(y.apply(f)).apply(t);
	//factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
}

/*
getY() {
return y;
}
*/
}

liefert:

javap Y.class
Compiled from "Y.jav"
class Y<DPK$, DPL$, DPM$, DPN$> {
Fun1$$<Fun1$$<Fun1$<DPL, DPM$>, Fun1$<DPL, DPM$>>, Fun1$<DPL, DPM$>> y;
public Y();
}

dagegen liefert

import java.lang.Integer;

class Y {
y;
//factorial;

Y() {
	y =  f -> t -> f.apply(y.apply(f)).apply(t);
	//factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
}

getY() {
  return y;
}

}

das Ergebnis:

javap Y.class
Compiled from "Y.jav"
class Y<EHE$, EHF$, EHG$, EHH$> {
Fun1$$<Fun1$$<Fun1$<EHE, EHF$>, Fun1$<EHE, EHF$>>, Fun1$<EHE, EHF$>> y;
public Y();
public <EGG$ extends EHE$, EFI$ extends EHF$, EGA$ extends EHE$> Fun1$$<Fun1$$<Fun1$<EGG, EGB$>, Fun1$<EFV, EFI$>>, Fun1$<EGA, EGE$>> getY();
}

RICHTIG WARE:

class Y <EFQ extends EFE, EFE extends EFS, EFS,
EFJ extends EFT, EFT extends EFR, EFR> {

Function<? super Function<? super Function<? super EFQ, ? extends EFR>,
	              ? extends Function<? super EFS, ? extends EFJ>>,
     ? extends Function<? super EFE, ? extends EFT>> y;
Y() {
y =  f -> t -> f.apply(y.apply(f)).apply(t);
}

}

import java.lang.Integer; class Y { y; //factorial; Y() { y = f -> t -> f.apply(y.apply(f)).apply(t); //factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); }); } /* getY() { return y; } */ } liefert: javap Y.class Compiled from "Y.jav" class Y<DPK$, DPL$, DPM$, DPN$> { Fun1$$<Fun1$$<Fun1$$<DPL$, DPM$>, Fun1$$<DPL$, DPM$>>, Fun1$$<DPL$, DPM$>> y; public Y(); } dagegen liefert import java.lang.Integer; class Y { y; //factorial; Y() { y = f -> t -> f.apply(y.apply(f)).apply(t); //factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); }); } getY() { return y; } } das Ergebnis: javap Y.class Compiled from "Y.jav" class Y<EHE$, EHF$, EHG$, EHH$> { Fun1$$<Fun1$$<Fun1$$<EHE$, EHF$>, Fun1$$<EHE$, EHF$>>, Fun1$$<EHE$, EHF$>> y; public Y(); public <EGG$ extends EHE$, EFI$ extends EHF$, EGA$ extends EHE$> Fun1$$<Fun1$$<Fun1$$<EGG$, EGB$>, Fun1$$<EFV$, EFI$>>, Fun1$$<EGA$, EGE$>> getY(); } RICHTIG WARE: class Y <EFQ extends EFE, EFE extends EFS, EFS, EFJ extends EFT, EFT extends EFR, EFR> { Function<? super Function<? super Function<? super EFQ, ? extends EFR>, ? extends Function<? super EFS, ? extends EFJ>>, ? extends Function<? super EFE, ? extends EFT>> y; Y() { y = f -> t -> f.apply(y.apply(f)).apply(t); } }
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: JavaTX/JavaCompilerCore#36
No description provided.