it’s already gone through a big revamp for usability as I tested it under “real” conditions.
it’s been massively simplified to three contraptions; card, canvas, and layercake.
I’ve made several updates. In particular, added over and under composite modes, along with several other things.
It probably operates more like people expect, now.
I plan on merging a lot of the functionality into the canvas target and layer widgets, to reduce the number of contraptions. Card target and layer contraptions will mostly remain the same. While the cards seem relatively limited compared to the canvases, they both serve a purpose: 1. being able to composite with the existing Decker drawing tools, and 2. a composited background for a canvas layer to trace over or underpaint.
I’ll add a tutorial deck to the set in the next few days
note: it’s already gone through a big revamp for usability as I tested it under “real” conditions. it’s been massively simplified to three contraptions; card, canvas, and layercake.
direct download of deck: https://codeberg.org/woodring/decker.patternshop/raw/branch/main/patternshop.deck
project and readme, which is pasted below: https://codeberg.org/woodring/decker.patternshop/src/branch/main
see https://codeberg.org/woodring for more decker things
It’s a module and several contraptions that emulate layered composited drawing in other drawing tools. Or, “Decker mega-underpaint mode.”
How it works:
make a card that you want to be the target of the compositing
put the ps_card contraption on that card
make at least two other cards that will act as drawing layers
put the ps_card contraption on each of those cards
click the L checkbox on those contraptions - they are now
layers
draw on the layers with the Decker drawing tools; you’ll have to switch to drawing mode
after done drawing, switch back to interact mode and the target card.
press the C checkbox, et voila! layered drawing on cards
hint: reorder the cards to help flip between a layer that you’re currently drawing on. the left and right arrow keys switch between cards.
or
make a card
put the ps_canvas contraption on that card
make at least two other cards
put the ps_canvas contraption on each of those cards
click the L checkbox on those contraptions - they are now
layers
draw on the layers with the pointer; use the b and p
buttons to change the brush and palette
after done drawing, switch back to the target card.
press the C checkbox, et voila! layered drawing on the
canvases
hint: to save your work, save the deck. all layers will be preserved, cards and canvases. composition and layers will be off the next time the deck is opened, to preserve the current state of the cards and canvases.
even more
canvases and cards can be combined. drawing on a layer card will update a canvas target and vice versa.
non-composition cards and canvases, i.e., layers, can be copied
to each other via ps_layercake. it’s an upgraded
select/rubberband box. if you copy something onto
a ps_layercake, but it’s on another card - cut the widget,
i.e., ps_layercake, and paste it in the new card.
layers are semi-permanent, unless they are wiped out with
drawing over them or pasting into them with ps_layercake.
saving a deck will retain them between sessions. IMPORTANT:
a layer will be wiped if composition is activated. the image
will be replaced by the contents of any other active layers.
switching from composition to layer is safe, switching from
layer to composition is destructive.
when a saved deck is opened again, composition and layers will be off. this is to ensure your results are not updated until you explicitly want them to be. be mindful though, since layers are off, too. to help protect your drawings, if there are no layers it will explicitly not composite.
IMPORTANT there is no undo. save your work, often.
a limitation is that compositions do not update if you switch
into drawing mode. cards can only be drawn on in drawing mode,
which means, compositions will not update again until it is
switched back to interactive mode, again. this limitation does
not affect canvas layers, as they can only be drawn on during
interactive mode. but, Decker’s drawing tools will not draw
on ps_canvases, only cards. free-form sketching with brushes
and patterns is available for cavnases.
ps_card and ps_canvasonly on ps_canvas, v button: toggle visibility of drawing
canvas from “solid”, “transparent”, “invert” and “none”
only on ps_canvas, y button: yank the controls away, so
they don’t block the corner. the r button appears on the
other side.
only on ps_canvas, r button: restore the controls after
being yanked away
C checkbox: composite - combine all currently active layers
and replace the card or canvas image with the layers. this is
destructive and will wipe out any contents on that card or
canvas. you can have multiple composites on and they will all
receive the combined layer results. exclusive with the L
checkbox. NOTE: unchecking C will stop composition. this
in effect, “freezes” whatever was the last set of combined
layers. good for incremental drawing, as now the image can be
turned into a layer by checking the L checkbox. but,
checking C, if it was previously L, will wipe the
contents of the layer if there is any other active layer. be
careful, save often.
L checkbox: layer - activate the card or canvas as a layer.
its image will be combined with all other images and output
onto active composite cards or layers. all layers are combined
in numerical order via their compositing operator. see the
following. exclusive with the C checkbox. NOTE:
unchecking L will stop combining (composing) this layer with
any other layer, so it will stop contributing to any active
composite (checked C cards or canvases) images. checking L
again will reactivate the layer. but, checking C will
wipe the contents of the layer if there is another active
layer. be careful, safe often.
+/- buttons: increases/decreases layer number. the smallest
layer is on top, with larger numbers after; i.e., compositing
happens in numerical order, such that the top layer
(smallest number) is added first. has no effect in composition
mode.
number box: shows the layer number for that ps_card or
ps_canvas has no effect in composition mode.
</> buttons: switch the compositing operator. it starts
in under (u) mode, i.e. underpaint - which is probably what
most people want. the order of operators is, starting with u:
+, -, *, &, |, <, >, =, o, u
compositing operators are: “what’s being done per pixel between
the image stack and the next layer being added.” o stands for
“over,” i.e., layer goes on top of everything. has no effect
in composition mode.
text box: shows the current compositing operation for this layer; i.e., given the previous layers, what does this layer do to the stack of images, since it’s a cumulative effect. has no effect in composition mode.
only on ps_canvas, b button: change the brush. it will ask
you for the name or number for the brush. to change the brush
in Decker card drawing mode, use the Style->Brush menu like
normal. custom brushes created by ps_layercake can be used.
has no effect in composition mode.
only on ps_canvas, p button: change the pattern. it will
ask you for the number for the pattern. to change the pattern
in Decker card drawing mode, use the Style->Pattern menu like
normal. has no effect in composition mode.
ps_layercakea copy & paste tool for cards and layers. think of it as select/rubberband box that has a few more features.
layercake operates in interactive mode. grab the corner handles to move it around and resize it. note: you cannot paste into an active composition target - it will be immediately replaced. paste into a layer - or - turn off composition.
hotkeys drive the other functions:
hotkeys
c > copy from the card background. completely replaces the
contents of the layercake buffer. see merge up.
v > paste to the card background. completely replaces what
the layercake covers. see merge down.
n > merge up, i.e. composite copy from the card background,
treating pattern 0 as transparent. a non-destructive copy.
m > merge down, i.e. composite copy to the card background,
treating pattern 0 as transparent. a non-destructive paste.
d, f, h, j > copy, paste, merge up, merge down for
a canvas, rather than a card. if you have multiple canvases on
a card, will try to do all of them.
b > turn the layercake contents into a custom brush. it will
ask you to name the new brush.
w > wipe/clear layercake
t > toggle/cycle through visibility modes; solid,
transparent, invert, and none.
NOTE: pasting or merging into an active composition card or canvas will have no effect. this is because it will be immediately replaced by any active layers, replacing whatever was pasted into that composite. turn composition off if you want to paste into a composite. but, if composition is turned on again, the pasted contents will immediately be lost.
reminder: save your deck frequently. there isn’t undo.
reminder: while C is checked, the card or canvas is an
active composition and will receive updates from active layers.
unchecking C will deactivate composition and “freeze” the
image. it will stop receiving layer updates. while L is
checked, the card or canvas is an active layer and will provide
content for active compositions. unchecking L deactivate
a layer and it will stop being included in any active
compositions.
hint: deactivating a layer makes sense if it might have been a “guide layer” to trace over, like sketching a rough layout or draft. this will remove the rough from the final composites. deactivating a composition makes sense to freeze the image if it is a final or if the image will be used as a layer for a new composition.
reminder: when composition is on, anything that you
directly draw into composition card or canvas will be
immediately wiped by layers. this includes ps_layercake
merges or pastes. turn composition off if you want to draw
on top of a composited layer.
hint: in general, draw on logical layers not compositions - unless the composition will be turned into a layer. layers are semi-permanent, unless drawn upon, while compositions are dynamic and are actively updated results of combining layers.
hint: to trace over the top of an existing layer, use
a transparent ps_canvas layer with a ps_card composition.
use the v button to toggle visibility modes on a layer.
composition doesn’t need to be actively on for the card. but if
it is, the card target will show the composition of all of the
currently active layers; including the one you’re drawing on if
it is active and transparent.
hint: use the v button to make canvases transparent or
hide them to see cards behind them; or other layers if they are
on the same card.
hint: there isn’t a palette contraption, but you can use a card to mark the numbers of brushes and palettes so you can visually refer to them - like a real world palette. also, that provides a way to save custom brushes, too, by marking them on a palette card.
reminder: Decker drawing tools can only be used on cards.
canvases are restricted to brushes and patterns that can be
selected via the b and p buttons.
hint: noted previously, it is possible to copy an image
into ps_layercake and then cut or copy the widget. pasting
layercake onto another card allows you to copy and then paste
the image there. this can be done with cards and canvases,
too, like normal Decker. this allows you to keep multiple
copies of compositions and layers in the same deck, to
experiment or back up your work.
hint: consider composing results onto cards and then
removing the ps_card contraption. this makes it so you don’t
accidentally turn on composition mode and lose your work. (save
often!)
hint: reorder the cards to help flip between card layers and compositions, like a flipbook.
hint: since both canvases and card can switch from composition mode to layer mode - this allows one to work incrementally. compose several layers together, turn layers and composition off, and then copy the results. use the copy as a layer and work from that. this also helps to keep Decker from slowing down, especially if you’re working in web Decker. “baking” several layers into one squashed image means Decker will only need to do a couple of composites, greatly speeding it up.
hint: the patternshop module and contraptions can be
dropped into any other Decker project and be used as-is. but,
all are required, the contraptions and the module: the
contraptions require the ps module.
I was using it for frame timing for the bpm.
current time - last beat > bpm gap -> send a bang
so, i just hacked it by reoverflowing to positive by adding 2^31.
i just realized it’s still not 100% correct, because i’m not accounting for the timing gap (jitter) that is getting lost due to 60 Hz quantization.
update: oh, right. it wasn’t working because the “last frame” time was never initialized - so “current time” - “last frame” will always be negative, since it’s “current time” - nil (0). that’s the real reason.
so, anyways - i don’t know if negative sys.ms is supposed to be a thing, but it certainly wasn’t expected. it’s how i usually time gaps and don’t worry about initializing the first frame time for the possibility of negative time.
Here’s a version that’s a little more robust that will regenerate the card and allows for interactive updates to it:
# paste this into a card's (slide's) script (menu Card->Script...)
on view do
# boilerplate start
if card.widgets.sentinel
each k in keys card.widgets
card.remove[card.widgets[k]]
end
end
f: card.add["field" "sentinel"]
f.show: "none"
# boilerplate end
# your slide commands go here for each card
# this is different for each card (slide)
f: card.add["field" "title"]
f.pos: 30,30
f.text: "here is a title"
f.font: "menu"
f: card.add["field" "info"]
f.pos: 50,100
f.size: 200,200
f.text: "here is some information"
end
As always, it depends.
If you want something simple or a DSL (domain specific language) like Adelie, not that I know of. Though, John has made a lot of different tools and modules that could stand in for parts of it.
But, the other way is that you can is using the built in Decker commands. If I add this to a card’s script, (go to the toolbar menu, Card->Script...) I can programmatically generate the card:
removed – see my next comment for an improved version
Again, maybe not 100% of what you’re looking for, but it’s there: https://beyondloom.com/decker/decker.html#cardinterface
Also, the reason that I didn’t (aside from running out of time) was the audio feedback for a biquad filter ended up being pretty computationally expensive.
So, it probably would have required reprocessing the entire playback prior to playing it to remove audio lag.
I squeaked mine through just before the end, too.
I updated the description to the entry and game page.
Millie - I didn’t end up connecting it to your synth, but I did steal your Twinkle, Twinkle, Little Star csv from it to use in mine.
A visual data flow programming sandbox/toy/tool for Decker. Inspired by Pd (Pure Data).
Make programs by dropping boxes (nodes) and connecting them together with wires or pipes - very little to no typing.
A more “physical” way of programming that is akin to wiring diagrams or pipe flows - where you can see the results immediately and programs don’t crash.
The first card has a tutorial to explain how to use dP. Dialog boxes will pop up to explain how to use it. Click in the boxes to continue to the next.
Cards in the deck (use left-right arrows to navigate through the cards or the Decker menu):
Made in Decker for Dec(k) Month 3 jam. Thanks to John for making Decker in the first place and Millie for the Twinkle, Twinkle, Little Star csv that I stole from her Janky Tunes sequencer.
CHANGELOG:
For me, I think the most appropriate metaphor is that it is the “workbench.” Or, the supercharged REPL: a computational notebook or a literate programming environment.
I’ve always gravitated towards things where I can work incrementally: Lisp, Lua, Jupyter notebooks, R-Studio markdown, etc. I’ve even gone so as far as making an environments where I can incrementally program and test C code, to emulate a notebook-like interface.
The other thing that I like, and you even mention this in the workbook section: it gives me the capability to build it as I need. That’s the Forth and Lisp creed. Or roughly, Unix creed. Do one thing and do it well - which I’ve always interpreted as, build only the thing you need.
It’s the peeve I have with other computer scientists or software engineers. They try to solve everyone’s problem, but end up either solving no one’s or doing it really badly.
So - yeah - Decker scratches the itch just right for me.
Yeah, thanks for the heads up. I was looking at the Janky code already, and had thought about it, too.
So, it’s not going to be a 1-for-1 emulation of Pd - because of that. I’m not sure Decker could handle the amount of processing. Maybe, maybe not.
But, I think a sound queue should suffice and give the appearance of realtime.
Oh, I should mention - the above picture runs in real-time already. I can type in where the 5s are, a different number, and they will automatically add up in real-time. That’s why it shows 10.
It’s just that I don’t have a visualization for the connections/wires/inputs and outputs, yet, so you can’t see them connected together. Because the output of “frame” connects to the first 5 box, the 5 box connects to the second 5 box, so the number gets copied, and then they both feed into +, and then plus outputs into the final box to show you 5+5=10.
Pd (Pure data) is a flow graph based programming environment, primarily, for real-time audio processing. It was made by Miller Puckette and also worked on Max/MSP <- (hence the name MSP).
Pd, along with Max/MSP/Jitter, are used for deejaying and veejaying, along with general audio and video processing. For instance, I have a Pd patch that I made for my computer to mix various audio sources, along with a custom equalizer, bs2b filter from scratch, etc. (I once used Max to do real-time special effects for a university play in collaboration with the theatre department and a computer graphics offshoot of the art and design college. Anyways.)
So, I want to see if I can do real-time audio processing on your sequencer. I hope I can squeeze enough cycles out of it to do something.
For the most part, dP is an experiment of mine for tinkering with data flow graph processing, because it can do more than audio - general programming. It could be something non-programmers could use for Decker. Audio engineers and deejays/veejays make their own Pd patches. Flow graph programming is frequently used in visualization tools, like VTK and ParaView, for instance.
It’s interesting to me because flow graph and graphics (my background) programming, in general, very much have a “feed-forward” view of programming - kind of like React or Unix pipes (hence, decker Pipes). It’s more procedural, event-loop, like a factory or process engineering view of programming - not a math based view of programming, which is more “call-back” or “inside-out,” in my opinion.
At least, it will be a neat toy that I hope to do some audio manipulation with your sequencer. (I’m not trying to oversell this as taking over the world, as flow graph programming has been around forever. It’s just an experiment of mine.)
Is this intended or a bug? Assigning get/set with the keystore appears to strip a level of list.
Or am I missing something?
lib: ()
lib.test: on _ do
a: (list (list (list 1,2,3)))
data.a: a
show[data.a]
data.a: data.a
show[data.a]
data.a: data.a
show[data.a]
data.a: data.a
show[data.a]
x: (list (list (list 4,5,6)))
y: (list (list 7,8,9))
z: (list 10,11,12)
w: 13,14,15
data.x: x
show[data.x]
data.y: y
show[data.y]
data.z: z
show[data.z]
data.w: w
show[data.w]
nil
end
will produce:
(((1,2,3)))
((1,2,3))
(1,2,3)
1
(((4,5,6)))
((7,8,9))
(10,11,12)
13
nil
This was run in v1.62 Decker
I’ve updated a few things related to the WebXDC stuff:
I’ve diverged from https://codeberg.org/rtn/decker-xdc such that my stuff just uses vanilla Decker.
I didn’t want to rely on a modified version of Decker for using it in WebXDC. As such, my xdc module https://codeberg.org/woodring/decker.xdc has an xdc.save_deck method to compensate for that vanilla web Decker cannot reliably save decks when running in a WebXDC environment. (rtn modified web Decker to do this, and it was his main modification).
Two, I’ve made a slimmed down version of web Decker v1.61 that originally was a modification rtn’s version https://codeberg.org/rtn/decker-xdc to bring it up to v1.60 - but since, it’s now just a packer to make WebXDC packed Deckers: https://codeberg.org/woodring/decker.decker-xdc.
My other things that used WebXDC are updated with the newer module. Technically, starter and whiteboard have a more up to date version than what is in the xdc module and card. That’s because I haven’t gotten around to documenting the changes that are in the newest version. So, it’s a bit behind.
Also, there’s a couple of new things I have made that aren’t WebXDC enabled, like Cammy: https://codeberg.org/woodring to see all of my Decker junk.
Cammy (or Leon if you prefer) - a rapid menu-less widget-making widget
Cut and paste for Cammy is here: https://codeberg.org/woodring/decker.cammy
(hit reload if the image isn’t playing, my apngs don’t loop)

Yes, you could do this through the listener, but I find this easier and faster – especially if you have a Cammy making button:
%%WGT0{"w":[{"name":"make_cammy","type":"button","size":[64,16],"pos":[432,32],"script":"on click do\n w: card.add[\"contraption\" \"cammy\"] \n w.pos: (card.size / 2) - (w.size / 2)\nend","text":"cammy"}],"d":{}}
Inspired by Pd https://puredata.info
More of my decker junk: https://codeberg.org/woodring
Also posted in the contraption bazaar
Layercake: a moveable cut & paste tool with line loop drawing
The cut & paste for the contraption is here, along with any updates in the future:
https://codeberg.org/woodring/decker.layercake
The APNG doesn’t seem to loop, so reload the page if the image doesn’t seem to do anything:

WARNING: THERE IS NO UNDO
Controls/Hotkeys:
L: start loop/segment or end as loop
S: start loop/segment or end as segment
click: add a line segment in loop or segment mode
T: toggle solid/transparent/invert
W: wipe (clear)
H: halt (stop drawing segment)
R: reset (halt and set brush and pattern to 1)
C: copy from card canvas
V: paste to card canvas
U: merge up (copy from card canvas treating white as transparent)
D: merge down (paste to card canvas treating white as transparent)
9/0: decrement/increment pattern (open listener to see current pattern number
1/2: decrement/increment brush (open listener to see current pattern number)
Hint: to see the brush and pattern, without the listener
start a line loop or segment with L or S
stretch out your line
use 9/0 and 1/2 to cycle through the patterns and brushes
press H to halt without drawing anything
the pattern and brush remains what it was set to
Layercake: a moveable cut & paste tool with line loop drawing
The cut & paste for the contraption is here, along with any updates in the future:
https://codeberg.org/woodring/decker.layercake
The APNG doesn’t seem to loop, so reload the page if the image doesn’t seem to do anything:

WARNING: THERE IS NO UNDO
Controls/Hotkeys:
L: start loop/segment or end as loop
S: start loop/segment or end as segment
click: add a line segment in loop or segment mode
T: toggle solid/transparent/invert
W: wipe (clear)
H: halt (stop drawing segment)
R: reset (halt and set brush and pattern to 1)
C: copy from card canvas
V: paste to card canvas
U: merge up (copy from card canvas treating white as transparent)
D: merge down (paste to card canvas treating white as transparent)
9/0: decrement/increment pattern (open listener to see current pattern number
1/2: decrement/increment brush (open listener to see current pattern number)
Hint: to see the brush and pattern, without the listener
start a line loop or segment with L or S
stretch out your line
use 9/0 and 1/2 to cycle through the patterns and brushes
press H to halt without drawing anything
the pattern and brush remains what it was set to
Yep - it works now. It’s either a bug or limitation.
That’s exactly what I do, except the problem is the base image of the prototype/contraption will be fixed. If I resize the contraption, and the image started at (200,200) after instantiation, it remains at (200,200). It cannot be changed. I’ve tried on view or a subordinate widget that tries to resize it - it stays fixed.
Then, when I composite the subordinate canvases into it, and the contraption is resized, the image will wrap. The image will not resize itself and I can’t force it to resize.
The only way I have gotten around this is by maximizing the card on the prototype page so it starts with a very large image buffer, and then shrink it on view, when it’s actually instantiated. Except, that has problems, too.
So, I figure the only real fix is to not draw on the prototype’s/contraption’s base image, but on a canvas, and show the canvas.
I figured it out. I don’t know if it’s a bug or a limitation, but it’s easy to reproduce:
A prototype/contraption background image will not resize itself. It is fixed, no matter what. For instance, if I make a prototype at (200,200) and then resize it, the image is fixed. It also causes strange compositing errors near the edge of the contraption if I am actively drawing into it.
To get around it, I will have to use another canvas as the background image, rather than the contraption’s image - because they should be resizing themselves, obeying the margins. The prototype’s/contraption’s card does not, and is permanently fixed size.
Also, maybe I am abusing the use of the prototype/contraption base image and it is not supposed to be drawn into during interaction.
Yeah… I’m not too keen on (pure) mathematical abstractions, since I think of what’s happening at the electro-mechanical level. Like for example, Haskell did some important things in my opinion - but it wasn’t type systems (macros are better): the Just-Nothing pattern is one of the best ways to handle errors in my opinion.
So something like Guy Belloch and the CM-5 makes more sense to me, since it tries to model parallel vector primitives: scan, reduce, permute, etc. - there’s still an implicit for all. Actually, it’s very close in terms of the vector abstraction with APL, but APL and friends are like brainfuck to me. It’s too terse. That’s why I gravitate more towards something that is explicit, models the hardware, and maybe a bit more verbose. Readability is important to me and I don’t like terse code.
Though, that’s not to say I want everything as array notation, because it only gets you so far. The relational model for multi-sets is immensely useful, too. But, I try to wedge it around parallel vector primitives - because that’s where the performance is.
That said, this probably doesn’t work to do anything for the performance in lil at all, but it’s the mental model I find most useful to think about vector computations, since it maps really well to the hardware (not necessarily lil’s virtual machine, though). Like Iverson and APL, I don’t necessarily care for the modern math model either (I find right-to-left and inside-out unnatural), but I don’t like APL’s either.
Actually, no - that wasn’t it.
Anyways, I’ll have the contraption done soon, but I think I am running into a corner case where it doesn’t like resizing when a canvas is beyond the boundaries or something. The clipping gets to be incorrect and things start wrapping even though I explicitly set the sizes of the canvas and clip.
Yeah, going back and reviewing the vector section in the lil tutorial, coming from a vectorization background, none of the examples really clicked with me.
I think the possibility is that I know what is going on under the hood and so I think more mechanically. That’s kind of why vactur is more column-oriented, too, rather than row-oriented.
I hope you don’t take these things as too critical, as a lot of it is design-choice and background, and what we like. This is trying to give you a bit of perspective of my pedagogical style of how I think of these things, and why some abstractions in lil are hard for me to penetrate.
Fixed intersection and difference with the cascading changes, understanding how “in” works now.
I think that’s what confuses me about lil’s design is certain concepts are overloaded. I get it’s a design choice to unify things to a smaller language, but it does take a bit of mind bending.
Like, “in” has many overloaded uses and I might have called it “isin” to be more apparent to me that it was a vector. Maybe that’s my observation, is that I might have tended towards vector verbiage that indicate that, and a scalar is a special case of a vector of size 1 that can be broadcast to the right shape.
It never occurred to me that x in y was the boolean vector. Was there an example of this that I missed?
I fixed constant, isin, allbut, and dropped partition. Any other suggestions are welcome for implementation improvements.
Other stuff are stylistic things for me, and I’ll tend to keep things like isin[x y] instead of x in y, because I find infix notation and right-to-left hard to read. I’ll always prefer stack/left-to-right/procedural looking code, personally.
Also, as an aside, the reason that there’s things like partitioning was I started to re-implement things as vector parallel idioms, like doing an exclusive scan to do “where,” but then found it was slow. I probably don’t need it as a practical manner, as it was a left over artifact that might get culled.
Thanks for the review. There were a few idioms that I was like, “huh, that didn’t work as I expected,” which is kind of why vactur was made.
It’s called vactur because it’s the vector library for dummies like me that don’t get all of the lil idioms.
That said, I love decker and lil, it’s just my brain is a bit weird and sometimes when an abstraction doesn’t make sense to me, it works better when I switch it to something that does.
Couple of new things & updates (things that are WebXDC Decker only are marked)
I’ll publish a deck/repo with vactur, eventually - but the short version is that the interface is a bit closer to a numpy/matlab/fortran abstraction, and provides things like left (right) join, zip, etc., too. It just makes more sense to me on how to manipulate vectors/relational tables.
all of my decker stuff, so far: https://codeberg.org/woodring