{"id":13461353,"url":"https://github.com/cosmos72/gomacro","last_synced_at":"2025-05-14T19:02:38.470Z","repository":{"id":37906876,"uuid":"82091206","full_name":"cosmos72/gomacro","owner":"cosmos72","description":"Interactive Go interpreter and debugger with REPL, Eval, generics and Lisp-like macros","archived":false,"fork":false,"pushed_at":"2024-07-27T22:46:36.000Z","size":15850,"stargazers_count":2210,"open_issues_count":50,"forks_count":96,"subscribers_count":31,"default_branch":"master","last_synced_at":"2025-04-03T02:41:25.088Z","etag":null,"topics":["debugger","eval","generics","golang","interpreter","macros","repl"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cosmos72.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":"2017-02-15T18:15:04.000Z","updated_at":"2025-03-31T12:31:34.000Z","dependencies_parsed_at":"2024-06-18T12:30:01.337Z","dependency_job_id":"19c7ebdf-69ca-4a63-b41c-2c024b6921f8","html_url":"https://github.com/cosmos72/gomacro","commit_stats":{"total_commits":1253,"total_committers":17,"mean_commits":73.70588235294117,"dds":0.0159616919393456,"last_synced_commit":"2ff796e3da1057c005cb33c58e4fd1231cc315a6"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cosmos72%2Fgomacro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cosmos72%2Fgomacro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cosmos72%2Fgomacro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cosmos72%2Fgomacro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cosmos72","download_url":"https://codeload.github.com/cosmos72/gomacro/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248161259,"owners_count":21057552,"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":["debugger","eval","generics","golang","interpreter","macros","repl"],"created_at":"2024-07-31T11:00:35.644Z","updated_at":"2025-04-10T04:51:14.917Z","avatar_url":"https://github.com/cosmos72.png","language":"Go","readme":"## gomacro - interactive Go interpreter and debugger with generics and macros\n\ngomacro is an almost complete Go interpreter, implemented in pure Go. It offers both\nan interactive REPL and a scripting mode, and does not require a Go toolchain at runtime\n(except in one very specific case: import of a 3\u003csup\u003erd\u003c/sup\u003e party package at runtime).\n\nIt has two dependencies beyond the Go standard library:\n\u003ca href=\"https://github.com/peterh/liner\"\u003egithub.com/peterh/liner\u003c/a\u003e\nand\n\u003ca href=\"https://golang.org/x/tools/go/packages\"\u003egolang.org/x/tools/go/packages\u003c/a\u003e\n\nGomacro can be used as:\n* a standalone executable with interactive Go REPL, line editing and code completion:\n  just run `gomacro` from your command line, then type Go code. Example:\n    ```\n    $ gomacro\n    [greeting message...]\n\n    gomacro\u003e import \"fmt\"\n    gomacro\u003e fmt.Println(\"hello, world!\")\n    hello, world!\n    14      // int\n    \u003cnil\u003e   // error\n    gomacro\u003e\n    ```\n  press TAB to autocomplete a word, and press it again to cycle on possible completions.\n\n  Line editing follows mostly Emacs: Ctrl+A or Home jumps to start of line,\n  Ctrl+E or End jumps to end of line, Ald+D deletes word starting at cursor...\n  For the full list of key bindings, see https://github.com/peterh/liner\n\n* a tool to experiment with Go **generics**: see [Generics](#generics)\n\n* a Go source code debugger: see [Debugger](#debugger)\n\n* an interactive tool to make science more productive and more fun.\n  If you use compiled Go with scientific libraries (physics, bioinformatics, statistics...)\n  you can import the same libraries from gomacro REPL (immediate on Linux and Mac OS X,\n  requires restarting on other platforms,\n  see [Importing packages](#importing-packages) below), call them interactively,\n  inspect the results, feed them to other functions/libraries, all in a single session.\n  The imported libraries will be **compiled**, not interpreted,\n  so they will be as fast as in compiled Go.\n\n  For a graphical user interface on top of gomacro, see [Gophernotes](https://github.com/gopherdata/gophernotes).\n  It is a Go kernel for Jupyter notebooks and nteract, and uses gomacro for Go code evaluation.\n\n* a library that adds Eval() and scripting capabilities to your Go programs in few lines\n  of code:\n\t```go\n\tpackage main\n\timport (\n\t\t\"fmt\"\n\t\t\"reflect\"\n\t\t\"github.com/cosmos72/gomacro/fast\"\n\t)\n\tfunc RunGomacro(toeval string) reflect.Value {\n\t\tinterp := fast.New()\n\t\tvals, _ := interp.Eval(toeval)\n\t\t// for simplicity, only use the first returned value\n\t\treturn vals[0].ReflectValue()\n\t}\n\tfunc main() {\n\t\tfmt.Println(RunGomacro(\"1+1\"))\n\t}\n\t```\n  Also, [github issue #13](https://github.com/cosmos72/gomacro/issues/13) explains\n  how to have your application's functions, variable, constants and types\n  available in the interpreter.\n\n  Note: gomacro license is [MPL 2.0](LICENSE), which imposes some restrictions\n  on programs that use gomacro.\n  See [MPL 2.0 FAQ](https://www.mozilla.org/en-US/MPL/2.0/FAQ/) for common questions\n  regarding the license terms and conditions.\n\n* a way to execute Go source code on-the-fly without a Go compiler:\n  you can either run `gomacro FILENAME.go` (works on every supported platform)\n\n  or you can insert a line `#!/usr/bin/env gomacro` at the beginning of a Go source file,\n  then mark the file as executable with `chmod +x FILENAME.go` and finally execute it\n  with `./FILENAME.go` (works only on Unix-like systems: Linux, *BSD, Mac OS X ...)\n\n* a Go code generation tool:\n  gomacro was started as an experiment to add Lisp-like macros to Go, and they are\n  extremely useful (in the author's opinion) to simplify code generation.\n  Macros are normal Go functions, they are special only in one aspect:\n  they are executed **before** compiling code, and their input and output **is** code\n  (abstract syntax trees, in the form of go/ast.Node)\n\n  Don't confuse them with C preprocessor macros: in Lisp, Scheme and now in Go,\n  macros are regular functions written in the same programming language\n  as the rest of the source code. They can perform arbitrary computations\n  and call any other function or library: they can even read and write files,\n  open network connections, etc... as a normal Go function can do.\n\n  See [doc/code_generation.pdf](https://github.com/cosmos72/gomacro/blob/master/doc/code_generation.pdf)\n  for an introduction to the topic.\n\n## Installation\n\n### Prerequites\n\n- [Go 1.18+](https://golang.org/doc/install)\n\n### Supported platforms\n\nGomacro is pure Go, and in theory it should work on any platform supported by the Go compiler.\nThe following combinations are tested and known to work:\n\n- Linux: amd64, 386, arm64, arm, mips, ppc64le\n- Mac OS X: amd64, 386 (386 binaries running on amd64 system)\n- Windows: amd64, 386\n- FreeBSD: amd64, 386\n- Android: arm64, arm (tested with [Termux](https://termux.com/) and the Go compiler distributed with it)\n\n### How to install\n\n  The command\n  ```\n  go install github.com/cosmos72/gomacro@latest\n  ```\n  downloads, compiles and installs gomacro and its dependencies\n\n## Current Status\n\nAlmost complete.\n\nThe main limitations and missing features are:\n\n* importing 3\u003csup\u003erd\u003c/sup\u003e party libraries at runtime currently only works on Linux, Mac OS X and *BSD.\n  On other systems as Windows and Android it is cumbersome and requires recompiling - see [Importing packages](#importing-packages).\n* when importing packages, both from standard library or from 3\u003csup\u003erd\u003c/sup\u003e party libraries, generics are not imported.\n* defining generic functions and types in interpreted code is experimental and incomplete - see [Generics](#generics)\n* conversions from/to unsafe.Pointer are not supported.\n* some corner cases using interpreted interfaces, as interface -\u003e interface type assertions and type switches, are not implemented yet.\n* some corner cases using recursive types may not work correctly.\n* goto can only jump backward, not forward\n* out-of-order code is under testing - some corner cases, as for example out-of-order declarations\n  used in keys of composite literals, are not supported.\n  Clearly, at REPL code is still executed as soon as possible, so it makes a difference mostly\n  if you separate multiple declarations with ; on a single line. Example: `var a = b; var b = 42`\\\n  Support for \"batch mode\" is in progress - it reads as much source code as possible before executing it,\n  and it's useful mostly to execute whole files or directories.\n\nThe [documentation](doc/) also contains the [full list of features and limitations](doc/features-and-limitations.md)\n\n## Extensions\n\nCompared to compiled Go, gomacro supports several extensions:\n\n* an integrated debugger, see [Debugger](#debugger)\n\n* configurable special commands. Type `:help` at REPL to list them,\n  and see [cmd.go:37](https://github.com/cosmos72/gomacro/blob/master/fast/cmd.go#L37)\n  for the documentation and API to define new ones.\n\n* untyped constants can be manipulated directly at REPL. Examples:\n    ```\n\tgomacro\u003e 1\u003c\u003c100\n\t{int 1267650600228229401496703205376}\t// untyped.Lit\n\tgomacro\u003e const c = 1\u003c\u003c100; c * c / 100000000000\n\t{int 16069380442589902755419620923411626025222029937827}\t// untyped.Lit\n\t```\n  This provides a handy arbitrary-precision calculator.\n\n  Note: operations on large untyped integer constants are always exact,\n  while operations on large untyped float constants are implemented with `go/constant.Value`,\n  and are exact as long as both numerator and denominator are \u003c= 5e1232.\n\n  Beyond that, `go/constant.Value` switches from `*big.Rat` to `*big.Float`\n  with precision = 512, which can accumulate rounding errors.\n\n  If you need **exact** results, convert the untyped float constant to `*big.Rat`\n  (see next item) before exceeding 5e1232.\n\n* untyped constants can be converted implicitly to `*big.Int`, `*big.Rat` and `*big.Float`. Examples:\n    ```go\n\timport \"math/big\"\n\tvar i *big.Int = 1\u003c\u003c1000                 // exact - would overflow int\n\tvar r *big.Rat = 1.000000000000000000001 // exact - different from 1.0\n\tvar s *big.Rat = 5e1232                  // exact - would overflow float64\n\tvar t *big.Rat = 1e1234                  // approximate, exceeds 5e1232\n\tvar f *big.Float = 1e646456992           // largest untyped float constant that is different from +Inf\n    ```\n  Note: every time such a conversion is evaluated, it creates a new value - no risk to modify the constant.\n\n  Be aware that converting a huge value to string, as typing `f` at REPL would do, can be very slow.\n\n* zero value constructors: for any type `T`, the expression `T()`\n  returns the zero value of the type\n\n* macros, quoting and quasiquoting: see\n  [doc/code_generation.pdf](https://github.com/cosmos72/gomacro/blob/master/doc/code_generation.pdf)\n\nand slightly relaxed checks:\n\n* unused variables and unused return values never cause errors\n\n## Examples\n\nSome short, notable examples - to run them on non-Linux platforms, see [Importing packages](#importing-packages) first.\n\n### plot mathematical functions\n\n* install libraries: `go get gonum.org/v1/plot gonum.org/v1/plot/plotter gonum.org/v1/plot/vg`\n* start the interpreter: `gomacro`\n* at interpreter prompt, paste the whole Go code listed at https://github.com/gonum/plot/wiki/Example-plots#functions\n  (the source code starts after the picture under the section \"Functions\", and ends just before the section \"Histograms\")\n* still at interpreter prompt, enter `main()`\n  If all goes well, it will create a file named \"functions.png\" in current directory containing the plotted functions.\n\n### simple mandelbrot web server\n\n* install libraries: `go get github.com/sverrirab/mandelbrot-go`\n* chdir to mandelbrot-go source folder: `cd; cd go/src/github.com/sverrirab/mandelbrot-go`\n* start interpreter with arguments: `gomacro -i mbrot.go`\n* at interpreter prompt, enter `init(); main()`\n* visit http://localhost:8090/\n  Be patient, rendering and zooming mandelbrot set with an interpreter is a little slow.\n\nFurther examples are listed by [Gophernotes](https://github.com/gopherdata/gophernotes/#example-notebooks-dowload-and-run-them-locally-follow-the-links-to-view-in-github-or-use-the-jupyter-notebook-viewer)\n\n## Importing packages\n\nGomacro supports the standard Go syntax `import`, including package renaming. Examples:\n```go\nimport \"fmt\"\nimport (\n    \"io\"\n    \"net/http\"\n    r \"reflect\"\n)\n```\nThird party packages - i.e. packages not in Go standard library - can also be imported with the same syntax.\n\nExtension: unpublished packages can also be imported from a local filesystem directory (implemented on 2022-05-28). Supported syntaxes are:\n```go\nimport (\n     \".\"                             // imports the package in current directory\n     \"..\"                            // imports the package in parent directory\n     \"./some/relative/path\"          // \"./\"  means relative to current directory\n     \"../some/other/relative/path\"   // \"../\" means relative to parent directory\n     \"/some/absolute/path\"           // \"/\"   means absolute\n)\n```\n\nFor an import to work, you usually need to follow its installation procedure: sometimes there are additional prerequisites to install, and the typical command `go get PACKAGE-PATH` may or may not be needed.\n\nThe next steps depend on the system you are running gomacro on:\n\n### Linux, Mac OS X and *BSD\n\nIf you are running gomacro on Linux, Mac OS X or *BSD, `import` will then just work:\nit will automatically download, compile and import a package. Example:\n```\n$ gomacro\n[greeting message...]\n\ngomacro\u003e import ( \"gonum.org/v1/gonum/floats\"; \"gonum.org/v1/plot\" )\n// debug: running \"go get gonum.org/v1/plot gonum.org/v1/gonum/floats\" ...\ngo: downloading gonum.org/v1/gonum v0.12.0\ngo: downloading gonum.org/v1/plot v0.12.0\n[ more \"go: downloading \" messages for dependencies...]\ngo: added gonum.org/v1/gonum v0.12.0\ngo: added gonum.org/v1/plot v0.12.0\n// debug: running \"go mod tidy\" ...\ngo: downloading golang.org/x/exp v0.0.0-20220827204233-334a2380cb91\ngo: downloading github.com/go-fonts/latin-modern v0.2.0\ngo: downloading rsc.io/pdf v0.1.1\ngo: downloading github.com/go-fonts/dejavu v0.1.0\n// debug: compiling plugin \"/home/max/go/src/gomacro.imports/gomacro_pid_44092/import_1\" ...\n\ngomacro\u003e floats.Sum([]float64{1,2,3})\n6       // float64\n```\n\nNote: internally, gomacro will compile and load a **single** Go plugin containing the exported declarations\nof all the packages listed in `import ( ... )`.\n\nThe command `go mod tidy` is automatically executed before compiling the plugin, and it tries - among other things -\nto resolve any version conflict due to different versions of the same package being imported directly\n(i.e. listed in `import ( ... )`) or indirectly (i.e. as a required dependency).\n\nGo plugins are currently supported only on Linux and Mac OS X.\n\n**WARNING** On Mac OS X, **never** execute `strip gomacro`: it breaks plugin support,\n            and loading third party packages stops working.\n\n\n### Other systems\n\nOn all other systems as Windows, Android and *BSD you can still use `import`,\nbut there are more steps: you need to manually download the package,\nand you also need to recompile gomacro after the `import` (it will tell you).\nExample:\n```\n$ go get gonum.org/v1/plot\n$ gomacro\n[greeting message...]\n\ngomacro\u003e import \"gonum.org/v1/plot\"\n// warning: created file \"/home/max/go/src/github.com/cosmos72/gomacro/imports/thirdparty/gonum_org_v1_plot.go\", recompile gomacro to use it\n```\n\nNow quit gomacro, recompile and reinstall it:\n```\ngomacro\u003e :quit\n$ go install github.com/cosmos72/gomacro\n```\n\nFinally restart it. Your import is now linked **inside** gomacro and will work:\n```\n$ gomacro\n[greeting message...]\n\ngomacro\u003e import \"gonum.org/v1/plot\"\ngomacro\u003e plot.New()\n\u0026{...} // *plot.Plot\n\u003cnil\u003e  // error\n```\n\nNote: if you need several packages, you can first `import` all of them,\nthen quit and recompile gomacro only once.\n\n## Generics\n\ngomacro contains two alternative, experimental versions of Go generics:\n\n* the first version is modeled after C++ templates, and is appropriately named \"C++ style\"\\\n  See [doc/generics-c++.md](doc/generics-c++.md) for how to enable and use them.\n\n* the second version is named \"contracts are interfaces\" - or more briefly \"CTI\".\n  It is modeled after several preliminary proposals for Go generics,\n  most notably Ian Lance Taylor's [Type Parameters in Go](https://github.com/golang/proposal/blob/master/design/15292/2013-12-type-params.md)\n  It has some additions inspired from [Haskell generics](https://wiki.haskell.org/Generics)\n  and original contributions from the author - in particular to create a simpler alternative to\n  [Go 2 contracts](https://go.googlesource.com/proposal/+/master/design/go2draft-contracts.md)\n\n  For their design document and reasoning behind some of the design choices, see [doc/generics-cti.md](doc/generics-cti.md)\n\nThe second version of generics \"CTI\" is enabled by default in gomacro.\n\nThey are in beta status, and at the moment only generic types and functions are supported.\nSyntax and examples:\n```go\n// declare a generic type with two type arguments T and U\ntype Pair#[T,U] struct {\n\tFirst T\n\tSecond U\n}\n\n// instantiate the generic type using explicit types for T and U,\n// and create a variable of such type.\nvar pair Pair#[complex64, struct{}]\n\n// equivalent:\npair := Pair#[complex64, struct{}] {}\n\n// a more complex example, showing higher-order functions\nfunc Transform#[T,U](slice []T, trans func(T) U) []U {\n\tret := make([]U, len(slice))\n\tfor i := range slice {\n\t\tret[i] = trans(slice[i])\n\t}\n\treturn ret\n}\nTransform#[string,int] // returns func([]string, func(string) int) []int\n\n// returns []int{3, 2, 1} i.e. the len() of each string in input slice:\nTransform#[string,int]([]string{\"abc\",\"xy\",\"z\"}, func(s string) int { return len(s) })\n```\nContracts specify the available methods of a generic type.\nFor simplicity, they do not introduce a new syntax or new language concepts:\ncontracts are just (generic) interfaces.\nWith a tiny addition, actually: the ability to optionally indicate the receiver type.\n\nFor example, the contract specifying that values of type `T` can be compared with each other\nto determine if the first is less, equal or greater than the second is:\n```Go\ntype Comparable#[T] interface {\n\t// returns -1 if a is less than b\n\t// returns  0 if a is equal to b\n\t// returns  1 if a is greater than b\n\tfunc (a T) Cmp(b T) int\n}\n```\nA type `T` implements `Comparable#[T]` if it has a method `func (T) Cmp(T) int`.\nThis interface is carefully chosen to match the existing methods of\n`*math/big.Float`, `*math/big.Int` and `*math/big.Rat`.\nIn other words, `*math/big.Float`, `*math/big.Int` and `*math/big.Rat` already implement it.\n\nWhat about basic types as `int8`, `int16`, `int32`, `uint`... `float*`, `complex*` ... ?\nGomacro extends them, automatically adding many methods equivalent to the ones declared\non `*math/big.Int` to perform arithmetic and comparison, including `Cmp` which is\ninternally defined as (no need to define it yourself):\n```Go\nfunc (a int) Cmp(b int) int {\n\tif a \u003c b {\n\t\treturn -1\n\t} else if a \u003e b {\n\t\treturn 1\n\t} else {\n\t\treturn 0\n\t}\n}\n```\nThus the generic functions `Min` and `Max` can be written as\n```Go\nfunc Min#[T: Comparable] (a, b T) T {\n\tif a.Cmp(b) \u003c 0 { // also \u003c= would work\n\t\treturn a\n\t}\n\treturn b\n}\nfunc Max#[T: Comparable] (a, b T) T {\n\tif a.Cmp(b) \u003e 0 { // also \u003e= would work\n\t\treturn a\n\t}\n\treturn b\n}\n```\nWhere the syntax `#[T: Comparable]` or equivalently `#[T: Comparable#[T]]`\nindicates that `T` must satisfy the contract (implement the interface) `Comparable#[T]`\n\nSuch functions `Min` and `Max` will then work automatically for every type `T`\nthat satisfies the contract (implements the interface) `Comparable#[T]`:\\\nall basic integers and floats, plus `*math/big.Float`, `*math/big.Int` and `*math/big.Rat`,\nplus every user-defined type `T` that has a method `func (T) Cmp(T) int`\n\nIf you do not specify the contract(s) that a type must satisfy, generic functions\ncannot access the fields and methods of a such type, which is then treated\nas a \"black box\", similarly to `interface{}`.\n\nTwo values of type `T` can be added if `T` has an appropriate method.\nBut which name and signature should we choose to add values?\nCopying again from `math/big`, the method we choose is `func (T) Add(T,T) T`\nIf receiver is a pointer, it will be set to the result - in any case,\nthe result will also be returned.\nSimilarly to `Comparable`, the contract `Addable` is then\n```Go\ntype Addable#[T] interface {\n\t// Add two values a, b and return the result.\n\t// If recv is a pointer, it must be non-nil\n\t// and it will be set to the result\n\tfunc (recv T) Add(a, b T) T\n}\n```\nWith such a contract, a generic function `Sum` is quite straightforward:\n```Go\nfunc Sum#[T: Addable] (args ...T) T {\n\t// to create the zero value of T,\n\t// one can write 'var sum T' or equivalently 'sum := T()'\n\t// Unluckily, that's not enough for math/big numbers, which require\n\t// the receiver of method calls to be created with a function `New()`\n\t// Once math/big numbers have such method, the following\n\t// will be fully general - currently it works only on basic types.\n\tsum := T().New()\n\n\tfor _, elem := range args {\n\t\t// use the method T.Add(T, T)\n\t\t//\n\t\t// as an optimization, relevant at least for math/big numbers,\n\t\t// also use sum as the receiver where result of Add will be stored\n\t\t// if the method Add has pointer receiver.\n\t\t//\n\t\t// To cover the case where method Add has instead value receiver,\n\t\t// also assign the returned value to sum\n\t\tsum = sum.Add(sum, elem)\n\t}\n\treturn sum\n}\nSum#[int]         // returns func(...int) int\nSum#[int] (1,2,3) // returns int(6)\n\nSum#[complex64]                 // returns func(...complex64) complex64\nSum#[complex64] (1.1+2.2i, 3.3) // returns complex64(4.4+2.2i)\n\nSum#[string]                         // returns func(...string) string\nSum#[string](\"abc.\",\"def.\",\"xy\",\"z\") // returns \"abc.def.xyz\"\n\n```\nPartial and full specialization of generics is **not** supported in CTI generics,\nboth for simplicity and to avoid accidentally providing Turing completeness at compile-time.\n\nInstantiation of generic types and functions is on-demand.\n\nCurrent limitations:\n* type inference on generic arguments #[...] is not yet implemented,\n  thus generic arguments #[...] must be explicit.\n* generic methods are not yet implemented.\n* types are not checked to actually satisfy contracts.\n\n## Debugger\n\nSince version 2.6, gomacro also has an integrated debugger.\nThere are three ways to enter it:\n* hit CTRL+C while interpreted code is running.\n* type `:debug STATEMENT-OR-FUNCTION-CALL` at the prompt.\n* add a statement (an expression is not enough) `\"break\"` or `_ = \"break\"` to your code, then execute it normally.\n\nIn all cases, execution will be suspended and you will get a `debug\u003e` prompt, which accepts the following commands:\\\n`step`, `next`, `finish`, `continue`, `env [NAME]`, `inspect EXPR`, `list`, `print EXPR-OR-STATEMENT`\n\nAlso,\n* commands can be abbreviated.\n* `print` fully supports expressions or statements with side effects, including function calls and modifying local variables.\n* `env` without arguments prints all global and local variables.\n* an empty command (i.e. just pressing enter) repeats the last command.\n\nOnly interpreted statements can be debugged: expressions and compiled code will be executed, but you cannot step into them.\n\nThe debugger is quite new, and may have some minor glitches.\n\n## Why it was created\n\nFirst of all, to experiment with Go :)\n\nSecond, to simplify Go code generation tools (keep reading for the gory details)\n\n---\n\nProblem: \"go generate\" and many other Go tools automatically create\nGo source code from some kind of description - usually an interface\nspecifications as WSDL, XSD, JSON...\n\nSuch specification may be written in Go, for example when creating JSON\nmarshallers/unmarshallers from Go structs, or in some other language,\nfor example when creating Go structs from JSON sample data.\n\nIn both cases, a variety of external programs are needed to\ngenerate Go source code: such programs need to be installed\nseparately from the code being generated and compiled.\n\nAlso, Go is currently lacking generics (read: C++-like templates)\nbecause of the rationale \"we do not yet know how to do them right,\nand once you do them wrong everybody is stuck with them\"\n\nThe purpose of Lisp-like macros is to execute arbitrary code\nwhile compiling, **in particular** to generate source code.\n\nThis makes them very well suited (although arguably a bit low level)\nfor both purposes: code generation and C++-like templates, which\nare a special case of code generation - for a demonstration of how\nto implement C++-like templates on top of Lisp-like macros,\nsee for example the project https://github.com/cosmos72/cl-parametric-types\nfrom the same author.\n\nBuilding a Go interpreter that supports Lisp-like macros,\nallows to embed all these code-generation activities\ninto regular Go source code, without the need for external programs\n(except for the interpreter itself).\n\nAs a free bonus, we get support for Eval()\n\n## LEGAL\n\nGomacro is distributed under the terms of [Mozilla Public License 2.0](LICENSE)\nor any later version.\n","funding_links":[],"categories":["Go","\u003ca id=\"324874bb7c3ead94eae6f1fa1af4fb68\"\u003e\u003c/a\u003eDebug\u0026\u0026调试","\u003ca name=\"Go\"\u003e\u003c/a\u003eGo"],"sub_categories":["\u003ca id=\"d22bd989b2fdaeda14b64343b472dfb6\"\u003e\u003c/a\u003e工具"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcosmos72%2Fgomacro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcosmos72%2Fgomacro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcosmos72%2Fgomacro/lists"}