diff --git a/docs/log.txt b/docs/log.txt
index da2e91def54..e1cb7397cf6 100644
--- a/docs/log.txt
+++ b/docs/log.txt
@@ -1,40 +1,40 @@
-2024/12/25 21:14:44 error parsing https://themargins.substack.com/feed.xml: http error: 403 Forbidden
-2024/12/25 21:14:44 Fetched posts from https://themargins.substack.com/feed.xml, took 49.408134ms
-2024/12/25 21:14:44 error parsing https://highgrowthengineering.substack.com/feed: http error: 403 Forbidden
-2024/12/25 21:14:44 Fetched posts from https://highgrowthengineering.substack.com/feed, took 50.367274ms
-2024/12/25 21:14:44 error parsing https://mikehudack.substack.com/feed: http error: 403 Forbidden
-2024/12/25 21:14:44 Fetched posts from https://mikehudack.substack.com/feed, took 51.198285ms
-2024/12/25 21:14:44 Fetched posts from https://macwright.com/rss.xml, took 101.031587ms
-2024/12/25 21:14:44 Fetched posts from https://www.slowernews.com/rss.xml, took 107.275764ms
-2024/12/25 21:14:44 Fetched posts from https://www.benkuhn.net/index.xml, took 113.467514ms
-2024/12/25 21:14:44 Fetched posts from https://anewsletter.alisoneroman.com/feed, took 143.19984ms
-2024/12/25 21:14:44 Fetched posts from https://twobithistory.org/feed.xml, took 157.946853ms
-2024/12/25 21:14:44 Fetched posts from https://jvns.ca/atom.xml, took 166.339748ms
-2024/12/25 21:14:44 Fetched posts from https://routley.io/reserialised/great-expectations/2022-08-24/index.xml, took 254.728485ms
-2024/12/25 21:14:44 Fetched posts from https://danluu.com/atom.xml, took 334.791869ms
-2024/12/25 21:14:44 Fetched posts from https://www.wildlondon.org.uk/blog/all/rss.xml, took 340.487643ms
-2024/12/25 21:14:44 Fetched posts from https://blog.golang.org/feed.atom?format=xml, took 506.758698ms
-2024/12/25 21:14:44 Fetched posts from https://scattered-thoughts.net/rss.xml, took 546.780632ms
-2024/12/25 21:14:45 Fetched posts from https://blog.veitheller.de/feed.rss, took 632.700853ms
-2024/12/25 21:14:45 Fetched posts from http://tonsky.me/blog/atom.xml, took 763.078423ms
-2024/12/25 21:14:45 Fetched posts from https://solar.lowtechmagazine.com/feeds/all-en.atom.xml, took 903.710762ms
-2024/12/25 21:14:45 Content still empty after HTML reader: https://todaythings.substack.com/p/to-acquire-a-goshawk-is-a-major-decision
-2024/12/25 21:14:46 Content still empty after HTML reader: http://tinylogger.com/max/wnTJ9xu3fw5UiXLp
-2024/12/25 21:14:46 Fetched posts from https://commoncog.com/blog/rss/, took 1.979912052s
-2024/12/25 21:14:46 Content still empty after HTML reader: https://www.youtube.com/watch?v=IQqtsm-bBRU
-2024/12/25 21:14:46 Content still empty after HTML reader: https://papermatch.mitanshu.tech/
-2024/12/25 21:14:46 Fetched posts from https://gochugarugirl.com/feed/, took 2.335260265s
-2024/12/25 21:14:47 Fetched posts from https://joy.recurse.com/feed.atom, took 3.1783554s
-2024/12/25 21:14:47 Get "https://www.fixbrowser.org/": tls: failed to verify certificate: x509: certificate signed by unknown authority
-2024/12/25 21:14:48 Not HTML: https://community.wolfram.com/c/portal/getImageAttachment?filename=tree.gif&userId=93201
-2024/12/25 21:14:49 Fetched posts from https://blaggregator.recurse.com/atom.xml?token=4c4c4e40044244aab4a36e681dfb8fb0, took 4.645319019s
-2024/12/25 21:14:49 Content still empty after HTML reader: https://mathstodon.xyz/@johncarlosbaez/113703444230936435
-2024/12/25 21:14:50 Fetched posts from https://hnrss.org/frontpage?points=50, took 6.130762396s
-2024/12/25 21:15:14 error parsing https://rachelbythebay.com/w/atom.xml: Get "https://rachelbythebay.com/w/atom.xml": dial tcp 216.218.228.215:443: i/o timeout
-2024/12/25 21:15:14 Fetched posts from https://rachelbythebay.com/w/atom.xml, took 30.003753781s
-2024/12/25 21:15:14 Skipping writing post, no content: https://www.youtube.com/watch?v=IQqtsm-bBRU
-2024/12/25 21:15:14 Skipping writing post, no content: https://papermatch.mitanshu.tech/
-2024/12/25 21:15:14 Skipping writing post, no content: https://mathstodon.xyz/@johncarlosbaez/113703444230936435
-2024/12/25 21:15:14 Skipping writing post, no content: https://todaythings.substack.com/p/to-acquire-a-goshawk-is-a-major-decision
-2024/12/25 21:15:14 Skipping writing post, no content: http://tinylogger.com/max/wnTJ9xu3fw5UiXLp
-2024/12/25 21:15:14 Templated 44 posts, took 5.81646ms
+2024/12/25 22:15:02 error parsing https://mikehudack.substack.com/feed: http error: 403 Forbidden
+2024/12/25 22:15:02 Fetched posts from https://mikehudack.substack.com/feed, took 41.447619ms
+2024/12/25 22:15:02 error parsing https://highgrowthengineering.substack.com/feed: http error: 403 Forbidden
+2024/12/25 22:15:02 Fetched posts from https://highgrowthengineering.substack.com/feed, took 44.518222ms
+2024/12/25 22:15:02 error parsing https://themargins.substack.com/feed.xml: http error: 403 Forbidden
+2024/12/25 22:15:02 Fetched posts from https://themargins.substack.com/feed.xml, took 59.37455ms
+2024/12/25 22:15:02 Fetched posts from https://www.benkuhn.net/index.xml, took 94.900731ms
+2024/12/25 22:15:02 Fetched posts from https://www.slowernews.com/rss.xml, took 101.794218ms
+2024/12/25 22:15:02 Fetched posts from https://joy.recurse.com/feed.atom, took 141.301456ms
+2024/12/25 22:15:02 Fetched posts from https://anewsletter.alisoneroman.com/feed, took 145.901227ms
+2024/12/25 22:15:02 Fetched posts from https://jvns.ca/atom.xml, took 157.283834ms
+2024/12/25 22:15:02 Fetched posts from https://twobithistory.org/feed.xml, took 204.833877ms
+2024/12/25 22:15:02 Fetched posts from https://www.wildlondon.org.uk/blog/all/rss.xml, took 235.522444ms
+2024/12/25 22:15:02 Fetched posts from https://danluu.com/atom.xml, took 342.602657ms
+2024/12/25 22:15:02 Fetched posts from https://scattered-thoughts.net/rss.xml, took 352.397709ms
+2024/12/25 22:15:02 Fetched posts from https://blog.golang.org/feed.atom?format=xml, took 397.201636ms
+2024/12/25 22:15:02 Fetched posts from https://blog.veitheller.de/feed.rss, took 574.902302ms
+2024/12/25 22:15:02 Fetched posts from https://routley.io/reserialised/great-expectations/2022-08-24/index.xml, took 724.253503ms
+2024/12/25 22:15:02 Fetched posts from http://tonsky.me/blog/atom.xml, took 773.803277ms
+2024/12/25 22:15:03 Content still empty after HTML reader: https://todaythings.substack.com/p/to-acquire-a-goshawk-is-a-major-decision
+2024/12/25 22:15:03 Fetched posts from https://solar.lowtechmagazine.com/feeds/all-en.atom.xml, took 1.554209362s
+2024/12/25 22:15:04 Fetched posts from https://commoncog.com/blog/rss/, took 1.961066655s
+2024/12/25 22:15:04 Content still empty after HTML reader: http://tinylogger.com/max/wnTJ9xu3fw5UiXLp
+2024/12/25 22:15:04 Fetched posts from https://gochugarugirl.com/feed/, took 2.782335794s
+2024/12/25 22:15:05 Content still empty after HTML reader: https://www.youtube.com/watch?v=IQqtsm-bBRU
+2024/12/25 22:15:05 Content still empty after HTML reader: https://papermatch.mitanshu.tech/
+2024/12/25 22:15:06 Get "https://www.fixbrowser.org/": tls: failed to verify certificate: x509: certificate signed by unknown authority
+2024/12/25 22:15:07 Fetched posts from https://blaggregator.recurse.com/atom.xml?token=4c4c4e40044244aab4a36e681dfb8fb0, took 5.284138199s
+2024/12/25 22:15:07 Content still empty after HTML reader: https://mathstodon.xyz/@johncarlosbaez/113703444230936435
+2024/12/25 22:15:08 Fetched posts from https://hnrss.org/frontpage?points=50, took 6.723174943s
+2024/12/25 22:15:32 error parsing https://rachelbythebay.com/w/atom.xml: Get "https://rachelbythebay.com/w/atom.xml": dial tcp 216.218.228.215:443: i/o timeout
+2024/12/25 22:15:32 Fetched posts from https://rachelbythebay.com/w/atom.xml, took 30.003166053s
+2024/12/25 22:16:02 error parsing https://macwright.com/rss.xml: context deadline exceeded
+2024/12/25 22:16:02 Fetched posts from https://macwright.com/rss.xml, took 1m0.014703904s
+2024/12/25 22:16:02 Skipping writing post, no content: https://www.youtube.com/watch?v=IQqtsm-bBRU
+2024/12/25 22:16:02 Skipping writing post, no content: https://papermatch.mitanshu.tech/
+2024/12/25 22:16:02 Skipping writing post, no content: https://mathstodon.xyz/@johncarlosbaez/113703444230936435
+2024/12/25 22:16:02 Skipping writing post, no content: https://todaythings.substack.com/p/to-acquire-a-goshawk-is-a-major-decision
+2024/12/25 22:16:02 Skipping writing post, no content: http://tinylogger.com/max/wnTJ9xu3fw5UiXLp
+2024/12/25 22:16:02 Templated 45 posts, took 7.619797ms
diff --git a/docs/posts/bad-research-idea-false-statements-in-e-graphs.html b/docs/posts/bad-research-idea-false-statements-in-e-graphs.html
index 5e3c4536e82..4b277e09a68 100644
--- a/docs/posts/bad-research-idea-false-statements-in-e-graphs.html
+++ b/docs/posts/bad-research-idea-false-statements-in-e-graphs.html
@@ -23,7 +23,7 @@
bad research idea: false statements in e-graphs
OK after much squinting at the progression of rewrite rules... I think I have found an example of where the logic goes wrong.
Can you spot the error?
-
+
The issue here is that the empty int list TupleInt.EMPTY is unified with TupleInt(0, partial(lambda i, self, j: Int.if_(j == self.length(), i, self[j])), 101, TupleInt.empty) aka TupleInt(0, lambda j: Int.if_(j == 0, 101, TupleInt.EMPTY[j])))
Now let's say we do a naive index the empty list like TupleInt.EMPTY[0]. We could say this incorrect, or how we can represent it is that it unifies with Int.NEVER. But it can show up in the e-graph, because in if_ conditionals, the false branch can end up doing indexing that is not allowed. So we want it to not mess things up.
And in this case then, it will evaluate to (lambda j: Int.if_(j == 0, 101, TupleInt.EMPTY[j])))(0) which is Int.if_(0 == 0, 101, TupleInt.EMPTY[0])) which is 101... So then what we get is that 101 is unified with Int.NEVER which... isn't good! Is really bad! Because it means all numbers can be unified together basically, i.e. false is true whatever.
To make a comment, please send an e-mail to solar (at) lowtechmagazine (dot) com. Your e-mail address is not used for other purposes, and will be deleted after the comment is published. If you don’t want your real name to be published, sign the e-mail with the name you want to appear.
+
+ Reactions
+
+
+
Greg
+
Hi Kris,
+
Thank you for the heated table article! A lot of times I’ll have an idea,
+but because I haven’t seen it done, and I’m a coward, I decide it’s
+probably a bad idea for some reason I can’t foresee. When you write an
+article like that, and include the historical use, then I’m bolstered to
+try it!
+
You mention “Western-style seating”, and I’m wondering what you think of
+this problem: One problem I have with heating myself or my little space, is
+that I’m reluctant to move, so I sit too long. There are various health
+effects of that, but one I’m battling right now is sciatica that has
+affected almost every night of sleep for 10 months.
+
I’m wondering if you’ve thought about that, and if you know if people who
+do “Eastern-style seating” have any different outcomes?
+
Cheers again for the article!
+Greg
+Australia
+
+
+
kris de decker
+
Hi Greg,
+
Indeed I have been looking into the advantages of sitting on the ground, and they are quite significant. While I chose a western-style sitting position for my office, I am considering switching to sitting on the ground in my home. It’s apparently much better for your body, although it does take practice.
+
All the best,
+Kris
+
+
+
Kostas
+
Hello Kris,
+
You may want to add to the article of heated table another insulation material.
+Mycelium panels. More resistant to high temperatures also.
+
Regards
+Kostas
+
+
+
Kieran
+
Good afternoon,
+
Thank you so much for this article. It was very enjoyable to read as most of your articles are! My wife and I love Japanese culture and as such I have considered buying/making a Kotatsu. For one reason or another we’ve decided not to.
+
But the idea of using the underfloor heating foil is a stroke of genius. Here in the UK, you can buy low wattage “tube heaters” at a very low cost (around £35 for the 80w model). They have a built-in thermostat and run off the 230v wall supply. They are generally used for protecting a greenhouse or shed from frost but I wonder if they would be suitable for this application too? Any thoughts?
+
Thanks again for the articles,
+Kieran
+
+
Patrick 'DoctorSockrates' Camarador
+
I wish this guide was out before I built a prototype “desktop kotatsu” to keep my fingers warm on the keyboard and mouse in my office. Probably would be safer than what I had lying around; I used a simple lapdesk and small blanket that was short enough to not be blocking the monitors on my monitor arms. My heating source was a desktop heater that was supposed to blow hot air on your hands directly, which was uncomfortable the first time I used it since the air wasn’t being trapped and I couldn’t move my mouse hand much underneath it. While it did have a safety shut off for tipping over or overheating, I would’ve loved to have a thermostat for my desktop kotatsu instead…perhaps now with this manual, I can rebuild.
+
Patrick “DoctorSockrates” Camarador
+
+
+
Wim
+
The plan sounds solid.
+Thank you for the ideas and the time you spend on making this world Low tech minded.
+
One remark, for a slightly worried EHS person:
+
From a Building Biology point of view it depends on how you design it if it would be considered " fit for consumption" or " healthy for Human Beings".
+EMF’s so close to your body can give all sorts of health issues, like headaches, poor sleep, nervous system disorders etc.
+Running a 3 wire system (with earth) to power the pad avoids a lot of that.
+
The 2 wire part should be as short as possible, and ideally avoided completely.
+The heating pad itself should be surrounded by a metal grid connected to earth to avoid excessive EMF’s.
+However, the very nature of the heating pad does not allow for a design that avoids EMF’ s , as far as my knowledge goes.
+
(You would need to experiment with maze size and use an EMF meter to see what is practical. )
+
Anyway, as always, grateful for your efforts turning complex things into easy solutions.
+
Kind regards,
+Wim
+
+
+
Eric Wagner
+
I was wondering if there was any reason one couldn’t use an electric blanket instead of building an electrically-heated table. You could still have some insulation blankets laid over top of the heated blanket on your lap instead of over the table.
+I feel there are benefits to this version, like direct contact with the body for quicker and more heat transfer, and a heated blanket could be used in a variety of position and locations. Some people might want a hard surface on their table for certain types of work, which you could have with the blankets on your lap instead. Also, Since the blankets are only covering your body instead of a whole table, they could be smaller, and finally, I imagine it would be simpler to install.
+I love the kotatsu invention, but it makes more sense to me if you are disconnected from the grid, or wanting to use some other type of energy other than electricity.
+
Eric Wagner
+
+
+
Kris De Decker
+
@Eric Wagner
+I have no experience with electric blankets, never used one. So I cannot really answer your question. One disadvantage I see is that the heating system and the insulation are one. If I spill coffee over my table, I could simply switch blankets. Also, if you put an electric blanket over the table, it will mostly heat up the table rather than your body. So indeed, you would need to put it on your lap. It’s a totally different approach. Also, I don’t see why the heated table would make more sense if you are disconnected from the grid. It works just as well with grid power.
+
@Wim
+Good point, I did not think of that. I have not noticed any adverse effects after a week of use, but then I am not sensitive to EMF. I could do a test with an EMF meter.
+
@Kieran
+I didn’t know tube heaters, but had a look online. I don’t think they are suited for a heated table. I see there are some that use as little power as my infrared heating foil, but they seem to have much less surface area. That means that their surface temperature will be higher, risking burns or fire when they come into contact with skin or clothes.
+
@Kostas
+Thanks, that is something I will try for the next table we build.
+
+
+
+
-
-
+
+
+
+
+
I did all tests at a maximum thermostat temperature of 44.5 degrees Celsius (112°F). Energy will be lower if you use a lower temperature setting. Apart from measuring energy use and temperatures, I noted my thermal comfort. I was sitting at the table wearing leather shoes, a thick layer of merino wool thermal underclothing, and thin work clothes above that. I did computer work. I did tests with an insulation of one to four blankets. The energy use and performance of your heated table may differ from mine. The energy use depends on the size and power of the heat source (step 2), the thermostat settings (step 4), the heat-insulating value of the blankets (step 8) and the carpet (step 7), the heat source insulation (step 6), and the table surface (step 1). As you add more heat insulation, the thermostat will turn off the heating source more often and for longer, resulting in lower energy use. The same happens when you set a lower maximum thermostat setting. ↩︎
+
+
+
Not accounting for the cost of a table or a carpet - things that are likely already around - you can build a one-person electrically heated table for less than 100 euros. Here are the costs for my table: 35 euros for the heating foil (I bought 2 meters for 75 euros and cut the roll to about half the size), 10 euros for the thermostat, 30 euros of cork insulation, and 40 euros for the second-hand “double” green wool blanket that is very large and thick. Total = 115 euros. I bought four other cheap second-hand blankets, all in an excellent state. You can spend hundreds or even thousands of euros on exquisite wool blankets if you have deep pockets. The costs (and the building time) increase as the table gets larger because there is more heating foil and insulation to add. ↩︎
+
+
+
Don’t make the mistake of putting the heat foil on the floor, radiating heat upwards to the table. Radiant heat sources don’t work by heating the air but by directly transmitting energy to your body. If energy radiates downwards, it will reach your thighs, knees, lower legs, and feet. In contrast, if the radiant energy comes from below, the bottom of the chair blocks most of it. Only your feet are directly exposed, but they will only be warmed when taking off your shoes. You also need to insulate the space below the heating foil and protect the top of the carbon heating film against damage, complicating the building process. ↩︎
+
+
+
Ingham, Peter, et al. “Wool and carpets-6000 years of innovation, quality and sustainability.” Key Engineering Materials 671 (2016): 490-496. See also: McNeil, Steve. “The thermal properties of wool carpets.” Technical Bulletin, AgResearch, NZ. AgResearch Limited Lincoln Research Centre| e Se||-Corner Springs Road & Gerald Street, Lincoln ita mīta i, mīta i het Private Bag 4749 (2016). ↩︎
- Cloudflare Ray ID: 8f7bd7c55a6907d4
+ Cloudflare Ray ID: 8f7c301c8d06dda4•
Your IP:
- 20.42.51.81
+ 20.42.51.97•Performance & security byCloudflare
diff --git a/docs/posts/portspoof-emulate-a-valid-service-on-all-65535-tcp-ports.html b/docs/posts/portspoof-emulate-a-valid-service-on-all-65535-tcp-ports.html
new file mode 100644
index 00000000000..07e568c8c3c
--- /dev/null
+++ b/docs/posts/portspoof-emulate-a-valid-service-on-all-65535-tcp-ports.html
@@ -0,0 +1,536 @@
+
+
+
+
+
+
+ James Routley | Feed
+
+
+
+ Back
+ Original
+
Portspoof: Emulate a valid service on all 65535 TCP ports
+
+
+
CPS, or continuation-passing style, is an intermediate representation for
+programs, particularly functional programs. It’s used in compilers for
+languages such as SML and Scheme.
+
+
In CPS, there are two rules: first, that function/operator arguments must
+always be trivial; second, that function calls do not return. From this, a
+lot falls out.
+
+
In this post, we’ll introduce CPS by building a simple (Plotkin1) CPS
+transform from a small Scheme-like language. We’ll sketch some optimizations on
+the IR. Then we’ll look at a couple of the common ways to actually compile the
+IR for execution.
+
+
Mini-Scheme
+
+
We have integers: 5
+
+
We have some operations on the integers: (+ 1 2), (< 3 4) (returns 1 or 0)
+
+
We can bind variables: (let ((x 1)) x) / (letrec ...) ?
+
+
We can create single-parameter functions2: (lambda (x) (+ x 1))
+and they can close over variables
+
+
We can call functions: (f x)
+
+
We can branch: (if (< x y) x y) (where we have decided to use 0 and 1 as
+booleans)
+
+
How do I…?
+
+
We’re going to implement a recursive function called cps incrementally,
+starting with the easy forms of the language and working up from there. Many
+people like implementing the compiler both in Scheme and for Scheme but I find
+that all the quasiquoting makes everything fussier than it should be and
+obscures the lesson, so we’re doing it in Python.
+
+
This means we have a nice clear separation of code and data. Our Python code is
+the compiler and we’ll lean on Python lists for S-expressions. Here’s what some
+sample Scheme programs might look like as Python lists:
Our cps function will take two arguments. The first argument, exp, is the
+expression to compile. The second argument, k, is a continuation. We have
+to do something with our values, but CPS requires that functions never
+returns. So what do we do? Call another function, of course.
+
+
This means that the top-level invocation of cps will be passed some useful
+top-level continuation like print-to-screen or write-to-file. All child
+invocations of cps will be passed either that continuation, a manufactured
+continuation, or a continuation variable.
So a continuation is just another function. Kind of.
+
+
While you totally can generate real first-class functions for use as
+continuations, it can often be useful to partition your CPS IR by separating
+them. All real (user) functions will take a continuation as a last
+parameter—for handing off their return values— and can arbitrarily escape,
+whereas all continuations are generated and allocated/freed in a stack-like
+manner. (We could even implement them using a native stack if we wanted. See
+“Partitioned CPS” and “Recovering the stack” from Might’s page.)
+
+
For this reason we syntactically distinguish IR function forms ["fun", ["x",
+"k"], ...] from IR continuation forms ["cont", ["x"], ...]. Similarly, we
+distinguish function calls ["f", "x"] from continuation calls ["$call-cont",
+"k", "x"] (where $call-cont is a special form known to the compiler).
Integers satisfy the trivial requirement. So does all constant data (if we
+had strings, floats, etc), variable references, and even lambda expressions.
+None of these require recursive evaluation, which is the core of the triviality
+requirement. All of this requires that our nested AST get linearized into a
+sequence of small operations.
+
+
Variables are similarly straightforward to compile. We leave the variable names
+as-is for now in our IR, so we need not keep an environment parameter around.
Now let’s look at function calls. Function calls are the first type of
+expression that requires recursively evaluating subexpressions. To evaluate (f
+x), for example, we evaluate f, then x, then do a function call. The order
+of evaluation is not important to this post; it is a semantic property of the
+language being compiled.
+
+
To convert to CPS, we have to both do recursive compilation of the arguments
+and also synthesize our first continuations!
+
+
To evaluate a subexpression, which could be arbitrarily complex, we have to
+make a recursive call to cps. Unlike normal compilers, this doesn’t return a
+value. Instead, you pass it a continuation (does the word “callback” help
+here?) to do future work when that value has a name. To generate
+compiler-internal names, we have a gensym function that isn’t interesting and
+returns unique strings.
+
+
The only thing that differentiates it from, for example, a JavaScript callback,
+is that it’s not a Python function but instead a function in the generated
+code.
Note that our generated function call from (f x) now also has a continuation
+argument that was not there before. This is because (f x) does not return
+anything, but instead passes the value to the given continuation.
+
+
Calls to primitive operators like + are our other interesting case. Like
+function calls, we evaluate the operands recursively and pass in an additional
+continuation argument. Note that not all CPS implementations do this for simple
+math operators; some choose to allow simple arithmetic to actually “return”
+values.
We also create a special form for the operator in our CPS IR that begins with
+$. So + gets turned into $+ and so on. This helps distinguish operator
+invocations from function calls.
+
+
Now let’s look at creating functions. Lambda expressions such as (lambda (x)
+(+ x 1)) need to create a function at run-time and that function body contains
+some code. To “return”, we use $call-cont as usual, but we have to also
+remember to create a new fun form with a continuation parameter (and then
+thread that through to the function body).
Alright, last in this mini language is our if expression: (if cond iftrue
+iffalse) where all of cond, iftrue, and iffalse can be arbitrarily
+nested expressions. This just means we call cps recursively three times.
+
+
We also add this new compiler builtin called ($if cond iftrue iffalse)
+that takes one trivial expression—the condition—and decides which of the
+branches to execute. This is roughly equivalent to a machine code conditional
+jump.
+
+
The straightforward implementation works just fine, but can you see what might
+go wrong?
The problem is that our continuation, k, need not be a continuation
+variable—it could be an arbitrary complicated expression. Our implementation
+copies it into the compiled code twice, which in the worst case could lead to
+exponential program growth. Instead, let’s bind it to a name and then use the
+name twice.
Last, let can be handled by using a continuation, as we’ve bound temporary
+variables in previous examples. You could also handle it by desugaring it into
+((lambda (x) body) value) but that will generate a lot more administrative
+overhead for your optimizer to get rid of later.
There you have it. A working Mini-Scheme to CPS converter. My implementation is
+~30 lines of Python code. It’s short and sweet but you might have noticed some
+shortcomings…
+
+
+
+
+
+
Now, you might have noticed that we’re giving names to a lot of trivial
+expressions—unnecessary cont forms used like let bindings. Why name the
+integer 3 if it’s trivial?
+
+
One approach people take to avoid this is meta-continuations, which I think
+many people call the “higher-order transform”. Instead of always generating
+conts, we can sometimes pass in a compiler-level (in this case, Python)
+function instead.
This approach, though occasionally harder to reason about and more complex,
+cuts down on a significant amount of code before it is ever emitted. For
+few-pass compilers, for resource-constrained environments, for enormous
+programs, … this makes a lot of sense.
+
+
Another approach, potentially easier to reason about, is to lean on your
+optimizer. You’ll probably want an optimizer anyway, so you might as well use
+it to cut down your intermediate code too.
+
+
+
+
Optimizations
+
+
Just like any IR, it’s possible to optimize by doing recursive rewrites. We
+won’t implement any here (for now… maybe I’ll come back to this) but will
+sketch out a few common ones.
+
+
The simplest one is probably constant folding, like turning (+ 3 4) into 7.
+The CPS equivalent looks kind of like this:
+
+
["$+","3","4","k"]# => ["$call-cont", "k", 7]
+["$if",1,"t","f"]# => t
+["$if",0,"t","f"]# => f
+
+
+
An especially important optimization, particularly if using the simple CPS
+transformation that we’ve been using, is beta reduction. This is the process of
+turning expressions like ((lambda (x) (+ x 1)) 2) into (+ 2 1) by
+substituting the 2 for x. For example, in CPS:
Substitution has to be scope-aware, and therefore requires threading an
+environment parameter through your optimizer.
+
+
+
As an aside: even if you “alphatise” your expressions to make them have
+unique variable bindings and names, you might accidentally create second
+bindings of the same names when substituting. For example:
This would create two bindings of x0, which violates the global uniqueness
+property.
+
+
+
You may not always want to perform this rewrite. To avoid code blowup, you may
+only want to substitute if the function or continuation’s parameter name
+appears zero or one times in the body. Or, if it occurs more than once,
+substitute only if the expression being substituted is an integer/variable.
+This is a simple heuristic that will avoid some of the worst-case scenarios but
+may not be maximally beneficial—it’s a local optimum.
+
+
Another thing to be aware of is that substitution may change evaluation order.
+So even if you only have one parameter reference, you may not want to
+substitute:
+
+
((lambda(f)(begin(g)f))
+ (do-a-side-effect))
+
+
+
As the program is right now, do-a-side-effect will be called before g and
+the result will become f. If you substitute do-a-side-effect for f in
+your optimizer, g will be called before do-a-side-effect. You can be more
+aggressive if your analyzer tells you what functions are side-effect free, but
+otherwise… be careful with function calls.
+
+
There are also more advanced optimizations but they go beyond an introduction
+to CPS and I don’t feel confident enough to sketch them out.
+
+
+
+
Alright, we’ve done a bunch of CPS→CPS transformations. Now we would like
+to execute the optimized code. To do that, we have to transform out of CPS into
+something designed to be executed.
+
+
To C, perchance to dream
+
+
In this section we’ll list a couple of approaches to generating executable code
+from CPS but we won’t implement any.
+
+
You can generate naive C code pretty directly from CPS. The fun and cont
+forms become top-level C functions. In order to support closures, you need to
+do free variable analysis and allocate closure structures for each.
+(See also the approach in scrapscript in the section called
+“functions”.) Then you can do a very generic calling convention where you pass
+closures around. Unfortunately, this is not very efficient and doesn’t
+guarantee tail-call elimination.
+
+
To support tail-call elimination, you can use trampolines. This
+mostly involves allocating a frame-like closure on the heap with each
+tail-call. If you have a garbage collector, this isn’t too bad; the frames do
+not live very long. In fact, if you instrument the factorial
+example in Eli’s blog post, you can see that the
+trampoline frames live only until the next one gets allocated.
+
+
This observation led to the development of the Cheney on the MTA
+algorithm, which uses the C call stack as a young generation for the garbage
+collector. It uses setjmp and longjmp to unwind the stack. This approach is
+used in CHICKEN Scheme and Cyclone Scheme. Take a look at
+Baker’s 1994 implementation.
+
+
If you don’t want to do any of this trampoline stuff, you can also do the One
+Big Switch approach which stuffs each of the funs and conts into a case
+in a massive switch statement. Calls become gotos. You can manage your
+stack roots pretty easily in one contiguous array. However, as you might
+imagine, larger Scheme programs might cause trouble with some C compilers.
+
+
Last, you need not generate C. You can also do your own lowering from CPS into
+a lower-level IR and then to some kind of assembly language.
+
+
+
+
Wrapping up
+
+
You have seen how to produce CPS, how to optimize it, and how to eliminate it.
+There’s much more to learn, if you are interested. Please send me material if
+you find it useful.
+
+
I had originally planned to write a CPS-based optimizer and code generator for
+scrapscript but I got stuck on the finer details of compiling pattern matching
+to CPS. Maybe I will return to this in the future by desugaring it to nested
+ifs or something.
Thanks to Vaibhav Sagar and Kartik
+Agaram for giving feedback on this post. Thanks to
+Olin Shivers for an excellent
+course on compiling functional programming languages.
Richard Kelsey has a nice paper (PDF) on
+transforming CPS to SSA form. Unfortunately, I have tried to implement it and
+it is not as simple as it looks. I think I’m missing something.
FVM, a nascent VM designed as a compile
+target for functional languages
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/posts/the-swedish-cabin-on-the-frontline-of-a-possible-hybrid-war.html b/docs/posts/the-swedish-cabin-on-the-frontline-of-a-possible-hybrid-war.html
index b4131ebcd72..ffe3703f7ab 100644
--- a/docs/posts/the-swedish-cabin-on-the-frontline-of-a-possible-hybrid-war.html
+++ b/docs/posts/the-swedish-cabin-on-the-frontline-of-a-possible-hybrid-war.html
@@ -17,6 +17,6 @@
Original
The Swedish cabin on the frontline of a possible hybrid war
-
At the end of an unmarked path on a tiny island at the edge of Stockholm’s extensive Baltic Sea archipelago lies an inconspicuous little wooden cabin, painted a deep shade of red. Water gently laps the snow-dusted rocks, and the smell of pine fills the air.
The site offers few clues to the geopolitical drama that has gripped Scandinavia in recent months, driven by accusations of infrastructure sabotage. But in fact the cabin houses a key cog in Europe’s digital connectivity, and a point of vulnerability in a potential hybrid war: a datacentre that amplifies the signal from a 1,615-mile fibre-optic cable running from northern Sweden to Berlin.
Last month, two nearby fibre-optic cables were severed, prompting a continuing investigation by Swedish authorities. Western intelligence officials from multiple countries have said they are confident a Chinese ship caused the cuts after leaving the Russian port of Ust-Luga, though views differ on whether the cuts were accidental or potentially deliberate.
Since Russia’s invasion of Ukraine in 2022, Sweden has experienced a rise in hybrid warfare – attacks on an adversary using methods other than traditional military action – blamed on pro-Russia groups. With governments in northern Europe on high alert over hybrid Russian activity, the Guardian was given exclusive access to the Stockholm datacentre site.
Daniel Aldstam, the chief security officer at GlobalConnect, which transports 50% of the internet capacity of the Nordics and runs the centre, described the approach to its location and ordinary outward appearance as “security through obscurity”.
“Essentially you have two different approaches,” he said. “Either you put a lot of fences around it which make it obvious that there is something critical, or you do it like we have done it here and try to keep things a little more discreet. But of course we have the normal stuff in terms of alarms, CCTV, access control and all of that.” Inside, cages full of equipment emit blinking lights and different-coloured cables line the ceiling.
After a recent suspected sabotage incident, the Polish prime minister, Donald Tusk, proposed a “navy policing” initiative involving joint military patrols by countries around the Baltic.
Travelling from Stockholm by helicopter over the archipelago, formed of 30,000 islands, rocks and skerries, it is clear to see how challenging the coastline is to protect. But its vastness also suggests how the “security through obscurity” approach could be effective – at least up to a point. Maps that show where all the undersea cables are laid are publicly available.
“We have hundreds of thousands of kilometres of fibre. How do you physically protect it? You can’t,” said Aldstam. “What is important here is the redundancy [using multiple cables offering alternative routes if one is cut off]. You need to have more fibres.”
With infrastructure seen as being particularly vulnerable to hybrid warfare, there are signs of tweaks to the “obscurity” approach, reflecting the fraught times.
GlobalConnect is in the process of setting up a bigger and more modern-looking datacentre nearby, which although still unmarked and painted a similar shade of red, is more obviously a building doing an important function. Inside it has its own diesel-powered backup generator to ensure it could continue running if electricity was cut off.
The vulnerability to sabotage of undersea cables and other critical infrastructure – particularly in the relatively shallow and busy Baltic – has come into sharp focus since Russia’s full-scale invasion of Ukraine.
In September 2022, the Nord Stream pipeline, which carried natural gas from Russia to Germany, was blown up. Initially, many assumed Russia was to blame. However, in August this year, German media reported that German authorities had issued an arrest warrant for a Ukrainian man on suspicion of being part of a team that planted explosive devices on the pipeline. Both sides in the war in Ukraine have denied responsibility and blame each other for the attack.
Nato, which has established a dedicated centre for undersea security, has warned that the security of nearly 1 billion people across Europe and North America is at risk of hybrid warfare by the alliance’s adversaries, due to vulnerabilities in windfarm, pipeline and power cable infrastructure. Earlier this month, the Nato secretary general, Mark Rutte, urged Europeans to “shift to a wartime mindset”.
For all the warnings, undersea cables, which can lie on or be buried in the seabed, look surprisingly slight.
“We call it a super mega cable, but it doesn’t sound super mega or look super mega,” said Patrik Gylesjö, who is responsible for overseeing the whole of GlobalConnect’s Sweden to Berlin cable project, which was completed earlier this year. “The name refers to its capacity rather than the size.”
Inside the cable, which is little more than 2cm in diameter, is a small section formed of 96 hair-thin fibre pairs – enough to support 1bn simultaneous Netflix streams, he said. The rest is made up of steel armouring and a waterproofing substance.
It would take only an anchor from a relatively small ship to break the cable, said Gylesjö. “If you would like to break this cable or cut it, you would not need a super-big tool. It’s quite fragile.”
Making it stronger, he added, would make it heaver, more expensive and “more complicated to deploy”.
Accidental breaks in undersea cables are incredibly rare. “It’s very rare that damage happens in general,” said Gylesjö. “Very rare. During our time as an operator of sea cables [more than 20 years] I think it has happened two to three times maximum.”
+
At the end of an unmarked path on a tiny island at the edge of Stockholm’s extensive Baltic Sea archipelago lies an inconspicuous little wooden cabin, painted a deep shade of red. Water gently laps the snow-dusted rocks, and the smell of pine fills the air.
The site offers few clues to the geopolitical drama that has gripped Scandinavia in recent months, driven by accusations of infrastructure sabotage. But in fact the cabin houses a key cog in Europe’s digital connectivity, and a point of vulnerability in a potential hybrid war: a datacentre that amplifies the signal from a 1,615-mile fibre-optic cable running from northern Sweden to Berlin.
Last month, two nearby fibre-optic cables were severed, prompting a continuing investigation by Swedish authorities. Western intelligence officials from multiple countries have said they are confident a Chinese ship caused the cuts after leaving the Russian port of Ust-Luga, though views differ on whether the cuts were accidental or potentially deliberate.
Since Russia’s invasion of Ukraine in 2022, Sweden has experienced a rise in hybrid warfare – attacks on an adversary using methods other than traditional military action – blamed on pro-Russia groups. With governments in northern Europe on high alert over hybrid Russian activity, the Guardian was given exclusive access to the Stockholm datacentre site.
Daniel Aldstam, the chief security officer at GlobalConnect, which transports 50% of the internet capacity of the Nordics and runs the centre, described the approach to its location and ordinary outward appearance as “security through obscurity”.
“Essentially you have two different approaches,” he said. “Either you put a lot of fences around it which make it obvious that there is something critical, or you do it like we have done it here and try to keep things a little more discreet. But of course we have the normal stuff in terms of alarms, CCTV, access control and all of that.” Inside, cages full of equipment emit blinking lights and different-coloured cables line the ceiling.
After a recent suspected sabotage incident, the Polish prime minister, Donald Tusk, proposed a “navy policing” initiative involving joint military patrols by countries around the Baltic.
Travelling from Stockholm by helicopter over the archipelago, formed of 30,000 islands, rocks and skerries, it is clear to see how challenging the coastline is to protect. But its vastness also suggests how the “security through obscurity” approach could be effective – at least up to a point. Maps that show where all the undersea cables are laid are publicly available.
“We have hundreds of thousands of kilometres of fibre. How do you physically protect it? You can’t,” said Aldstam. “What is important here is the redundancy [using multiple cables offering alternative routes if one is cut off]. You need to have more fibres.”
With infrastructure seen as being particularly vulnerable to hybrid warfare, there are signs of tweaks to the “obscurity” approach, reflecting the fraught times.
GlobalConnect is in the process of setting up a bigger and more modern-looking datacentre nearby, which although still unmarked and painted a similar shade of red, is more obviously a building doing an important function. Inside it has its own diesel-powered backup generator to ensure it could continue running if electricity was cut off.
The vulnerability to sabotage of undersea cables and other critical infrastructure – particularly in the relatively shallow and busy Baltic – has come into sharp focus since Russia’s full-scale invasion of Ukraine.
In September 2022, the Nord Stream pipeline, which carried natural gas from Russia to Germany, was blown up. Initially, many assumed Russia was to blame. However, in August this year, German media reported that German authorities had issued an arrest warrant for a Ukrainian man on suspicion of being part of a team that planted explosive devices on the pipeline. Both sides in the war in Ukraine have denied responsibility and blame each other for the attack.
Nato, which has established a dedicated centre for undersea security, has warned that the security of nearly 1 billion people across Europe and North America is at risk of hybrid warfare by the alliance’s adversaries, due to vulnerabilities in windfarm, pipeline and power cable infrastructure. Earlier this month, the Nato secretary general, Mark Rutte, urged Europeans to “shift to a wartime mindset”.
For all the warnings, undersea cables, which can lie on or be buried in the seabed, look surprisingly slight.
“We call it a super mega cable, but it doesn’t sound super mega or look super mega,” said Patrik Gylesjö, who is responsible for overseeing the whole of GlobalConnect’s Sweden to Berlin cable project, which was completed earlier this year. “The name refers to its capacity rather than the size.”
Inside the cable, which is little more than 2cm in diameter, is a small section formed of 96 hair-thin fibre pairs – enough to support 1bn simultaneous Netflix streams, he said. The rest is made up of steel armouring and a waterproofing substance.
It would take only an anchor from a relatively small ship to break the cable, said Gylesjö. “If you would like to break this cable or cut it, you would not need a super-big tool. It’s quite fragile.”
Making it stronger, he added, would make it heaver, more expensive and “more complicated to deploy”.
Accidental breaks in undersea cables are incredibly rare. “It’s very rare that damage happens in general,” said Gylesjö. “Very rare. During our time as an operator of sea cables [more than 20 years] I think it has happened two to three times maximum.”
Reactions
+To make a comment, please send an e-mail to solar (at) lowtechmagazine (dot) com. Your e-mail address is not used for other purposes, and will be deleted after the comment is published. If you don’t want your real name to be published, sign the e-mail with the name you want to appear.
+Reactions
+Greg
+Hi Kris,
+Thank you for the heated table article! A lot of times I’ll have an idea, +but because I haven’t seen it done, and I’m a coward, I decide it’s +probably a bad idea for some reason I can’t foresee. When you write an +article like that, and include the historical use, then I’m bolstered to +try it!
+You mention “Western-style seating”, and I’m wondering what you think of +this problem: One problem I have with heating myself or my little space, is +that I’m reluctant to move, so I sit too long. There are various health +effects of that, but one I’m battling right now is sciatica that has +affected almost every night of sleep for 10 months.
+I’m wondering if you’ve thought about that, and if you know if people who +do “Eastern-style seating” have any different outcomes?
+Cheers again for the article! +Greg +Australia
+kris de decker
+Hi Greg,
+Indeed I have been looking into the advantages of sitting on the ground, and they are quite significant. While I chose a western-style sitting position for my office, I am considering switching to sitting on the ground in my home. It’s apparently much better for your body, although it does take practice.
+All the best, +Kris
+Kostas
+Hello Kris,
+You may want to add to the article of heated table another insulation material. +Mycelium panels. More resistant to high temperatures also.
+Regards +Kostas
+Kieran
+Good afternoon,
+Thank you so much for this article. It was very enjoyable to read as most of your articles are! My wife and I love Japanese culture and as such I have considered buying/making a Kotatsu. For one reason or another we’ve decided not to.
+But the idea of using the underfloor heating foil is a stroke of genius. Here in the UK, you can buy low wattage “tube heaters” at a very low cost (around £35 for the 80w model). They have a built-in thermostat and run off the 230v wall supply. They are generally used for protecting a greenhouse or shed from frost but I wonder if they would be suitable for this application too? Any thoughts?
+Thanks again for the articles, +Kieran
+Patrick 'DoctorSockrates' Camarador
+I wish this guide was out before I built a prototype “desktop kotatsu” to keep my fingers warm on the keyboard and mouse in my office. Probably would be safer than what I had lying around; I used a simple lapdesk and small blanket that was short enough to not be blocking the monitors on my monitor arms. My heating source was a desktop heater that was supposed to blow hot air on your hands directly, which was uncomfortable the first time I used it since the air wasn’t being trapped and I couldn’t move my mouse hand much underneath it. While it did have a safety shut off for tipping over or overheating, I would’ve loved to have a thermostat for my desktop kotatsu instead…perhaps now with this manual, I can rebuild.
+Patrick “DoctorSockrates” Camarador
+Wim
+The plan sounds solid. +Thank you for the ideas and the time you spend on making this world Low tech minded.
+One remark, for a slightly worried EHS person:
+From a Building Biology point of view it depends on how you design it if it would be considered " fit for consumption" or " healthy for Human Beings". +EMF’s so close to your body can give all sorts of health issues, like headaches, poor sleep, nervous system disorders etc. +Running a 3 wire system (with earth) to power the pad avoids a lot of that.
+The 2 wire part should be as short as possible, and ideally avoided completely. +The heating pad itself should be surrounded by a metal grid connected to earth to avoid excessive EMF’s. +However, the very nature of the heating pad does not allow for a design that avoids EMF’ s , as far as my knowledge goes.
+(You would need to experiment with maze size and use an EMF meter to see what is practical. )
+Anyway, as always, grateful for your efforts turning complex things into easy solutions.
+Kind regards, +Wim
+Eric Wagner
+I was wondering if there was any reason one couldn’t use an electric blanket instead of building an electrically-heated table. You could still have some insulation blankets laid over top of the heated blanket on your lap instead of over the table. +I feel there are benefits to this version, like direct contact with the body for quicker and more heat transfer, and a heated blanket could be used in a variety of position and locations. Some people might want a hard surface on their table for certain types of work, which you could have with the blankets on your lap instead. Also, Since the blankets are only covering your body instead of a whole table, they could be smaller, and finally, I imagine it would be simpler to install. +I love the kotatsu invention, but it makes more sense to me if you are disconnected from the grid, or wanting to use some other type of energy other than electricity.
+Eric Wagner
+Kris De Decker
+@Eric Wagner +I have no experience with electric blankets, never used one. So I cannot really answer your question. One disadvantage I see is that the heating system and the insulation are one. If I spill coffee over my table, I could simply switch blankets. Also, if you put an electric blanket over the table, it will mostly heat up the table rather than your body. So indeed, you would need to put it on your lap. It’s a totally different approach. Also, I don’t see why the heated table would make more sense if you are disconnected from the grid. It works just as well with grid power.
+@Wim +Good point, I did not think of that. I have not noticed any adverse effects after a week of use, but then I am not sensitive to EMF. I could do a test with an EMF meter.
+@Kieran +I didn’t know tube heaters, but had a look online. I don’t think they are suited for a heated table. I see there are some that use as little power as my infrared heating foil, but they seem to have much less surface area. That means that their surface temperature will be higher, risking burns or fire when they come into contact with skin or clothes.
+@Kostas +Thanks, that is something I will try for the next table we build.
+