Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Reviewing vactur, it seems like some of these operations reimplement Lil primitives or brief idioms. For example,

vac.constant: on _ n c do
  on _ do c end @ (range n) end
end

Replicates n copies of a constant c. This could be implemented in terms of the primitive "take"; possibly with an enclosed version of c if it may be something other than an atom:

3 take 5
# (5,5,5)
3 take list 11,22
# ((11,22),(11,22),(11,22))

Likewise,

vac.isin: on _ v s do
  t: vac.constant[(count v) 0]
  each x in s
    t: t | (v = x)
  end
  t
end

The core of this loop could be expressed as

max each x in s v = x end

But the whole operation appears to be equivalent to the primitive "in":

(2,3,5) in (4,11,17,5,3)
# (0,1,1)

The "partitioning[]" function is implemented in terms of "where" (a primitive in some APL-family languages, but not Lil); 

vac.where: on _ m do
  extract index where value from m
end
vac.partitioning: on _ m do
  vac.where[m],vac.where[!m]
end

But we can do the equivalent in a single query by using a "by" clause to group rows:

extract index by value from m

Not only does this reduce overhead, it makes the formulation more general:

vac.partitioning[1,0,1,1,0,1]
# (0,2,3,5,1,4)
extract index by value from 1,0,1,1,0,1
# (0,2,3,5,1,4)
extract index by value from "ABAABA"
# (0,2,3,5,1,4)

Please don't take this as discouraging your efforts; just pointing out some alternatives.

(1 edit) (+1)

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.

(1 edit) (+1)

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.

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.

(3 edits)

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?

(+1)

Lil’s vector-handling made more sense to me when I learned that it was inspired by a language called K, which was inspired by a language called APL, which was designed (among other things) to be a more modern alternative to traditional mathematical notation. Mathematicians will use + to represent addition of integers or complex numbers or matrixes or anything other random thing that obeys the algebraic laws of addition, and APL (and eventually Lil) uses + in a similar way.

If you think about vectors in the way they’re normally handled in languages that weren’t designed around the concept (like Python or Fortran), then yeah, you’re not going to get the full benefit. I also have found Lil to be a bit mind-bending (I came up with 1+0*range 5 for what I’ve now learned is more idiomatically expressed as 5 take 1), but it’s still so much more approachable than APL or even K, and there’s this whole cool retro-themed multimedia sketchpad tool built around it.

(2 edits)

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.

(4 edits)

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.