From 1ec058a65b728bc21ddd59aaa8b4e73c11350880 Mon Sep 17 00:00:00 2001
From: Lukas Stadler <lukas.stadler@oracle.com>
Date: Tue, 20 Sep 2016 17:25:15 +0200
Subject: [PATCH] RExpression extends RVector (instead of wrapping an RList)

---
 .../com/oracle/truffle/r/engine/REngine.java  |   5 +-
 .../truffle/r/nodes/builtin/base/AsCall.java  |   9 +-
 .../r/nodes/builtin/base/AsFunction.java      |  21 +-
 .../r/nodes/builtin/base/AsVector.java        |  13 +-
 .../truffle/r/nodes/builtin/base/Combine.java |   7 +-
 .../r/nodes/builtin/base/Expression.java      |  10 +-
 .../r/nodes/builtin/base/Identical.java       |  14 +-
 .../r/nodes/builtin/base/IsTypeFunctions.java |  11 +-
 .../r/nodes/builtin/base/ListBuiltin.java     |   6 +-
 .../truffle/r/nodes/builtin/base/Mapply.java  |  19 +-
 .../truffle/r/nodes/builtin/base/Parse.java   |  11 +-
 .../base/printer/ExpressionPrinter.java       |   6 +-
 .../vector/CachedExtractVectorNode.java       |   7 +-
 .../vector/CachedReplaceVectorNode.java       |   4 -
 .../access/vector/WriteIndexedVectorNode.java |   6 +-
 .../r/nodes/builtin/RList2EnvNode.java        |   5 +-
 .../r/nodes/unary/CastExpressionNode.java     |  10 +-
 .../truffle/r/nodes/unary/CastListNode.java   |   6 -
 .../r/nodes/unary/CastToContainerNode.java    |   6 -
 .../r/nodes/unary/CastToVectorNode.java       |   7 -
 .../truffle/r/nodes/unary/DuplicateNode.java  |   6 -
 .../oracle/truffle/r/runtime/RDeparse.java    |  10 +-
 .../oracle/truffle/r/runtime/RSerialize.java  |   9 +-
 .../com/oracle/truffle/r/runtime/RType.java   |   8 +-
 .../truffle/r/runtime/data/RDataFactory.java  |  12 +-
 .../truffle/r/runtime/data/RExpression.java   | 207 +++---------------
 .../truffle/r/runtime/data/RLanguage.java     |   2 +-
 .../oracle/truffle/r/runtime/data/RList.java  |   4 +-
 .../truffle/r/runtime/data/RListBase.java     |   3 +-
 .../data/RSharingAttributeStorage.java        |   6 +-
 .../truffle/r/runtime/data/RVector.java       |   2 +-
 .../closures/RAbstactVectorToListClosure.java |   7 -
 .../data/model/RAbstractListBaseVector.java   |  58 +++++
 .../data/model/RAbstractListVector.java       |  38 +---
 34 files changed, 207 insertions(+), 348 deletions(-)
 create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractListBaseVector.java

diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
index e7805e21ab..623538e2f4 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
@@ -29,6 +29,7 @@ import java.util.Map;
 import java.util.stream.Collectors;
 
 import com.oracle.truffle.api.CallTarget;
+import com.oracle.truffle.api.CompilerAsserts;
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -283,7 +284,7 @@ final class REngine implements Engine, Engine.Timings {
     public RExpression parse(Map<String, Object> constants, Source source) throws ParseException {
         List<RSyntaxNode> list = parseImpl(constants, source);
         Object[] data = list.stream().map(node -> RASTUtils.createLanguageElement(node)).toArray();
-        return RDataFactory.createExpression(RDataFactory.createList(data));
+        return RDataFactory.createExpression(data);
     }
 
     @Override
@@ -382,6 +383,7 @@ final class REngine implements Engine, Engine.Timings {
 
     @Override
     public Object eval(RExpression expr, MaterializedFrame frame) {
+        CompilerAsserts.neverPartOfCompilation();
         Object result = null;
         for (int i = 0; i < expr.getLength(); i++) {
             result = expr.getDataAt(i);
@@ -395,6 +397,7 @@ final class REngine implements Engine, Engine.Timings {
 
     @Override
     public Object eval(RLanguage expr, MaterializedFrame frame) {
+        CompilerAsserts.neverPartOfCompilation();
         RNode n = (RNode) expr.getRep();
         // TODO perhaps this ought to be being checked earlier
         if (n instanceof ConstantNode) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java
index 8d86ad3188..446875d8fe 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java
@@ -43,6 +43,7 @@ import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RSymbol;
+import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 
 @RBuiltin(name = "as.call", kind = PRIMITIVE, parameterNames = {"x"}, behavior = PURE)
@@ -78,13 +79,15 @@ public abstract class AsCall extends RBuiltinNode {
             RLanguage l = (RLanguage) x.getDataAt(0);
             f = ((ReadVariableNode) RASTUtils.unwrap(l.getRep())).getIdentifier();
         }
-        return Call.makeCallSourceUnavailable(f, makeNamesAndValues(x.getList()));
+        return Call.makeCallSourceUnavailable(f, makeNamesAndValues(x));
     }
 
-    private RArgsValuesAndNames makeNamesAndValues(RList x) {
+    private RArgsValuesAndNames makeNamesAndValues(RAbstractContainer x) {
         int length = x.getLength() - 1;
         Object[] values = new Object[length];
-        System.arraycopy(x.getDataWithoutCopying(), 1, values, 0, length);
+        for (int i = 0; i < length; i++) {
+            values[i] = x.getDataAtAsObject(i + 1);
+        }
         ArgumentsSignature signature;
         if (nullNamesProfile.profile(x.getNames(attrProfiles) == null)) {
             signature = ArgumentsSignature.empty(values.length);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java
index dbef318443..721a233753 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java
@@ -47,6 +47,7 @@ import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RFunction;
@@ -66,6 +67,8 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 @RBuiltin(name = "as.function.default", kind = INTERNAL, parameterNames = {"x", "envir"}, behavior = PURE)
 public abstract class AsFunction extends RBuiltinNode {
 
+    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
+
     @Override
     protected void createCasts(CastBuilder casts) {
         casts.arg("x").mustBe(instanceOf(RAbstractListVector.class).or(instanceOf(RExpression.class)), RError.SHOW_CALLER2, RError.Message.TYPE_EXPECTED, RType.List.getName());
@@ -74,7 +77,7 @@ public abstract class AsFunction extends RBuiltinNode {
 
     @Specialization
     @TruffleBoundary
-    protected RFunction asFunction(RAbstractListVector x, REnvironment envir) {
+    protected RFunction asFunction(RAbstractVector x, REnvironment envir) {
         if (x.getLength() == 0) {
             throw RError.error(this, RError.Message.GENERIC, "argument must have length at least 1");
         }
@@ -85,15 +88,15 @@ public abstract class AsFunction extends RBuiltinNode {
             saveArguments = SaveArgumentsNode.NO_ARGS;
             formals = FormalArguments.NO_ARGS;
         } else {
-            assert x.getNames() != null;
-            RStringVector names = x.getNames();
+            assert x.getNames(attrProfiles) != null;
+            RStringVector names = x.getNames(attrProfiles);
             String[] argumentNames = new String[x.getLength() - 1];
             RNode[] defaultValues = new RNode[x.getLength() - 1];
             AccessArgumentNode[] argAccessNodes = new AccessArgumentNode[x.getLength() - 1];
             RNode[] init = new RNode[x.getLength() - 1];
             for (int i = 0; i < x.getLength() - 1; i++) {
                 final RNode defaultValue;
-                Object arg = x.getDataAt(i);
+                Object arg = x.getDataAtAsObject(i);
                 if (arg == RMissing.instance) {
                     defaultValue = null;
                 } else if (arg == RNull.instance) {
@@ -129,9 +132,9 @@ public abstract class AsFunction extends RBuiltinNode {
         }
 
         RBaseNode body;
-        Object bodyObject = x.getDataAt(x.getLength() - 1);
+        Object bodyObject = x.getDataAtAsObject(x.getLength() - 1);
         if (bodyObject instanceof RLanguage) {
-            body = ((RLanguage) x.getDataAt(x.getLength() - 1)).getRep();
+            body = ((RLanguage) x.getDataAtAsObject(x.getLength() - 1)).getRep();
         } else if (bodyObject instanceof RSymbol) {
             body = ReadVariableNode.create(((RSymbol) bodyObject).getName());
         } else {
@@ -149,10 +152,4 @@ public abstract class AsFunction extends RBuiltinNode {
         RootCallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode);
         return RDataFactory.createFunction(RFunction.NO_NAME, callTarget, null, envir.getFrame());
     }
-
-    @Specialization
-    @TruffleBoundary
-    protected RFunction asFunction(RExpression x, REnvironment envir) {
-        return asFunction(x.getList(), envir);
-    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
index ed845bb4cb..e9c48b7c3c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java
@@ -61,6 +61,7 @@ import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RAttributable;
+import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RLanguage;
@@ -126,7 +127,10 @@ public abstract class AsVector extends RBuiltinNode {
             if (res instanceof RAttributable && hasAttributes.profile(((RAttributable) res).getAttributes() != null)) {
                 // the assertion should hold because of how cast works and it's only used for
                 // vectors (as per as.vector docs)
-                if (res instanceof RAbstractVector) {
+                if (res instanceof RExpression) {
+                    expressionProfile.enter();
+                    return res;
+                } else if (res instanceof RAbstractVector) {
                     vectorProfile.enter();
                     if (listProfile.profile(res instanceof RAbstractListVector)) {
                         // attributes are not dropped for list results
@@ -140,9 +144,6 @@ public abstract class AsVector extends RBuiltinNode {
                 } else if (res instanceof RSymbol) {
                     symbolProfile.enter();
                     return RDataFactory.createSymbol(((RSymbol) res).getName());
-                } else if (res instanceof RExpression) {
-                    expressionProfile.enter();
-                    return res;
                 } else {
                     CompilerDirectives.transferToInterpreter();
                     throw RInternalError.unimplemented("drop attributes for " + res.getClass().getSimpleName());
@@ -199,6 +200,8 @@ public abstract class AsVector extends RBuiltinNode {
 
         protected abstract static class CastPairListNode extends CastNode {
 
+            private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
+
             @Specialization
             @TruffleBoundary
             protected Object castPairlist(RAbstractListVector x) {
@@ -208,7 +211,7 @@ public abstract class AsVector extends RBuiltinNode {
                     return RNull.instance;
                 } else {
                     Object list = RNull.instance;
-                    RStringVector names = x.getNames();
+                    RStringVector names = x.getNames(attrProfiles);
                     for (int i = x.getLength() - 1; i >= 0; i--) {
                         Object name = names == null ? RNull.instance : RDataFactory.createSymbolInterned(names.getDataAt(i));
                         Object data = x.getDataAt(i);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java
index eac4155fc6..90f3be7834 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java
@@ -141,11 +141,7 @@ public abstract class Combine extends RBuiltinNode {
 
         RNode.reportWork(this, size);
 
-        if (cachedPrecedence == EXPRESSION_PRECEDENCE) {
-            return RDataFactory.createExpression((RList) result);
-        } else {
-            return result;
-        }
+        return result;
     }
 
     @ExplodeLoop
@@ -345,6 +341,7 @@ public abstract class Combine extends RBuiltinNode {
             case RAW_PRECEDENCE:
                 return RDataFactory.createRawVector(new byte[size], names);
             case EXPRESSION_PRECEDENCE:
+                return RDataFactory.createExpression(new Object[size], names);
             case LIST_PRECEDENCE:
                 return RDataFactory.createList(new Object[size], names);
             case NO_PRECEDENCE:
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Expression.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Expression.java
index a3a40ea0d9..a0c481ef01 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Expression.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Expression.java
@@ -34,7 +34,6 @@ import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
-import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RPromise;
 
 @RBuiltin(name = "expression", kind = PRIMITIVE, parameterNames = {"..."}, nonEvalArgs = 0, behavior = PURE)
@@ -55,23 +54,20 @@ public abstract class Expression extends RBuiltinNode {
         for (int i = 0; i < argValues.length; i++) {
             data[i] = convert((RPromise) argValues[i]);
         }
-        RList list;
         if (hasNonNull) {
             String[] names = new String[signature.getLength()];
             for (int i = 0; i < names.length; i++) {
                 names[i] = signature.getName(i);
             }
-            list = RDataFactory.createList(data, RDataFactory.createStringVector(names, RDataFactory.COMPLETE_VECTOR));
+            return RDataFactory.createExpression(data, RDataFactory.createStringVector(names, RDataFactory.COMPLETE_VECTOR));
         } else {
-            list = RDataFactory.createList(data);
+            return RDataFactory.createExpression(data);
         }
-        return RDataFactory.createExpression(list);
     }
 
     @Specialization
     protected Object doExpression(RPromise language) {
-        RList list = RDataFactory.createList(new Object[]{convert(language)});
-        return RDataFactory.createExpression(list);
+        return RDataFactory.createExpression(new Object[]{convert(language)});
     }
 
     private Object convert(RPromise promise) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java
index e1a33d3f20..7e88547cd7 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java
@@ -22,7 +22,7 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
-import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
@@ -42,11 +42,10 @@ import com.oracle.truffle.r.runtime.conn.RConnection;
 import com.oracle.truffle.r.runtime.data.RAttributable;
 import com.oracle.truffle.r.runtime.data.RAttributes;
 import com.oracle.truffle.r.runtime.data.RAttributes.RAttribute;
-import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RExternalPtr;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RLanguage;
-import com.oracle.truffle.r.runtime.data.RList;
+import com.oracle.truffle.r.runtime.data.RListBase;
 import com.oracle.truffle.r.runtime.data.RPairList;
 import com.oracle.truffle.r.runtime.data.RS4Object;
 import com.oracle.truffle.r.runtime.data.RSymbol;
@@ -256,7 +255,7 @@ public abstract class Identical extends RBuiltinNode {
     }
 
     @Specialization
-    protected byte doInternalIdenticalGeneric(RList x, RList y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment) {
+    protected byte doInternalIdenticalGeneric(RListBase x, RListBase y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment) {
         if (x.getLength() != y.getLength()) {
             return RRuntime.LOGICAL_FALSE;
         }
@@ -352,11 +351,6 @@ public abstract class Identical extends RBuiltinNode {
         return RRuntime.asLogical(((RConnection) x).getDescriptor() == ((RConnection) y).getDescriptor());
     }
 
-    @Specialization
-    protected byte doInternalIdenticalGeneric(RExpression x, RExpression y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment) {
-        return doInternalIdenticalGeneric(x.getList(), y.getList(), numEq, singleNA, attribAsSet, ignoreBytecode, ignoreEnvironment);
-    }
-
     @SuppressWarnings("unused")
     @Fallback
     protected byte doInternalIdenticalWrongTypes(Object x, Object y, Object numEq, Object singleNA, Object attribAsSet, Object ignoreBytecode, Object ignoreEnvironment) {
@@ -368,7 +362,7 @@ public abstract class Identical extends RBuiltinNode {
     }
 
     protected boolean vectorsLists(RAbstractVector x, RAbstractVector y) {
-        return x instanceof RList && y instanceof RList;
+        return x instanceof RListBase && y instanceof RListBase;
     }
 
     protected boolean argConnections(Object x, Object y) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java
index 87b2f73c14..a4c38c2da7 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java
@@ -49,6 +49,7 @@ import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RList;
+import com.oracle.truffle.r.runtime.data.RListBase;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RPairList;
 import com.oracle.truffle.r.runtime.data.RRaw;
@@ -101,18 +102,18 @@ public class IsTypeFunctions {
             return RRuntime.LOGICAL_FALSE;
         }
 
-        @Specialization(guards = "!isListVector(arg)")
+        @Specialization(guards = {"!isRList(arg)", "!isRExpression(arg)"})
         protected byte isRecursive(RAbstractVector arg) {
             return RRuntime.LOGICAL_FALSE;
         }
 
         @Specialization
-        protected byte isRecursive(RList arg) {
+        protected byte isRecursive(RListBase arg) {
             return RRuntime.LOGICAL_TRUE;
         }
 
         protected boolean isListVector(RAbstractVector arg) {
-            return arg instanceof RList;
+            return arg instanceof RListBase;
         }
 
         @Fallback
@@ -131,14 +132,14 @@ public class IsTypeFunctions {
             return RRuntime.LOGICAL_TRUE;
         }
 
-        @Specialization(guards = "!isRList(arg)")
+        @Specialization(guards = {"!isRList(arg)", "!isRExpression(arg)"})
         protected byte isAtomic(RAbstractVector arg) {
             return RRuntime.LOGICAL_TRUE;
         }
 
         protected static boolean isNonListVector(Object value) {
             return value instanceof Integer || value instanceof Double || value instanceof RComplex || value instanceof String || value instanceof RRaw ||
-                            (value instanceof RAbstractVector && !(value instanceof RList));
+                            (value instanceof RAbstractVector && !(value instanceof RListBase));
         }
 
         protected boolean isFactor(Object value) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ListBuiltin.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ListBuiltin.java
index 6ab93b8aac..5f79770abc 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ListBuiltin.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ListBuiltin.java
@@ -99,7 +99,8 @@ public abstract class ListBuiltin extends RBuiltinNode {
     }
 
     @Specialization(guards = "!args.isEmpty()")
-    protected RList list(RArgsValuesAndNames args, @Cached("create()") ShareObjectNode shareObjectNode) {
+    protected RList list(RArgsValuesAndNames args,
+                    @Cached("create()") ShareObjectNode shareObjectNode) {
         Object[] argArray = args.getArguments();
         for (int i = 0; i < argArray.length; i++) {
             shareObjectNode.execute(argArray[i]);
@@ -118,7 +119,8 @@ public abstract class ListBuiltin extends RBuiltinNode {
     }
 
     @Specialization(guards = {"!isRArgsValuesAndNames(value)", "!isRMissing(value)"})
-    protected RList listSingleElement(Object value, @Cached("create()") ShareObjectNode shareObjectNode) {
+    protected RList listSingleElement(Object value,
+                    @Cached("create()") ShareObjectNode shareObjectNode) {
         shareObjectNode.execute(value);
         if (suppliedSignatureArgNames == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java
index ae415ae792..bc052272d9 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java
@@ -50,6 +50,7 @@ import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
+import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RLogicalVector;
@@ -124,6 +125,8 @@ public abstract class Mapply extends RBuiltinNode {
             }
         }
 
+        private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
+
         public abstract Object[] execute(VirtualFrame frame, RAbstractListVector dots, RFunction function, RAbstractListVector additionalArguments);
 
         private static Object getVecElement(VirtualFrame frame, RAbstractListVector dots, int i, int listIndex, int[] lengths, Subscript indexedLoadNode) {
@@ -213,13 +216,13 @@ public abstract class Mapply extends RBuiltinNode {
             }
             Object[] values = new Object[dotsLength + moreArgsLength];
             String[] names = new String[dotsLength + moreArgsLength];
-            RStringVector dotsNames = dots.getNames();
+            RStringVector dotsNames = dots.getNames(attrProfiles);
             if (dotsNames != null) {
                 for (int listIndex = 0; listIndex < dotsLength; listIndex++) {
                     names[listIndex] = dotsNames.getDataAt(listIndex).isEmpty() ? null : dotsNames.getDataAt(listIndex);
                 }
             }
-            RStringVector moreArgsNames = moreArgs.getNames();
+            RStringVector moreArgsNames = moreArgs.getNames(attrProfiles);
             for (int listIndex = dotsLength; listIndex < dotsLength + moreArgsLength; listIndex++) {
                 values[listIndex] = moreArgs.getDataAt(listIndex - dotsLength);
                 names[listIndex] = moreArgsNames == null ? null : (moreArgsNames.getDataAt(listIndex - dotsLength).isEmpty() ? null : moreArgsNames.getDataAt(listIndex - dotsLength));
@@ -258,11 +261,11 @@ public abstract class Mapply extends RBuiltinNode {
         protected ElementNode[] createElementNodeArray(RAbstractListVector dots, RAbstractListVector moreArgs) {
             int length = dots.getLength() + moreArgs.getLength();
             ElementNode[] elementNodes = new ElementNode[length];
-            RStringVector dotsNames = dots.getNames();
+            RStringVector dotsNames = dots.getNames(attrProfiles);
             for (int i = 0; i < dots.getLength(); i++) {
                 elementNodes[i] = insert(new ElementNode(VECTOR_ELEMENT_PREFIX + (i + 1), dotsNames == null ? null : (dotsNames.getDataAt(i).isEmpty() ? null : dotsNames.getDataAt(i))));
             }
-            RStringVector moreArgsNames = moreArgs.getNames();
+            RStringVector moreArgsNames = moreArgs.getNames(attrProfiles);
             for (int i = dots.getLength(); i < dots.getLength() + moreArgs.getLength(); i++) {
                 elementNodes[i] = insert(new ElementNode(VECTOR_ELEMENT_PREFIX + (i + 1),
                                 moreArgsNames == null ? null : moreArgsNames.getDataAt(i - dots.getLength()).isEmpty() ? null : moreArgsNames.getDataAt(i - dots.getLength())));
@@ -287,14 +290,14 @@ public abstract class Mapply extends RBuiltinNode {
         }
 
         protected boolean sameNames(RAbstractListVector list, RAbstractListVector cachedList) {
-            if (list.getNames() == null && cachedList.getNames() == null) {
+            if (list.getNames(attrProfiles) == null && cachedList.getNames(attrProfiles) == null) {
                 return true;
-            } else if (list.getNames() == null || cachedList.getNames() == null) {
+            } else if (list.getNames(attrProfiles) == null || cachedList.getNames(attrProfiles) == null) {
                 return false;
             } else {
                 for (int i = 0; i < list.getLength(); i++) {
-                    String name = list.getNames().getDataAt(i);
-                    String cachedName = cachedList.getNames().getDataAt(i);
+                    String name = list.getNames(attrProfiles).getDataAt(i);
+                    String cachedName = cachedList.getNames(attrProfiles).getDataAt(i);
 
                     if (name == cachedName) {
                         continue;
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java
index 529f8b30e4..d47ac8295c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java
@@ -58,7 +58,6 @@ import com.oracle.truffle.r.runtime.context.Engine.ParseException;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RLanguage;
-import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RSymbol;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
@@ -134,17 +133,17 @@ public abstract class Parse extends RBuiltinNode {
     private Object doParse(RConnection conn, int n, String[] lines, String prompt, Object srcFile, String encoding) {
         String coalescedLines = coalesce(lines);
         if (coalescedLines.length() == 0 || n == 0) {
-            return RDataFactory.createExpression(RDataFactory.createList());
+            return RDataFactory.createExpression(new Object[0]);
         }
         try {
             Source source = srcFile != RNull.instance ? createSource(srcFile, coalescedLines) : createSource(conn, coalescedLines);
             RExpression exprs = RContext.getEngine().parse(null, source);
             if (n > 0 && n < exprs.getLength()) {
-                RList list = exprs.getList();
-                Object[] listData = list.getDataCopy();
                 Object[] subListData = new Object[n];
-                System.arraycopy(listData, 0, subListData, 0, n);
-                exprs = RDataFactory.createExpression(RDataFactory.createList(subListData));
+                for (int i = 0; i < n; i++) {
+                    subListData[i] = exprs.getDataAt(i);
+                }
+                exprs = RDataFactory.createExpression(subListData);
             }
             // Handle the required R attributes
             if (srcFile instanceof REnvironment) {
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ExpressionPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ExpressionPrinter.java
index 1ba4a67e7a..d8fcdd5d29 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ExpressionPrinter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ExpressionPrinter.java
@@ -29,7 +29,6 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RExpression;
-import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 
 final class ExpressionPrinter extends AbstractValuePrinter<RExpression> {
@@ -50,9 +49,8 @@ final class ExpressionPrinter extends AbstractValuePrinter<RExpression> {
         valPrintCtx.parameters().setSuppressIndexLabels(true);
 
         out.print("expression(");
-        RList exprs = expr.getList();
         RStringVector names = (RStringVector) expr.getAttr(dummyAttrProfiles, RRuntime.NAMES_ATTR_KEY);
-        for (int i = 0; i < exprs.getLength(); i++) {
+        for (int i = 0; i < expr.getLength(); i++) {
             if (i != 0) {
                 out.print(", ");
             }
@@ -60,7 +58,7 @@ final class ExpressionPrinter extends AbstractValuePrinter<RExpression> {
                 out.print(names.getDataAt(i));
                 out.print(" = ");
             }
-            ValuePrinters.INSTANCE.print(exprs.getDataAt(i), valPrintCtx);
+            ValuePrinters.INSTANCE.print(expr.getDataAt(i), valPrintCtx);
         }
         out.print(')');
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java
index 8fc53aa127..2e87926b33 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java
@@ -41,7 +41,6 @@ import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RAttributes;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
-import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RLogical;
@@ -163,8 +162,10 @@ final class CachedExtractVectorNode extends CachedVectorNode {
         int extractedVectorLength = positionsCheckNode.getSelectedPositionsCount(positionProfiles);
         final RVector extractedVector;
         switch (vectorType) {
-            case Language:
             case Expression:
+                extractedVector = RType.Expression.create(extractedVectorLength, false);
+                break;
+            case Language:
             case PairList:
                 extractedVector = RType.List.create(extractedVectorLength, false);
                 break;
@@ -194,7 +195,7 @@ final class CachedExtractVectorNode extends CachedVectorNode {
 
             switch (vectorType) {
                 case Expression:
-                    return new RExpression((RList) extractedVector);
+                    return extractedVector;
                 case Language:
                     return materializeLanguage(extractedVector);
                 default:
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java
index 2d88a57700..ca7282c166 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java
@@ -44,7 +44,6 @@ import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RAttributes;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
-import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RMissing;
@@ -193,9 +192,6 @@ final class CachedReplaceVectorNode extends CachedVectorNode {
                     vector.initAttributes(attrs.copy());
                 }
                 break;
-            case Expression:
-                vector = ((RExpression) castVector).getList();
-                break;
             default:
                 vector = (RAbstractVector) castVector;
                 break;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/WriteIndexedVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/WriteIndexedVectorNode.java
index c485fd53a3..b96380cab8 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/WriteIndexedVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/WriteIndexedVectorNode.java
@@ -50,7 +50,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
-import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractListBaseVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
@@ -469,7 +469,7 @@ abstract class WriteIndexedVectorNode extends Node {
         }
     }
 
-    private static final class WriteListAction extends WriteIndexedScalarNode<RAbstractListVector, RTypedValue> {
+    private static final class WriteListAction extends WriteIndexedScalarNode<RAbstractListBaseVector, RTypedValue> {
 
         private final boolean setListElementAsObject;
         private final boolean isReplace;
@@ -487,7 +487,7 @@ abstract class WriteIndexedVectorNode extends Node {
         }
 
         @Override
-        void apply(RAbstractListVector leftAccess, Object leftStore, int leftIndex, RTypedValue rightAccess, Object rightStore, int rightIndex) {
+        void apply(RAbstractListBaseVector leftAccess, Object leftStore, int leftIndex, RTypedValue rightAccess, Object rightStore, int rightIndex) {
             Object rightValue;
             if (setListElementAsObject) {
                 rightValue = rightAccess;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RList2EnvNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RList2EnvNode.java
index daddbaf9e3..385e36f70e 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RList2EnvNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RList2EnvNode.java
@@ -24,6 +24,7 @@ package com.oracle.truffle.r.nodes.builtin;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
@@ -34,12 +35,14 @@ import com.oracle.truffle.r.runtime.nodes.RBaseNode;
  */
 public final class RList2EnvNode extends RBaseNode {
 
+    private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
+
     @TruffleBoundary
     public REnvironment execute(RAbstractListVector list, REnvironment env) {
         if (list.getLength() == 0) {
             return env;
         }
-        RStringVector names = list.getNames();
+        RStringVector names = list.getNames(attrProfiles);
         if (names == null) {
             throw RError.error(this, RError.Message.LIST_NAMES_SAME_LENGTH);
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java
index 10e7fe8bfe..60f816057c 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java
@@ -94,18 +94,14 @@ public abstract class CastExpressionNode extends CastBaseNode {
         if (obj instanceof RList) {
             RList list = (RList) obj;
             // TODO other attributes
-            return RDataFactory.createExpression(RDataFactory.createList(data, list.getNames(attrProfiles)));
+            return RDataFactory.createExpression(data, list.getNames(attrProfiles));
         } else {
-            return create(data);
+            return RDataFactory.createExpression(data);
         }
     }
 
     private static RExpression create(Object obj) {
-        return create(new Object[]{obj});
-    }
-
-    private static RExpression create(Object[] objArray) {
-        return RDataFactory.createExpression(RDataFactory.createList(objArray));
+        return RDataFactory.createExpression(new Object[]{obj});
     }
 
     public static CastExpressionNode createNonPreserving() {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
index 8a67bbad26..067eaf2114 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java
@@ -32,7 +32,6 @@ import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RAttributes;
 import com.oracle.truffle.r.runtime.data.RAttributes.RAttribute;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
-import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RList;
@@ -86,11 +85,6 @@ public abstract class CastListNode extends CastBaseNode {
         return ret;
     }
 
-    @Specialization
-    protected RList doExpression(RExpression operand) {
-        return operand.getList();
-    }
-
     @Specialization
     protected RList doLanguage(RLanguage operand) {
         RList result = RContext.getRRuntimeASTAccess().asList(operand);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java
index 7bd1fd595c..6446fb5726 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java
@@ -24,7 +24,6 @@ package com.oracle.truffle.r.nodes.unary;
 
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.runtime.RType;
-import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RNull;
@@ -61,11 +60,6 @@ public abstract class CastToContainerNode extends CastBaseNode {
         return vector;
     }
 
-    @Specialization
-    protected RExpression cast(RExpression expression) {
-        return expression;
-    }
-
     @Specialization
     protected RLanguage cast(RLanguage lang) {
         return lang;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java
index cdc3daf50b..f4f299fa5e 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java
@@ -25,9 +25,7 @@ package com.oracle.truffle.r.nodes.unary;
 import com.oracle.truffle.api.dsl.NodeField;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
-import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RFunction;
-import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
@@ -69,11 +67,6 @@ public abstract class CastToVectorNode extends CastNode {
         return vector;
     }
 
-    @Specialization
-    protected RList cast(RExpression expression) {
-        return expression.getList();
-    }
-
     public static CastToVectorNode create() {
         return CastToVectorNodeGen.create(false);
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/DuplicateNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/DuplicateNode.java
index b68f11c03f..9e94fc4d50 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/DuplicateNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/DuplicateNode.java
@@ -25,7 +25,6 @@ package com.oracle.truffle.r.nodes.unary;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.runtime.RInternalError;
-import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RExternalPtr;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RLanguage;
@@ -65,11 +64,6 @@ public abstract class DuplicateNode extends RBaseNode {
         return p.copy();
     }
 
-    @Specialization
-    protected RExpression duplicate(RExpression e) {
-        return e.copy();
-    }
-
     @Specialization
     protected RLanguage duplicate(RLanguage l) {
         return l.copy();
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java
index 5084d3acdc..95e71bd0f2 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java
@@ -26,6 +26,7 @@ import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.source.SourceSection;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RAttributable;
+import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
 import com.oracle.truffle.r.runtime.data.RAttributes;
 import com.oracle.truffle.r.runtime.data.RAttributes.RAttribute;
 import com.oracle.truffle.r.runtime.data.RComplex;
@@ -73,6 +74,9 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxVisitor;
  * handled in {@code RASTDeparse} via the {@link RRuntimeASTAccess} interface.
  */
 public class RDeparse {
+
+    private static final RAttributeProfiles DUMMY_ATTR_PROFILES = RAttributeProfiles.create();
+
     public static final int KEEPINTEGER = 1;
     public static final int QUOTEEXPRESSIONS = 2;
     public static final int SHOWATTRIBUTES = 4;
@@ -590,7 +594,7 @@ public class RDeparse {
                 }
 
                 if (value instanceof RExpression) {
-                    append("expression(").appendListContents(((RExpression) value).getList()).append(')');
+                    append("expression(").appendListContents((RExpression) value).append(')');
                 } else if (value instanceof RAbstractListVector) {
                     RAbstractListVector obj = (RAbstractListVector) value;
                     try (C c = withAttributes(obj)) {
@@ -959,10 +963,10 @@ public class RDeparse {
         /**
          * Handles {@link RList}, (@link RExpression}. Method name same as GnuR.
          */
-        private DeparseVisitor appendListContents(RAbstractListVector v) {
+        private DeparseVisitor appendListContents(RAbstractVector v) {
             int n = v.getLength();
             boolean lbreak = false;
-            Object names = v.getNames();
+            Object names = v.getNames(DUMMY_ATTR_PROFILES);
             RStringVector snames = names == RNull.instance ? null : (RStringVector) names;
             for (int i = 0; i < n; i++) {
                 if (i > 0) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java
index 620f7f224f..9964f1c01d 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java
@@ -70,6 +70,7 @@ import com.oracle.truffle.r.runtime.data.RVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.gnur.SEXPTYPE;
 import com.oracle.truffle.r.runtime.instrument.RPackageSource;
@@ -693,7 +694,7 @@ public class RSerialize {
                         data[i] = elem;
                     }
                     if (type == SEXPTYPE.EXPRSXP) {
-                        result = RDataFactory.createExpression(RDataFactory.createList(data));
+                        result = RDataFactory.createExpression(data);
                     } else {
                         // this could (ultimately) be a list, factor or dataframe
                         result = RDataFactory.createList(data);
@@ -1611,15 +1612,15 @@ public class RSerialize {
 
                         case EXPRSXP:
                         case VECSXP: {
-                            RList list;
+                            RAbstractVector list;
                             if (type == SEXPTYPE.EXPRSXP) {
-                                list = ((RExpression) obj).getList();
+                                list = (RExpression) obj;
                             } else {
                                 list = (RList) obj;
                             }
                             stream.writeInt(list.getLength());
                             for (int i = 0; i < list.getLength(); i++) {
-                                Object listObj = list.getDataAt(i);
+                                Object listObj = list.getDataAtAsObject(i);
                                 writeItem(listObj);
                             }
                             break;
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java
index fc67027116..4d6af76e83 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java
@@ -215,10 +215,16 @@ public enum RType {
                 return RDataFactory.createComplexVector(length, fillNA);
             case Character:
                 return RDataFactory.createStringVector(length, fillNA);
-            case List:
+            case Expression: {
+                Object[] data = new Object[length];
+                Arrays.fill(data, RNull.instance);
+                return RDataFactory.createExpression(data);
+            }
+            case List: {
                 Object[] data = new Object[length];
                 Arrays.fill(data, RNull.instance);
                 return RDataFactory.createList(data);
+            }
             case Raw:
                 return RDataFactory.createRawVector(length);
             default:
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
index f79b2dc62b..d7986b1a56 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java
@@ -380,8 +380,16 @@ public final class RDataFactory {
         return traceDataCreated(new RList(data, newDimensions, names));
     }
 
-    public static RExpression createExpression(RList list) {
-        return traceDataCreated(new RExpression(list));
+    public static RExpression createExpression(Object[] data, int[] newDimensions) {
+        return traceDataCreated(new RExpression(data, newDimensions, null));
+    }
+
+    public static RExpression createExpression(Object[] data, RStringVector names) {
+        return traceDataCreated(new RExpression(data, null, names));
+    }
+
+    public static RExpression createExpression(Object[] data) {
+        return traceDataCreated(new RExpression(data, null, null));
     }
 
     public static RSymbol createSymbol(String name) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java
index d787eefaa1..13c33c089a 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java
@@ -22,19 +22,19 @@
  */
 package com.oracle.truffle.r.runtime.data;
 
-import com.oracle.truffle.r.runtime.RRuntime;
+import java.util.Arrays;
+
 import com.oracle.truffle.r.runtime.RType;
-import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 
-public class RExpression implements RShareable, RAbstractContainer {
+public class RExpression extends RListBase implements RAbstractVector {
 
     private static final RStringVector implicitClassHeader = RDataFactory.createStringVectorFromScalar(RType.Expression.getClazz());
 
-    private final RList data;
+    public String elementNamePrefix;
 
-    public RExpression(RList data) {
-        this.data = data;
+    RExpression(Object[] data, int[] dims, RStringVector names) {
+        super(data, dims, names);
     }
 
     @Override
@@ -42,198 +42,53 @@ public class RExpression implements RShareable, RAbstractContainer {
         return RType.Expression;
     }
 
-    public RList getList() {
-        return data;
-    }
-
-    public Object getDataAt(int index) {
-        return data.getDataAt(index);
-    }
-
-    @Override
-    public RAttributes initAttributes() {
-        return data.initAttributes();
-    }
-
-    @Override
-    public final void initAttributes(RAttributes newAttributes) {
-        data.initAttributes(newAttributes);
-    }
-
-    @Override
-    public final void setAttr(String name, Object value) {
-        data.setAttr(name, value);
-    }
-
-    @Override
-    public Object getAttr(RAttributeProfiles attrProfiles, String name) {
-        return data.getAttr(attrProfiles, name);
-    }
-
-    @Override
-    public RAttributes getAttributes() {
-        return data.getAttributes();
-    }
-
-    @Override
-    public final void resetAllAttributes(boolean nullify) {
-        data.resetAllAttributes(nullify);
-    }
-
-    @Override
-    public boolean isComplete() {
-        return data.isComplete();
-    }
-
-    @Override
-    public int getLength() {
-        return data.getLength();
-    }
-
-    @Override
-    public RAbstractContainer resize(int size) {
-        return data.resize(size);
-    }
-
-    @Override
-    public boolean hasDimensions() {
-        return data.hasDimensions();
-    }
-
-    @Override
-    public int[] getDimensions() {
-        return data.getDimensions();
-    }
-
-    @Override
-    public void setDimensions(int[] newDimensions) {
-        data.setDimensions(newDimensions);
-    }
-
-    @Override
-    public Class<?> getElementClass() {
-        return RExpression.class;
-    }
-
-    @Override
-    public Object getDataAtAsObject(int index) {
-        return data.getDataAtAsObject(index);
-    }
-
     @Override
-    public RStringVector getNames(RAttributeProfiles attrProfiles) {
-        return data.getNames(attrProfiles);
-    }
-
-    @Override
-    public void setNames(RStringVector newNames) {
-        data.setNames(newNames);
-    }
-
-    @Override
-    public RList getDimNames(RAttributeProfiles attrProfiles) {
-        return data.getDimNames();
-    }
-
-    @Override
-    public void setDimNames(RList newDimNames) {
-        data.setDimNames(newDimNames);
-    }
-
-    @Override
-    public Object getRowNames(RAttributeProfiles attrProfiles) {
-        return data.getRowNames();
-    }
-
-    @Override
-    public void setRowNames(RAbstractVector rowNames) {
-        data.setRowNames(rowNames);
-    }
-
-    @Override
-    public final RStringVector getClassHierarchy() {
-        RStringVector v = (RStringVector) data.getAttr(RRuntime.CLASS_ATTR_KEY);
-        if (v == null) {
-            return getImplicitClass();
-        } else {
-            return v;
-        }
-    }
-
-    @Override
-    public RStringVector getImplicitClass() {
-        return implicitClassHeader;
-    }
-
-    @Override
-    public boolean isObject(RAttributeProfiles attrProfiles) {
-        return false;
-    }
-
-    @Override
-    public boolean isTemporary() {
-        return data.isTemporary();
-    }
-
-    @Override
-    public boolean isShared() {
-        return data.isShared();
-    }
-
-    @Override
-    public void incRefCount() {
-        data.incRefCount();
-    }
-
-    @Override
-    public void decRefCount() {
-        data.decRefCount();
-    }
-
-    @Override
-    public boolean isSharedPermanent() {
-        return data.isSharedPermanent();
-    }
-
-    @Override
-    public RShareable makeSharedPermanent() {
-        data.makeSharedPermanent();
+    public RVector materialize() {
         return this;
     }
 
     @Override
-    public RShareable getNonShared() {
-        RList newData = (RList) data.getNonShared();
-        return newData == data ? this : RDataFactory.createExpression(newData);
+    protected RExpression internalCopy() {
+        return new RExpression(Arrays.copyOf(data, data.length), dimensions, null);
     }
 
     @Override
-    public RExpression copy() {
-        return RDataFactory.createExpression((RList) data.copy());
+    protected RVector internalDeepCopy() {
+        // TOOD: only used for nested list updates, but still could be made faster (through a
+        // separate AST node?)
+        RExpression listCopy = new RExpression(Arrays.copyOf(data, data.length), dimensions, null);
+        for (int i = 0; i < listCopy.getLength(); i++) {
+            Object el = listCopy.getDataAt(i);
+            if (el instanceof RVector) {
+                Object elCopy = ((RVector) el).deepCopy();
+                listCopy.updateDataAt(i, elCopy, null);
+            }
+        }
+        return listCopy;
     }
 
     @Override
-    public RShareable materializeToShareable() {
-        return this;
+    public RExpression createEmptySameType(int newLength, boolean newIsComplete) {
+        return RDataFactory.createExpression(new Object[newLength]);
     }
 
     @Override
-    public RAbstractContainer setClassAttr(RStringVector classAttr) {
-        return data.setClassAttr(classAttr);
+    public RExpression copyWithNewDimensions(int[] newDimensions) {
+        return RDataFactory.createExpression(data, newDimensions);
     }
 
     @Override
-    public String toString() {
-        return String.format("RExpression(data=%s)", data);
+    protected RExpression internalCopyResized(int size, boolean fillNA) {
+        return RDataFactory.createExpression(copyResizedData(size, fillNA));
     }
 
     @Override
-    public int getTypedValueInfo() {
-        return data.getTypedValueInfo();
+    public RStringVector getImplicitClass() {
+        return getClassHierarchyHelper(implicitClassHeader);
     }
 
     @Override
-    public void setTypedValueInfo(int value) {
-        data.setTypedValueInfo(value);
+    public void setNA(Object store, int index) {
+        setDataAt(store, index, RNull.instance);
     }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java
index 275b3ad910..9920f6fba2 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java
@@ -46,7 +46,7 @@ import com.oracle.truffle.r.runtime.nodes.RBaseNode;
  *
  */
 @ValueType
-public class RLanguage extends RSharingAttributeStorage implements RAbstractContainer, RAttributable, RShareable {
+public class RLanguage extends RSharingAttributeStorage implements RAbstractContainer, RAttributable {
 
     /*
      * Used for RLanguage construction from separate AST components.
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java
index ab6f6ac84f..d2ca5dd64a 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java
@@ -25,8 +25,9 @@ package com.oracle.truffle.r.runtime.data;
 import java.util.Arrays;
 
 import com.oracle.truffle.r.runtime.RType;
+import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 
-public final class RList extends RListBase {
+public final class RList extends RListBase implements RAbstractListVector {
 
     public static final RStringVector implicitClassHeader = RDataFactory.createStringVectorFromScalar(RType.List.getClazz());
 
@@ -80,5 +81,4 @@ public final class RList extends RListBase {
     public RStringVector getImplicitClass() {
         return getClassHierarchyHelper(implicitClassHeader);
     }
-
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RListBase.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RListBase.java
index 981f73569a..8879815c07 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RListBase.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RListBase.java
@@ -27,6 +27,7 @@ import java.util.Arrays;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.Utils;
+import com.oracle.truffle.r.runtime.data.model.RAbstractListBaseVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.ops.na.NACheck;
@@ -46,7 +47,7 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck;
  * {@code ExtractListElement}, which is a node that can extract an element of a list or abstract
  * vector and put it in the consistent sharing state.
  */
-public abstract class RListBase extends RVector implements RAbstractListVector {
+public abstract class RListBase extends RVector implements RAbstractListBaseVector {
 
     protected final Object[] data;
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RSharingAttributeStorage.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RSharingAttributeStorage.java
index 18920ff210..a685b13e48 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RSharingAttributeStorage.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RSharingAttributeStorage.java
@@ -53,18 +53,18 @@ public abstract class RSharingAttributeStorage extends RAttributeStorage impleme
     }
 
     @Override
-    public boolean isSharedPermanent() {
+    public final boolean isSharedPermanent() {
         return refCount == SHARED_PERMANENT_VAL;
     }
 
     @Override
-    public RSharingAttributeStorage makeSharedPermanent() {
+    public final RSharingAttributeStorage makeSharedPermanent() {
         refCount = SHARED_PERMANENT_VAL;
         return this;
     }
 
     @Override
-    public RTypedValue getNonShared() {
+    public final RTypedValue getNonShared() {
         if (isShared()) {
             RShareable res = copy();
             assert res.isTemporary();
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java
index 0115ab8555..7891a43ee8 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java
@@ -54,7 +54,7 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck;
  * - non-shared => shared
  * </pre>
  */
-public abstract class RVector extends RSharingAttributeStorage implements RShareable, RAbstractVector, RFFIAccess {
+public abstract class RVector extends RSharingAttributeStorage implements RAbstractVector, RFFIAccess {
 
     private static final RStringVector implicitClassHeaderArray = RDataFactory.createStringVector(new String[]{RType.Array.getName()}, true);
     private static final RStringVector implicitClassHeaderMatrix = RDataFactory.createStringVector(new String[]{RType.Matrix.getName()}, true);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RAbstactVectorToListClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RAbstactVectorToListClosure.java
index 1bd456fb5d..5dcf20f16b 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RAbstactVectorToListClosure.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RAbstactVectorToListClosure.java
@@ -22,10 +22,8 @@
  */
 package com.oracle.truffle.r.runtime.data.closures;
 
-import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RList;
-import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
@@ -69,9 +67,4 @@ final class RAbstactVectorToListClosure extends RToVectorClosure implements RAbs
     public RVector createEmptySameType(int newLength, boolean newIsComplete) {
         return RDataFactory.createList(new Object[newLength]);
     }
-
-    @Override
-    public RStringVector getNames() {
-        throw RInternalError.shouldNotReachHere();
-    }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractListBaseVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractListBaseVector.java
new file mode 100644
index 0000000000..0bf27c7035
--- /dev/null
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractListBaseVector.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.runtime.data.model;
+
+import com.oracle.truffle.r.runtime.data.RNull;
+
+public interface RAbstractListBaseVector extends RAbstractVector {
+
+    @Override
+    Object getDataAtAsObject(int index);
+
+    @Override
+    default Object getDataAtAsObject(Object store, int i) {
+        return getDataAtAsObject(i);
+    }
+
+    Object getDataAt(int index);
+
+    @Override
+    default boolean checkCompleteness() {
+        return true;
+    }
+
+    @Override
+    default Class<?> getElementClass() {
+        return Object.class;
+    }
+
+    @SuppressWarnings("unused")
+    default void setDataAt(Object store, int index, Object value) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    default void setNA(Object store, int index) {
+        setDataAt(store, index, RNull.instance);
+    }
+}
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractListVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractListVector.java
index 8a4905a799..681861e7e5 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractListVector.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/model/RAbstractListVector.java
@@ -24,28 +24,8 @@ package com.oracle.truffle.r.runtime.data.model;
 
 import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.data.RList;
-import com.oracle.truffle.r.runtime.data.RNull;
-import com.oracle.truffle.r.runtime.data.RStringVector;
 
-public interface RAbstractListVector extends RAbstractVector {
-
-    @Override
-    Object getDataAtAsObject(int index);
-
-    @Override
-    default Object getDataAtAsObject(Object store, int i) {
-        return getDataAtAsObject(i);
-    }
-
-    Object getDataAt(int index);
-
-    @Override
-    RList materialize();
-
-    @Override
-    default boolean checkCompleteness() {
-        return true;
-    }
+public interface RAbstractListVector extends RAbstractListBaseVector {
 
     @Override
     default RType getRType() {
@@ -53,19 +33,5 @@ public interface RAbstractListVector extends RAbstractVector {
     }
 
     @Override
-    default Class<?> getElementClass() {
-        return Object.class;
-    }
-
-    @SuppressWarnings("unused")
-    default void setDataAt(Object store, int index, Object value) {
-        throw new UnsupportedOperationException();
-    }
-
-    RStringVector getNames();
-
-    @Override
-    default void setNA(Object store, int index) {
-        setDataAt(store, index, RNull.instance);
-    }
+    RList materialize();
 }
-- 
GitLab