Goal, an embeddable scripting array language.
Yon 71ade205f4 improve AST formatting performance
Also remove redundant spacing in an application edge-case when there's a
closing paren left.
2025-10-21 11:16:23 +00:00
archive/zip basic readme info for extension packages 2025-06-16 09:57:51 +00:00
cmd flush buffered writer handles on exit (see issue #56) 2025-08-26 09:56:53 +00:00
docs a couple of fixes in help (see issue #53) 2025-08-16 16:28:51 +00:00
encoding/base64 no padding in base64 url encoding 2025-06-21 14:43:36 +00:00
examples examples/cmudict.goal: move misplaced ' 2025-02-17 08:40:44 +00:00
help a couple of fixes in help (see issue #53) 2025-08-16 16:28:51 +00:00
internal comment updates 2025-04-28 11:38:46 +00:00
io/fs follow various lint suggestions 2025-02-14 15:12:31 +00:00
lib lib/os.goal: replace x with equivalent 1 in fold-while 2025-06-12 08:32:56 +00:00
math basic readme info for extension packages 2025-06-16 09:57:51 +00:00
os flush buffered writer handles on exit (see issue #56) 2025-08-26 09:56:53 +00:00
scan follow various lint suggestions 2025-02-14 15:12:31 +00:00
scripts a couple of fixes in help (see issue #53) 2025-08-16 16:28:51 +00:00
testdata improve AST formatting performance 2025-10-21 11:16:23 +00:00
.gitignore benchmark refactorings & add benchstats.sh script 2025-02-10 09:03:54 +00:00
adverbs.go fast-path for =' for use in generic code 2025-04-24 09:17:27 +00:00
adverbspecial.go fast-path for =' for use in generic code 2025-04-24 09:17:27 +00:00
amend.go amend dict: minor code & error message tweaks 2025-04-11 15:13:26 +00:00
amendspecial.go amend: refactorings & renamings 2025-03-07 08:41:16 +00:00
apply.go Fix edge-case i[] (see issue #55) 2025-08-20 14:32:35 +00:00
arithd.go arithd.go: move specializations to bottom 2025-02-24 16:51:36 +00:00
arithm.go rename i2len into posi2len; new i2len 2025-02-25 11:36:08 +00:00
arrays.go arrays.go: move some code around & comments 2025-03-02 10:44:30 +00:00
ast.go improve AST formatting performance 2025-10-21 11:16:23 +00:00
benchs_test.go vm.go: small tweak & comment 2025-03-06 08:55:53 +00:00
CHANGES.md extend time to accept extra tzdata or offset location argument 2025-10-19 09:27:23 +00:00
cmpsearch.go optimize +' *' and so on 2025-03-01 12:09:08 +00:00
compiler.go improve AST formatting performance 2025-10-21 11:16:23 +00:00
context.go update Version and CHANGES for release 2025-09-15 14:41:41 +00:00
context_test.go follow various lint suggestions 2025-02-14 15:12:31 +00:00
Credits.md minor updates to match the FAQ 2024-08-25 07:36:54 +00:00
csv.go adverbs: refactorings & comments 2025-02-28 16:39:39 +00:00
dicts.go amend: refactorings & renamings 2025-03-07 08:41:16 +00:00
encdec.go minor refactoring 2025-03-02 08:01:12 +00:00
errors.go use new immut function to replace many MarkImmutable 2025-01-23 18:33:12 +00:00
fills.go various small refactorings 2025-02-16 08:59:11 +00:00
flip.go flip.go: remove redundant assignment 2025-03-01 16:21:07 +00:00
fns.go support (r;...)#t form too 2025-08-14 08:19:18 +00:00
functions.go follow various lint suggestions 2025-02-14 15:12:31 +00:00
fuzz_test.go follow various lint suggestions 2025-02-14 15:12:31 +00:00
go.mod update random number generator: use math/rand/v2 2024-10-27 16:49:54 +00:00
group.go satisfy statickcheck warning (not a bug, though, but maybe clearer) 2025-03-15 07:13:46 +00:00
join.go refactor join code 2025-02-24 15:46:54 +00:00
json.go minor refactoring 2025-03-02 08:01:12 +00:00
less.go less.go: use generics and cmp 2025-03-02 08:26:22 +00:00
LICENSE add LICENSE 2022-12-26 10:21:43 +00:00
math.go amend: refactorings & renamings 2025-03-07 08:41:16 +00:00
norm.go amend dict: minor code & error message tweaks 2025-04-11 15:13:26 +00:00
opcode.go vm.go: minor cleanups 2025-03-02 10:57:06 +00:00
parser.go fix panic on invalid syntax ..[a:] (see issue #52) 2025-06-17 16:52:08 +00:00
parsev.go regexp.go: refactorings & comments 2025-02-27 15:22:25 +00:00
radix.go sorting code: minor tweaks and comment updates 2025-02-27 09:01:21 +00:00
rand.go minor refactoring 2025-03-02 08:01:12 +00:00
README.md add link to "Internationalization Puzzles" repos 2025-10-09 18:29:10 +00:00
refcount.go cleanups in array normalization code 2025-02-17 08:33:31 +00:00
regexp.go regexp.go: refactorings & comments 2025-02-27 15:22:25 +00:00
rt.go renamings: improve naming consistency 2025-02-21 16:07:02 +00:00
sfns.go support cut where r_S form too 2025-08-14 08:02:58 +00:00
sort.go cmpsearch.go: a few more refactorings 2025-02-27 10:15:47 +00:00
sort_test.go sorting code: minor tweaks and comment updates 2025-02-27 09:01:21 +00:00
stringer.go vm.go: minor cleanups 2025-03-02 10:57:06 +00:00
strings.go move fixed "c"$I code to separate function (see issue #53) 2025-08-16 17:42:42 +00:00
time.go extend time to accept extra tzdata or offset location argument 2025-10-19 09:27:23 +00:00
TODO TODO updates 2025-06-22 07:49:40 +00:00
unsafe.go refactor sorting and caching 2025-02-26 16:47:45 +00:00
utf8.go various minor refactorings & BCE hints 2025-02-22 15:45:26 +00:00
utils.go arrays.go: move some code around & comments 2025-03-02 10:44:30 +00:00
valstring.go renamings: improve naming consistency 2025-02-21 16:07:02 +00:00
value.go move code using unsafe package to separate file 2025-02-02 08:47:55 +00:00
variadics.go small simplification in ` and ´ code 2025-03-03 11:05:39 +00:00
vm.go vm.go: small tweak & comment 2025-03-06 08:55:53 +00:00

Goal

Goal is an embeddable array programming language with a bytecode interpreter, written in Go. The command line intepreter can execute scripts or run in interactive mode. Goal shines the most in common scripting tasks, like handling columnar data or text processing. It is also suitable for exploratory programming.

Install

To install the command line interpreter, you only need to have the go compiler installed (Go 1.22 or later required). There are no extra dependencies.

You can then build the intepreter with:

go build ./cmd/goal

You should now have a working goal executable in the current directory. Use the --help option for command-line usage.

Running goal without arguments opens the REPL. For a better experience using the REPL with the usual keyboard shortcuts, you can install the readline wrapper rlwrap program and then use instead rlwrap goal. The rlwrap program is available as a package on most systems.

SIMD optimization. On amd64, various operations will use vectorized SIMD assembly implementations by default, requiring SSE CPU extensions up to SSE4.2, representing a subset of the available instructions when GOAMD64 is set to v2. You may disable those optimizations by passing the -tags nosse4 option to the build command.

Extensions. The default build only includes the os extension package. The -tags full option enables all standard extension packages (including extra math functions). For more fine-grained control, see instructions in cmd/goal directory.

Links

Examples

Aside from the examples found in the documentation, there are various places with code written in Goal:

  • The examples directory contains AoC solutions and a few other short scripts.
  • The lib directory contains various library utilities. You might want to add it to the GOALLIB environment variable to simplify import paths.
  • The testdata/scripts directory contains various example scripts used in regression testing; they come along an expected result after a /RESULT: comment.
  • The scripts directory contains a few code generation scripts.
  • The ip repos by @bstrat contains solutions to "Internationalization Puzzles".

Here's how a Goal script looks like:

/ Handle command-line arguments: script name + optional file.
(2<#ARGS)and:error"USAGE: goal wordstats.goal [file]"
/ Read STDIN or filename given by last argument; lowercase everything.
src:_ 'read?[1=#ARGS;STDIN;*|ARGS]
/ Get all words (Unicode letters + dashes).
words:rx/[\p{L}-]+/[src;-1]
/ Print number of words; number of distinct words; five most frequent words.
say(#words;#dw:?words;5@!>dw!=%words)

See the tutorial for detailed explanations on a similar example with syntax highlighting!

Tooling

Community

Contribute

User testing and bug reports are welcome! Feel free to open an issue, send a pull request, or send a patch by email.

See the implementation notes to get started about the internals. You might want to check problems.md and old issues before submitting a new issue.