{"id":18047288,"url":"https://github.com/akabe/evilml","last_synced_at":"2025-04-10T05:14:19.350Z","repository":{"id":36338510,"uuid":"40643230","full_name":"akabe/evilml","owner":"akabe","description":"A compiler from ML to C++ template language","archived":false,"fork":false,"pushed_at":"2015-08-27T13:48:59.000Z","size":1650,"stargazers_count":158,"open_issues_count":0,"forks_count":4,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-10T05:14:12.157Z","etag":null,"topics":["cpp","functional-programming","ocaml"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/akabe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-13T06:45:49.000Z","updated_at":"2024-08-25T21:18:52.000Z","dependencies_parsed_at":"2022-09-06T00:40:37.603Z","dependency_job_id":null,"html_url":"https://github.com/akabe/evilml","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akabe%2Fevilml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akabe%2Fevilml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akabe%2Fevilml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akabe%2Fevilml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/akabe","download_url":"https://codeload.github.com/akabe/evilml/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248161277,"owners_count":21057555,"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":["cpp","functional-programming","ocaml"],"created_at":"2024-10-30T19:10:59.840Z","updated_at":"2025-04-10T05:14:19.323Z","avatar_url":"https://github.com/akabe.png","language":"JavaScript","readme":"Evil ML\n=======\n\n[![Build Status](https://travis-ci.org/akabe/evilml.svg)](https://travis-ci.org/akabe/evilml)\n\nEvil ML is a joke compiler from ML to **C++ template language**\n(not ordinary C++ code). Please, don't use this for practical purposes.\n\nC++ template is a **higher-order pure functional** programming language\ntraditionally used for **compile-time** computation, while its syntax is\nverbose and hard to use.\n[ML](https://en.wikipedia.org/wiki/ML_%28programming_language%29),\na higher-order functional programming language, is simple, practical and\neasy to understand, so that we jokingly implemented this compiler. You can\neasily use black magic in C++ template programming. This will give you nightmares.\n\nP.S. `constexpr` (supported C++11 or above) is useful. Why don't you use it?\n\nFeatures\n--------\n\n- [OCaml](http://ocaml.org)-like higher-order pure functional language\n  (Hindley-Milner polymorphism, no value restriction).\n- Type inference is performed. Most types are automatically inferred.\n- Variant types are supported.\n- You can write raw C++ code in `(*! ... *)` in top level.\n- `#use \"foo.ml\"` loads .ml files in top level (double semi-colons `;;`\n  are not needed at the end). The .ml files you can load are found in\n  directory [evilml/include](https://github.com/akabe/evilml/blob/master/include).\n\nDifference from OCaml:\n\n- Strings have type `char list` (type `string` does not exist).\n- Module system and separate compilation are not supported.\n- User-defined operators are not allowed.\n- `type` keyword in top level can only define *variant types*. You cannot\n  declare aliases of types and records.\n- Pattern match is only performed by `match`. Patterns cannot appear in formal\n  arguments and l.h.s. of let bindings.\n- Exhaustivity checking of pattern matching is not implemented. (future work)\n- Identifiers are defined as regular expression `[a-zA-Z_][a-zA-Z0-9_]*`.\n  Primes cannot be used, and names that begin `__ml_` are\n  reserved by this compiler. Identifiers of data constructors begin capital\n  letters.\n- Top-level shadowing of identifiers (variables, types, and constructors) is\n  prohibited.\n\nInstall\n-------\n\n```\n./configure\nmake\nmake install\n```\n\nUsage\n-----\n\nYou can compile `foo.ml` as follows:\n\n```\nevilml foo.ml\n```\n\nDemo: quick sort\n----------------\n\n[examples/quicksort/qsort.ml](examples/quicksort/qsort.ml) implements quick sort\nof a list of 8 elements. You can compile the ML program into C++ template as\n[online demo](http://akabe.github.io/evilml/).\n\n1. Check the check box of \"Generate stand-alone code (embedding evilml.hpp)\"\n2. Push the button \"Compile\"\n3. Copy and paste the generated C++ code into file `qsort.cpp`\n4. Try to compile and run it:\n\n```\n$ g++ qsort.cpp\n$ ./a.out\n1  2  3  4  5  6  7  8\n```\n\nIn order to make sure that sorting is executed in compile time,\nwe suggest to use `g++ -S qsort.cpp` and open `qsort.s`:\n\n```asm\n...\n\tmovl\t$1, 4(%esp)   ; pass 1 to printf\n\tmovl\t$.LC0, (%esp)\n\tcall\tprintf\n\tmovl\t$2, 4(%esp)   ; pass 2 to printf\n\tmovl\t$.LC0, (%esp)\n\tcall\tprintf\n\tmovl\t$3, 4(%esp)   ; pass 3 to printf\n\tmovl\t$.LC0, (%esp)\n\tcall\tprintf\n\tmovl\t$4, 4(%esp)   ; pass 4 to printf\n\tmovl\t$.LC0, (%esp)\n\tcall\tprintf\n\tmovl\t$5, 4(%esp)   ; pass 5 to printf\n\tmovl\t$.LC0, (%esp)\n\tcall\tprintf\n\tmovl\t$6, 4(%esp)   ; pass 6 to printf\n\tmovl\t$.LC0, (%esp)\n\tcall\tprintf\n\tmovl\t$7, 4(%esp)   ; pass 7 to printf\n\tmovl\t$.LC0, (%esp)\n\tcall\tprintf\n\tmovl\t$8, 4(%esp)   ; pass 8 to printf\n\tmovl\t$.LC1, (%esp)\n\tcall\tprintf\n...\n```\n\n(Of course, you can use `std::cout` to print integers in `qsort.cpp`,\n however we make use of `printf` for readable assembly code.)\n\nBugs\n----\n\n- `let rec diverge _ = diverge ()` should be infinite loop, but generated C++\n  code causes compilation error. `let rec diverge n = diverge (n+1)` passes C++\n  compilation. (I don't know the formal definition of reduction rules of C++\n  template expressions.)\n- C++03 template prohibits operation of float-point values, so that this\n  compiler outputs wrong code.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakabe%2Fevilml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fakabe%2Fevilml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakabe%2Fevilml/lists"}