objectionary / eo

EOLANG, an Experimental Pure Object-Oriented Programming Language Based on 𝜑-calculus
https://www.eolang.org
MIT License
1.01k stars 127 forks source link

`∆` should not be an attribute #2845

Closed maxonfjvipon closed 7 months ago

maxonfjvipon commented 9 months ago

Delta binding in phi calculus is a special binding, where is not so much an attribute as an special container for data (sequence of bytes). It would be good to have such implementation in our eo-runtime. Current implementation where is the same attribute as any other - is a bit confusing.

maxonfjvipon commented 9 months ago

When we set data to the bytes, it looks like this:

Phi ret = Phi.Φ.attr("org").get().attr("eolang").get().attr("bytes").get();
ret = new PhWith(ret, 0, new Data.Value<>(new byte[] {(byte) 0x01, (byte) 0x02, ...}))

Here we set object Data.Value to the attribute of EObytes.

If we remove attribute from EObytes I would say it should look like this:

Phi ret = Phi.Φ.attr("org").get().attr("eolang").get().attr("bytes").get();
ret = new Data.Value(ret, new byte[] {(byte) 0x01, (byte) 0x02, ...});

Current implementation of Data.Value is almost perfect:

final class Value<T> extends PhDefault implements Data<T> {
    private final T val;
    public Value(final T value) {
        super(Phi.Φ);
        this.val = value;
        this.vertex = PhDefault.VTX.best(value);
    }
    // other methods
}

In my vision it would look something like:

final class Value implements Data, Phi {
    private final Phi origin;
    private final byte[] bytes;
    public Value(final Phi phi, final byte[] bts) {
        this.origin = phi;
        this.bytes = bts;
    }
    public Attr attr(final String name) {
        return this.origin.attr(name);
    }
    // Other Phi methods would use methods of this.origin
    public byte[] take() {
        return this.bytes;
    }
}

And the last step - dataization. Logic in Dataized#take method in my vision would look like this:

public byte[] take() {
    Phi src = this.phi;
    while (!src instanceof Data) {
        if (src instanceof Atom) {
            src = src.lambda();
        } else {
            src = src.attr("φ").get();
        }
    }
    return src.take();
}

@yegor256 WDYT?

maxonfjvipon commented 9 months ago

@yegor256 WDYT?

yegor256 commented 9 months ago

@maxonfjvipon indeed, good idea, let's do it!

maxonfjvipon commented 9 months ago

There's a problem occurred.

  1. I made interface Phi extended Data. So there's one more method byte[] take(); for every Phi object
  2. Then we create a decorator for phi with data:
    public class PhData implements Phi {
    private final Phi origin;
    private final byte[] data;
    public PhData(final Phi phi, final byte[] bytes) {
        this.origin = phi;
        this.data = bytes;
    }
    public byte[] take() {
        return this.data;
    }
    public Phi copy() {
        return new PhData(this.origin.copy(), this.data);
    }
    public Attr attr(final int pos) {
        return this.origin.attr(pos);
    }
    public Attr attr(final String name) {
        return this.origin.attr(name);
    }
    public String locator() {
        return this.origin.locator();
    }
    public String forma() {
        return this.origin.forma();
    }
    public String toString() {
        // tbd
    }
    public String φTerm() {
        return this.origin.φTerm();
    }
    }
  3. It's used like this:
    Phi int = Phi.Φ.attr("org").get().attr("eolang").get().attr("int").get();
    Phi bytes = Phi.Φ.attr("org").get().attr("eolang").get().attr("bytes").get().copy();
    int.attr(0).put(new PhData(bytes, new byte[] {(byte) 0x01, ...}))

Looks ok, until we try to take as-bytes attribute from PhData and dataize it. For example:

Phi bytes = new PhBytes(new EObytes(Phi.Φ), new byte[] {(byte) 0x01})
new Dataize(bytes.attr("as-bytes").get()).take() 

What's going on here: dataize bytes.as-bytes -> dataize bytes.as-bytes.φ -> dataize bytes.as-bytes.ρ

So here we take as-bytes, which isEObytes$EOas_bytes object, then we take ρ from it, which is EObytes object, not PhData decorator.

As result - we get error, because EObytes throws exception in take() method. Maybe decorator is not a good option for injecting data.

0pdd commented 7 months ago

@maxonfjvipon the puzzle #2989 is still not solved.