I think the K would likely be both simpler and harder than your first example by reading very straightforwardly in a single direction but with operators reading like line noise. In your case, my Numpy is rusty, but I think this is the Ruby equivalent of what you were doing?
textb = 'What hath the Flying Spaghetti Monster wrought?'
p textb.bytes.product((0...8).to_a).map{_1>>_2}.map{_1 & 1}
Or with some abominable monkey patching:
class Array
def outer(r) = product(r.to_a)
def right_shift = map{_1>>_2}
end
p textb.bytes.outer(0...8).right_shift.map{_1 & 1}
I think this latter is likely to be a closer match to what you'd expect in an array language in terms of being able to read in a single direction and having a richer set of operations. We could take it one step further and break the built in Array#&:
class Array
def &(r) = map{_1 & r}
end
p textb.bytes.outer(0...8).right_shift & 1
Which is to say that I don't think the operator-style line-noise nature of K is what gives it its power. Rather that it has a standard library that is fashioned around this specific set of array operations. With Ruby at least, I think you can bend it towards the same Array nature-ish. E.g. a step up from the above that at least contains the operator overloading and instead coerces into a custom class:
textb = 'What hath the Flying Spaghetti Monster wrought?'
class Object
def k = KArray[*self.to_a]
end
class String
def k = bytes.k
end
class KArray < Array
def outer(r) = product(r.to_a).k
def right_shift = map{_1>>_2}.k
def &(r) = map{_1 & r}.k
end
p textb.k.outer(0...8).right_shift & 1
With some care, I think you could probably replicate a fair amount of K's "verbs" and "adverbs" (I so hate their naming) in a way that'd still be very concise but not line-noise concise.
that all seems correct; the issue i had was not that python is less flexible than ruby (though it is!) but that it required a lot of mental effort to map back from the set of point-free array operations to my original intent. this makes me think that my trouble with j and k is not the syntax at all. but conceivably if i study the apl idiom list or something i could get better at that kind of thinking?
I think you could twist Python into getting something similarly concise one way or other ;) It might not be the Python way, though. I agree it often is painful to map. I think in particular the issue for me is visualizing the effects once you're working with a multi-dimensional set of arrays. E.g. I know what outer/product does logically, but I have to think through the effects in a way I don't need to do with a straightforward linear map(). I think I'd have been more likely to have ended up with something like this if I started from scratch even if it's not as elegant.
p textb.bytes.map{|b| (0...8).map{|i| (b>>i) & 1} }.flatten
EDIT: This is kind of embarrassing, but we can of course do just this:
textb.bytes.flat_map{_1.digits(2)}
But I think the general discussion still applies, and it's quite interesting how many twists and turns it took to arrive at that