from tracyspcy@lemmy.ml to programming@programming.dev on 27 Feb 12:59
https://lemmy.ml/post/43783589
How it all started?
Sometimes, there are moments in life then you feel loosing control over your life, when there is to much on a plate and all this overwhelms you, makes you anxious. For me, solution always was to use kind of “get things done” tools, to organize myself. I tried enormous amount of todo apps, even bought a paper todo, but this wasn’t enough this time. Every restriction in functionality, every missed feature made me feel I’m loosing control again. And one moment I gave up and decided it is time to make my own tool and make it right (in my understanding), i.e . a todo that is highly customazible and instead of hardcoded features can have any you want. Despite todo app is an anecdote and there are thousands of them, same as with an edit tool microsoft it is quite a challenging task to make a really good one.
Design/Concept
Luckily, I had 2 weeks of winter holidays and I decided to invest this time into this project. I thought a lot on how to make a todo that potentially have any possible feature that anyone can simply add just when they need it. My solution was a Virtual Machine with persistent storage + Tasks that have their own executable instructions. So in this design any todo app could be a simple wrapper around i/o and all functionality would be powered by the virtual machine.
Problems/Complexity
Creation of a working vm is a complex task for sure. I will not mention every problem I had faced during last months, but will just list some features I implemented to solve them:
- NaN-boxing — All stack values are 64-bit (u64) encoding 6 distinct types (Null, Boolean(TRUE_VAL,FALSE_VAL), STRING_VAL, CALLDATA_VAL, U32_VAL, MEM_SLICE_VAL (offset: 25 bits, size: 25 bits)).
- InlineVec — Fixed-size array-backed vector implementation used for stack, control stack, call stack, and jump stack with specified limits.
- Dynamic Memory/Heap — growable Vec heap; memory slices use 25-bit offset and 25-bit size fields (limited by MEM_SLICE_VAL).
- Definite Loops — DO…LOOP with control stack limit =2 ie 2 nested loops only possible for now.
- Conditional jump - IF…THEN with jump stack limit =2 ie 2 nested IF…THEN statements only possible for now.
- Custom binary encoding/decoding implementation.
- Also vm has zero dependencies.
Current state
My Virtual Machine is still in it’s early days and may be missing some important instructions, but already now it can be used for a todo app demo with programmable tasks. All operations — from simple CRUD to the tasks’ own instructions — are executed by the virtual machine. The concept in a nutshell is, that any kind of automation or workflow can be enabled by task instructions executed by the VM, rather than hardcoded functions in the app - exactly what I wanted to achieve initially! There are 4 demo task instructions that are not a part of the todo code, but instead are in toml file which could be updated any time with a new one:
- chain - Creates next task once when another is completed. Removes calldata after call - called once
- either - Sets complete if either one or another task is completed + deletes not completed task (see gif)
- destructable - task self destructs when it’s status set to complete
- hide - Keeps task hidden while specified task’s status is not complete.
Example link: github.com/tracyspacy/spacydo/tree/main/…/todo
When I added the todo example, I realized, that the originally hardcoded states in the VM were a limitation. If I would make them generic (which I did), the Virtual Machine would serve more than just todo apps: new use cases such as tasks orchestration and even state machines became possible. I added a finite state machine primitive example as well - a traffic light - where task is a simple state machine which has own state transition rules in calldata that executes each task’s instructions call.
Example link: github.com/tracyspacy/spacydo/…/traffic_light
I’m still working on this project alone and struggle to get other people involved to help me stabilize and finalize the VM.
Anyway, this journey is interesting and insightful, and I’m curious what comes next.
#programming
threaded - newest
How about abusing a lightweight init with grouping (dinit, s6, maybe runit. Systemd would likely get in your way) as a todo/tasker machine?
hey! I think it is a bit different layer - all of these are process orchestration/supervision tools working on os level, so managing state of todo tasks like “fix bug” is wrong usage for such tools. The VM, I’m working on is embeddable and sandboxed - manages states of a application, so potentially process supervision tool may be built using VM since it has persistent storage and state will be preserved even on process crash + “tasks” have own instructions that means it more flexible than static configs : instead of
foreground { kill <process> }it can contain logic and conditions (get process by id -> get its state -> if state is idle -> kill )foreground { push <process_id> get_state push_state <idle> eq if kill <process> then }.