Skip to content

Releases: skx/yal

v0.16.0

14 Apr 19:23
@skx skx
6c624f7
Compare
Choose a tag to compare

This release was mostly about introspection and interoperability.

  • Implement (builtins), (specials), and (stdlib).
  • Updated (join) to take an optional second parameter.
    • This is inserted between the list values as part of the flattening.
  • Added (find), (flatten), and (occurrences) to stdlib/stdlib/lists.lisp.
  • Allow functions to have default values for arguments.
    • Introduced in #131, after being reported in #130.
    • (inc) and (dec) have been updated to use this support.
  • Implemented (body) and (source) to return the body/source of a lisp primitive.
    • Implemented in #132, after inspiration from l1 in #115.
  • Added (exit) and (forever) as special forms.
    • Implemented in #135, after being reported in #133.
  • Added ($ "ls -l|wc -l") as another special.
    • This allows running shell commands and returns the output as either a string, or a list.
    • Implemented in #136, after being reported in #134.

v0.15.1

01 Mar 07:37
@skx skx
Compare
Choose a tag to compare

Identical to v0.15.0, but with updated CI that should hopefully build binaries.

v0.15.0

27 Feb 16:54
@skx skx
51e0a83
Compare
Choose a tag to compare
  • Updated the LSP support to only calculate possible completions once.
    • Since we only complete on the standard library this can't change.
    • Reported in #111, resolved in #112.
  • Updated our CI process to run the lisp-specific test-cases on PRs
    • Implemented in #113
  • Added string<, string=, and similar methods.
    • Implemented in #116.
  • Added flexible sort-by method
    • Also implemented in #116.
  • Implemented cos, sin, and tan, as well as variants along with pi.
    • Implemented in #117.
  • Added extra argument testing to (random) and (base)
    • With test-cases and fuzz-testing for more fixes.
    • Implemented in #118.
  • Fixed crashes with empty special forms, e.g. "(print (do))" and (print (let*())).
    • Fuzzing now looks good, though of course it is impossible to say:
      • fuzz: elapsed: 19h4m10s, execs: 5319853 (303/sec), new interesting: 492 (total: 4095)
      • fuzz: elapsed: 19h4m12s, execs: 5319918 (40/sec), new interesting: 492 (total: 4095)
  • Allow loading a file with "(require 'foo)"
    • This will load foo.yal, and return nil if that file is not present.
    • Reported in #114, and implemented in #119.
  • Added stack:push, stack:pop, etc.
    • Implemented in #120.
  • Added a config-package, holding helpers for STDIN/STDOUT.
    • These are used by (read) and (print)
    • Implemented in #123, after a broken attempt in #121.
    • Added STDERR and a -debug flag in #125.
  • Added (version).
    • Reported in #122, implemented in #124.
  • Added hash/digest functions in #126
    • (md5), (sha1), and (sha256).
  • Hashes are converted to strings with their keys sorted.
    • Implemented in #127
    • This allows the following code to return "true", as expected:
      • (eq { :name "Steve" :surname "Kemp" } { :surname "Kemp" :name "Steve" })

v0.14.0

30 Nov 17:58
@skx skx
fda7046
Compare
Choose a tag to compare

This release features the introduction of LSP (Language Server Protocol) support, allowing you to view the integrated help-text inside your editor/IDE.

Although the LSP protocol allows a lot of things to be done, in a portable fashion, we only support the two following things:

  • Display integrated help-information, on hover, for functions in the standard-library.
  • Provide auto-completion for all functions defined within the standard-library.

Further details, screenshots, and configuration samples are provided within LSP.md.

This release features no other changes, just the LSP additions which were requested in #108 and resolved in #109 .

v0.13.0

22 Nov 17:38
@skx skx
caf59f7
Compare
Choose a tag to compare

Welcome to the latest release of yal.

New Features

This release brings support for struct, which allows defining structures, with named fields.

Struct support is documented in our PRIMITIVES.md reference, but in brief you may define a structure and this will auto-generate several new methods operating upon that structure.

Sample usage might look something like this;

; define a new structure named "pet" with two fields
(struct pet name age)

; create an instance of that structure
(set! spot (struct "Spot" 4))

; Show details via the (auto-generated) access-methods.
(print "%s is %d" (pet.name spot) (pet.age spot))

Type checking works as you'd expect too.

Breaking Changes

The (let ..) special form was removed, instead use (let* ..).

Other Changes

This release features internal cleanups, simplifying our core evaluation method, and breaking out our special forms in a dedicated source-file:

ChangeLog

  • Implemented support for (struct)
    • This allows named objects, with fields, to be passed around and used.
    • Reported in #82, resolved in #93.
  • Reduce the number of times hash-values are evaluated.
    • This was reported in #95, and resolved in #96.
  • Simplified our eval
    • Moved our special-forms into eval/specials.go.
    • Simplified the logic of argument collection
    • Reported in #94, resolved in #97.
  • Updated (type) to return (foo) for a struct named .. foo!
    • Allow type checking of structure types too:
  • Updated the CI process to report errors when pull-requests are made against our repository.
    • Reported in #98, resolved in #102.
  • Remove support for (let ..).
    • This was reported in #100, and resolved in #103.
  • Resolved some issues found by the fuzzer.
  • Moved examples beneath examples/
  • Moved (env) from the core to the builtin-package.

Next Release

The next release will aim to add LSP support for our lisp dialect, as reported in #108 .

v0.12.0

12 Nov 14:06
@skx skx
508f7c2
Compare
Choose a tag to compare

This release features a whole number of changes, improvements, and additions compared to the previous one.

New Features

  • Introduced a character-type alongside our existing string/number/list types.
    • Reported in #64, resolved in #65.
  • Introduced the use of real format strings for printf and sprintf.
    • This forces the use of real types (print "My number is %d" 34).
    • Previously all values were output as strings, via %s.
    • Reported in #66, resolved in #67.
  • Added a REPL mode, as is traditional for lisp interpreters.
    • Reported in #70, closed in #73.
    • The REPL allows loading an init-file, if present:
      • Implemented in 5347f1c
      • An example .yalrc file was later added to the project.
  • Added support for binary and hexadecimal (numerical) literals.
    • Reported in #78, resolved in #79.
  • Added new list primitives intersection, member, and union.
  • Added the special form (symbol).
    • Reported in #84, resolved in #85.
  • Added substr.
    • Reported in #86, resolved in #88.
  • Implemented numerical conversion functions (base), and (number).
    • Reported in #80, resolved in #89.
  • Added a lot of test functions in lisp-tests.lisp.
    • Reported in #83, resolved in #91.

Changes

  • Aliased functions are reported as such when displayed by the CLI driver.
    • i.e. When you execute yal -h [regexp].
    • Reported in #68, resolved in #69.
  • Simplified the implementation of our main driver, main.go.
    • Reported in #71, closed in #72.
  • Added example sorting-routines in 2924190
    • insertion-sort, written in lisp.
    • quick-sort, written in lisp.
    • And a benchmark showing which was faster.
    • Code is present in sorting.lisp.
  • Moved the implementation of (nth ..) from lisp to the golang core.
    • This was done for speed-reasons when it became obvious it was a limiting factor in our sorting benchmark.
    • Reported in #75, closed in #76.
  • Updated our (append) to work in a way that makes more sense.
    • This was triggered by our sorting.lisp example file needing some work to run.
    • Reported in #74, closed in #77.
  • Document the usage of the rlwrap tool to provide completion to the REPL.
    • Reported in #81, resolved in #90.

Regressions?

None known.

Future Plans?

I'd like to take a stab at implementing structures, as reported in #82. But beyond that I have nothing specific scheduled, or planned.

Personally I'm using this application to provide an embedded scripting language for a hardware-related project, some of the code there could be moved here, but I've not yet decided if that makes sense. (Specifically I'm thinking about operations working on bits, and logical operations such as and, or, xor.)

v0.11.1

21 Oct 19:42
@skx skx
76140cd
Compare
Choose a tag to compare

This point-release was primarily issued so that we can serve binaries for the Microsoft Windows platform.

Compared to the significant changes in the v0.11.0 release this is a point-release, at best.

Changes

  • Fixed to build upon Windows, in #60.
  • Allow alias to work on pairs of new/old symbols.
    • e.g. (alias a print b print .. x print)
  • Updated our standard-library, breaking it out into a series of themed files.
    • This makes it nicer to look at, and also more extensible for the future.
    • Reported in #61, closed in #63.

v0.11.0

17 Oct 17:12
@skx skx
Compare
Choose a tag to compare

This release features the addition of many new primitive functions, whether added to the golang core, or the standard library which is implemented in lisp itself.

We also restored test-coverage back to 100% in all our internal packages.

In brief the changes were:

  • Moved date/time functions into either "date:" or "time:" namespaces as appropriate.
    • Reported in #33, closed in #35.
  • Added new file functions (file:lines), (file:read), (file:stat), etc
    • Reported in #32, closed in #36.
  • Restored our test-coverage to 100%
    • Reported in #31, closed in #37.
  • Added a builtin function (alias) to alias functions.
    • (set! pr print) could have done the same thing, for example, but this makes intent clearer to read.
    • Reported in #38, closed in #38.
  • Added (directory:walk) to our standard-library.
    • This uses the new builtin (directory:entries) function.
    • Reported in #34, closed in #41.
  • Added (random) to choose a random integer.
    • Use that to implement (random:char), and (random:item)
    • Reported in #43, closed in #44.
  • Overhauled our README.md and documentation.
    • Reported in #40, closed in #42.
  • 100% consistency when functions are invoked with invalid counts of arguments
    • Implemented in #45.
  • Correctly pad hours, minutes, and seconds in the output of (hms)
    • Reported in #47, closed in #48.
  • Allow the use of regular expressions to select which help to view.
    • Reported in #50, closed in #54.
  • Allow writing to files, via (file:write ..)
    • Reported in #49, closed in #55.
  • Use (alias) to define (first) and (rest), rather than using duplication.
  • (range) now uses the upper bound inclusively.
    • This means (nat 10) and (seq 10) now stop at 10, not 9.
  • Added a new "-v" flag to our binary, to show our version.
    • Reported in #51, closed in #56.
  • Fixed the division function such that "(/ x)" is the same as 1/x.
    • reported in #52, closed in #57.
  • Allow (= .. ) (numerical equality test) to accept arbitrary arguments.
    • Reported in #53, resolved in #58.
  • Added (/= ..) function, for numerical inequality testing.
    • This returns true if all arguments are unique.
    • This returns false if any argument has been seen before.
    • Reported in #53, and resolved in #59.

Regressions

The only know regression is the failure to build this release upon Windows platforms, this was resolved in #60.

However I have still postponed the handling of #22:

  • Half of me thinks we leave as-is.
  • The other half of me thinks that we could add hacks.
    • But as noted they will spread, due to potentially arbitrarily deep nesting of scopes/environments.
  • Finally the third half of me thinks we could be even more explicit, via the use of some (upvalue ..)-like solution.
    • Explicit here means that we're being very explicit the author must mentally consider scopes, and adding a new form is more explicit than a magical third-argument to (set!..)

Future Plans

  • Nothing obvious springs to mind, though no doubt minor changes and additions will occur to me.

Feedback?

Something missing? A regression broke your build? Please file an issue.

v0.10.0

15 Oct 11:47
@skx skx
Compare
Choose a tag to compare

This release features the addition of many new primitive functions, whether added to the golang core, or the standard library which is implemented in lisp itself.

New Features

As noted there are a bunch of new functions available:

  • (date)
    • Returns the day of the week, and other fields.
    • Helpers are available (weekday), (day), (month), and (year).
  • (help)
    • This returns any available (optional) help for either our built-in, or lisp-provided functions.
    • The output of everything core is available via yal -h.
  • (time)
    • Returns the time as a list of integers.
    • Helpers are available (hour), (minute), (second), and (hms).
  • Some new list functions were added
    • (butlast), (drop), (every), (repeated), and (take).
  • Some new file/directory functions were added:
    • (glob "pattern") - Returns all filenames that match a pattern.
    • (directory? path) - Return true if the given path exists and is a directory.
    • (exists? path) - Return true if the given path exists.
    • (file? path) - Return true if the given path exists and is a file. (Or rather, is not a directory!)
  • The ability to execute commands upon the system via (shell).

Our standard library was broken into two files stdlib/yal.lisp and stdlib/mal.lisp.

Regressions

Unfortunately our test-coverage is no longer at 100% across all packages, but that will be corrected in the near future.

  • The built-in/special-form (let ..) has been removed, (let* ..) remains.
  • The built-in/special-form (begin ..) has been removed, use (do ..) instead.

Finally our internal "builtin" API changed, to allow golang-primitives to update the environment. This allowed moving (gensym), etc, from the core to the builtin-package.

Future Plans

The next release will build upon the increased I/O primitives available in this release, I think "slurp" will be rewritten with some new file primitives:

  • (file:read "/etc/passwd")
    • This will return the file contents, as a single string.
  • (file:lines "/etc/passwd")
    • This will return a list of strings, one for each line of the given file.
  • (file:stat "/etc/passwd")
    • This will return details about the given file/directory.
      • (file:size), (file:mode) can be written as helpers using that detail. Just like we have (ẁeekday) using details from (date).
  • (directory:walk) will allow invoking a function on every file beneath a path.
    • Using glob and string manipulation is fiddly to use for writing a path-traverser.

With these additions added I _ suspect_ "(hour)" will become "(time:hour)", and similar renaming for the date-based fields. We'll see.

Feedback?

Something missing? A regression broke your buiild? Please file an issue.

v0.9.0

01 Oct 14:21
@skx skx
Compare
Choose a tag to compare

This release focused upon increased compatibility with Mal, which meant allowing alternative ways of expressing things that had previously been possible in a niche way.

For example this is how we defined a factorial-function:

(define fact (lambda (n)
  (if (<= n 1)
    1
      (* n (fact (- n 1))))))

That is nice and clear, but using "define" and "lambda" might be confusing. So now we can write that in the way that a Mal user might expect and prefer:

(set! fact (fn* (n)
      (if (<= n 1)
        1
          (* n (fact (- n 1))))))

We've increased compatibility by adding expected standard-forms, such as fn*, let*, set!, and defmacro!. We've also updated the standard-library, which is written in lisp, to add some methods users might expected - for example false?, slurp, true?, vals, and contains?.

Test-coverage remains at 100%, and our fuzz-tester hasn't revealed any unexpected segfaults/panics.

Finally we updated our README.md file, and added (arch) and (os) methods, to allow conditional execution at run-time, based on environment. It is also possible to execute code upon the CLI without reading a file:

yal -e "(print (os))"