diff --git a/.codacy.yml b/.codacy.yml
index 6225d8753c..0608595481 100644
--- a/.codacy.yml
+++ b/.codacy.yml
@@ -25,4 +25,7 @@
# package name contains capital letter and such names are conventional.
---
exclude_paths:
- - "eo-runtime/src/test/java/org/eolang/SnippetTestCase.java"
+ - "eo-runtime/src/test/java/EOorg/EOeolang/EOtxt/EOsprintfTest.java"
+ - "eo-runtime/src/test/java/EOorg/EOeolang/EOtxt/package-info.java"
+ - "eo-runtime/src/main/java/EOorg/EOeolang/EOtxt/EOsprintf.java"
+ - "eo-runtime/src/main/java/EOorg/EOeolang/EOtxt/package-info.java"
diff --git a/eo-maven-plugin/pom.xml b/eo-maven-plugin/pom.xml
index 7cdb9ddfa9..59df46e3da 100644
--- a/eo-maven-plugin/pom.xml
+++ b/eo-maven-plugin/pom.xml
@@ -306,6 +306,7 @@ SOFTWARE.
rewritten_sources/pom.xmlduplicate_classes/pom.xmlsimple/pom.xml
+ hash_package_layer/pom.xml
diff --git a/eo-parser/src/main/resources/org/eolang/parser/stars-to-tuples.xsl b/eo-parser/src/main/resources/org/eolang/parser/stars-to-tuples.xsl
index 89a7a9c656..633a796b72 100644
--- a/eo-parser/src/main/resources/org/eolang/parser/stars-to-tuples.xsl
+++ b/eo-parser/src/main/resources/org/eolang/parser/stars-to-tuples.xsl
@@ -28,7 +28,7 @@ SOFTWARE.
-
+
diff --git a/eo-parser/src/test/resources/org/eolang/parser/packs/syntax/tuples.yaml b/eo-parser/src/test/resources/org/eolang/parser/packs/syntax/tuples.yaml
index 378e3c6b48..db27bec7e2 100644
--- a/eo-parser/src/test/resources/org/eolang/parser/packs/syntax/tuples.yaml
+++ b/eo-parser/src/test/resources/org/eolang/parser/packs/syntax/tuples.yaml
@@ -43,6 +43,7 @@ tests:
- //o[@base='tuple' and @line=5]/o[@base='tuple']/o[@base='tuple']/o[@base='.empty' and @method]
- //o[@base='arr']/o[@base='tuple' and @line=9 and @pos=5]
- //o[@base='arr']/o[@base='.empty' and @line=9 and @pos=6]
+ - //o[@name='y' and @base='.reduced']/o[@base='tuple' and not(@star)]/following-sibling::o[@base='.empty' and @method]
eo: |
* > xs
* 1 > xl
@@ -53,3 +54,7 @@ eo: |
d.e.f
g.h.i
(arr *).elements
+ list
+ .reduced > y
+ *
+ [x]
diff --git a/eo-runtime/src/main/eo/org/eolang/structs/list.eo b/eo-runtime/src/main/eo/org/eolang/structs/list.eo
new file mode 100644
index 0000000000..e62ccd8b73
--- /dev/null
+++ b/eo-runtime/src/main/eo/org/eolang/structs/list.eo
@@ -0,0 +1,289 @@
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2024 Objectionary.com
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
++architect yegor256@gmail.com
++home https://github.com/objectionary/eo
++package org.eolang.structs
++rt jvm org.eolang:eo-runtime:0.0.0
++rt node eo2js-runtime:0.0.0
++version 0.0.0
+
+# List implements based operations on collections like reducing, mapping, filtering, etc.
+# Decorates and extends `tuple`.
+[origin] > list
+ origin > @
+
+ # Is it empty?
+ 0.eq ^.origin.length > [] > is-empty
+
+ # Create a new list with this element added to the end of it.
+ [x] > with
+ list > @
+ with.
+ ^.origin
+ x
+
+ # Create a new list with an element inserted by the provided index.
+ [index item] > withi
+ concat. > @
+ with.
+ ^.head index
+ item
+ ^.tail
+ ^.origin.length.minus index
+
+ # Reduce with index from "start" using the function "func".
+ # Here "func" must be an abstract object with three free attributes.
+ # The first one for the accumulator, the second one
+ # for the element of the collection and the third one for the index.
+ [start func] > reducedi
+ ^.origin.length > origin-len!
+ if. > @
+ 0.eq origin-len
+ start
+ rec-reduced start 0.as-bytes
+
+ [accum index] > rec-reduced
+ if. > @
+ eq.
+ 1.plus > next-index!
+ index.as-int > idx-as-int
+ ^.origin-len
+ ^.func > accumulated
+ accum
+ ^.^.origin.at idx-as-int
+ idx-as-int
+ ^.rec-reduced
+ accumulated
+ next-index
+
+ # Reduce from "start" using the function "func".
+ # Here "func" must be an abstract object with two free attributes.
+ # The first one for the accumulator, the second one for the element
+ # of the collection.
+ [start func] > reduced
+ ^.reducedi > @
+ start
+ ^.func accum item > [accum item idx] >>
+
+ # Map with index. Here "func" must be an abstract
+ # object with two free attributes. The first
+ # one for the element of the collection, the second one
+ # for the index.
+ [func] > mappedi
+ list > @
+ ^.reducedi
+ *
+ [accum item idx] >>
+ with. > @
+ accum
+ ^.func item idx
+
+ # Map without index. Here "func" must be an abstract
+ # object with one free attribute, for the element
+ # of the collection.
+ [func] > mapped
+ ^.mappedi > @
+ ^.func item > [item idx] >>
+
+ # For each collection element dataize the object
+ # Here "func" must be an abstract object with
+ # two free attributes: the element of the
+ # collection and its index.
+ # The result of `func` must be dataizable.
+ [func] > eachi
+ ^.reducedi > @
+ true
+ [acc item index] >>
+ seq > @
+ *
+ acc
+ ^.func item index
+
+ # For each collection element dataize the object
+ # Here "func" must be an abstract object with
+ # one free attribute, the element of the collection.
+ [func] > each
+ ^.eachi > @
+ ^.func item > [item index] >>
+
+ # Create a new list without the i-th element.
+ [i] > withouti
+ list > @
+ ^.reducedi
+ *
+ [accum item idx] >>
+ if. > @
+ ^.i.eq idx
+ accum
+ accum.with item
+
+ # Create a new list without the `element` which is `.eq` to given one.
+ [element] > without
+ list > @
+ ^.reduced
+ *
+ [accum item] >>
+ if. > @
+ ^.element.eq item
+ accum
+ accum.with item
+
+ # Checks if all elements of the current list are `.eq`
+ # to the all elements of given collection.
+ [other] > eq
+ and. > @
+ eq.
+ ^.origin.length
+ other.length
+ ^.reducedi
+ true
+ [accum item idx] >>
+ and. > @
+ accum
+ eq.
+ item
+ ^.other.at idx
+
+ # Concatenates current list with given one.
+ [passed] > concat
+ reduced. > @
+ list
+ passed
+ ^
+ accum.with item > [accum item]
+
+ # Returns index of the first particular item in list.
+ # If the list has no this item, index-of returns -1
+ [wanted] > index-of
+ ^.reducedi > @
+ -1
+ [accum item index] >>
+ if. > @
+ and.
+ -1.eq accum
+ item.eq ^.wanted
+ index
+ accum
+
+ # Returns index of the last particular item in list.
+ # If the list has no this item, returns -1
+ [wanted] > last-index-of
+ ^.reducedi > @
+ -1
+ [accum item index] >>
+ if. > @
+ item.eq ^.wanted
+ index
+ accum
+
+ # Returns `true` if the list contains `element`.
+ # Otherwise, `false`.
+ [element] > contains
+ not. > @
+ eq.
+ -1
+ ^.index-of element
+
+ # Returns a new list sorted via `.lt` method.
+ # @todo #3251:30min The object does not work. After moving `list` object
+ # to eo-runtime this is the only method which does not work because it's quite
+ # hard to implement properly, especially after big changes in EO semantic.
+ # We need to get it done and write some tests for it.
+ ^ > [] > sorted
+
+ # Filter list with index with the function `func`.
+ # Here `func` must be an abstract
+ # object with two attributes. The first
+ # one for the element, the second one
+ # for the index. The result of dataization
+ # the `func` should be boolean, that is `true` or `false`.
+ [func] > filteredi
+ ^.origin.length > origin-length!
+ list > @
+ rec-filtered 0.as-bytes *
+
+ [idx-as-bytes accum] > rec-filtered
+ ^.^.origin > original
+ if. > @
+ idx-as-bytes.eq ^.origin-length
+ accum
+ ^.rec-filtered
+ as-bytes.
+ 1.plus
+ idx-as-bytes.as-int > index
+ if.
+ ^.func
+ ^.^.origin.at index > item
+ index
+ accum.with item
+ accum
+
+ # Filter list without index with the function `func`.
+ # Here `func` must be an abstract object
+ # with one attribute for the element.
+ # The result of dataization the `func`
+ # should be boolean, that is `true` or `false`.
+ [func] > filtered
+ ^.filteredi > @
+ ^.func item > [item index] >>
+
+ # Get the first `index` elements from the start of the list.
+ [index] > head
+ index > idx!
+ switch > @
+ *
+ *
+ 0.eq idx
+ list *
+ *
+ 0.gt idx
+ ^.tail index.as-int.neg
+ *
+ ^.origin.length.lte idx
+ ^
+ *
+ true
+ list
+ ^.reducedi
+ *
+ [accum item index] >>
+ if. > @
+ index.gte ^.idx
+ accum
+ accum.with item
+
+ # Get the last `index` elements from the end of the list.
+ [index] > tail
+ index > idx!
+ ^.origin.length.minus idx.as-int > start!
+ if. > @
+ 0.gt start
+ ^
+ list
+ ^.reducedi
+ *
+ [accum item idx] >>
+ if. > @
+ idx.gte ^.start
+ accum.with item
+ accum
diff --git a/eo-runtime/src/main/eo/org/eolang/tuple.eo b/eo-runtime/src/main/eo/org/eolang/tuple.eo
index 519b2da26b..e19433db53 100644
--- a/eo-runtime/src/main/eo/org/eolang/tuple.eo
+++ b/eo-runtime/src/main/eo/org/eolang/tuple.eo
@@ -33,8 +33,7 @@
[] > empty
0 > length
- [i] > at
- error "Can't get an object from the empty tuple" > @
+ error "Can't get an object from the empty tuple" > [i] > at
[x] > with
tuple > @
diff --git a/eo-runtime/src/main/eo/org/eolang/txt/sprintf.eo b/eo-runtime/src/main/eo/org/eolang/txt/sprintf.eo
new file mode 100644
index 0000000000..d41f5c4584
--- /dev/null
+++ b/eo-runtime/src/main/eo/org/eolang/txt/sprintf.eo
@@ -0,0 +1,39 @@
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2024 Objectionary.com
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
++architect yegor256@gmail.com
++home https://github.com/objectionary/eo
++package org.eolang.txt
++rt jvm org.eolang:eo-runtime:0.0.0
++rt node eo2js-runtime:0.0.0
++version 0.0.0
+
+# The sprintf object allows you to format and output text depending
+# on the arguments passed to it.
+# When arguments are processed - they're dataized and converted to objects
+# depending on next flags:
+# - %s - converts object to `string`
+# - %d - converts object to `int`
+# - %f - converts object to `float`
+# - %x - converts object to `bytes`
+# - %b - converts object to boolean, `true` or `false`.
+[format args] > sprintf /string
diff --git a/eo-runtime/src/main/java/EOorg/EOeolang/EOio/EOstdin$EOnext_line.java b/eo-runtime/src/main/java/EOorg/EOeolang/EOio/EOstdin$EOnext_line.java
index bd77c68d0d..76039234c1 100644
--- a/eo-runtime/src/main/java/EOorg/EOeolang/EOio/EOstdin$EOnext_line.java
+++ b/eo-runtime/src/main/java/EOorg/EOeolang/EOio/EOstdin$EOnext_line.java
@@ -34,6 +34,7 @@
import org.eolang.PhDefault;
import org.eolang.Phi;
import org.eolang.Versionized;
+import org.eolang.XmirObject;
/**
* Standard Input. Consumes only one line.
@@ -42,6 +43,7 @@
* @checkstyle TypeNameCheck (5 lines)
*/
@Versionized
+@XmirObject(oname = "stdin.next-line")
public final class EOstdin$EOnext_line extends PhDefault implements Atom {
@Override
public Phi lambda() {
diff --git "a/eo-runtime/src/main/java/EOorg/EOeolang/EOio/EOstdin$EO\317\206.java" "b/eo-runtime/src/main/java/EOorg/EOeolang/EOio/EOstdin$EO\317\206.java"
index 881dd66ef5..1ed52c1646 100644
--- "a/eo-runtime/src/main/java/EOorg/EOeolang/EOio/EOstdin$EO\317\206.java"
+++ "b/eo-runtime/src/main/java/EOorg/EOeolang/EOio/EOstdin$EO\317\206.java"
@@ -32,6 +32,7 @@
import org.eolang.PhDefault;
import org.eolang.Phi;
import org.eolang.Versionized;
+import org.eolang.XmirObject;
/**
* Standard Input. Consumes all data.
@@ -40,6 +41,7 @@
* @checkstyle TypeNameCheck (5 lines)
*/
@Versionized
+@XmirObject(oname = "stdin.@")
public final class EOstdin$EOφ extends PhDefault implements Atom {
@Override
public Phi lambda() {
diff --git a/eo-runtime/src/main/java/EOorg/EOeolang/EOtxt/EOsprintf.java b/eo-runtime/src/main/java/EOorg/EOeolang/EOtxt/EOsprintf.java
new file mode 100644
index 0000000000..36672da669
--- /dev/null
+++ b/eo-runtime/src/main/java/EOorg/EOeolang/EOtxt/EOsprintf.java
@@ -0,0 +1,162 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016-2024 Objectionary.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/*
+ * @checkstyle PackageNameCheck (4 lines)
+ */
+package EOorg.EOeolang.EOtxt;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.StringJoiner;
+import org.eolang.AtVoid;
+import org.eolang.Atom;
+import org.eolang.Data;
+import org.eolang.Dataized;
+import org.eolang.ExFailure;
+import org.eolang.Param;
+import org.eolang.PhDefault;
+import org.eolang.Phi;
+import org.eolang.XmirObject;
+
+/**
+ * Sprintf.
+ *
+ * @since 0.39.0
+ * @checkstyle TypeNameCheck (5 lines)
+ */
+@XmirObject(oname = "sprintf")
+public final class EOsprintf extends PhDefault implements Atom {
+ /**
+ * Ctor.
+ */
+ public EOsprintf() {
+ this.add("format", new AtVoid("format"));
+ this.add("args", new AtVoid("args"));
+ }
+
+ @Override
+ public Phi lambda() throws Exception {
+ final String format = new Param(this, "format").strong(String.class);
+ final Phi args = this.take("args");
+ final Phi retriever = args.take("at");
+ final Long length = new Param(args, "length").strong(Long.class);
+ final List