{"id":25777160,"url":"https://github.com/jaccomoc/jactl","last_synced_at":"2026-04-15T12:03:13.216Z","repository":{"id":151149835,"uuid":"513677353","full_name":"jaccomoc/jactl","owner":"jaccomoc","description":"A secure scripting language for event-loop/reactive Java-based applications.","archived":false,"fork":false,"pushed_at":"2024-10-24T02:10:03.000Z","size":4613,"stargazers_count":49,"open_issues_count":5,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-24T11:25:20.126Z","etag":null,"topics":["apache-license-2","compiler","java","open-source","programming-language","scripting-language"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jaccomoc.png","metadata":{"files":{"readme":"docs/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":"2022-07-13T21:33:06.000Z","updated_at":"2024-10-24T02:10:07.000Z","dependencies_parsed_at":"2023-04-13T01:48:48.110Z","dependency_job_id":"106c50eb-2af2-48ab-ba60-237d090ddc1a","html_url":"https://github.com/jaccomoc/jactl","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaccomoc%2Fjactl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaccomoc%2Fjactl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaccomoc%2Fjactl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaccomoc%2Fjactl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaccomoc","download_url":"https://codeload.github.com/jaccomoc/jactl/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240987435,"owners_count":19889335,"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":["apache-license-2","compiler","java","open-source","programming-language","scripting-language"],"created_at":"2025-02-27T06:01:37.868Z","updated_at":"2026-04-15T12:03:08.184Z","avatar_url":"https://github.com/jaccomoc.png","language":"Java","funding_links":[],"categories":["JVM语言"],"sub_categories":[],"readme":"# Jactl Programming Language\n\n![logo](https://jactl.io/assets/logo-picture.jpg \"Jactl\")\n\n[Jactl](https://jactl.io) is a powerful scripting language for the JVM platform whose syntax is a combination of bits\nfrom Java, Groovy, and Perl.\nIt can be run from a REPL and from the commandline for commandline scripts but its main goal is\nto be integrated into Java applications and provide a secure, locked-down mechanism that\ncustomers/users can use to customise the application behaviour.\n\nIt is especially suited to event-loop/reactive applications due to its built-in suspend/resume\nmechanism based on continuations that ensures it never blocks the execution thread on which it is\nrunning.\n\n:star: Please consider giving this project a star as a way to encourage me to continue making improvements\nto Jactl.\n\n### Why Another JVM Language?\n\nI wanted a language that was a joy to code in, was easy for Java programmers to pick up, \nprovided a secure extension mechanism for applications, and was non-blocking.\nNothing I found satisfied all these needs, and so Jactl was born.\n\nSee the [FAQ](https://jactl.io/faq) for a more detailed answer and answers to other questions.\n\n## Features\n\n### Familiar Syntax\nJactl syntax is concise and is mostly just a subset of Java and Groovy syntax with a bit of Perl thrown in for\ngood measure, so it is easy to pick up for anyone familiar with Java:\n\n```groovy\nint fib(int x) {\n  return x \u003c= 2 ? 1 : fib(x-1) + fib(x-2);\n}\nprintln 'fib(20) = ' + fib(20);\n```\n\nJactl adopts a lot of Groovy syntax so semicolons are optional, typing is optional, double-quoted strings\nallow for embedded expressions, and `return` is optional for the last expression of a function so the previous example\ncould also be written like this:\n\n```groovy\ndef fib(x) { x \u003c= 2 ? 1 : fib(x-1) + fib(x-2) }\nprintln \"fib(20) = ${fib(20)}\"\n```\n\nJactl is a multi-paradigm language and so has both Object Oriented and Functional programming features.\nHere is an example showing a more functional programming approach using some built-in higher-order\nfunctions and built-in regex support to take a file of markdown, extract the top level headings, and generate \na table of contents:\n```groovy\n// Sanitise text to make suitable for a link\ndef linkify = { s/ /-/g;  s/[^\\w-]//g }\n\n// Find all top level headings in input and generate markdown for table of contents:\nstream(nextLine).filter{ /^# /r }\n                .map{ $1 if /^# (.*)/r }\n                .map{ \"* [$it](#${ linkify(it.toLowerCase()) })\" }\n                .each{ println it }\n```\n\nAnother example showing Jactl's pattern matching with destructuring:\n```groovy\nswitch (x) {\n  /X=(\\d+),Y=(\\d+)/n -\u003e  $1 + $2   // regex match with capture vars\n  [1,*]              -\u003e 'matched'  // list whose first element is 1\n  [_,_]              -\u003e 'matched'  // list with 2 elements\n  [int,String,_]     -\u003e 'matched'  // 3 element list. 1st is an int, 2nd is a String\n  [a,_,a]            -\u003e a * 2      // 1st and last elements the same in 3 element list\n  [a,*,a] if a \u003c 10  -\u003e a * 3      // list with at least 2 elements. 1st and last the same and \u003c 10\n  [a,${2*a},${3*a}]  -\u003e a          // match if list is of form [2,4,6] or [3,6,9] etc\n  [a,b,c,d]          -\u003e a+b+c+d    // 4 element list\n}\n```\n\nA simple quicksort:\n```groovy\ndef qsort(x) {\n  switch (x) {\n    [],[_] -\u003e x\n    [h,*t] -\u003e qsort(t.filter{it \u003c h}) + h + qsort(t.filter{it \u003e= h})\n  }\n}\n```\n\nSee [Language Features](https://jactl.io/language-features) for more language features and examples.\n\n### Compiles to Java bytecode\nJactl scripts compile to bytecode to take advantage of the performance capabilities of the JVM.\n\n### Supports Java 8+\nCompatible with Java 8 and later versions.\n\n### Comes with an IntelliJ Plugin\nThere is an IntelliJ plugin that supports syntax colouring, auto-indenting, completions, find definition/usages,\nrunning scripts, debugging scripts, and more.\nSee [IntelliJ Plugin](https://github.com/jaccomoc/jactl-intellij-plugin) for more details.\n\n### Never blocks\nJactl never blocks the execution thread on which a script is running.\nThis is to support execution in reactive or event loop based applications.\n\nBlocking operations in Jactl can only occur when invoking a blocking/asynchronous function.\nWhen executing such a function, the script will be suspended and when the blocking function completes,\nthe script execution state is resumed from the point at which it was suspended.\nThis is done via an internal _continuation_ mechanism.\n\nScript-writers can write their code as though it blocks and do not have to be concerned about which functions are\nasynchronous and which are synchronous or have to jump through the normal asynchronous programming hoops with the\nuse of callbacks to be invoked after a long-running operation completes.\n\nWhen a blocking operation is invoked, Jactl creates a Continuation object that captures the state of the running\nscript such as the value of all local variables and the current call stack.\nWhen the long-running operation completes, the script state is restored and the script continues\nfrom where it left off.\n\n### Checkpointing\n\nThe execution state of a script can be checkpointed when needed and this checkpointed state can be persisted or\ndistibuted over a network in order to recover and resume scripts after a failure.\n\n### Extendable\nEasy to integrate additional functions and methods into the language for application-specific needs.\n\n### Secure\nUnlike many other JVM based languages, in Jactl the things that a script writer can do are tightly controlled.\nThe only things available to the script writer are the built-in functions and the functions that you provide.\nThis allows Jactl scripts to be safely executed in frameworks where creating threads, writing to files,\nconnecting to remote systems, and performing other blocking operations would not normally be allowed.\n\nWhen you integrate the Jactl compiler into your application you provide it with the functions that you want\nyour script writers to have access to and this ensures they can only do things that you permit them to do.\nThis means you don't need to worry about them accessing files or data that they shouldn't be accessing,\nfor example.\n\n### No Dependencies\nThe core Jactl language has no dependencies on external libraries apart from the ASM library \nwhich it embeds within itself after renaming (to avoid clashes with any other instance of ASM\non the classpath).\n\n### Dynamic or Static Typing\nThe language allows you to choose whether to specify a type for your variables, parameters,\nand return types.\nYou can choose to provide types for stricter type checking or for optimisation reasons, or you\ncan leave things dynamically typed.\n\n### Jactl REPL\nJactl has a REPL (Read-Evaluate-Print-Loop) to allow you to easily play with the language and prototype \ncode at the commandline.\n\n### Commandline Scripts\nJactl scripts can be run from the commandline to replace use of various Unix utilities such as\n`awk`, `sed`, or even `Perl`.\n\n### Language Features\n* Closures\n* Functional programming\n  * Functions as values\n  * Higher-order functions\n  * Map, filter, collect, each, etc.\n  * [Pattern matching with destructuring](https://jactl.io/blog/2023/12/21/switch-expressions.html)\n* Classes with inheritance\n* Strong/weak typing\n* Parameters with default values\n* Named parameters for function calls\n* Multi-line strings\n* Strings with interpolated expressions\n* Regex matching syntax\n* Regex capture variables\n\nSee [Language Features](https://jactl.io/language-features) for an overview with examples of the language\nfeatures.\n\n## Download\n\nTo run command line scripts you only need the Jactl jar which can be downloaded from Maven Central:\n[https://repo1.maven.org/maven2/io/jactl/jactl/2.2.0/jactl-2.2.0.jar](https://repo1.maven.org/maven2/io/jactl/jactl/2.2.0/jactl-2.2.0.jar)\n\nTo download the Jactl REPL, which gives you an interactive shell for trying out Jactl code, see the\n[jactl-repl](https://github.com/jaccomoc/jactl-repl) project.\n\n## Building\n\n### Requirements\n\n* Java 8+\n* Gradle 8.0.2\n* ASM 9.6\n\n### Build\n\nDownload the source code from GitHub as a zip file or use `git` to clone the repository:\n```shell\ngit clone https://github.com/jaccomoc/jactl.git\ncd jactl\n./gradlew build\n```\n\nThat will build `jactl-${VERSION}.jar` under the `build/libs` directory where `${VERSION}` is the current version or\nwhatever version you have downloaded/checked out.\n\nTo push to your Maven repository you can use `publishToMaven`:\n```shell\n./gradlew build publishToMaven\n```\n\n## Integration\n\nTo use Jactl you will need to add a dependency on the Jactl library.\n\n### Gradle\n\nIn the `dependencies` section of your `build.gradle` file:\n```groovy\nimplementation group: 'io.jactl', name: 'jactl', version: '2.2.0'\n```\n\n### Maven\n\nIn the `dependencies` section of your `pom.xml`:\n```xml\n\u003cdependency\u003e\n \u003cgroupId\u003eio.jactl\u003c/groupId\u003e\n \u003cartifactId\u003ejactl\u003c/artifactId\u003e\n \u003cversion\u003e2.2.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Learn More\n\nThe [Jactl Documentation Site](https://jactl.io) has the complete documentation including a language guide, and \nan integration guide.\nIt should be your first port of call.\n\nRelated GitHub projects:\n\n* The [Jactl REPL project](https://github.com/jaccomoc/jactl-repl) provides a simple Read-Eval-Print-Loop shell for running Jactl code interactively.\n* The [Jactl-Vertx library](https://github.com/jaccomoc/jactl-vertx) provides some basic Vert.x integration capabilities.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaccomoc%2Fjactl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaccomoc%2Fjactl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaccomoc%2Fjactl/lists"}