martes, 25 de febrero de 2020

not all containers are made equal

So if you want to give another spin to your container knowledge, you know there are a few projects that relate to containers and are not just docker.

- https://wiki.archlinux.org/index.php/systemd-nspawn
- https://voidlinux.org/news/2017/12/advent-containers.html
- https://www.infoq.com/articles/containers-hypervisors-2019/
- https://github.com/p8952/bocker
- https://dev.to/napicella/containers-from-scratch-in-18-lines-of-code-3pmn
- https://ericchiang.github.io/post/containers-from-scratch/
- https://news.ycombinator.com/item?id=15608435
- https://www.ardanlabs.com/blog/2020/02/docker-images-part1-reducing-image-size.html

And here is a cool 'build-your-own-docker' talk

jueves, 20 de febrero de 2020

Larry Tesler RIP, Bert Sutherland RIP

Very sad week for our field. Two great great great pioneers on the computer science, human-computer-interface, and thought advancing concepts left the analogic world.

There are a bunch of stories in these HN links:

  • https://news.ycombinator.com/item?id=22361282
  • https://news.ycombinator.com/item?id=22370667

jueves, 13 de febrero de 2020

Transitive closure in k, and more

I found this gist on finding reachable nodes in a graph super entertaining. Every time I read on APL/J/K I feel this intense deep puzzle solving that heats my brain a little bit, but feels awesome when you arrive at the end. And it all makes sense there.

About 10 years ago I was having those feelings with the Shwartzian transform and JAPHs around the net.  Perl is the gateway drug.


Transitive Closure in k

In The APL Orchard, ngn said:

the or-dot-and [∨.∧] trick is one of the most beautiful apl expressions ever, worth staring at :)

Well I had better learn it then...

Apparently it computes a transitive closure of a binary relation. Let's hit Wikipedia.

Transitive:

A relation R on a set X is transitive if, for all x, y, z in X, whenever x R y and y R z then x R z.

Closure:

"A set is closed under an operation if performance of that operation on members of the set always produces a member of that set."

OK - I understand that in an abstract sense, but let's see it in action, using the latest Shakti k.

Take the problem of finding, for each node in a graph, all nodes that node can access via 1+ jumps.

Concretely, let's say we have a 2D matrix m, where m[x] (row x) shows which places x can reach directly. If m[x;y] is 1, then x can get to y directly; if it's 0, then it can't.

Let's assume the edges are one-way (if A can get to B, that doesn't mean B can get to A), and let's make m really simple for now.

 m:(0 1 0;0 0 1;0 0 0)
 m
0 1 0  / A can get to B, but not to C
0 0 1  / B can get to C, but not to A
0 0 0  / C can't get to anything

To see whether A can get to C via B, we'd want to see a 1 in at least two places: for A -> B, and B -> C. To see where A can get to via B (C or otherwise), we can multiply the A -> B bit (m[0;1]) by B's row (m[1]):

 m[0;1]
1
 m[1]
0 0 1
 m[0;1] * m[1]  / multiplies all of B's row by the "A -> B" bit
0 0 1

To see where A can get to in two hops (via anywhere), we need to do this check for all of A's bits, and all 'intermediary' hops. If a 1 appears in a column, that means there is at least one way that A can get to that place indirectly.

 (m[0;0] * m[0]; m[0;1] * m[1]; m[0;2] * m[2])
0 0 0
0 0 1
0 0 0

We can do that 'is 1 in the column?' check by doing an element-wise max (|):

 (m[0;0] * m[0]) | (m[0;1] * m[1]) | (m[0;2] * m[2])
0 0 1

Or more concisely, using 'max-over' (|/) instead of inserting the max verbs in between manually:

 |/ (m[0;0] * m[0]; m[0;1] * m[1]; m[0;2] * m[2])
0 0 1

Or more concisely, as a function:

 |/ {m[0;x] * m[x]} 0 1 2
0 0 1

Or more concisely, by exploiting the fact that multiplication in k is element-wise:

 m[0] * m
0 0 0      / 0 * 0 1 0
0 0 1      / 1 * 0 0 1
0 0 0      / 0 * 0 0 0

 |/ m[0] * m
0 0 1

So that's everywhere A can get in two hops. If we want to see where each node can get to in two hops, we need to run this for each m[x] on the left. So we can use 'each-left', which has the form x v\ y where v is a verb like *. (I'm going to tweak the appearance of k9's output slightly.)

 m *\ m
0 0 0
0 0 1
0 0 0

0 0 0
0 0 0
0 0 0

0 0 0
0 0 0
0 0 0

As before, we can compress this down using |/, but this time we need to apply it to each 3x3 matrix:

 |/' m *\ m
0 0 1
0 0 0
0 0 0

We can also write this as:

 m (|/*)\ m
0 0 1
0 0 0
0 0 0

Now in doing this calc, we lost info about where each node can get to in one hop. We can either add that back in using max:

 m | m (|/*)\ m
0 1 1            / OK! A can get to B and C
0 0 1            / B can only get to C
0 0 0            / C still can't get to anything

Or we can assume each node can 'hop' to itself, so the 'one hop' routes don't get wiped out by the 'two hops' computation:

 m: (1 1 0; 0 1 1;0 0 1)
 m (|/*)\ m
1 1 1
0 1 1
0 0 1

That was a pretty easy example, so let's make a more complex network to see how performs. Let's assume all nodes can get to themselves directly, and also that:

  • A -> B
  • B -> C and D
  • D -> E

In other words:

 m:(1 1 0 0 0;0 1 1 1 0;0 0 1 0 0;0 0 0 1 1;0 0 0 0 1)
 m
1 1 0 0 0
0 1 1 1 0
0 0 1 0 0
0 0 0 1 1
0 0 0 0 1

/ Or if we're lazy, we can tweak an identity matrix (updated via leprechaun1066 - thanks!):
/ https://www.reddit.com/r/apljk/comments/f0m5ff/transitive_closure_in_k/fgvblq2/

 .[;;:;1]/({x=\x}@!5;0 1;1 2;1 3)
1 1 0 0 0
0 1 1 1 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1

And let's apply our process from before:

 m:(1 1 0 0 0;0 1 1 1 0;0 0 1 0 0;0 0 0 1 1;0 0 0 0 1)
 m (|/*)\ m
1 1 1 1 0
0 1 1 1 1
0 0 1 0 0
0 0 0 1 1
0 0 0 0 1

We can now see that A can get to C and D (because B can get to them directly), and that B can get to E (because D can get to E directly).

We know A should be able to get to E in three hops (via B and D). We can see this if we apply our process twice; so let's do that by wrapping up the process in a function, f, and applying it twice:

 f: {x (|/*)\ x}
 f@m
1 1 1 1 0
0 1 1 1 1
0 0 1 0 0
0 0 0 1 1
0 0 0 0 1

 f@f@m
1 1 1 1 1  <- top right bit changed!
0 1 1 1 1
0 0 1 0 0
0 0 0 1 1
0 0 0 0 1

Instead of explicitly applying the function twice, we can apply it repeatedly until the output stops changing using 'fixedpoint-over', /::

 f/:m
1 1 1 1 1
0 1 1 1 1
0 0 1 0 0
0 0 0 1 1
0 0 0 0 1

And that result is the transitive closure.

Next steps


Btw, if you want some more, https://www.youtube.com/watch?v=v7Mt0GYHU9A or https://www.youtube.com/watch?v=hzPd3umu78g .

lunes, 10 de febrero de 2020

spicing up your prompt

I've been using this very silly overloading of the prompt for some time, and even though it's dead simple, it gets to cheer me up sometimes.

On every emacs startup, and every 24 hours, you get  a different message on your prompt when 'm-x'.

Happy hacking,

;; Smex
(require 'smex)
(smex-initialize)
(global-set-key (kbd "M-x") 'smex)
(global-set-key (kbd "M-X") 'smex-major-mode-commands)
;; This is your old M-x.
(global-set-key (kbd "C-c C-c M-x") 'execute-extended-command)
(defun rgc-smex-set-prompt ()
(interactive)
(let ((prompts '("Act as if"
"Act without expectation"
"All is well"
"Allow for delays"
"Always be honest"
"Always be yourself"
"Always deliver quality"
"Ask powerful questions"
"Audit your metrics"
"Audit your mistakes"
"Based on results"
"Be constantly curious"
"Be here now"
"Be the change"
"Be the communication"
"Believe in yourself"
"Believe you can"
"Brainstorm alternative ideas"
"Branding is essential"
"Build for scalability"
"Build quality relationships"
"Build redundancy procedures"
"Build strategic partnerships"
"Cash is king"
"Cashflow is queen"
"Celebrate all success"
"Change is good"
"Citius, Altius, Fortius (Faster, Higher, Stronger)"
"Clear the air"
"Commit or quit"
"Communicate with clarity"
"Compare creates despair"
"Competition fuels growth"
"Congruency builds credibility"
"Connection builds trust"
"Contrast creates captivation"
"Dare to suck"
"Do it now"
"Do your best"
"Dreams come true"
"Drill your skills"
"Embrace Carpe Diem"
"Embrace constant change"
"Emotions create relatability"
"Energy draws attention"
"Enforce consequences rigorously"
"Exceptional makes memorable"
"Exclusivity adds value"
"Focus and win"
"Focus vs. scattered"
"Friends are treasures"
"Get over it"
"Grace under pressure"
"Go for it"
"Handle breakdowns immediately"
"Happiness is Choice"
"Health is wealth"
"Hope trumps all"
"I’m determined"
"Identify key milestones"
"It is possible"
"Judgement free zone"
"Just be awesome"
"Keep it cool"
"Keep information flowing"
"Keep it simple"
"Keep morale high"
"Knowledge is power"
"Laughter is best"
"Leaders are early"
"Learn from yesterday"
"Let it go"
"Laughter is medicine"
"Life is awesome"
"Life is beautiful"
"Life won’t wait"
"Live life daily"
"Live, love, laugh"
"Live your potential"
"Love endures delay"
"Love is everything"
"Manage your reputation"
"Manage your resistance"
"Manage resources effectively"
"Massive motions mesmerize"
"Mastery abhors mediocrity"
"Model the masters"
"Money amplifies emotions"
"Monitor budgets regularly"
"Never give up"
"Never look back"
"Next big feat?"
"Nothing is Impossible"
"Nurture your best"
"Participation equals value"
"Passion is enrolling"
"People complicate everything"
"Perfectionism stalls progress"
"Practice makes permanent"
"Prioritize all tasks"
"Polish your weaknesses"
"Raise your vibration"
"Reduce your overheads"
"Remember to Live"
"Reward high performance"
"Seize the day"
"Set clear targets"
"Sexy is confidence"
"Share the wealth"
"Share your vision"
"Speak the truth"
"Success is yours"
"Teamwork dream work"
"This will pass"
"Time heals everything"
"Track all progress"
"Train your team"
"Trust the process"
"Value your time"
"Yes you can"
"Accept yourself"
"Act justly"
"Aim high"
"Alive & well"
"Amplify hope"
"Baby steps"
"Be awesome"
"Be colorful"
"Be fearless"
"Be honest"
"Be kind"
"Be spontaneous"
"Be still"
"Be yourself"
"Beautiful chaos"
"Breathe deeply"
"But why?"
"Call me"
"Carpe diem"
"Cherish today"
"Chill out"
"Come back"
"Crazy beautiful"
"Dance today"
"Don’t panic"
"Don’t stop"
"Dream big"
"Dream bird"
"Enjoy life"
"Enjoy today"
"two word quoteEverything counts"
"Explore magic"
"Fairy dust"
"Fear not"
"Feeling groowy"
"Find balance"
"Follow through"
"For real"
"Forever free"
"Forget this"
"Friends forever"
"Game on"
"Getting there"
"Give thanks"
"Good job"
"Good vibration"
"Got love?"
"Hakuna Matata"
"Happy endings"
"Have faith"
"Have patience"
"Hello gorgeous"
"Hold on"
"How lovely"
"I can"
"I remember…"
"I will"
"Imperfectly perfect"
"Infinite possibilities"
"Inhale exhale"
"Invite tranquility"
"Just because"
"Just believe"
"Just imagine"
"Just sayin…"
"Keep calm"
"Keep going"
"Keep smiling"
"Laugh today"
"Laughter heals"
"Let go"
"Limited edition"
"Look up"
"Look within"
"Loosen up"
"Love endures"
"Love fearlessly"
"Love you"
"Miracle happens"
"Move on"
"No boundaries"
"Not yet"
"Notice things"
"Oh snap"
"Oh, really?"
"Only believe"
"Perfectly content"
"Perfectly fabulous"
"Pretty awesome"
"Respect me"
"Rise above"
"Shift happens"
"Shine on"
"Sing today"
"Slow down"
"Start living"
"Stay beautiful"
"Stay focused"
"Stay strong"
"Stay true"
"Stay tuned"
"Take chances"
"Thank you"
"Then when?"
"Think different"
"Think first"
"Think twice"
"Tickled pink"
"Treasure today"
"True love"
"Trust me"
"Try again"
"Unconditional love"
"Wanna play?"
"What if?"
"Why not?"
"Woo hoo!"
"You can"
"You matter"
"You sparkle"
)))
(setq smex-prompt-string
(concat
(nth (random (length prompts)) prompts)
": "))))
(run-at-time nil (* 3600 24) 'rgc-smex-set-prompt)
(provide 'smex-configs)
view raw smex-configs.el hosted with ❤ by GitHub