May 22, 2026

Global Health Crisis and Technical Breakthroughs: A May 2026 Update

Executive Summary

The late weeks of May 2026 have been defined by a stark contrast between accelerating scientific innovation and a crumbling global health infrastructure. While researchers have announced breakthroughs in low-cost hydrogen production and formal AI verification, a resurgent Ebola outbreak in Central Africa is being exacerbated by a deliberate withdrawal of United States leadership and funding. Meanwhile, the geopolitical landscape remains volatile as tensions simmer over Arctic sovereignty and the future of Taiwan.

Global Health: The Ituri Ebola Outbreak and the American Void

A significant Ebola outbreak, involving the rare Bundibugyo strain, has taken root in the gold-rich Ituri province of the Democratic Republic of the Congo. This crisis is being compounded by a systemic withdrawal of U.S. global health support. Following massive budget cuts to USAID and the CDC, American funding for health programs in the DRC has collapsed from $1.4 billion in 2024 to just $21 million in 2026. Experts argue that the closure of specialized labs, such as NIH facility in Frederick, Maryland, has left the world without critical research capacity at a moment of maximum vulnerability.

AI Research Moving on from LLMs

A technical shift is underway in AI industry. New Energy-Based Models (EBMs) are moving away from simple language prediction toward formal verification. Systems like Olive from Logical Intelligence have achieved near-perfect scores on formal reasoning benchmarks, signaling a future where AI correctness is verified by deterministic compilers rather than mere probabilistic fluency.

Energy Transition: Breakthroughs in Hydrogen Production

Two major advancements in materials science have significantly improved the outlook for decentralized energy production. Researchers at the University of Birmingham have developed a new perovskite catalyst that enables hydrogen production from industrial waste heat at temperatures as low as 150°C.

Simultaneously, the University of Hong Kong has introduced a specialized stainless steel (SS-H2) designed for seawater electrolysis. By resisting corrosion in harsh chloride environments, this material could replace expensive platinum-coated titanium components, potentially reducing the structural material costs of electrolyzers by up to 97.5%.

Geopolitics: Greenland Sovereignty and the Taiwan Price

Geopolitical friction has intensified in the Arctic as hundreds of residents in Nuuk protested the opening of a new, expanded U.S. consulate. The Trump administration has been exerting intense pressure on Greenland and Denmark to grant Washington veto power over foreign investments, framing it as a national security necessity.

On the other side of the globe, the May 2026 Trump-Xi Summit in Beijing has revealed a shift in the U.S.-China power dynamic. In exchange for cooperation on global trade and maritime security in the Strait of Hormuz, China appears to be extracting significant concessions regarding the future of Taiwan, as the U.S. grapples with its own economic vulnerabilities and the ongoing stalemate in the Middle East.

Sources

May 19, 2026

Global Reckonings: May 2026 Update 2


Summary

In the Arctic, the Trump administration’s demand for veto power over Greenlandic investments has sparked a sovereignty crisis that tests the endurance of the Danish-Greenlandic partnership.

In the courts, OpenAI has cleared a massive legal hurdle with the dismissal of Elon Musk’s $150 billion lawsuit, even as its own engineers begin to organize against the ethical trajectory of the technology.

Meanwhile, the strategic landscape of modern warfare is shifting; Ukraine’s record-breaking drone offensive has turned Russia’s vast geography into a defensive liability.

Globally, the human cost remains high as the Ituri province in the Democratic Republic of the Congo faces an Ebola outbreak complicated by conflict and the absence of a vaccine.

The Arctic Sovereignty Crisis

The pursuit of “national security” is increasingly colliding with the autonomy of smaller nations. In closed-door negotiations, the United States is exerting intense pressure on Greenland and Denmark to grant Washington veto power over foreign infrastructure investments. The U.S. demands a major role in Greenland as a means to exclude Chinese and Russian influence, but the move has backfired in Nuuk.

Greenlandic Prime Minister Jens-Frederik Nielsen has resisted the “all or nothing” demands, framing American interference as a threat to Greenland’s internal governance and environmental standards. This friction comes as the Trump administration continues to re-evaluate its global alliances, with many in the Arctic watching the upcoming July 4th holiday for further shifts in U.S. policy.

OpenAI’s Courtroom Victory

The legal cloud over the world’s most prominent AI firm has lifted, if only partially. A federal jury recently rejected Elon Musk’s $150 billion lawsuit against OpenAI, citing the statute of limitations. While the verdict clears the path for a potential OpenAI IPO later this year, the company faces a new challenge from within.

Tech workers building A.I. are increasingly vocal about their fears, with engineers at firms like Google DeepMind unionizing to demand a voice in how their technology is deployed. These workers cite ethical concerns over military contracts and the potential for lethal autonomous weapons, leveraging their rare technical expertise to force a dialogue that regulators have yet to master.

The Geography of Vulnerability

The nature of defense is being rewritten by the sheer volume of low-cost technology. Ukraine recently launched its largest drone operation of the year, sending 600 drones across 14 Russian regions in a single night. This massed precision strike highlights a new strategic reality: Russia’s vastness, once a shield, is now a vulnerability that is impossible to defend comprehensively.

As technology accelerates on one front, older tragedies resurface on another. In the Democratic Republic of the Congo, the Ituri Ebola outbreak has been declared a global health emergency. The situation is uniquely perilous; the Bundibugyo strain has no approved vaccine, and the population—already “stretched to breaking point” by militia conflict and aid cuts—faces economic collapse if health restrictions prevent mining and trade.

Structural Stalemate

In the Middle East, the Iran War remains in a tense “hold-off.” While President Trump authorized new strikes, he has paused the operation as Iranian defenses adapt and U.S. air tactics face increased scrutiny.

This military stalemate is mirrored by the economic one discussed during the recent Beijing summit. Despite the diplomatic pageantry, analysts suggest that the fundamental trade imbalance between the US and China is a structural accounting problem driven by domestic consumption policies that no single summit can solve.

Sources

May 18, 2026

Strategic Limbo and the Cost of War: A Mid-May 2026 Global Update

New Series of Posts

This is the start of an experiment in AI-assisted short reviews of media items I have read or watched recently, with longer term implications on the state of the world as we know it.

Some of the reviewed sources are behind a paywall and some may be in languages other than English, like the Helsingin Sanomat article linked below.

Summary

Global developments in mid-May 2026 highlight a world caught in a “strategic limbo” as the Iran War enters a new, more dangerous phase. Domestically, the Trump administration faces a dual challenge of record-low consumer confidence driven by a deepening inflation crisis and growing controversy over the public funding of religious festivals. Globally, the compounding effects of the Strait of Hormuz blockade are manifesting as a systemic fertilizer crisis and manufacturing shutdowns in East Asia, while the World Health Organization (WHO) grapples with a new Ebola emergency in the Democratic Republic of the Congo.

US Domestic Issues

President Trump’s economic agenda is facing its sternest test yet as the national average gas price hit $4.52 per gallon, a 40% increase from last year. For Trump, Soaring Prices Test Voters reports that consumer confidence has dipped to an all-time low in May 2026, with inflation outpacing wage growth. This economic strain coincides with the “Rededicate 250” prayer festival on the National Mall, where thousands gathered for a government-funded worship service that critics argue blurs the line between church and state.

Iran and the “Second Strait”

The stalemate in the Iran War appears to be fracturing. Analysts report that Tehran expects a U.S. attack within 48 hours as both sides seek to improve their negotiating leverage. Iran’s new retaliatory strategy reportedly includes targeting U.S. data centers in the UAE and potentially severing submarine fiber-optic cables, creating what experts call a “second Strait of Hormuz.” This escalation follows the failure of the “blockade of the blockade” strategy and ongoing disputes over Iran’s enriched uranium stockpiles.

A Planet Under Pressure

The World Health Organization has declared the Ebola outbreak in the DRC and Uganda an emergency of international concern. The outbreak, caused by the Bundibugyo virus, is complicated by the presence of M23 militia forces in regions like Goma. Simultaneously, Karachi struggles under brutal extreme heat, with temperatures hitting 44.1°C. Climate scientists note that human-caused climate change has tripled the probability of such events, which are now becoming a “brutal new reality” for South Asia.

Supply Chain Strangles

The maritime blockade is causing a “wave of scarcity” across the globe. Taiwan’s plastic habit is colliding with shortages as the disruption of petrochemical flows from the Middle East forced a 42% production cut at Formosa Petrochemical. More critically, the Hormuz crisis has disrupted global fertilizer markets, blocking one-third of the world’s supply. The World Food Programme (WFP) warns that an additional 45 million people could face acute hunger as a result. Amidst these crises, the pursuit of truth remains perilous; journalism has never been more dangerous, with 2025 recorded as the deadliest year on record for media workers.

Sources

December 11, 2019

Melting, everywhere

Melting of large deposits of ice, in glaciers and in permafrost, has been frequently with about in the recent years. When it comes to meeting on Greenland, we seem to be following the rates of the worst case predictions of older IPCC reports.

https://www.washingtonpost.com/climate-environment/2019/12/10/greenland-ice-losses-have-septupled-are-pace-sea-level-worst-case-scenario-scientists-say/

https://www.tiede.fi/artikkeli/uutiset/gronlanti-sulaa-kuumimman-ennusteen-mukaan

There are some alarming developments in the Arctic permafrost of Sundries and Alaska. It seems like we will soon be crossing one threshold of positive feedback very soon.

https://www.washingtonpost.com/weather/2019/12/10/arctic-may-have-crossed-key-threshold-emitting-billions-tons-carbon-into-air-long-dreaded-climate-feedback/


“Especially noteworthy is the report’s conclusion that the Arctic already may have become a net emitter of planet-warming carbon emissions due to thawing permafrost, which would only accelerate global warming. Permafrost is the carbon-rich frozen soil that covers 24 percent of the Northern Hemisphere’s land mass, encompassing vast stretches of territory across Alaska, Canada, Siberia and Greenland. 
There has been concern throughout the scientific community that the approximately 1,460 billion to 1,600 billion metric tons of organic carbon stored in frozen Arctic soils, almost twice the amount of greenhouse gases as what is contained in the atmosphere, could be released as the permafrost melts.”
https://www.nytimes.com/2019/12/14/opinion/sunday/climate-change-arctic.html
The ice is a great white shield that reflects incoming solar warming back to space during the long summer days of the midnight sun. Otherwise, it would be absorbed by the ocean. Losing this ice, the study explained, would be the warming equivalent of an extra 25 years of emissions at current rates.”

Long time no see

I haven't written anything in quite a while. Maybe I should.

This  page has been functioning as my dumping found for excess thoughts, caused by reading way too much news, especially during the years 2002-2009 when I had something like an addiction, following the war on Iraq and the global economic downturn, fueled by the subprime crisis. I have certainly followed news very actively, but not with such an addiction anymore.

Recently, there has been a heightened level of interest in physical signs of climate change, rise of far right populist movements and overall political polarization in developed countries. I feel that a prolonged global trade war between the US and China is still just in its infancy, and will get quite a lot more intense, before settling into a new status quo.

The next economic downturn in the US will leave much more devastation behind it than most people currently realize, due to the pro-cyclic Republican tax policies that have produced a massive budget deficit at the very top of the business cycle. There will be no room for stimulus in the next downturn. The result will be either a self-enforcing austerity or a dramatic collapse in the value of the dollar and possible loss of US credit rating.

After some strange, partially media-led turmoil, our Finnish government is now led by a much younger group of people than ever since the 70's. This is a welcome development, but I hope they keep their feet on the ground. The centre-leftist government is met with a corporate media dead-set against some of its goals. It is difficult to filter the substance from the opinion.

With these developments, I am feeling that there is a risk of getting a information indigestion. It is certainly not helped by all the information that I need to digest in my professional life, which nowadays seems to consist of continuous learning of new software development tools and libraries.

December 20, 2017

Haskell and type composition the easy way

Below is a small Haskell module that I wrote as an exercise. It defines nifty little utility in the form of a generic type composition mechanism. A composite type is any type in which a type constructor is applied to a another type (denoted with type variables, like a (b c)). It can represent for example a list of optional values, i.e [Maybe Int], aka [] (Maybe Int), or an IO operation sequence that operates on a list of values (IO [a]), etc.

Haskell provides many useful high-level programming constructs for managing individual types, but its standard libraries lack a truly flexible denotation for extending those high-level functions to composition data types. Some of these issues are solved by using so-called "monad transformers", which are very sophisticated, but must be separately defined for each individual monad. And as the name says, their application is limited to monads, and they cannot be used for the many quite useful classes of type constructors at the lower levels of the functor hierarchy, such as Functors, Foldables, Traversables or Applicatives.

The small (and silly) test function at the end of the modules shows, how this modules enables flexible intermingling of overlapping data types using both the monadic do syntax and plain fmap calls. While this only seems to apply to compositions of two types at a time, it quite easily generalizes to any number of types, via meta-composition. If a, b, c ... g are functors, then so is (Comp a b). IO [Maybe Int] can be tagged as Comp (Comp IO []) Maybe Int. Hmmm... Maybe the next step is to generalize these operations to a recursive data type representing arbitrary chains of composition.

One cannot help but appreciate how all of these very useful operations are relatively short one-liners. (Readability for persons not familiar with Haskell or Scala is another question.

{-# LANGUAGE FlexibleContexts #-}

-- A generic type composition module by Reino Ruusu, December 2017, Espoo, Finland

-- The simple type composition tag defined here can do many of the tasks that
-- monad transformers are used for, but in a much more generic way, allowing
-- useful compositions of Functors, Foldables, Traversables, Applicatives and
-- Monads (with certain restrictions).

import Control.Applicative
import Control.Monad
import Data.Foldable
import Data.List

-- This type tags a composition type as a parameterized type constructor
newtype Comp m n a = Comp (m (n a))

-- Decorate a `raw' composition type
comp :: m (n a) -> Comp m n a
comp = Comp

-- Undecorate a tagged composition type
decomp :: Comp m n a -> m (n a)
decomp (Comp x) = x

-- Lift a raw outer type to the composition type (inner has to be Applicative)
lift1 :: (Functor m, Applicative n) => m a -> Comp m n a
lift1 = Comp . (pure <$>)

-- Lift a raw inner type to the composition type (outer has to be Applicative)
lift2 :: (Applicative m) => n a -> Comp m n a
lift2 = Comp . pure

-- Foldable instance
instance (Foldable m, Foldable n) => Foldable (Comp m n) where
  -- foldMap :: Monoid k => (a -> k) -> Comp m n a -> k
  foldMap f (Comp x) = foldr (\a l -> foldMap f a `mappend` l) mempty x 

-- Functor instance
instance (Functor m, Functor n) => Functor (Comp m n) where
  -- fmap :: (a -> b) -> (Comp m n a) -> (Comp m n b)
  fmap f (Comp x) = Comp (fmap (fmap f) x)

-- Applicative instance
instance (Applicative m, Applicative n) => Applicative (Comp m n) where
  -- pure :: a -> Comp m n a
  pure = comp . pure . pure
  -- (<*>) :: Comp m n (a -> b) -> Comp m n a -> Comp m n b
  Comp f <*> Comp x = Comp (liftA2 (<*>) f x)

-- Monoid instance
instance (Applicative m, Applicative n, Monoid a) => Monoid (Comp m n a) where
  -- mempty :: Comp m n a
  mempty = pure mempty
  -- mappend :: Comp m n a -> Comp m n a -> Comp m n a
  mappend = (*>)

-- Monad instance (only works if inner type is Traversable, unlike IO, for example)
instance (Monad m, Monad n, Traversable n) => Monad (Comp m n) where
  -- return = pure
  -- (>>=) :: Comp m n a -> (a -> Comp m n b) -> Comp m n b
  Comp x >>= f = Comp $ x >>= fmap join . sequence . fmap (decomp . f)


-- Test routine, builds a (Comp IO []) monad in the do block
-- First fmap (show) applies to (Comp IO [] Int), resulting in (Comp IO [] String).
-- After decomp, second fmap applies to (IO [String]).
-- Execution results in 4*(1 + 4) calls to print, and a return value of
-- "4, 5, 6, 7, 3, 4, 5, 6, 2, 3, 4, 5, 1, 2, 3, 4"

test :: () -> IO String
test () = fmap (intercalate ", ") $ decomp $ fmap (show) $ do
  a <- lift2 [1, 2, 3, 4]
  lift1 (print a)
  b <- lift2 [5, 6, 7, 8]
  lift1 (print (a, b))
  return (b - a) :: Comp IO [] Int

November 26, 2017

The beauty of Haskell

I've been taking a more serious look into Haskell programming, and have deeply fell in love with its "purity", i.e. its nature as a purely functional programming language, in which everything is expressed entirely in terms of what happens to data.

Another very attracting feature is its very rich toolbox of higher level programming constructs that allow one to express complex data processing tasks in just a few function calls.

A third beautiful aspect of the language is its typing system, which provides automated type matching of undeclared functions and variables. It provides a type checking system just like any other strongly typed language, but without the need to separately declare the types of each and every variable.

On the other hand, these features make Haskell quite difficult to read for people who are not familiar with it, but on the other hand, the amount of code to read can be very small, and absolutely oozing with semantics, i.e. there code is typically very dense, and the reader is not bothered with unnecessary details, such as the name of an iteration variable.

The way in which stateful programming is expressed in Haskell, which is a pure language in the sense that absolutely no side effects are allowed in the code, can be a bit confusing for a beginner, but after one gets the hang of it, one starts to really appreciate the pure functional programming paradigm.

With no side effects and a strong typing system, any program that compiles actually does something, there is no concept of a run-time failure, except in the case of a match against a partially defined pattern, or similar situations.

Additionally, lazy evaluation allows one to express interactive processes simply as ordinary pure functions, which is really convenient, though may be quite confusing.

Below is an example of a hangman program, written in Haskell, using lazy evaluation and the State monad. The program lets the user guess a word one letter at a time. If the user makes 5 wrong guesses, he loses the game.


-- A hangman game using the State monad in Haskell by Reino Ruusu, 2017

import System.Environment
import System.Random
import Control.Monad.State.Lazy
import Data.Char

-- Hangman IO
main = do
  args <- getArgs
  if null args then
    putStrLn "Please provide a file containing words. (One per line.)"
  else do
    -- Select random word
    words <- readFile (head args)
    word <- randomElement (lines words)
    -- Play the game
    interact $ hangmanMain (map toLower word)

-- Hangman game as a pure lazy string processing function
hangmanMain :: String -> String -> String
hangmanMain word = unlines . ("Welcome to Haskell Hangman":) . hangman . ("":) . lines
  where
    hangman input = map snd $ takeUntil fst $ evalState (sequence steps) initialState
      where
        steps = map (hangmanIteration word) input
        initialState = (initialGuess, 0)
          where
            -- Alphabetic characters replaced with underscores
            initialGuess = map (\w -> if isAlpha w then '_' else w) word

-- A single iteration of hangman: State update followed by output
hangmanIteration :: String -> String -> State (String, Int) (Bool, String)
hangmanIteration word input = update >> report
  where
    update = unless (null input) $ do
      -- Check user's guess and update state
      (guess, strikes) <- get
      if elem l word && not (elem l guess) then
        put (newguess guess, strikes) -- Hit
      else
        put (guess, strikes + 1) -- Miss
      where
        l = head input
        newguess = zipWith (\w g -> if w == l then w else g) word
    report = do
      (guess, strikes) <- get
      -- Status message - example: __a_e__ ###
      let status = guess ++ " " ++ (replicate strikes '#')
      -- Check game outcome
      return $ if guess == word then
                 (True, status ++ "\nYou won!") -- Win
               else if strikes >= 5 then
                 (True, status ++ "\nYou lost! (" ++ word ++ ")") -- Loss
               else
                 (False, status) -- Continue

-- Utility functions

-- Take elements up to and including the first for which f returs True
takeUntil f l = first ++ [head last]
  where (first, last) = break f l

-- Select a random element from a list (as an IO operation)
randomElement list = do
  i <- randomRIO (0, length list - 1)
  return (list !! i)



The execution of the game looks like this:
Welcome to Haskell Hangman
____________
a
____________ #
e
____________ ##
i
_i________i_ ##
o
_i__o_____i_ ##
u
_i__ou____i_ ##
s
_is_ou__s_i_ ##
c
_iscou__s_i_ ##
v
viscou__s_i_ ##
t
viscou_ts_i_ ##
y
viscou_ts_i_ ###
n
viscounts_i_ ###
p
viscounts_ip ###
l
viscounts_ip ####
h
viscountship ####
You won!
Note how the game itself is defined as a pure function that simply processes the input string into the output string. Furthermore, all iteration in the code happens via higher level programming constructs that clearly define rules for processing of data, instead of bothering with low-level things such as updating an iteration variable. All the IO is performed by calling this function via the interact function, which simply maps input and output from the console to a pure function from string to string. The business logic can then be defined purely by describing the relationship between the input and the output, without bothering with any aspects of the IO operations.

The steps of the game are here described using the State monad, which allows one to define processing as a combination of stateful operations.

An almost equally elegant solution can be achieved by the very versatile mapAccumL operation, which provides for simultaneous accumulation of state and processing of data. However, in this approach, the hangmanIteration function is much less understandable in isolation, whereas in the version based on the State monad, the state update is directly specified by the definition of the iteration function itself. The state monad allows us to also make use of elegant and semantically rich higher level constructs, such as unless above.


-- A hangman game in Haskell by Reino Ruusu, 2017

import System.Environment
import System.Random
import Data.List
import Data.Char

-- Hangman IO
main = do
  args <- getArgs
  if null args then
    putStrLn "Please provide a file containing words. (One per line.)"
  else do
    -- Select random word
    words <- readFile (head args)
    word <- randomElement (lines words)
    -- Play the game
    interact $ hangmanMain (map toLower word)

-- Hangman game as a pure lazy string processing function
hangmanMain :: String -> String -> String
hangmanMain word = unlines . ("Welcome to Haskell Hangman":) . hangman . ("":) . lines
  where
    hangman input = map snd $ takeUntil fst output
      where
        output = snd $ mapAccumL (hangmanIteration word) initialState input
        initialState = (initialGuess, 0)
          where
            -- Alphabetic characters replaced with underscores
            initialGuess = map (\w -> if isAlpha w then '_' else w) word

-- A single iteration of hangman: State update followed by output
hangmanIteration :: String -> (String, Int) -> String -> ((String, Int), (Bool, String))
hangmanIteration word state input = (newState, report newState)
  where
    -- Check user's guess and update state
    newState = if null input then
                 state
               else if elem l word && not (elem l guess) then
                 (newguess guess, strikes) -- Hit
               else
                 (guess, strikes + 1) -- Miss
      where
        l = head input
        (guess, strikes) = state
        newguess = zipWith (\w g -> if w == l then w else g) word
    report (guess, strikes) = let
      -- Status message - example: __a_e__ ###
      status = guess ++ " " ++ (replicate strikes '#')
      -- Check game outcome
      in if guess == word then
           (True, status ++ "\nYou won!") -- Win
         else if strikes >= 5 then
           (True, status ++ "\nYou lost! (" ++ word ++ ")") -- Loss
         else
           (False, status) -- Continue

-- Utility functions

-- Take elements up to and including the first for which f returs True
takeUntil f l = first ++ [head last]
  where (first, last) = break f l

-- Select a random element from a list (as an IO operation)
randomElement list = do
  i <- randomRIO (0, length list - 1)
  return (list !! i)