{"id":28229282,"url":"https://github.com/dibsonthis/glide--old","last_synced_at":"2025-06-14T04:31:37.168Z","repository":{"id":64425207,"uuid":"563399940","full_name":"dibsonthis/Glide--old","owner":"dibsonthis","description":"Glide programming language","archived":false,"fork":false,"pushed_at":"2022-12-14T13:49:59.000Z","size":59490,"stargazers_count":41,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-18T15:13:58.966Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dibsonthis.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}},"created_at":"2022-11-08T14:33:22.000Z","updated_at":"2024-08-05T07:55:46.000Z","dependencies_parsed_at":"2022-12-31T19:18:38.511Z","dependency_job_id":null,"html_url":"https://github.com/dibsonthis/Glide--old","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dibsonthis/Glide--old","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dibsonthis%2FGlide--old","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dibsonthis%2FGlide--old/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dibsonthis%2FGlide--old/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dibsonthis%2FGlide--old/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dibsonthis","download_url":"https://codeload.github.com/dibsonthis/Glide--old/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dibsonthis%2FGlide--old/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259759829,"owners_count":22907052,"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":[],"created_at":"2025-05-18T15:13:58.863Z","updated_at":"2025-06-14T04:31:37.161Z","avatar_url":"https://github.com/dibsonthis.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Glide\nDocumentation for the Glide programming language.\n\nLink to video demo: [Glide reddit post](https://www.reddit.com/r/ProgrammingLanguages/comments/ybjtax/glide_data_transformation_language_documentation/)\n\n## Purpose\n\nThe purpose of Glide is simple. I wanted a way to easily read and write data transformation workflows. With this in mind, the language relies heavily on the arrow (injection) operator '-\u003e' to feed data long the chain. This documentation will feature examples of how it's used.\n\nThe other reason this language exists, is learning. I wanted to learn how languages are made and uncover the black magic of parsers/iterpreters/compilers. Glide is my 15th attempt at a new language, the ones before have been abandoned due to the codebase being an absolute mess, or the language itself offering nothing new and exciting (at least for me). I decided to stick it out with Glide, and hoping to end the cycle of project hopping by continuing to refactor and upgrade instead of deleting and starting from scratch.\n\n# How to compile and start having fun with Glide\n\nClone and open source code in VSCode. The first thing you want to look at is ```main.cpp```. There, you should see ```Type type = Type::DEV;```. There are three different types here: _DEV_ | _INTERP_ | _REPL_, we'll go through each one below.\n\n### DEV\n\nIf DEV is selected, we're in development mode, running the code now will build and debug the compiler. \nThe output will be stored in \"bin/build/dev\". \nTo run, make sure to select: ```C/C++: g++.exe build and debug active file``` (Windows) or ```C/C++: clang++ build and debug active file``` (Mac)\n\nDEV will read directly from ```dev_env/source.gl```, so make sure to put your Glide code in there. You can create other Glide files in that folder and import them into ```source.gl``` too.\n\n### INTERP\n\nIf INTERP is selected, you're now building an optimised version of the compiler. \nThe output will be stored in \"bin/build/interp\". \nTo run, make sure to select: ```C/C++: g++.exe build interpreter``` (Windows) or ```C/C++: clang++ build interpreter``` (Mac)\n\nAfter compiling the interpreter, you should copy and paste the executable inside ```test_env```. This directory is where you can test your newly created interpreter. You can run the interpreter using ```./glide \"main.gl\"``` (or any other .gl file in that directory).\n\n### REPL\n\nIf REPL is selected, you're now building an optimised version of the REPL (Read Execute Print Loop). \nThe output will be stored in \"bin/build/repl\". \nTo run, make sure to select: ```C/C++: g++.exe build repl``` (Windows) or ```C/C++: clang++ build repl``` (Mac)\n\nAfter compiling the interpreter, you should copy and paste the executable inside ```test_env```. This directory is where you can test your newly created REPL. You can run the REPL using ```./glide-repl```. The REPL is probably the fastest way to prototype Glide code.\n\n## Standard Lib\n\nThere are some pre-built imports that are heavily used (by me), those can for the time being be referred to as the \"standard library\".\n\n## Examples\n\nThere are some Glide examples in the ```test_env/src/examples``` directory. All you have to do is run those files.\n\n## Glide outside of the repo\n\nAfter you've compiled the interpreter/REPL, feel free to move the executables to any other location. I personally have my own directory that I use as an isolated Glide test environment.\n\n## Syntax highlighting\n\nSyntax highlighting is currently non-existent. Best thing to do is mark the file as a C file in VScode, at least it'll look prettier.\n\n# Current status of Glide\n\nCurrent status: Work in progress\n\nYou _will_ encounter many bugs, maybe some segfaults here and there, and some undefined behaviour.\nErrors are currently quite terrible, and it's a known issue that error line/col numbers can be hilariously incorrect. This is being worked on.\nDo _NOT_ use Glide in any production environment, for real. It's not at that stage yet.\n\n# Syntax\n\n## Data types\n\nGlide only has a few simple data types: bool, int, float, string, list, object and empty\n\nThe language is dynamically typed and therefore there is no need to declare the variable type. (Note: a type system is in the works, and once fully implemented, this documentation will be updated accordingly. I'm still unsure whether I want typing to be a requirement by the compiler, or a choice given to the programmer. Stay tuned, I guess).\n\nExample - Variable declaration:\n\n```\nx = 12\ny = 3.45\nstr = \"hi there, universe\"\nls = [ 1 2 3 \"four\" 5.0 ]\nobj = @{\n  name: \"John\"\n  age: 45\n}\n```\n\n## Arrow (Injection) Operator\n\nAs mentioned in the intro, the arrow (-\u003e) operator is by far the most important aspect of Glide. It allows the programmer to do a few useful things:\n  - Inject a value into an operator to create a partial operator\n  - Inject a value into a function to create a partial function (aka curried functions)\n  - Feed data down a transformation chain\n\nExample - Simple chaining using the arrow operator\n\n```\nx = 4 -\u003e *5 -\u003e +2 -\u003e +(5/2)   // result: 24.5\n```\n\n## Partial Operators\n\nGlide gives you the ability to create partial operators. These are operators that are incomplete and only evaluated once the required operands are injected.\n\nExample - Partial Operator\n\n```\nmul3 = (*3)\n4 -\u003e mul3   // result: 12\n3 -\u003e mul3   // result: 9\n```\n\nYou can even create a fully partial operator (in the case of a binary operator, this means it has no operands at all).\n\nExample - Fully partial operator\n\n```\nadd = (+)\nadd5 = 5 -\u003e add\n5 -\u003e add5   // result: 10\n```\n\nIn the example above, we created a variable with a fully partial operator (+), with no operands. We then injected a value of 5 into it, which took the place of its left hand operand, and saved it as another variable. Finally, we injected 5 into the new variable, which took the place of its next empty operand (the right hand operand). Because the operator now has both required operands, it is then evaluated to produce the result of 10.\n\n## Functions\n\nAs with any other programming language, Glide gives the ability to create and call functions.\n\n(Note: The previous version of this language had two different ways to create functions, through function definitions and through lambdas. The current implementation only allows lambdas, however this might also change as well.)\n\nExample - Simple Add Function\n\n```\nadd = [a b] =\u003e {\n  ret a + b\n}\n```\n\nAll functions are injected with their surrounding scope upon creation, which means closures are also possible.\n\nExample - Closures:\n\n```\nouter = [] =\u003e {\n  x = 12\n  inner = [] =\u003e {\n    ret x\n  }\n  ret inner\n}\n\nf = outer[]\nf[]   // result: 12\n```\n\nFunctions are also injected with a pointer to themselves, which makes recursion possible.\n\nExample - Recursion:\n\n```\nfib = [n] =\u003e {\n\n   if [n == 0] =\u003e {\n     ret 0\n  }\n  if [n \u003c= 2] =\u003e {\n     ret 1\n  }\n\n  ret fib[n-1] + fib[n-2]\n  \n}\n```\n\n### Calling functions\n\nThere are multiple ways functions can be called in Glide. The first one is the simple bracket notation:\n\n```\nx = 12\ny = 8\nadd[x y]    // result: 20\n```\n\nThe other way is through injection:\n\n```\nadd4 = [x] =\u003e {\n  ret x + 4\n}\n\n10 -\u003e add4 -\u003e *2   // result: 28\n```\n\nInjecting a value into a function adds that value as an argument. If all the required arguments are present or injected, then the function is called and the value is returned. In the example above, the function 'add4' required only one argument, and once that argument is injected, the function is invoked.\n\n### Partial (Curried) Functions\n\nLet's take another look at the add function we defined previously. It requires two arguments, but what happens if we inject only one?\n\n```\nadd4 = 4 -\u003e add\n5 -\u003e add4   // result: 9\n```\n\nAs you can see, if the function still requires more arguments after injection, it isn't evaluated. Instead, it returns a curried/partial function that contains the injected value as preloaded argument. This allows us to create curried/partial functions relatively easily.\n\n## Range Operator\n\nAn important operator, especially for looping, is the range (..) operator:\n\n```\nlist_1_10 = 1..10\n```\n\nIt's an easy way to create lists to iterate through.\n\n## Loops\n\nGlide contains both for and while loops. \n\n### For loops:\n\nExample - Simple for loop:\n\n```\nfor [1..10] =\u003e {\n    print[\"hi\\n\"]\n}\n```\n\nFor loops have an interesting implementation detail which seemed like a good idea at the time, however it could cause bugs if the user is unaware of it. If, as with the example above, a for loop was only given a list to iterate through, the body of that loop automatically gets access to two variables: '\\_i' and '\\_it'. \\_i is the current index, and \\_it is the current element. This provides a lot of convenience in simple loops, however it introduces complexity in nested loops. It's advisable to only omit the index when the loop is simple and flat. So, how do we get around this issue in less simple loops?\n\nExample - For loop with index:\n\n```\nfor [1..10 index] =\u003e {\n  print[index]\n}\n```\n\nWe can directly define a variable for the index. This allows us to access the current index by name, and not by a scoped variable. This means that in a nested loop, we can access any outer index without confusion or error.\n\nWe can go one step further and define the item variable.\n\nExample - For loop with index and item\n\n```\nfor [1..10 index item] =\u003e {\n  print[\"Index: \" index \"\\n\"]\n  print[\"Item: \" item \"\\n\"]\n}\n```\n\nIt is highly recommended that you declare at least the index when creating loops, even if they're basic loops, in the case they need to be refactored to be nested in the future. If you're certain your loop will always remain flat, then feel free to omit the index or item variables.\n\n### While loops\n\n```\nwhile [x \u003c= 10] =\u003e {\n  x = x + 1\n}\n```\n\nWhile loops take a single conditional and loops until that conditional stops being met.\n\n## If Statements and If Blocks\n\nIn Glide, you can write one off if statements, or if blocks which act as an if/else if(s)/else statement.\n\nExample - If Statement:\n\n```\nif [x != 3] =\u003e {\n  x = 3\n}\n```\n\nExample - If block:\n\n```\nif =\u003e {\n  x \u003c 3: {\n    x = 0\n  }\n  x \u003e 3: {\n    x = 10\n  }\n  default: {\n    x = 100\n  }\n}\n```\n\n## Lists\n\nLists can contain any type of element. They can be constructed using the range (..) operator, as seen in previous examples, or by explicitly building them. Notice that in Glide, list items are not comma separated. \n\nList items can be accessed by index using the dot-bracket notation.\n\nExample - Lists:\n\n```\nx = [ 1 2 3 \"hello\" \"goodbye\" ]\nx.[3]   // result: \"hello\"\nx.[0] = 100   // result: [ 100 2 3 \"hello\" \"goodbye\" ]\n```\n\nWe can also add lists together:\n\n```\nx = [1 2 3] + [4 5 6]   // result: [1 2 3 4 5 6]\n```\n\n### List built-in properties:\n\nlength: ``` x.length ```: retrieves the length of the list\n\n## Objects\n\nObjects are containers consisting of key/value pairs.\n\nExample - Objects:\n\n```\nobj = @{\n  first: \"James\"\n  last: \"Smith\"\n  get_name: [] =\u003e {\n    ret first + \" \" + last\n  }\n}\n  \nobj.last          // returns: \"Smith\"\nobj.get_name[]    // returns \"James Smith\"\n```\n\nAn interesting feature of Glide objects is that properties can access any previously defined property in the object (as per the get_name function above).\n\nObjects can also be added together, which merges the right object's properties with the left's. If the left and right object share the same property, that property is replaced with the right's.\n\nExample - Adding objects:\n\n```\nx = \n  @{ name: \"Irene\" score: 12 } \n  + \n  @{ name: \"Irene\" score: 29 grade: \"B\" }\n  \n// returns @{ name: \"Irene\" score: 29 grade: \"B\" }\n```\n\n## Chaining\n\nAs touched upon previously, Glide's entire reason for existing is to be able to easily read and write data transformation. In the context of Glide, this is called chaining. \n\nExample - Chaining:\n\n```\nx =\n(10, 20) -\u003e add\n-\u003e +2\n-\u003e add12\n-\u003e mul4\n-\u003e some_function\n-\u003e *12\n-\u003e (y =)\n-\u003e [x] =\u003e { ret x * (3+2) }\n```\n\nSome interesting points on the above:\n\n- You can inject directly into a lambda, which makes chaining a really powerful way to transform data without too much pre-meditation.\n- You can assign variables directly inside a chain (y =), which can act as a way of \"saving state\" in the middle of a transformation.\n- You can inject multiple values into a function/operator using a comma-separated list, as shown in the first line of the transformation.\n\n## Standard Lib\n\nAs it stands currently, the standard lib has some useful functionality primed at data transformation.\n\n### Map\n\n_map_ creates a copy of the list provided and applies the given function/operator to each element:\n\n```\n1..100 -\u003e std.map[*2]\n1..100 -\u003e std.map[([x] =\u003e { ret x * 2 })]\n```\n\n### Filter\n\n_filter_ filters the provided list based on the given condition: \n\n```\n1..100 -\u003e std.filter[\u003e10] -\u003e std.filter[\u003c20]\n1..100 -\u003e std.filter[([x] =\u003e { ret x \u003c 20 \u0026\u0026 x \u003e 10 })]\n```\n\n### Reduce\n\n_reduce_ reduces the provided list based on the given function/operation:\n\n```\n1..100 -\u003e std.reduce[+]\n1..100 -\u003e std.reduce[([a b] =\u003e { ret a + b })]\n```\n\n### Zip\n\n_zip_ takes two lists and applies the given function to each element of the same index:\n\n```\n(1..100, 1..100) -\u003e std.zip[+]\n(1..100, 1..100) -\u003e std.zip[([a b] =\u003e { ret a + b })]\n```\n\n## Implementation\n\nGlide is written in C++. The compiler produces bytecode (kind of, it's not really a byte) instructions that are evaluated using a virtual machine also built in C++. As it currently stands, the performance is not exactly optimal and work is being done to improve it on this front.\n\n## Closing note\n\nGlide is very much a work in progress, with many _many_ bugs that are being identified and fixed daily. This is not intended to be a language used in any production environment (yet), and can be classed as a toy language until all issues are ironed out.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdibsonthis%2Fglide--old","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdibsonthis%2Fglide--old","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdibsonthis%2Fglide--old/lists"}