Git Product home page Git Product logo

rimu's Introduction

rimu's People

Contributors

ahdinosaur avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

rimu's Issues

Function closures

Is your feature request related to a problem? Please describe.
You should be able to return a closure function.

Describe the solution you'd like

let
  equals: (a) => (b) => a == b
in
  equals(0)
    - 0

Implementation details
At the moment, we return functions as values, without the environment they "close over". A function value should now have an environment attached, which will be used when evaluating.

Describe alternatives you've considered

Additional context

Block: SwitchAll

Describe the solution you'd like

Example:

switchAll
case x > 10
then "greater than ten"
case x > 20
then "greater than twenty"

Returns a list of all that match

TODO Checklist

  • Add to rimu-parse
    • Add unit test(s)
  • Add to rimu-eval
    • Add unit test(s)
  • Add spec tests
    • Use related JSON-e spec tests to start
  • Add to examples
    • Add example to playground
  • Add to docs
    • Check complete on roadmap

Describe alternatives you've considered

Additional context

Stdlib: MapValues

Describe the solution you'd like

Example:

mapValues
  object:
    a: 1
    b: 2
    c: 3
  each: (value, key) =>
    value + 1

TODO Checklist

  • Add to rimu-parse
    • Add unit test(s)
  • Add to rimu-eval
    • Add unit test(s)
  • Add spec tests
    • Use related JSON-e spec tests to start
  • Add to examples
    • Add example to playground
  • Add to docs
    • Check complete on roadmap

Describe alternatives you've considered

Additional context

Block: Switch

Describe the solution you'd like

Example:

switch
case os.name == "macos"
then "brew"
case os.name == "linux" && os.distribution == "debian"
then "apt"

Is not super important since nested if-then-else if-then-else if-then works too.

TODO Checklist

  • Add to rimu-parse
    • Add unit test(s)
  • Add to rimu-eval
    • Add unit test(s)
  • Add spec tests
    • Use related JSON-e spec tests to start
  • Add to examples
    • Add example to playground
  • Add to docs
    • Check complete on roadmap

Describe alternatives you've considered

Additional context

A possible change to syntax: wisp-y lists

Is your feature request related to a problem? Please describe.

With the current Rimu syntax, when you call a function as a block, you pass arguments to the function as a block list.

add
  - 10
  - 20

This is confusing in two ways:

  • At the moment, the arguments to the block function is a block. If it's a list, it's presumed to be a list of arguments. Otherwise a single value is interpreted as the first and only argument. Sometimes you pass a value to the block, and it's a list, and you expect that list to be the first and only argument.
  • The -'s look like minus signs. The visual difference between the dash as a list marker and the dash for a unary negation operator is so small. More difference in the syntax highlighting will help, but still.

Describe the solution you'd like

A new approach would be change how lists are handled.

A list is a bunch of blocks, one after another, on the same level of indentation.

(Or this becomes a new concept: a tuple. And list stays the same.)

So

add
  10
  20

(This is very similar to wisp)

Then the question becomes, what do we do when you want to have two separate lists, one after another?

In wisp, this is handled with the : marker.

So

concat
  : 
    "a"
    "b"
    "c"
  : 
    "d"
    "e"
    "f"

???

Open questions

  • How do we differentiate between a single indented block value and a block list with a single value?
let
  list:
    - "a"
in list
let
  list:
    "a"
in list

I'm not sure yet, so for now will let the back brain have a think. Unless anyone else has thoughts.

How might this be added to Rimu?

What are possible alternatives?

Additional context

Multi-line values and strings

Describe the solution you'd like

A design similar to:

(Draft documentation)

Rimu supports multi-line values with > and >"

>

A multi-line expression.

Identation is removed, newlines are removed.

story: >
  """Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Eleifend donec pretium
  vulputate sapien nec sagittis aliquam malesuada."""

""" is the multi-line string character.

>"

A multi-line string.

Identation is removed. Newlines are preserved.

story: >"
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Eleifend donec pretium
  vulputate sapien nec sagittis aliquam malesuada.

Describe alternatives you've considered or related projects

Additional context

Complete the core standard library

Is your feature request related to a problem? Please describe.

The Rimu standard library is incomplete.

Describe the solution you'd like

A core standard library based on: https://clojuredocs.org/quickref

This issue is to create other issues for the missing functions.

What are possible alternatives?

Additional context

  • Continuation of #17

Let expression?

let (a = 10, b = 20) { a + b }
let (
  a = 10,
  b = 20,
  c = 40,
) {
  a + b / c
}

OR

let a = 10, b = 20 { a + b }
let
  a = 10,
  b = 20,
  c = 40,
{
  a + b / c
}

Meta dev

  • license
  • code-of-conduct.md
  • github tags
  • contributing.md
  • changelog.md
  • releasing.md

Type literals?

$type: AptInstall
pkg: "vim"
$string: "vim"
fn add (a: Number, b: Number) => a + b
fn add (a: String, b: String) => a + b
fn add (a: List, b: List) => a + b

???

Start the Standard Library

Describe the solution you'd like

A core standard library based on: https://clojuredocs.org/quickref

At the moment, a function body can only be a Rimu expression. But for a standard library, we need to be able to access things in Rust-land, such as the length of a list's vec.

TODO Checklist

  • Change Value's Function into an enum
    • Existing case is Function::Rimu
    • New case is Function::Rust, where the enum references a Rust function.
  • Create rimu-stdlib crate
    • Create length function

Describe alternatives you've considered

Additional context

Stdlib: Filter

Describe the solution you'd like

Example:

filter
  list:
    - value: 10
    - value: 20
    - value: 30
  each: (item) => item.value > 15

TODO Checklist

  • Add to rimu-parse
    • Add unit test(s)
  • Add to rimu-eval
    • Add unit test(s)
  • Add spec tests
  • Add to examples
    • Add example to playground
  • Add to docs
    • Check complete on roadmap

Describe alternatives you've considered

Additional context

Syntax: let =

Is your feature request related to a problem? Please describe.

At the moment there's an overlap in how we use key:.

  1. Object keys
  2. Let assignments

Even though the two usages have different semantics (and different highlighting).

Describe the solution you'd like

Maybe instead of

message:
  let
    name: "Charlie"
  in
    "hello " + mood

We should do:

message:
  let
    name = "Charlie"
  in
    "hello " + mood

How might this be added to Rimu?

What are possible alternatives?

Or we keep the status quo.

Additional context

truthiness

do we even want to coerce values into booleans when evaluating an if?

what if that was a type error?

Function literal

Describe the solution you'd like

Example:

(x, y) => x + y

Or to within a block

$exec: (x, y) =>
  a: x + y
  b: x - y

Describe alternatives you've considered or related projects

Additional context

rimu-eval

keen to replace rhai with a tiny evaluator based on slac

also:

  • change Number so no more uints, ints, and floats: only big decimals

Block: Type

Describe the solution you'd like

Example:

- type set
  width: 10
  color: 4
- type rotate
  right: 18
- type move
  forward: 50

Where each $type identifier refers to a schema identifier.

TODO Checklist

  • Add to rimu-parse
    • Add unit test(s)
  • Add to rimu-eval
    • Add unit test(s)
  • Add spec tests
  • Add to examples
    • Add example to playground
  • Add to docs
    • Check complete on roadmap

Describe alternatives you've considered

Additional context

  • Depends on #22

Fix section in docs/index#use-cases about comparing to Nix (and Bazel)

Complex configs: [...] declarative package managers (Nix) [...] are complex enough to need functional config generation.

Hmm, but Nix already realizes this point, doesn't it? 👀

(i.e. there's no point in using Rimu within Nix, because you can already do everything within Nix)

https://www.reddit.com/r/rust/comments/17035r0/comment/k3jxyr5/

I think I'm trying to say something like "Rimu can do functional config generation like Nix". I'll think about how to say that better.

Playground: Click on output item to highlight corresponding Rimu code

Is your feature request related to a problem? Please describe.
Now with #42 done, each output value has a span to the corresponding Rimu code.

Describe the solution you'd like
When you click on an output item, the corresponding Rimu code is highlighted.

Something like https://lezer-playground.vercel.app/

Describe alternatives you've considered

Additional context

  • Will require being able to serialize and maintain a mapping from value spans to serialization spans. So custom serializers, not easy.

Use a bump / arena memory allocator

Is your feature request related to a problem? Please describe.
Since Rimu is a template language, all the objects allocated during evaluation can be de-allocated after the result is returned (serialized). This means no need for a garbage collector and no need even for a standard heap allocator. Rimu may benefit from a bump / arena allocator.

Describe the solution you'd like
Investigate using bumpaloo, or another bump / arena allocator.

Describe alternatives you've considered

Additional context

Block: Function

Describe the solution you'd like

Example:

fn [a, b]
do a + b

TODO Checklist

  • Add to rimu-parse
    • Add unit test(s)
  • Add to rimu-eval
    • Add unit test(s)
  • Add spec tests
  • Add to examples
    • Add example to playground
  • Add to docs
    • Check complete on roadmap

Describe alternatives you've considered

Additional context

Playground fails with `oom` error

Describe the bug
Playground fails with oom error

To Reproduce
Steps to reproduce the behavior:

  1. Keep using the playground
  2. Eventually will error
  3. In development, only stack I can see is __rg__oom

Expected behavior
You can keep using the playground without error.

Screenshots
Screenshot from 2023-09-21 11-35-37

Device (please complete the following information):

  • OS: Ubuntu Regolith
  • OS version: 20.04
  • If web,
    • Browser: Firefox

Additional context

Eval should return spanned values

Describe the solution you'd like

Eval should return spanned values.

Would be important for validating values against schemas and displaying good errors

Describe alternatives you've considered

Additional context

defining and calling functions

Operators:

  • $fn
  • $apply

but the question is: how do we "render" a Template::Function if we return a Value and there's no Value::Function?

reorganize crates

  • rimu-meta (previously rimu-report)
  • rimu-ast (block and expression ast)
  • rimu-parse (lexer and compiler, for both block and expr)
  • (rimu-format)
  • rimu-value
  • rimu-env
  • rimu-eval (evaluator, for both block and expr)
    • maybe includes env?
  • rimu
  • rimu-repl
  • (rimu-cli)

Stdlib: Map

Describe the solution you'd like

Example:

let
  pkgs:
    - "zsh"
    - "vim"
in
  map
    list: pkgs
    each: (pkg) =>
      command: "apt install ${pkg}" 

TODO Checklist

  • Add to rimu-parse
    • Add unit test(s)
  • Add to rimu-eval
    • Add unit test(s)
  • Add spec tests
    • Use related JSON-e spec tests to start
  • Add to examples
    • Add example to playground
  • Add to docs
    • Check complete on roadmap

Describe alternatives you've considered

Additional context

Evaluate Profile-Guided Optimization (PGO) and LLVM BOLT

Hi!

Recently I did many Profile-Guided Optimization (PGO) benchmarks on multiple projects (including static analysis tools and compilers like Rustc, Clang, Clangd, Clang Tidy, and many others) - the results are available here. So that's why I think it's worth trying to apply PGO to Rimu.

I can suggest the following things to do:

  • Evaluate PGO's applicability to Rimu tooling (like the command-line REPL).
  • If PGO helps to achieve better performance - add a note to Rimu's documentation about that. In this case, users and maintainers will be aware of another optimization opportunity for Rimu.
  • Provide PGO integration into the build scripts. It can help users and maintainers easily apply PGO for their own workloads.
  • Optimize prebuilt binaries with PGO.

Here are some examples of how PGO is already integrated into other projects' build scripts:

After PGO, I can suggest evaluating LLVM BOLT as an additional optimization step after PGO.

For the Rust projects, I recommend starting with cargo-pgo.

I understand that the project is in the earliest development stages so consider the issue like an idea for future improvements.

Is there a better syntax?

Is there a better syntax for Rimu? Could we better combine YAML (data) and LISP (code-as-data)?

I see wisp and I wonder if there's something to use here.

One idea would be to only use : when describing data, and the block operations become special syntax.

For example:

let
  pkgs:
    - "zsh"
    - "vim"
in
  map pkgs
  each (pkg) =>
    command: "apt install ${pkg}" 

But even this example needs help.

I see a few "pure" directions: pure LISP code-as-data, pure functional everything-is-auto-curried, etc. And maybe something good lies down that path, but I don't want to be so pure that it's inaccessible to newbies.

yaml subset

inspired by StrictYaml

  • all keys are strings.
  • values are encoded as JSON is
    • strings are "strings"
    • numbers are 12
    • etc

also note: the Rust YAML serde parser doesn't support span information: dtolnay/serde-yaml#181. so is a potential reason to implement our own parser with chumsky.

Better data-driven integration test runner

Describe the solution you'd like

If the data-driven integration tests fail, we should know exactly which test case caused the failure.

At the moment, one #[test] runs multiple data tests, so it's hard to know what exactly went wrong.

We should improve this somewhat.

Design inspiration

  • JSON-e uses a build.rs to build a test file based on their spec data. At first I was resistant, but maybe that is the best approach.

Describe alternatives you've considered

The alternative is we write a re-usable test macro. Myabe that's better.

Additional context

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.