{"id":21493545,"url":"https://github.com/alienkevin/slick-lang","last_synced_at":"2026-03-04T06:31:10.336Z","repository":{"id":44837214,"uuid":"212341393","full_name":"AlienKevin/Slick-lang","owner":"AlienKevin","description":"A slick programming language","archived":false,"fork":false,"pushed_at":"2022-12-30T19:17:59.000Z","size":530,"stargazers_count":4,"open_issues_count":6,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-20T18:41:17.401Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/AlienKevin.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":"2019-10-02T12:53:59.000Z","updated_at":"2022-01-14T03:37:56.000Z","dependencies_parsed_at":"2023-01-31T14:00:30.801Z","dependency_job_id":null,"html_url":"https://github.com/AlienKevin/Slick-lang","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/AlienKevin/Slick-lang","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlienKevin%2FSlick-lang","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlienKevin%2FSlick-lang/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlienKevin%2FSlick-lang/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlienKevin%2FSlick-lang/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AlienKevin","download_url":"https://codeload.github.com/AlienKevin/Slick-lang/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlienKevin%2FSlick-lang/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30074142,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T05:31:57.858Z","status":"ssl_error","status_checked_at":"2026-03-04T05:31:38.462Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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-11-23T15:43:23.623Z","updated_at":"2026-03-04T06:31:09.548Z","avatar_url":"https://github.com/AlienKevin.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Slick\n\n\u003cimg src=\"medias/slick_logo.png\" width=\"200px\"/\u003e\n\n# Introduction\n\nSlick is a statically typed functional programming language transpiled to JavaScript.\n\nSlick aims to *unclutter* software development and is heavily influenced by [Elm](https://elm-lang.org/) and [Neo](https://github.com/douglascrockford/howjavascriptworks).\n\nSlick is an experimental language and is not intended to be used in production. However, contributions are always welcome! 😁\n\n[Try Slick online now!](https://slick-playground.netlify.com)\n\n# Hello World\n\n```\n_ :\n\tprint 'Hello World!'\n```\n\n`_`  is the placeholder symbol for a binding name. You can repeatedly use `_` in your code to render side effects such as printing to the console.\n\n`print` is the built-in function to print any value to standard output.\n\nFunction invocations use space to separate callee and arguments instead of parentheses to avoid parenthesis hell.\n\n# Comments\n\n```\n# Slick only has single-line comments\n\n# Combine multiple\n# single-line comments\n# to form a multi-line comment\n```\n\n# Primitive Types\n\nSlick only has three primitive types:\n\n## Num\n\n### How are numbers represented?\n\nNumbers in Slick are all arbitrary precision (by default to 20 significant figures) floating point numbers. There is not separate integer type to avoid type complexity and unnecessary type conversion between integers and floats. Unlike most languages, Slick does not suffer from floating point rounding errors so all calculations are accurate up to 20 significant figures. (you can change the number of sig figs in the compiler setting in the future).\n\n### How can I work with `Num`?\n\nInfix operators:\n\n```\n+, -, *, / for add, subtract, multiply, and divide\n% for modulo (getting the remainder of dividing two numbers)\n```\n\nMath functions see reference.\n\n## Text\n\nTexts in Slick are lists of Unicode codepoints surrounded with `'`s (single quotes). \n\n### Why no `char` type?\n\nUnlike languages like C and Java, Slick does not have a `char` type because one user-perceived character like 'ñ' may consists of multiple Unicode codepoints (n+◌̃ ) thus a character needs to be stored as a list of codepoints. A list of Unicode codepoints is exactly what `Text` is so there's no point in creating a separate type. \n\n### How can I work with `Text`?\n\nYou still have all the familiar operations like `slice` and `length` but they now have *user-perceived characters* as unite of operation instead of Unicode codepoints. So calling `length` on `अनुच्छेद` returns 5 because the text contains just 5 user-perceived characters (अ + नु + च् + छे + द) instead of 8 Unicode codepoints (अ + न + ु + च + ् + छ + े + द). The rules for splitting text into user-perceived characters follows the Unicode standard [UAX #29](http://www.unicode.org/reports/tr29/).\n\nYou can concatenate two texts using `\u0026`:\n\n```\nprint ('Hello ' \u0026 'world!') # Hello world!\n```\n\n## Bool\n\nBooleans in Slick are either `True` or `False`.\n\n### How can I work with `Bool`?\n\n```\nTrue ⋏ False = False # ('⋏' for and operator)\nTrue ⋎ False = True # ('⋎' for or operator)\n```\n\nIn the code editor, type `/\\` to create `⋏` and `\\/` to create `⋎`.\n\n# Bindings\n\n```\nname :\n\t'Bob'\n```\n\nBindings are immutable. The value of the binding must be on the next line after the `:` (colon) for consistent code style. Function expression is an exception. Function header must be on the same line as the `:`.\n\n```\n# Valid binding names\nfoo\nlongBindingNme\n\n# Invalid binding names\nlong_binding_name # Use camelCase instead of '_'\n$bindingName # No symbols other than '?' are permitted\nFoo # binding name can only start with lowercase\n    # uppercase reserved for type names\n```\n\n# Functions\n\n```\nadd : ƒ a b\n\ta + b\n```\n\nAll functions in slick are expressions and starts with the `ƒ` symbol. Notice that the `ƒ` is italic, not a normal `f`. You can use keyboard shorthand `\\f` in the code editor to type `ƒ` (see how to install Slick VS Code extension). Put any parameters after `ƒ` and separate each with a space. The function body is an expression and Slick evaluates that expression to produce the function return value.\n\n```\nadd = Num → Num → Num\nadd : ƒ a b\n\ta + b\n```\n\nWe recommend putting a type declaration above the function. Adding type declaration both confirms that the type you think the function possesses is correct and serves as compiler-verified documentation for the function. In Slick, we don't specially highlight the return type of the function in its type declaration. Instead, we chain all parameter types and the return type together with `→` (keyboard shorthand `-\u003e` ). The reason for this is because all functions in Slick are [curried](https://medium.com/javascript-scene/curry-and-function-composition-2c208d774983) and the `→` separated type declaration allows [partial applications](https://scotch.io/tutorials/javascript-functional-programming-explained-partial-application-and-currying) on all functions.\n\nAnother way to declare short functions is to surround the function body with `()` without a line break after the function header:\n\n```\nadd = Num → Num → Num\nadd : ƒ a b (a + b)\n```\n\n# Records\n\n```\nbob :\n    {\n        name : 'Bob'\n        age: 45\n        employeed: True\n    }\n```\n\nRecord maps a `Text` key to a value of any type. No duplicate keys are allowed.\n\nYou can access record property using the `.`  (dot) operator\n\n```\n# 'Bob'\nname :\n\tbob.name\n```\n\nRecords are immutable. Use `|`  (bar) to update record property:\n\n```\nalice :\n    {\n        bob |\n        name : 'Alice'\n    }\n```\n\nThe `alice` record is created by updating the `name` property of record `bob` to `'Alice'`.\n\n# Lists\n\n```\nlist:\n\t[1, 2, 3]\n```\n\nLists are immutable and can only contain values of same type.\n\nHere we will only give a simple example. Refer to the API documentation in the end for more details.\n\nCreate a list of even numbers from 1 to 10:\n```\nevenList :\n\tList.filter # calls the List.filter function\n\tƒ element (element % 2 = 0) # keep only even elements in the list\n\t(List.range 1 10) # create a list ranging from 1 to 10\n```\nNotice that function calls can span multiple lines. Here we are calling `List.filter` function with a function that keeps even elements and a list produced by `List.range`.\n\n# If Expression\n\n```\nvalue :\n\t0\n\nvalueName :\n    if value \u003e 0\n        'positive'\n    elif value = 0\n        'zero'\n    else\n        'negative'\n_ :\n\t# outputs 'value is zero'\n\tprint ('value is ' \u0026 valueName)\n\t\t\n```\n\n# Type Aliases\n\nSlick is all about data structures. All program states are stored using data structures (or Abstract Data Types, ADTs). Sometimes you may find yourself repeat the type names of an ADT as you use them throughout the program, then it's the time to introduce a `type alias` for that ADT.\n\n```\n# Grid stands for a 2-dimensional list of numbers\ntype alias Grid :\n\tList List Num\n```\n\nType aliases help maintain the DRY (Don't Repeat Yourself) principle in your code and make refactoring the ADT much easier later.\n\n# Custom Types\n\nPrimitive data types - `Bool`, `Text`, and `Num` - usually do the job. However, many properties do not fit nicely into the three primitive types. For example, you may want to represent day of the week in your program. At first, you may be tempted to just settle with `Text`:\n\n```\ndayOfWeek :\n\t'Friday'\n```\n\nHowever, too many things that are not day of week can be stored in `Text` :\n\n```\ndayOfWeek :\n\t'hello'\n```\n\nYou may be satisfied with using the `Text` representation until you want to convert `dayOfWeek` to a number:\n\n```\ndayOfWeek :\n\t'monday'\n\ndayNumber :\n\tif dayOfWeek = 'Sunday' then\n\t\t0\n\telif dayOfWeek = 'Monday' then\n\t\t1\n\telif dayOfWeek = 'Tuesday' then\n\t\t2\n\telif dayOfWeek = 'Wednesday' then\n\t\t3\n    elif dayOfWeek = 'Thursday' then\n\t\t4\n\telif dayOfWeek = 'Friday' then\n\t\t5\n\telse\n\t\t6\n```\n\nNow there are a lot of `elif`s and `then`s. Let's simplify this `if-elif-else` chain with `case` expression.\n\n```\ndayOfWeek :\n\t'monday'\n\ndayNumber :\n\tcase dayOfWeek of\n\t\t'Sunday' →\n\t\t\t0\n\t\t'Monday' →\n\t\t\t1\n\t\t'Tuesday' →\n\t\t\t2\n\t\t'Wednesday' →\n\t\t\t3\n\t\t'Thursday' →\n\t\t\t4\n\t\t'Friday' →\n\t\t\t5\n\t\t_ →\n\t\t\t6\n```\n\nWhat we did is basically extracting the `dayOfWeek` binding to the top of the `case` expression, remove the `if`, `elif`s, and `else`s, and replace `then` with `→`. Notice the last `_` (underscore) placeholder? That just means `else`.\n\nAll looks good but oops! All of a sudden, `dayNumber` yields `6` when `dayOfWeek` is `monday` instead of the correct result `1` because `monday ≠ Monday` and we drop all the way to the bottom `_` catch-all else case. This kind of bug is also very hard to catch because the programming logic is perfect except for a single character.\n\nIs this the best we can do?\n\nNo!\n\nEnter custom types 👏👏👏\n\nYou can create a custom `DayOfWeek` type to precisely capture all seven days of the week with no room for invalid states:\n\n```\ntype DayOfWeek :\n\tSunday\n\tMonday\n\tTuesday\n\tWednesday\n\tThursday\n\tFriday\n\tSaturday\n```\n\nWell, what's special about this? Now, you can't need to worry about invalid day of week because they are impossible! The Slick compiler checks it for you to make sure the integrity of the custom type. Let's rewrite the `dayNumber` using new the custom type `DayOfWeek`:\n\n```\ndayOfWeek :\n\t# 'monday' or 'Monday' no longer works because now dayOfWeek is a custom type, not a Text\n\tMonday\n\ndayNumber :\n\tcase dayOfWeek of\n\t\tSunday →\n\t\t\t0\n\t\tMonday →\n\t\t\t1\n\t\tTuesday →\n\t\t\t2\n\t\tWednesday →\n\t\t\t3\n\t\tThursday →\n\t\t\t4\n\t\tFriday →\n\t\t\t5\n\t\t# if you omit any one DayOfWeek, Slick will not compile the code\n\t\tSaturday →\n\t\t\t6\n\n```\n\n# Case Expression\n\nHere's another simple example of how to use case expression on custom types:\n\n```\ntype Fruit :\n\tApple\n\tBanana\n\tOrange\n\nfruit :\n\tBanana\n\n# 0.75\nfruitPrice :\n\tcase fruit of\n\t\tApple →\n\t\t\t2\n\t\tBanana →\n\t\t\t0.75\n\t\tOrange →\n\t\t\t1.5\n```\n\n# Install Slick\n\nCreate a new npm project using:\n\n```bash\nnpm init\n```\n\nNow your project tree should look like:\n\n```\npackage-lock.json\npackage.json\n```\n\nCreate a `src` folder:\n\n```\nsrc/\npackage-lock.json\npackage.json\n```\n\nAdd `helloWorld.slk` to the `src` folder:\n\n```\n# helloWorld.slk\n_ :\n\tprint 'Hello World from Slick!'\n```\n\nYour project should now look like:\n\n```\nsrc/\n\t|- helloWorld.slk\npackage-lock.json\npackage.json\n```\n\nInstall the slick compiler:\n\n```bash\nnpm install slick-make\n```\n\nNow your project tree should have a `node_modules` folder added by `npm`:\n\n```\nnode_modules/\nsrc/\n\t|- helloWorld.slk\npackage-lock.json\npackage.json\n```\n\nIn your `package.json`, add a `scripts` property:\n\n```bash\n\"scripts\": {\n    \"slick\": \"node node_modules/slick-make/dist/cli.js\"\n}\n```\n\nRun you slick program:\n\n```bash\nnpm run slick run src/helloWorld.slk\n```\n\n```\nHello World from Slick!\n```\n\n🎉🎉🎉 Congratulation! You just ran you first Slick program!\n\nSee the `examples` folder for more examples.\n\n# Set up Slick in Visual Studio Code\nInstall [slick-vscode-extension](https://marketplace.visualstudio.com/items?itemName=KevinLi.slick-lang) and you are all set with full syntax highlighting and symbol shorthands.\n\n![Slick vscode extension demo](medias/vscode_demo.png)\n\n# Symbol Shorthands\n|You type   | to get  |\n|---|---|\n|`\\f` |`ƒ`  |\n|`-\u003e` |`→`  |\n|`\u003e=` |`≥`  |\n|`\u003c=` |`≤`  |\n|`!=` |`≠`  |\n|`/\\` |`⋏`  |\n|`\\/` |`⋎`  |\n\n\n# API functions\n\n## Text functions\n```\nlower       Text → Text\nupper       Text → Text\nlower?      Text → Bool\nupper?      Text → Bool\nnth         Num → Text → Maybe Text\ntake        Num → Text → Text\ntakeLast    Num → Text → Text\ntrim        Text → Text\nsplit       Text → Text → List Text\ncapitalize  Text → Text\nendsWith    Text → Text → Bool\nstartsWith  Text → Text → Bool\nslice       Num → Num → Text → Text\nmember      Text → Text → Bool\nlength      Text → Num\nchar        Num → Maybe Text\njoin        Text → List Text → Text\n```\n\n## List functions\n```\nmap         (a → b) → List a → List b\nmapIndexed  (a → Num → b) → List a → List b\nfilter      (a → Bool) → List a → List a\nreject      (a → Bool) → List a → List a\nfind        (a → Bool) → List a → Maybe a\nreduce      (a → b → a) → a → List b → a\nreduceLast  (a → b → a) → a → List b → a\nall         (a → Bool) → List a → Bool\nany         (a → Bool) → List a → Bool\nfirst       List a → Maybe a\ntail        List a → List a\nhead        List a → List a\nlast        List a → Maybe a\nnth         Num → List a → Maybe a\ntake        Num → List a → List a\ntakeLast    Num → List a → List a\nslice       Num → Num → List a → List a\nmember      a → List a → Bool\ninsert      Num → a → List a → List a\nappend      a → List a → List a\nprepend     a → List a → List a\nupdate      Num → a → List a → List a\ndrop        Num → List a → List a\ndropLast    Num → List a → List a\nconcat      List a → List a → List a\nadjust      Num → (a → a) → List a → List a\nlength      List a → Num\nrange       Num → Num → List Num\nsum         List Num → Num\n```\n\n# Num functions\n```\nabs        Num → Num\nmax        Num → Num → Num\nmin        Num → Num → Num\nneg        Num → Num\nsqrt       Num → Num\nround      Num → Num\nfloor      Num → Num\nceil       Num → Num\ntrunc      Num → Num\npi         Num\ne          Num\nsin        Num → Num\ncos        Num → Num\ntan        Num → Num\nasin       Num → Num\nacos       Num → Num\natan       Num → Num\natan2      Num → Num → Num\n```\n\n# other built-in functions\n```\nnot        Bool → Bool\nprint      a → Text\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falienkevin%2Fslick-lang","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falienkevin%2Fslick-lang","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falienkevin%2Fslick-lang/lists"}