Skip to content

Instantly share code, notes, and snippets.

@vidarh
Last active January 5, 2024 11:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vidarh/3cd1e200458758f3d58c88add05816d1 to your computer and use it in GitHub Desktop.
Save vidarh/3cd1e200458758f3d58c88add05816d1 to your computer and use it in GitHub Desktop.
A hairy exploration of k

For context, you probably want to look at this HN comment[1], and the chain leading up to it from [2], as well as the followup [3]

[1] https://news.ycombinator.com/item?id=38877833 [2] https://news.ycombinator.com/item?id=38862446 [3] https://news.ycombinator.com/item?id=38878014

Basically, it's an exploration in trying and repeatedly failing understand k, and eventually figuring out roughly how to translate this:

    ,/+|(8#2)\textb

into the far more verbose:

     textb.bytes.encode(8.reshape(2)).mreverse.flatten(1)

... which still does not fully accurately reflect the k.

textb="What hath the Flying Spaghetti Monster wrought?"
# Firstly, I finally realised after a bunch of testing that 1) "(8#2)" does something like this.
# That is, the result of 8#2 is (2 2 2 2 2 2 2 2), which was totally not what I expected.
def reshape(len,items) = [].fill(0...x)
class Integer
# For the special case of (x#y) where x is a positive integer, which is frankly the only one
# I've looked at, we can do:
# So now 4.reshape(2) returns [2 2 2 2] just like (4#2) in ngn/k
def reshape(items) = Array(items)*self
# Now we can do something somewhat like what I think "encode" is
# actually doing - this can be golfed down, but anyway:
# With this, "a".ord.encode(8.reshape(2)) returns [0,1,1,0,0,0,0,1],
# equivalent to (8#2)\ "a" in ngn\k
def encode(shape)
q = self
Array(shape).reverse.map do |m|
val = q % m
q = q / m
val
end.reverse
end
end
# Now we can break Array too.
class Array
# First a minor concession to how Ruby methods even on the Array
# class sees the focal point as the Array rather than the elements.
# E.g. `self` in #map is the Array. If the focus is to be on applying the
# same operation to each element, then it might be more convenient
# if `self` was the element. With this, we can do ary.amap{reverse}
# instead of ary.map{|e| e.reverse} or ary.map{ _1.reverse}.
# To get closer to k, we'd have needed a postfix operator that we could
# override to take a block, but unfortunately there are no overridable
# postfix operators in Ruby. E.g. we can hackily make
# ary.>>(some_dummy_value) {a block} work, but not even
# ary >> (some_dummy_value) { a block} and certainly not
# ary >> { a block }
#
def amap(&block) = map { _1.instance_eval(&block) }
# If we could do a "nice" operator based map, we'd just have left it
# at that. But to smooth over the lack of one, we can forward some
# methods to amap:
def encode(...) = amap{encode(...)}
# ... with the caveat that I realised afterwards that this is almost certainly
# horribly wrong, in that I think the k "encode" applies each step of the
# above to each element of the array and returns a list of *columns* of modulos.
# I haven't tried to replicate that, as it breaks my mind to think about
# operating on it that way. That is, [65,70].encode(2.reshape(10))
# really ought to return [[6,7],[5,0]] to match the k, but it returns
# [[6,5],[7,0]]. Maybe the k result will make more sense to me if I
# take a look at how encode is implemented...
def mreverse = amap{reverse}
end
# Now we can finally get back to the original, with the caveat that due to
# the encode() difference, the "mreverse.flatten(1)" step is in actuality
# working quite differently, in that for starters it's not transposing the arrays.
#
p textb.bytes.encode(8.reshape(2)).mreverse.flatten(1)
# So to sum up:
#
# textb -> textb.bytes since strings and byte arrays are distinct in Ruby
# (8#2) -> 8.reshape(2)
# x\y -> y.encode(x) ... but transposed.
# |x -> x.mreverse
# ,/+x -> x.flatten(1) .. but really should be x.transpose.flatten(1)
#
# Of course with a hell of a lot of type combinations and other cases the k
# verbs supports that I haven't tried to copy.
@vidarh
Copy link
Author

vidarh commented Jan 5, 2024

(P.S: Don't actually go doing any of the horrible deeds I've done above in "real" Ruby code, or Matz and the developers who come after you will haunt you forever)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment