Elektrine
Log in Register
Paige Chat Timeline Gallery Friends Email Drive DNS Private DNS Domains VPN Kairo Nerve
Remote

Jeremy Gibbons

@jer_gib@functional.cafe
mastodon 4.8.0-alpha.3+glitch
  • Open on functional.cafe

Professor of Computing at University of Oxford: functional programming, types, program construction, verification. Formerly @jer_gib@types.pl.

963 Followers
137 Following
34 Posts
Joined August 08, 2023
Web:
https://www.cs.ox.ac.uk/people/jeremy.gibbons/
Twitter:
@jer_gib
Blog:
https://patternsinfp.wordpress.com/
Youtube:
https://www.youtube.com/playlist?list=PLqFG9BDHUhiA1k3YXFb9U8HktruQ1tG97
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 2w ago
Replying to
@david_chisnall@infosec.exchange ...of which two million were last Tuesday
1
0
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 3mo ago
Replying to
@jaror@social.edu.nl Let me be honest about the real motivation for the book. As I've given talks about it, I've been describing it as my "greatest hits album": reworked and updated material from some favourites among my own papers, plus a few "cover versions" of papers by others that I wish I had written myself.
17
2
5
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 3mo ago
Replying to
@mjd@mathstodon.xyz Nowhere yet, I'm afraid, but soon to appear via Cambridge University Press.
5
1
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 3mo ago
Replying to
I should declare that the cover image is my mockup, using "Kekub" by Victor Vasarely: https://en.vasarely.hu/artworks/15371/
en.vasarely.hu
4
0
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 3mo ago
Replying to
@jaror@social.edu.nl In particular, I promised myself No New Research. I tried to do that on my previous sabbatical, seven years ago, and got sidetracked by https://doi.org/10.1145/3236779 And on the sabbatical before that, another seven years earlier, and got sidetracked by https://doi.org/10.1145/2034773.2034777 I'm proud of both those papers, but they didn't get the book written!
doi.org
4
0
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to
@ltchen@mathstodon.xyz "Some textbooks include selected solutions to exercises, but does it make solving those exercises fruitless? Certainly not." I'm going to remember that line!
7
0
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 6mo ago
Replying to
@liamoc Not just programming. We give students writing exercises to help them learn to write. If they appeal to a machine as soon as it gets tricky, they'll never learn to do it themselves. Similarly for going to the gym.
8
0
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 3mo ago
Replying to
@jaror@social.edu.nl These are excellent questions! To which I don't really have a good answer. I do think the theory is well enough developed for this kind of application. I think sudoku has been well covered, in particular by Richard Bird. I actually have no experience in writing things like web servers: I couldn't take that approach with confidence without a lot of preparation. Someone else will have to write the different book you have in mind.
2
0
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to

@byorgey@mathstodon.xyz I call that operator "long zip with", or lzw for short. It's in my Underappreciated Unfold paper (1998), but also in my dissertation (1991).

4
8
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to

@byorgey@mathstodon.xyz @oantolin@mathstodon.xyz @das_g@chaos.social In fact, this recursion is a concat after an unfold. So it's also a list futumorphism:

futu :: (b -> Maybe ([a],b)) -> b -> [a]
futu g z = case g z of
  Nothing       -> []
  Just (ys, z') -> ys ++ futu g z'

(Not stated is the requirement that the generated chunk ys should be nonempty, in order to guarantee progress. Alternatively one can make the body return Maybe (a,[a],b), enforcing the requirement structurally.) Then we have:

conjugate :: [Int] -> [Int]
conjugate = futu strip where
  strip [] = Nothing
  strip ns = Just (replicate m (length ns), takeWhile (>0) [ n - m | n <- ns ])
    where m = minimum ns
2
1
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to

@byorgey@mathstodon.xyz Your way is a fold. There's also (of course!) an unfold:

transpose :: [[a]] -> [[a]]
transpose = unfoldr next where
  next xss
    | any null xss = Nothing
    | otherwise    = Just (map head xss, map tail xss)

That works for rectangular arrays. Coping also with upper left triangular ones needs a bit more work.

2
7
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to

@byorgey@mathstodon.xyz Given lzw, I think you have

conjugate :: [Int] -> [Int]
conjugate = foldr incr []
  where incr n ms = lzw (+) (replicate n 1) ms
2
4
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to
@pigworker @MartinEscardo @jonmsterling ...and Simon Thompson
2
0
1
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to

@byorgey@mathstodon.xyz @oantolin@mathstodon.xyz @das_g@chaos.social This still takes time proportional to the sum of the partition, because we're only stripping off 1 at a time. You can improve that by stripping off minimum ns in one go:

conjugate :: [Int] -> [Int]
conjugate [] = []
conjugate ns = replicate m (length ns) ++ conjugate (takeWhile (>0) [ n - m | n <- ns ])
    where m = minimum ns

We are effectively snipping off the largest leftmost rectangle from the Ferrers diagram, rather than a single column. I would guess that this achieves the desired complexity.

1
2
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to

@byorgey@mathstodon.xyz For this you want the heterogeneous big brother of lzw:

lzw2 :: (a->b->c) -> a -> b -> [a] -> [b] -> [c]
lzw2 f u v (x:xs) (y:ys) = f x y : lzw2 f u v xs ys
lzw2 f u v xs []         = [ f x v | x <- xs ]
lzw2 f u v [] ys         = [ f u y | y <- ys ]

then you can write

conjugate' :: [Int] -> [Int]
conjugate' = foldr incr []
  where incr n ms = lzw2 ($) id 0 (replicate n succ) ms
1
1
1
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to

@byorgey@mathstodon.xyz I guess lzw3 is the more natural one. Given

data OneOrBoth a b = This a | That b | Those a b

then it is equivalently

lzw3 :: (OneOrBoth a b -> c) -> [a] -> [b] -> [c]
1
0
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to

@byorgey@mathstodon.xyz What's more, lzw is another unfold. To be more precise, uncurry (lzw f) is an instance of unfoldr.

1
5
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to
@mjd@mathstodon.xyz @byorgey@mathstodon.xyz Thanks - I'll have to meditate on that!
1
10
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to
@mc@mathstodon.xyz I wouldn't count it an additional "contribution". It's one aspect of validation of the contribution. If the formalization does not itself introduce new techniques or insights, it's comparable to some performance evaluation or user acceptance testing.
1
0
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago

@pigworker@types.pl You'll enjoy this month's Guardian Genius crossword

1
0
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to
@lindsey Perhaps it is productive to take an event-based as opposed to state-based perspective?
0
4
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 4mo ago
Replying to
@oantolin@mathstodon.xyz I believe you are right to be suspicious. And it's not because it has to extract the last element each time (so I don't think arrays would help). Consider a "triangular" partition such as 10=4+3+2+1. My program splits off a unit-width rectangle at each step, so assembles the conjugate partition (which happens to be the same) one by one. @byorgey@mathstodon.xyz @das_g@chaos.social
0
0
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to

@byorgey@mathstodon.xyz There should also be a way to write that using replicate n succ directly, but now I have to rush off and do something less interesting.

0
1
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to

@byorgey@mathstodon.xyz I'm in two minds about whether I prefer lzw2 above or lzw3 below:

lzw3 :: (a->b->c) -> (b->c) -> (a->c) -> [a] -> [b] -> [c]
lzw3 f g h (x:xs) (y:ys) = f x y : lzw3 f g h xs ys
lzw3 f g h xs []         = map h xs
lzw3 f g h [] ys         = map g ys

lzw3 is more general (you can implement lzw2 using it, and I think not vice versa), but at least in this case a bit clunkier to use:

conjugate' :: [Int] -> [Int]
conjugate' = foldr incr []
  where incr n ms = lzw3 ($) id ($0) (replicate n succ) ms
0
1
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 6mo ago
Replying to
@jfdm Presumably both anglophone?
0
2
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to
@jonmsterling Surely you need some qualifier such as "comfortably" in the conclusion? Many (perhaps most) people are living close to the edge, and can afford to pay one electricity bill or buy one new pair of kid's shoes but not two. They can afford it, but not comfortably.
0
2
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to
@lindsey Without having seen your definitions, wouldn't something like "eventually captures the entire state" be a necessary part of correctness?
0
10
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to
@byorgey@mathstodon.xyz What's the conjugate of an integer partition?
0
12
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to

@byorgey@mathstodon.xyz @oantolin@mathstodon.xyz @das_g@chaos.social Here's another go, I think getting to your desired running time of O(length p + maximum p). Start off by observing that it's an unfold:

conjugate :: [Int] -> [Int]
conjugate = unfoldr strip where
  strip [] = Nothing
  strip ns = Just (length ns, takeWhile (>0) [ n - 1 | n <- ns ])

This assumes that the input is a non-increasing list of positive naturals, and returns a result similarly.

0
6
0
0
Open post
Jeremy Gibbons @jer_gib@functional.cafe
· 5mo ago
Replying to
@oantolin@mathstodon.xyz @byorgey@mathstodon.xyz @das_g@chaos.social I didn't think about it very carefully... will have to ponder further.
0
1
0
0
Back
313k7r1n3
Elektrine

Tor hidden service

elekhj7afj4qnrr4yd3bkzslsyo5jgfxw3orgjkhlcxifueodybyiiad.onion

I2P eepsite

j6b6cyk6gjmepjih7jjadxgxvvf3lzzujljuu2v4biemzpg3naya.b32.i2p

Platform

  • Email
  • Chat
  • Timeline
  • VPN
  • DNS

Company

  • About
  • Contact
  • FAQ
  • Lite (no JS)

Legal

  • Terms of Service
  • Privacy Policy
  • Transparency Report
  • Report Abuse
  • Warrant Canary
  • VPN Policy

Support

  • support@elektrine.com
  • Report Security Issue
Mail client setup IMAP mail.elektrine.com:993 POP3 mail.elektrine.com:995 SMTP mail.elektrine.com:465
© 2026 Elektrine. All rights reserved. Server: 22:50:52 UTC