{"id":19838964,"url":"https://github.com/objectionary/speco","last_synced_at":"2025-05-01T18:31:44.906Z","repository":{"id":65803795,"uuid":"558766137","full_name":"objectionary/speco","owner":"objectionary","description":"Object Specialization for EO Programs","archived":false,"fork":false,"pushed_at":"2024-11-05T20:16:43.000Z","size":279,"stargazers_count":6,"open_issues_count":24,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-05T21:25:34.448Z","etag":null,"topics":["eolang","java","oop","specialization"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/objectionary.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-28T08:46:01.000Z","updated_at":"2024-10-26T20:14:41.000Z","dependencies_parsed_at":"2023-10-21T14:25:36.654Z","dependency_job_id":"5e4d95a6-ad9c-4a43-b4d3-d9bcdf1f6cc8","html_url":"https://github.com/objectionary/speco","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/objectionary%2Fspeco","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/objectionary%2Fspeco/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/objectionary%2Fspeco/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/objectionary%2Fspeco/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/objectionary","download_url":"https://codeload.github.com/objectionary/speco/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224270869,"owners_count":17283869,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eolang","java","oop","specialization"],"created_at":"2024-11-12T12:19:44.632Z","updated_at":"2025-05-01T18:31:44.898Z","avatar_url":"https://github.com/objectionary.png","language":"Java","readme":"\u003cimg alt=\"logo\" src=\"https://www.objectionary.com/cactus.svg\" height=\"100px\" /\u003e\n\n[![EO principles respected here](https://www.elegantobjects.org/badge.svg)](https://www.elegantobjects.org)\n[![DevOps By Rultor.com](https://www.rultor.com/b/objectionary/speco)](https://www.rultor.com/p/objectionary/speco)\n[![We recommend IntelliJ IDEA](https://www.elegantobjects.org/intellij-idea.svg)](https://www.jetbrains.com/idea/)\n\n[![mvn](https://github.com/objectionary/speco/actions/workflows/mvn.yml/badge.svg?branch=master)](https://github.com/objectionary/speco/actions/workflows/mvn.yml)\n[![PDD status](https://www.0pdd.com/svg?name=objectionary/speco)](https://www.0pdd.com/p?name=objectionary/speco)\n[![codecov](https://codecov.io/gh/objectionary/speco/branch/master/graph/badge.svg)](https://codecov.io/gh/objectionary/speco)\n[![Maven Central](https://img.shields.io/maven-central/v/org.eolang/speco.svg)](https://maven-badges.herokuapp.com/maven-central/org.eolang/speco)\n[![Hits-of-Code](https://hitsofcode.com/github/objectionary/speco)](https://hitsofcode.com/view/github/objectionary/speco)\n[![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/objectionary/speco/blob/master/LICENSE.txt)\n\nSpecialization of objects in EO programs.\n\n**Speco** is a tool that is aimed to be launched on the EO program converted to a collection of .xmir files,\nwhich has undergone modifications performed by [AOI](https://github.com/objectionary/aoi) tool.\n\nConsider the following EO program:\n\n```\n[] \u003e cat\n  [] \u003e talk\n    QQ.io.stdout \u003e @\n      \"Meow!\"\n\n[] \u003e dog\n  [] \u003e talk\n    QQ.io.stdout \u003e @\n      \"Woof!\"\n  [] \u003e eat\n    QQ.io.stdout \u003e @\n      \"I am eating\"\n\n[x] \u003e pet1\n  x.talk \u003e @\n\n[x] \u003e pet2\n  seq \u003e @\n    x.talk\n    x.eat\n```\n\nThe following block in the `.xmir` file of this program will be generated after AOI launch:\n\n```\n\u003caoi\u003e\n    \u003cobj fqn=\"pet1.x\"\u003e\n       \u003cinferred\u003e\n          \u003cobj fqn=\"cat\"/\u003e\n          \u003cobj fqn=\"dog\"/\u003e\n       \u003c/inferred\u003e\n    \u003c/obj\u003e\n    \u003cobj fqn=\"pet2.x\"\u003e\n       \u003cinferred\u003e\n          \u003cobj fqn=\"dog\"/\u003e\n       \u003c/inferred\u003e\n    \u003c/obj\u003e\n\u003c/aoi\u003e\n```\n\nAs we can see, object `x` from `pet1` is only used with its `talk` attribute, therefore it can either be\nan instance of `cat` or `dog`. Whereas `x` located `pet2` is used with both `talk` and `eat`, which\nlets us determine that `x` can only be an instance of `dog`.\n\nRight now object `pet1` has only one implementation, which looks like below in xmir format.\nIt does not give any hints on what object `x` may be in this context.\n\n```\n\u003co abstract=\"\" line=\"20\" name=\"pet1\" pos=\"0\"\u003e\n   \u003co line=\"20\" name=\"x\" pos=\"1\"/\u003e\n   \u003co base=\"x\" line=\"21\" pos=\"2\"/\u003e\n   \u003co base=\".talk\" line=\"21\" name=\"@\" pos=\"3\"/\u003e\n\u003c/o\u003e\n```\n\n**Speco** makes it obvious what `x` is in the provided context. For example, it will turn object `pet1`\ninto these two declarations of objects `pet1_spec_x_cat` and `pet1_spec_x_dog`, which are specific\nfor `cat` and `dog` correspondingly.\n\n```\n\u003co abstract=\"\" line=\"20\" name=\"pet1_spec_x_cat\" pos=\"0\" spec=\"pet1\"\u003e\n   \u003co line=\"20\" name=\"x\" pos=\"1\"/\u003e\n   \u003co base=\"x\" line=\"21\" pos=\"2\"/\u003e\n   \u003co base=\".talk\" line=\"21\" name=\"@\" pos=\"3\"/\u003e\n\u003c/o\u003e\n```\n\n```\n\u003co abstract=\"\" line=\"20\" name=\"pet1_spec_x_dog\" pos=\"0\" spec=\"pet1\"\u003e\n   \u003co line=\"20\" name=\"x\" pos=\"1\"/\u003e\n   \u003co base=\"x\" line=\"21\" pos=\"2\"/\u003e\n   \u003co base=\".talk\" line=\"21\" name=\"@\" pos=\"3\"/\u003e\n\u003c/o\u003e\n```\n\nIt will generate a collection of modified `.xmir` files as an output.\n\n## Usage\n\nBuild the app locally:\n```bash\n$ make build\n```\n\nand run:\n```bash\n$ java -jar speco.jar --help\n```\n\nTo run a transformation:\n```bash\n$ java -jar speco.jar --source=\u003cinput\u003e --target=\u003coutput\u003e\n```\n\nor use make command:\n```bash\n$ make trans\n```\n\n## How it works\n\nThe tool works according to an algorithm consisting of 7 transformation rules.\n\nRule 1:\n* Create a `\u003cspeco/\u003e` node consisting of specialized `\u003cversions/\u003e` nodes for all objects inferred by AOI;\n* Each node has attributes:\n  * `@name` -- name of the polymorphic object,\n  * `@var` -- name of the polymorphic attribute of this object,\n  * `@spec` -- name of the object that specializes this attribute;\n* Each node consists of a single object copied from the `\u003cobjects/\u003e` node by name `@name`, but also changed attributes:\n  * `@name` replaced by `@name_spec_@var_@spec`\n  * `@spec` equal `version@spec`\n* Copy all specialized objects (content of the `\u003cversion/\u003e` node) to the `\u003cobjects/\u003e` node.\n\nRule 2:\n* For all applications: if there is a polymorphic base object and a specialized version is uniquely determined, then a replacement to determined version occurs.\n\nRule 3:\n* For each object, for each of its specialized/polymorphic versions, create a `with-*` attribute that would returns a new object for the current version. The current state of the object should be deeply copied into the new object.\n\nRule 4:\n* Search for all fence attributes, that reference to the `memory` wrapper object;\n* Create copies of these attributes, modifying them so that tuple with the object it returned before and the \"parent\" object is returned.\n\nRule 5:\n* Replace accessing the \"parent\" object with creating an intermediate tuple object and getting its first element.\n\nRule 6:\n* Replace calls of the \"parent\" object (all except the first one) with calls of the second elements of intermediate tuples in the order in the program. Later this should be replaced by using EOG.\n\nRule 7:\n* Modify the `*-as-tuple` attribute so that it returns a new object instead of changing itself by using the `with-*` attribute.\n\n## How to Contribute\n\nFork repository, make changes, send us a pull request.\nWe will review your changes and apply them to the `master` branch shortly,\nprovided they don't violate our quality standards. To avoid frustration,\nbefore sending us your pull request please run full Maven build:\n\n```bash\n$ mvn clean install -Pqulice\n```\n\nYou will need Maven 3.3+ and Java 8+.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobjectionary%2Fspeco","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fobjectionary%2Fspeco","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobjectionary%2Fspeco/lists"}