{"id":16762398,"url":"https://github.com/tlack/xxl","last_synced_at":"2025-09-15T02:05:19.575Z","repository":{"id":145866010,"uuid":"49749312","full_name":"tlack/xxl","owner":"tlack","description":"a minimal vector programming language","archived":false,"fork":false,"pushed_at":"2020-10-11T20:01:54.000Z","size":1199,"stargazers_count":181,"open_issues_count":3,"forks_count":11,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-04-02T02:38:27.573Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tlack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2016-01-15T22:50:40.000Z","updated_at":"2025-03-19T12:54:24.000Z","dependencies_parsed_at":null,"dependency_job_id":"ba1720c5-cd36-4487-aadd-8b017c0e5937","html_url":"https://github.com/tlack/xxl","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tlack/xxl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlack%2Fxxl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlack%2Fxxl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlack%2Fxxl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlack%2Fxxl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tlack","download_url":"https://codeload.github.com/tlack/xxl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tlack%2Fxxl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275194018,"owners_count":25421441,"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","status":"online","status_checked_at":"2025-09-15T02:00:09.272Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-10-13T04:44:40.382Z","updated_at":"2025-09-15T02:05:19.545Z","avatar_url":"https://github.com/tlack.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"![XXL logo](https://raw.githubusercontent.com/tlack/xxl/master/doc/logo.png)\n\n# What is XXL?\n\nXXL is a new programming language whose goals are simplicity, power, and speed.\nWe throw out most of conventional programming language thinking in order to\nattain these goals.\n\n## Status\n\nPasses tests. Useful for writing small utilities, for me. \n\nIdeas valid, but development stalled pending rethink of virtual machine. The current\nVM leaks memory during complex operations and is generally too slow. A more modular\ntype system would be nice as well.\n\nTested so far on Linux (64bit x86 \u0026 GCC or Clang), OS X (Clang), Windows\n(Cygwin64), Android under termux, Intel Edison and Raspberry Pi. Should work on iOS as well\nbut untested.\n\n## Examples\n\n### Manipulate variables\n\nIn XXL, we call functions verbs, and they can have only one or two arguments (named `x` and `y`).\n\nYou call a verb like `x func` or `x func y`. \n\nCode reads left to right. There is no order of operations. Semicolons are important. \nComments are `//` to end of line.\n\nAside from the poorly documented built-in verbs, there isn't much to learn in terms of syntax.\n\nWhen you name variables, you specify their names as a special name starting\nwith `'`, and use the `as` or `is` verb. Afterward you refer to them without the\n`'`. \n\n(Note: the `0.` and `1.` below are part of the XXL interactive prompt.)\n\n```\n0. 41,6,2 as 'ages     // create a variable named ages with \"as\"\n(41,6,2)\n1. 'ages is (41,6,2)   // equivalent to the above, reverse order with \"is\"\n(41,6,2)\n2. ages\n(41,6,2)\n3. 'ages is 41,6,2     // WRONG! there is no order of operations - group with ()\n(41,6,2)\n4. ages                \n41                     // oops..\n5. ages; 666           // semicolons separate expressions\n666                    // repl shows you result of last expr\n```\n\nXXL is functional, so you don't use any loops to manipulate values:\n```\n3. ages each {x * 2}\n(82,12,4)\n4. ages each {x str,\" years old\"} join \"\\n\"      // join into separate lines\n\"41 years old\\n6 years old\\n2 years old\\n\"\n```\n(Note: `\\n` is nerd speak for newline or linebreak in the terminal)\n\nTo save time, XXL has the questionable feature of allowing you to omit the `x` part of the\nvery beginning of a function. You'll often see this pattern employed for brevity in the examples \nbelow. Examples:\n\n```\n3. ages each {x * 2}\n(82,12,4)\n4. ages each {* 2}\n(82,12,4)\n5. ages each {x str,\" years old\"} join \"\\n\"\n\"41 years old\\n6 years old\\n2 years old\"\n6. ages each {str,\" years old\"} join \"\\n\"\n\"41 years old\\n6 years old\\n2 years old\"\n```\n\n`each` is a regular function (verb), believe it or not. It happens to understand what to do\ngiven a list (vector) on the left side and a function on the right. In contrast to most languages, \nXXL doesn't really have any syntax that defines looping abilities. It's all just regular XXL functions.\n\n### Quasi-JSON encoder\n\nNot really to spec, but what is? About 6 lines of code, without the tests:\n\n![json encoder screenshot with syntax highlighting](https://raw.githubusercontent.com/tlack/xxl/master/doc/jsonencode.png)\n\nHere's what's going on in this monster. I'll explain the parts, and then the sequence of how it comes together. \n\n```\n// (e)nclose (c)urly(b)races, (s)quare(b)brackets, (q)uotes:\n'ecb is {\"{\",x,\"}\"}; 'esb is {\"[\",x,\"]\"}; 'eq is {\"\\\"\",x,\"\\\"\"}; \n```\nLine 1: Define three functions to enclose values in the typical JSON delimeters. `ecb`/`esb`/`eq` enclose their \nargument in curly braces, square braces, or quotes, respectively. They use the name `x` to refer to their argument. \n\n```\n'jc is {join \",\"}; 'jac is {each y jc};  // join x with commas; apply y to each of x then join with commas\n```\nLine 2: `jc` (join comma) joins the contents of its argument together with a comma in between each item. `jac` does the same\nthing, but after first calling its right argument (`y`) on each item - `jac` here is a mnemonic for \"join and call\". \n\nThe astute might notice that `jc` and `jac` don't refer to`x`, because the first verb inside a function will be invoked \nautomatically with `x` as the left argument. In small functions, `x` is almost always the first term in the function's \ncode, so being able to omit it results in some expressivity. More on this later.\n\n```\n'pair is {encode,\":\",(y encode)};        // key:val pair for dict\n```\nLine 3: `pair` calls another function, `encode` (which we define later), without referring to `x`. It then appends a `:` to the\nstring that is returned from `encode`, and then appends that to the result of calling `encode` with the `y` argument.\nThis is a form of recursion.\n\n```\n'dict is {key as 'k; x val as 'v; [k],v \u003e: pair jc ecb}; // get keys/vals, pair merge, commas, braces\n```\nLine 4: `dict` takes a dictionary as an argument, gets its keys as a list using the built-in `key` verb, and saves them in a \nnew variable called `k`. The values of the dictionary (also a list) are extracted using the built-in `val` verb and\nbecome `v`. \n\nThese two lists then become the left and right arguments for successive calls to `jc` using the \"each pair\" or `\u003e:` verb.\nEach of the key/value pairs will get commas between them. Then, we enclose the whole of the dictionary in curly braces,\nlike `{\"name\":\"Tyler\",\"age\":\"2\"}`.\n\nAll the looping verbs have short names that end in `:`.\n\n```\n'many is {as 'el type case ('char, {el str eq}, 'dict, {el dict}, {el jac encode esb})};\n```\nLine 5: `many` isn't as grody as it looks. Its purpose is to handle multiple-item collections (called vectors in XXL). \nIn our case, we have to worry about two main ones: character vectors (strings) and dictionaries.\n\nFirst, we store the value of `x` as `el` (element). Then we extract the value's type\nusing the `type` verb, and then use the `case` verb to decide how to treat all the different types.\n\n`x case (y0, f0, y0, f0, ..., else0)` will check x against each of the `y` values; if it matches, the corresponding\nfunction `f` will be invoked with `x` as its argument. If none match, `x else0` will be invoked.\n\nIf it's a character vector (a string), we pass `el` through the `str` verb to remove its tag (a feature we'll explain later).\n\nIf it's a dictionary, we call our `dict` function. \n\nIf it's anything else, we recurse by calling `encode` again, and then enclose the result in square braces (think arrays of numbers).\n\n```\n'encode is {ravel[many,str]};            // ravel calls x y[0] for arrays (len \u003e 1), x y[1] for scalars\n```\nLine 6: And finally the star of the show, `encode`. `ravel` is a verb that allows you to take one branch of logic for single-item\nvalues (like the number `3`), or a different branch for values that have many items, like an array or string (vector of char).\nDepending on the type of `x`, `encode` will dispatch either `many` (for multiple values) or `str` (for simple, single values).\n\n### MySQL Slow Query Watcher\n\nHere we use command-line MySQL to get process list, turn into table, find interesting slow queries.\n\nNote that the `0.`, `1.` etc is XXL's prompt in interactive mode. The number you see next to the \nprompt allows you to refer later to that line of input or the result XXL produced for it. Don't type\nthis part, or the comments, at the interactive REPL.\n\n```\n0. 'slowtime is 2;\n// get output, split it by line, then by column, save\n1. \"mysql -e \\\"show full processlist\\\" --batch\" Shell.get split \"\\n\" each {split \"\\t\"} as 'lines; \n// the first line is column headings, massage data for each row, create table with keys:data\n2. lines first each {make '} : (lines behead curtail each {make \"issstiss\"}) as 'procs;\n// Use  except  with an anonymous function to filter rows we don't care about\n3. procs except {@'Time\u003cslowtime | (x@'State=\"\")}\n['Id:194128i, 'User:\"destructoid\", 'Host:\"localhost\", 'db:\"destructoid\", 'Command:'Execute, \n  'Time:3i, 'State:\"Sending data\", 'Info:\"SELECT * from ... \"]\n```\n\nOriginally used as a one-liner to fix a performance issue on a site.\n\n### Simple Web Server (Counter)\n\nHere's an example web server application that acts as a counter. \n\nYou can run this as`./c examples/web-ctr.xxl`. \n\nXXL doesn't include HTTP support explicitly (yet), so this server speaks a\nlittle HTTP. Source code in full:\n\n```\n0 as 'ctr;\n\n'make_http_response is {\n\t[\n\t\t\"HTTP/1.0 200 OK\",\n\t\t\"Content-Type: text/plain\",\n\t\t\"Connection: close\",\n\t\t\"Server: xxl v0.0\"\n\t] show as 'template;\n\ttemplate join \"\\r\\n\",\n\t\"\\r\\n\", \"\\r\\n\",\n\tx,\n\t\"\\r\\n\", \"\\r\\n\"\n\tflat\n};\n\n(8080,\"localhost\") Net.bind {\n\tctr + 1 as '.ctr repr make_http_response\n}\n```\n\n(We didn't show the XXL prompt here, just the code itself.)\n\nThis simple server uses `(socket_options) Net.bind (handler)` to start a\nlistening network connection and setup a callback.\n\nWhen invoked, the callback fetches the value of `ctr` (a global), adds 1 to it,\nresets the global (`as` allows you to assign in other contexts - like globally here with `'.ctr`),\nconvert that number to a string (`repr`), and then create a somewhat-valid HTTP\nresponse with that string.\n\n`make_http_response` basically construct a simple string from your output, flattens the list,\nand returns it to `Net.bind` to send. \n\n## Docs\n\nHere's some useful info, but no real docs yet.\n\n* [Groceries tutorial](\nhttps://github.com/tlack/xxl/blob/master/doc/groceries.xxl) - a short tutorial \nwritten for non-programmers.\n\n* [Mailboxes soliloquy](https://github.com/tlack/xxl/blob/master/doc/sect_mbox.xxl). Mailboxes are \nlike a message queue and allow your program to use multiple threads.\n\n* [Posts](https://github.com/tlack/xxl/blob/master/doc/sect_posts.xxl) are a general concept \nfor sharing data between XXL and the outside world. Work in progress!\n\n* [List of verbs](\nhttps://github.com/tlack/xxl/blob/master/doc/lang.xxl) in XXL, represented as an XXL table\n\n* [Working with files](https://github.com/tlack/xxl/blob/master/doc/sect_files.xxl)\n\n* [Notes about logic](https://github.com/tlack/xxl/blob/master/doc/sect_logic.xxl)\n\n* [Implementation notes](https://github.com/tlack/xxl/blob/master/doc/implementation.md)\n\nSee the various tests for more examples. In particular, you may appreciate\n`test-logic.h`, and `test-semantics.h`.\n\n## Philosophy\n\n- *Terse*. It is much better to express yourself clearly in a few words rather\n  than many. We provide powerful operators that allow you to do more while\n  describing less.\n\n- *Accessible*. XXL avoids niche-y programmer terms like \"map\" and \"reduce\" in\n  favor of common English \n\n- *Minimalistic*, but not spare. Provide tools people commonly need, even if\n  they're a bit duplicative of other, more primitive approaches.\n\n- *Fast*. XXL cares deeply about performance, for the same reason a person should care\n  about the quality of any tool they use for professional work. \n\n- *Tangible*. Abstractions provided by many systems and platforms make it much harder\n  to reason about what your program is doing. XXL just helps you program the computer\n  in the way the computer wants to be programmed. Those with a background in assembly\n  might see some familiar tones in XXL.\n\nThese goals have not yet been attained.\n\n## Motivation\n\nI need a swiss army knife for data manipulation with predictable performance and concise\nsyntax. I want to use some of the more exotic features I've tasted in other languages,\nbut not all of them. In particular, I feel like programming has gotten a little too stack-\nheavy. \n\n## Features\n\n### Minimal, easy to grasp syntax\n\nXXL may seem odd at first glance but it's much simpler than other languages\nwhich suffer from complex grammars, rules, and special cases. You don't have\nto understand APL, K/Q or even functional programming to use XXL.\n\nClean, very easy to understand and parse left-to-right syntax with only three \nspecial forms: comments, strings, and grouping (i.e., `( )`, `[ ]` and `{ }`).\n\nEverything else is either a noun or a verb. Learn the verbs and you know the \nlanguage.\n\nValues and variables are called nouns. The first time you create a noun,\nyou usually refer to it using a tag: `'z is 1`. You can use `as` if you\nwant to build up an expression and save it: `1,2,3+1 as 'numbers`.\n\nIf you didn't use a tag name (like 'numbers) and instead just wrote `numbers`,\nXXL would try to find an existing noun named numbers, and insert the contents\nof that instead, which probably isn't what you want.\n\nVerbs are either postfix (also called unary: having one variable, called `x`):\n```1,2,3 len```\nor infix (binary: two variables, called `x` and `y`)\n```1,2,3 + (4,5,6)```.\n\nVerbs work with the things immediately to the left or left and right. There is\nno grouping or precedence. This is much easier to keep track of mentally\nand allows you to much easily scan code. Use (), [], or {} to group values\nif you must, but many times you can write long expressions with few groupings.\n\nThere is nothing special about `len`, or `+`, or any of the built-in verbs.\nThey are simply verbs that have been created for you already. You can create\nyour own system-level verbs or replace ones that already exist.\n\nYou can create nouns in the middle of expressions and refer to them later, such\nas this in this tedious example:\n```1,2,3+2 as 'num + num```\n\nAgnostic about whitespace. Don't let invisible special characters ruin your day.\n\n### Trees\n\nWe don't yet have a full tree data type yet, but operations on list-of-lists\nare pretty diverse. After all, XXL is written in terms of its own verbs and values.\n\n`x nest [open,close]` creates sublists in x between matching open\nand close tags. Create parsers like an animal.\n\n*Note:* In the examples below, `0.`, `1.`, etc are the XXL command line prompt.\nAbridged output shown on the line below.\n\n```\n0. 1,4,4,0,5,5,6 nest [4,5]\n[1i, [4i, (4,0,5i), 5i], 6i]\n```\n\n`x ravel [funmany, funone]` calls funone if x is scalar, funmany otherwise.\nPair with `self` to recurse. A napkin sketch of a markdown parser:\n\n```\n0. 'body is {behead curtail};\n1. 'mdtxt is \"My *Markdown* parser\";\n2. 'html is ['b:{\"\u003cb\u003e\",x,\"\u003c/b\u003e\"}]; // define some formatting templates\n3. mdtxt nest [\"*\",\"*\"] :: {ravel [{x body html.b},str]} flat\n\"My \u003cb\u003eMarkdown\u003c/b\u003e parser\"\n```\n\nThe contents of the html callbacks, the nest control parameters, are all just\ndata that you can build up or pull in from anywhere. Compare with traditional\ncontrol structures used to manipulate data which exist inside the source code\nonly and are not mutable at runtime.\n\nOr use `deep` and `wide` for more explicit macro-control of\nrecursion. \n\n### Erlang-inspired mailboxes\n\nThread safe for both readers and writers (at some cost to performance of\ncourse). Fast enough to be usable for basic purposes (800 request/reply cycles\na second on a $5 Digital Ocean box). \n\n```\n0. [] Mbox.new as 'myservice;\n1. myservice Mbox.watch {x show}\n2. myservice Mbox.send 55;\n55\n```\n\n`watch` spawns a thread to act on mailbox messages. The `55` seen here is from\nthe `show` statement in the lambda. A `y` variable is available inside the\ncallback to maintain state; it starts as [] and it set to whatever your\nfunction returns.\n\nSee [`doc/sect_mbox.xxl`](https://github.com/tlack/xxl/blob/master/doc/sect_mbox.xxl)\nfor more.\n\n### Files\n\nThe `File` namespace contains file-related stuff. Let's explore:\n\n```\n0. File\n['basename:'1(...), 'cwd:'1(...), 'dirname:'1(...), 'get:'1(...), 'ls:'1(...), 'path:'1(...), 'set:'2(...)]\n```\n\n`[] File.cwd` tells you the current working directory:\n\n```\n1. [] File.cwd\n\"/mnt/tlack/work/xxl\"\n```\nNote: Here we use `[]` as a placeholder because `cwd` doesn't take any arguments.\n\n`fname File.dirname` strips the last component off a name.\n\n```\n2. [] File.cwd File.dirname\n\"/mnt/tlack/work/\"\n```\n\n`pattern File.ls` shows you what's in a folder:\n```\n3. [] File.cwd,\"/*.c\" File.ls\n[\"/mnt/tlack/work/net.c\", \"/mnt/tlack/work/repl.c\", ....]\n```\n\n`data File.set fname` sets the contents of file `fname` to `data`, which must be a string (vector of char).\nIt returns the data so you can continue using it in your expression.\n\n```\n4. \"Hello world!\" File.set \"test.txt\"\n\"Hello world!\"\n```\n\n`fname File.get` reads and returns the contents of `fname` as a char vector.\n```\n5. \"test.txt\" File.get\n\"Hello world!\"\n```\n\n`pathpartslist File.path` converts from lists of filename parts to actual platform-specific paths.\n\n```\n6. [\"mnt\",\"tlack\",\"work\",\"xxl\"] File.path\ninputs@0: [\"mnt\",\"tlack\",\"work\",\"xxl\"] File.path\noutputs@0:\n\"mnt/tlack/work/xxl\"\n```\n\n### Tables\n\nWell, the beginnings of them anyway. \n\n```\n0. \"name,age,job\\nBob,30,Programmer\\nJane,25,CFO\\nTyler,2,Dinosaur Hunter\" as 'data;\n1. data split \"\\n\" each {split \",\"} as 'fields;     // in a fantasy world where csv is never escaped\n2. fields first:(fields behead) as 'emp             // : creates dicts or tables \n[\"name\", \"age\", \"job\"]:[\n[\"Bob\", \"30\", \"Programmer\"],\n[\"Jane\", \"25\", \"CFO\"],\n[\"Tyler\", \"2\", \"Dinosaur Hunter\"]]\n```\n\nThis is similar to the MySQL example above in that we are unpacking data and\nmaking a table out of it.\n\nNotice that the printed representation of the table is similar to what you'd\ntype in to regenerate it.\n\nThe in-memory table works very much like a regular value, and you can join it\nwith more dictionaries to append rows with `,` as you'd expect. \n\n```\n3. emp,[\"name\":\"Steve\",\"age\":\"42\",\"job\":\"Fact Checker\"]\n[\"name\", \"age\", \"job\"]:[\n[\"Bob\", \"30\", \"Programmer\"],\n[\"Jane\", \"25\", \"CFO\"],\n[\"Tyler\", \"2\", \"Dinosaur Hunter\"],\n[\"Steve\", \"42\", \"Fact Checker\"]]\n```\n\nOr join it with a list that has a value for each column:\n\n```\n4. emp,[\"Arca\",\"2\",\"Tiny Dog\"]\n[\"name\", \"age\", \"job\"]:[\n[\"Bob\", \"30\", \"Programmer\"],\n[\"Jane\", \"25\", \"CFO\"],\n[\"Tyler\", \"2\", \"Dinosaur Hunter\"],\n[\"Arca\", \"2\", \"Tiny Dog\"]]\n```\n\nNotice that we did not save the result of expression 3 (where we joined `emp`\nwith a dictionary containing Steve's record) so the change was not saved to\n`emp`.  Like most verbs in XXL, `,` does not modify the x argument, it creates\nand returns a new value. Looks like Steve is going to have to check someone\nelse's facts from here on out. \n\nUse `amend` (or equivalent the short operator `!`) to update `emp` in place.\n`emp![[\"age\"],{::{base 10}}]` would convert the ages to numbers so you can\nruthlessly compute them. In this example, \"age\" has to be put into a list here\nbecause otherwise it would think you want to update three indices - \"a\", \"g\",\nand \"e\". \n\nGet individual rows with `emp@0` or `0,2 from emp`, or rows with `\"age\" from\nemp` or `emp@\"age\"` or, if the key \"age\" was a tag like `'age`, you could use\nsimply `emp.age`. \n\nSearch for matching values using `match` (or `~`) or filter rows with \n`{..} from emp` or `emp except {..}`.\n\nStill no joins, many rough edges, untested performance.\n\n### Other\n\n- Variable names can't contain numbers, so you can build up some pretty clean and\n  short expressions that mirror mathematics. `3u b5` means `3 u b 5`, or \n\t`b(u(3),5)`, assuming u is a single argument (unary) function and b is a two argument (binary) function.\n\tIf you're recoiling in horror right now at losing your precious numerals in variable\n\tnames, consider how often you're just poorly naming a temp variable. \n\n- Variable names can contain `?`, so you can name your predicate functions in a\n\tpleasant manner.\n\n- Values can have \"tags\" associated with them, allowing you to create an\n\tOOP-like concept of structure within data, while all regular operations work\n\tseamlessly as if you were using the underlying data type. Consider the\n\tclassic OOP example of a \"point\", which in XXL would just be a tagged int\n\tvector like `'point#(100,150)`.\n\n- Vector-oriented and convenient manipulation on primitive values. For instance,\n  `1,2,3 * (4,5,6)` is perfectly legal and returns 4,10,18. This is a huge time saver\n\tand eliminates many loops. It's also pretty fast, which somewhat makes up for the\n\tdangerously slow interpreter. \n\n- Diverse integer type options, including 128bit octaword (`1 make 'octa`). At\n\tthis time we don't display the int type when displaying the representation of\n\tthe numeric value. Use the `x type` verb to discovere what size of int you\n\tare working with.\n\n- Fast-enough unboxed binary data files. 25 million int/s to disk per second on $5/mo\n\tDigital Ocean droplet via `1024*1024*50 count Xd.set \"/tmp/50m.xd\"`\n\n- Threading support, kinda. XXL has the notion of threads available internally, but \n  the only way they are usable from inside XXL code is via `mb Mbox.watch {..}`.\n\tThis is because modifications to contexts' data items are not locked or synchronized,\n\tSo chaos will surely ensue if you modify global data from threads. Thus, the mailbox\n\tacts as both a safe communication mechanism for threads, and a way to discourage global\n\tstate mutation. See [`doc/sect_mbox.xxl`](https://github.com/tlack/xxl/blob/master/doc/sect_mbox.xxl)\n\tfor more.\n\n- Built in simple networking. Client-speaks-first protocols are a snap to implement.\n  World's easiest echo server: `[8888,\"\"]Net.bind{\"Echo: \",x}`. Net.bind creates one\n\tthread to service each port/service.\n\n- Vim syntax file in tools/syntax/vim-syntax.vim (which is generated by vim-build.xxl\n  in that same directory).\n\n- No stinkin loops (and no linked lists, either)\n\n- Supports `\\\\` to exit the REPL, as god intended (`quit` and `exit` too)\n\n- BSD license\n\n## Not yet implemented\n\nXXL is still very much a work in progress and is mostly broken. That said, here are the \nmajor features I anticipate finishing soon-ish.\n\n- **Currently has severe memory leaks and performance problems**\n- ~~Floats!~~ We've got floats now - no comparison tolerance yet tho.\n- ~~Dictionary literals (dictionaries do work and exist as a primitive type, just\n\tcan't decide on a literal syntax for them)~~\n\tSettled on and implemented `['a:1,'b:2]` by creating `:` as the make-dict operator\n\tand making `,` smart about dicts.\n- JSON\n- FancyRepl(tm)\n- Dates/times (need to figure out core representation and a way to express them as literals\nin code..)\n- ~~In-memory tables~~ Few operations yet, and bugs remain, but the notion of tables has\n  slowly seeped in. See tests.\n- ~~Non-pointer tags implementation to avoid logic to enc/decode to binary for disk and IPC~ \nTemporarily replaced tag representation with 128bit pointer string. Fast to compare,\nalmost as fast as possible to create (memcpy), zero overhead on IPC ingest/excrete, \nnot terribly large on today's memory sizes.\n- I/O (~~files~~, ~~sockets~~, mmap)\n- Logged updates (I like [Kdb's approach to this](http://code.kx.com/wiki/Cookbook/Logging))\n- ~~Mailboxes/processes (implemented as a writer-blocks general list)~~ Available in \"Mbox\"\n  class. \n- Streams, laziness (perhaps based on mailboxes? studying other systems now)\n- Tail call optimization in functions using the `self` keyword \n\t[as per Kuc's approach](https://github.com/zholos/kuc/blob/1cace4608ba0398de6054349abea9b97100386cd/func.c#L726)\n- Sorted vectors\n- Grouped/index types\n- Well-supported Apter trees ([see also APL's approach](https://dfns.dyalog.com/n_Trees.htm)).\n\n## Well known bugs\n\nWork in progress on these:\n\n- Interpreter speed and memory leaks. These are at times severe.\n\n- The interpreter still recurses too much in some scenarios, even though its\n\tmain loop is self-managed on the heap. C call stack depth gets too deep. I\n\thave a simple plan to resolve this, but it requires a (much needed) rewrite\n\tto `applyexpr()`, which can be thought of as the interpreter loop.\n\n- The join verb (`,`) is still finnicky about joining like-types of data with\n\tgeneral lists. In particular, I often find myself a bit puzzled by results\n\tlike `['a,2],3` - should this be a two-item list with two items in the first\n\tsublist, or a three element list? Before you answer, consider `['a,2] as\n\t'q;q,3`. When in doubt, build parts separately and combine.\n\n- You can't name a variable you define `x` or `y`, since the interpreter treats\n\tthose specially. There's no real reason for this other than the idea that\n\tit's faster to resolve this short literal symbol manually using what we know\n\tabout the calling frame, rather than setting it as a regular variable in the\n\tdictionary that is used by the context to resolve symbols. The setting part\n\tworks, it's just resolving `x` afterward doesn't consider the dictionary.\n\n## Open questions\n\n- Date and time stamps: Nanosecond precision from uint64 sufficient? What about literal\n  representation? Can we use `1997.12.31.09.31.45.333` or something non-pollutey like that?\n\tNeed to patch up apply() to allow you to index `'day` and similar.\n\n## Maybe later\n\n- JS/Emscripten (both in terms of Node.js interop and use of XXL in the browser)\n- LLVM IR \n- GUI\n\n## Probably not\n\n- Unicode\n\n## Installation\n\nPretty rough right now. You'll need a C compiler and a minimally POSIX\nenvironment but that's about it. \n\n### Customize your build\n\nXXL is meant to be tailored to the device you're using it on. You can remove\nYou can customize the features that XXL includes out of the box.\n\nWe use a build script called `./c` instead of a Makefile. It tries to make some\nguesses about how your system is configured and what options are best to use.\nWe use a shell script to keep it simple (without having to resort to Autoconf).\nWhen in doubt, you can make your own decisions by editing the `c` source. It's\nvery simple.\n\nAround line 15 of this file you'll see a line like:\n\n```\nSTDLIB=\"-DOCTA -DSTDLIBFILE -DSTDLIBGLOB -DSTDLIBMBOX -DSTDLIBNET -DSTDLIBSHAREDLIB -DSTDLIBSHELL -DSTDLIBXD \"\n```\n\nEach of those \"-D\" statements enables a feature. You can remove those features\nif you don't want any of them.\n\nIn particular, on platforms that do not support glob.h you should remove `-DSTDLIBGLOB`.\n\nIf you're on a 32 bit system that doesn't provide support for 128bit integers, which we call\noctawords in XXL, remove `-DOCTA`.\n\nIf you don't have support for sockets on your platform, remove `-DSTDLIBNET`.\n\nNo filesystem? Remove `-DSTDLIBFILE`.\n\nWithout threading? Remove `-DSTDLIBMBOX` and `-DTHREAD` in DEFS a few lines above.\n\nNot Unix-like? Remove `-DSTDLIBSHELL`.\n\nNo shared libraries, or don't care for `dlopen`? Remove `-DSTDLIBSHAREDLIB`.\n\n### Regenerating auto-built .h files\n\nSome of the .h files in the source are automatically generated by some\nprimitive .js scripts. If you don't have Node installed, or don't care to\nrebuild those (it's not necessary unless you change the definitions of the\nbuilt in data types), just comment out \"BUILDH\" at the top of the `./c` \nscript.\n\nTry something like:\n\n```\ngit clone https://github.com/tlack/xxl.git\ncd xxl\n./c\n```\n\nThe default build has a TON of debugging info turned on which it will violently\nspit at you while you use it. Commented out the \"DEBUG=\" line in `./c` to make the\nsystem more silent and friendly - but perhaps less predictable when things go\nwrong (which they will.. often). \n\nTurning off debugging also allows XXL to run much more quickly.\n\n## Size\n\nXXL is about 3,000 lines of hand-written C, plus 2,000 lines of auto-generated\n.h files. Stripped executable is about 400kb.\n\nI dislike large systems and aim to keep XXL small, but I also want programmers\nto be able to easily get at functionality they need, both through a decent set\nof built-ins, and through something akin to npm (still pondering this).\n\nI believe XXL could be reduced to 1,000 lines or less of JavaScript or another\nlanguage that offers a more flexible type system than C's. I also wrote different\nversions of similar code a lot for speed; implementing everything in terms\nof each() (and other forms of iteration) would probably require much less code.\n\n## Inspiration\n\nK4/Q by [Kx Systems\u0026trade;](http://kx.com), the quirky\n[Klong by Nils Holm](http://t3x.org/klong/), Erlang\n(process model, introspection, parse tree/transforms), \n[Kerf's approachablity](http://kerfsoftware.com), \nIo (self-similarity of objects and asceticism) \nand C (simplicity, performance, rectangularity of data).\n\n## Imminent Rename\n\n(I was trying to make this an eminent domain joke.)\n\nI'm considering renaming XXL to `tx`, so if you see some mixing of names here\nand there, please be patient with me as I consider this change. Input\nappreciated!\n\n## Contact, Community, Chat\n\nVisit with the XXL crew and many other smart folks on #kq and #xxl on Freenode IRC.\n\n## Credits\n\nWetly birthed by @tlack \u003clackner@gmail.com\u003e at [Building.co](http://building.co) in sunny Miami \n\nMany thanks to co-conspirators:\n\nEblin Lopez @ classic.com, Mike Martinez @ classic.com, Khalife Nizar @ Ironhack for\nkeeping me grounded and much input. :)\n\n@joebo for help with Android.\n\n## Disclaimer\n\nNo warranty. Trademarks right of their respective owners. \n\nThis project is not related in any way to the interesting [XL project by\nDinechin et al](http://xlr.sourceforge.net/).\n\n## License\n\nBSD-L (3 clause)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftlack%2Fxxl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftlack%2Fxxl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftlack%2Fxxl/lists"}