24,527 karma · joined September 17, 2011
,-------------------------------------------.
| |\
| ,===================================. | \
| | | | \
| | C:\>lynx susam.net | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| |___________________________________| | ,
| | /-,
,-|___________________________________________|/ /|
/ (_____________________________) / |
/_______________________________________________ / |
| | |___
| [@] | | )
| [==========] | / /
| |||||||||| [==========] | / /
|_________________________________________________|/ /
_________________________________________________ /
/ # = = = = # # # # = = = = # # # /- - -/ /,__/
/ //
/ = = = = = = = = = = = = = ## # # # # # # # //
/ ## = = = = = = = = = = = = = # # # = = = # //
/ ### = = = = = = = = = = = ## = = = # /`
/ #### = = = = = = = = = = ### # = = = # /
/ ### ### ============= ## ## # # # === = # /
`-----------------------------------------------'My primary computing and web browsing device remains my laptop, with Emacs and Firefox being my main tools. One thing that does manage to distract me sometimes is YouTube recommendations. As a result I have written a little userscript for myself to disable shorts and recommendations: https://github.com/susam/userscripts/blob/main/js/ytx.user.j...
So far the userscript has been successful. As a side effect of disabling the recommendations sidebar, the video panel expands to occupy a larger part of the screen which I quite like. Here is a screenshot: https://susam.github.io/blob/img/userscripts/ytx.png
Also, I still depend heavily on physical textbooks, a rollerball pen and a stack of plain A4 paper for most of my learning and exploration activities. This routine has helped me to stay away from modern attention media too.
The largest three primes it can show are
3317044064679887385961783
3317044064679887385961801
3317044064679887385961813
Visit https://susam.net/primegrid.html#3317044064679887385961781-2... to see them plotted. Click the buttons labelled '·' and 't' to enable the grid and tooltips, then hover over each circle to see its value.So essentially it can test all 81-bit integers and some 82-bit integers for primality. It does so using the Miller-Rabin primality test with prime bases derived from https://oeis.org/A014233 (OEIS A014233). The algorithm is implemented in about 80 lines of plain JavaScript. If you view the source, look for the function isPrimeByMR.
The Miller-Rabin test is inherently probabilistic. It tests whether a number is a probable prime by checking whether certain number theoretic congruence relations hold for a given base a. The test can yield false positives, that is, a composite number may pass the test. But it cannot have false negatives, so a number that fails the test is definitely composite. The more bases for which the test holds, the more likely it is that the tested number is prime. It has been computationally verified that there are no false positives below 3317044064679887385961981 when tested with prime bases 2, 3, 5, ..., 41. So although the algorithm is probabilistic, it functions as a deterministic test for all numbers below this bound when tested with these 13 bases.
// ==UserScript==
// @name Hostile Volume Winner
// @match https://hostilevolume.com/
// ==/UserScript==
(function () {
const s = document.createElement('script')
s.textContent = `
(function () {
function visible (id) {
return !document.getElementById(id).classList.contains('hidden')
}
function win () {
if (visible('victory-screen')) return
if (visible('instructions-modal')) {
document.getElementById('start-btn').click()
setTimeout(win, 2000)
return
}
setTimeout(function () {
document.getElementById('l13-age-input').value = '01011970'
window.cancelAnimationFrame(levels[currentLevelIndex].frame)
}, 100)
window.setVolume(25)
setTimeout(win, 3500)
}
win()
})()
`
document.body.appendChild(s)
})()
If you don't have a userscript manager, you can just copy the script between the two backticks and paste it to the web browser's Developer Tools console.'You must write docs. Docs must be in your repo. You must write tests. You must document your architecture. Etc. Etc.'
These were all best practices before LLMs existed and they remain so even now. I have been writing extensive documentation for all my software for something like twenty years now, whether it was for software I wrote for myself, for my tiny open source projects or for businesses. I will obviously continue to do so and it has nothing to do with:
> AI changes the game
The reason is simply that tests and documentation are useful to humans working on the codebase. They help people understand the system and maintain it over time. If these practices also benefit LLMs then that is certainly a bonus, but these practices were valuable long before LLMs existed and they remain valuable even now regardless of how AI may have changed the game.
It is also a bit funny that these considerations did not seem very common when the beneficiaries were fellow human collaborators, but are now being portrayed as very important once LLMs are involved. I'd argue that fellow humans and your future self deserved these considerations even more in the first place. Still, if LLMs are what finally motivate people to write good documentation and good tests, I suppose that is a good outcome since humans will end up benefiting from it too.
> Another good example of recursion is quicksort, a sorting algorithm developed by C.A.R. Hoare in 1962. Given an array, one element is chosen and the others partitioned in two subsets - those less than the partition element and those greater than or equal to it. The same process is then applied recursively to the two subsets. When a subset has fewer than two elements, it doesn't need any sorting; this stops the recursion.
> Our version of quicksort is not the fastest possible, but it's one of the simplest. We use the middle element of each subarray for partitioning. [...]
It was one of the first few 'serious' algorithms I learnt to implement on my own. More generally, the book had a profound impact on my life. It made me fall in love with computer programming and ultimately choose it as my career. Thanks to K&R, Tony Hoare and the many other giants on whose shoulders I stand.
Some detractors might say that RSS is dead today, but the reality is far from it. In fact, most of the traffic to my personal website comes from RSS feeds. A little game on my website even became moderately popular after someone discovered it via my RSS feed and shared it here on HN [2].
In fact the three largest sources of traffic to my website are, in decreasing order, RSS feeds, newsletters and search engines. Reviewing the referer (sic) data in my web server logs from time to time, I was surprised to discover just how many community maintained tech newsletters exist on the Web and how active their user bases are. Once in a while, a newsletter picks up one of my silly or quirky posts, which then brings a large number of visits from its followers. But I digress. Back to RSS/Atom feeds now.
So I was saying that there is indeed a decent user base around RSS feeds. I can see from the 'referer' logs that every time I publish a new note or article on my website, a good number of visitors arrive by clicking a feed entry that shows up in their feed reader. I know this with some confidence by looking at the 'referer' headers of visits to my HTML pages and the subsequent browsing of the website, as opposed to the isolated and automated fetches of the XML feeds. So there must be a reasonably active base of users around RSS feeds. It is a bit like being part of an invisible social network that we know exists and that we can measure through indirect evidence.
Many personal websites publish a blogroll with a list of their favourite bloggers. One thing I wish more blogrolls had is links to the bloggers' feeds or, even better, an OPML file that I could import into my feed reader. Then I could keep multiple collections of blogs in my feed reader, for example Alice's Blogroll, Bob's Blogroll and so on. I do publish an OPML file for my blogroll [3], and I urge other personal websites with blogrolls to do the same.
[1] https://github.com/kantord/blogtato#design-philosophy
For better or worse, my first version of any post tends to contain quite a few typos. It usually takes a few train rides of re-reading the post and making notes of the typos, then fixing them and pushing the changes once I get home, before most of them get weeded out. So there is at least one rather low grade indicator that the writing is coming from an imperfect human brain. I also double-space between sentences which can be another low grade indicator for people who care to 'view source'.
But even so, I find myself increasingly wary that something I wrote might be mistaken for LLM output. It is a nagging worry that has slightly dampened the joy of writing. I very well understand why people have become more suspicious about LLM-generated writing. But I do hope that once things settle down perhaps in a few years, the current hair trigger suspicion will ease and that people who still handcraft their blogs will not feel a persistent sense of suspicion lingering over their work.
If you haven't seen it already, Codeberg is seeking donations here: <https://docs.codeberg.org/improving-codeberg/donate/>. A good way to support a product you like rather than becoming the product yourself.
Go for it if Tailwind works for your team.
Inline CSS for your solo project? Chase your dream.
Still stuck on SASS? It'll work just fine.
All in on modern CSS? Go ahead and shine.I had two plain star charts as well, one for the northern hemisphere, which I used constantly, and one for the southern hemisphere, which I rarely needed. But plain star charts cannot show where the planets would be from month to month. So I relied heavily on the monthly charts published by the newspapers. Retrograde planetary motions were hard to estimate manually unless you were an expert. At the age of 10, I wasn't an expert. So the monthly charts were very useful to me.
When my father switched to a different newspaper, I was flabbergasted to discover that our new paper did not publish sky charts. What an outrageous omission! So I promptly wrote a letter to the editor about it and posted it. A month later, the newspaper published my letter in the 'Letters to the Editor' column. Since it was a national paper, I was beaming with joy at the thought that people across the country would read my complaint. Another month later, the paper began publishing sky charts.
These days we can take a mobile phone app and point it at the sky but there is a certain joy in simply exploring the night sky with minimal assistance, appreciating the beauty and mysteries of the universe and pondering philosophical questions like why we are here and why any of this exists. I do not want to sound like a lunatic (and if I do, I suppose I do not mind) but I think it is one of the most immersive experiences a human being can have with the universe.
As a bonus, it can be quite useful to impress your girlfriend too, provided she is of a certain kind. I remember when I met mine about a decade ago, we would sometimes be stuck at traffic lights and I would start calling out objects in the night sky. "That's Jupiter up there. That's Betelgeuse, the red giant star that could go supernova one day. That's Rigel, one of my favourite stars. And there are the Pleiades, one of the most photogenic star clusters. If you draw an imaginary line through the three stars of Orion's Belt and extend it eastward, you reach Sirius, the brightest star." And so on. Within a few weeks, she started joining in, and we would try to name as many objects as possible before the lights turned green again. Fortunately, she found all this entertaining rather than seeing it as evidence of complete derangement, and we are now married.
.ytd-rich-shelf-renderer { display: none }
This single line of CSS seems to just work fine for me. (function () {
const css = `
#secondary { display: none }
.ytd-rich-shelf-renderer { display: none }
`
const style = document.createElement('style')
style.textContent = css
document.head.appendChild(style)
})() // ==UserScript==
// @name No YT Sidebar and Shorts
// @match https://www.youtube.com/*
// ==/UserScript==
function noYTSidebar () {
const element = document.getElementById('secondary')
if (element === null) {
window.setTimeout(noYTSidebar, 1000)
return
}
element.getElementById('secondary').style.display = 'none'
}
function noYTShorts () {
const elements = document.querySelectorAll('ytd-rich-shelf-renderer')
if (elements.length === 0) {
window.setTimeout(noYTShorts, 1000)
return
}
for (e of document.querySelectorAll('ytd-rich-shelf-renderer')) {
e.style.display = 'none'
}
}
noYTSidebar()
noYTShorts() // ==UserScript==
// @name No Shorts
// @match https://www.youtube.com/shorts/*
// @match https://www.facebook.com/reel/*
// ==/UserScript==
window.document.body.innerHTML = ''
This isn't as comprehensive as the uBlock filter but it has worked pretty well for me so far.The trick is to not auto-publish anything. Every comment posted to the website first gets written to a text file which I then review, usually during the weekends. I ignore all the spam, fix any obvious typos in the legitimate comments and then publish them to my website.
I am not a regular contributor to Wikipedia but the little time I have spent contributing there has exposed me to its very elaborate culture, with barnstars being one artefact of that culture, alongside policy acronyms everyone seems to know by heart, WikiProjects organised around every imaginable topic, userboxes that are little badges that say something about you, etc.
By the way, I added a few userboxes for the Logo programming language, in case there are any Wikipedians out here who happen to love Logo: https://en.wikipedia.org/wiki/Category:User_logo
Indeed. I no longer call them social media. They have all become attention media platforms. I recently expressed my thoughts about this on my blog at <https://susam.net/attention-media-is-not-social-media.html>.
These days I typically resolve the domain names of these attention media platforms to 127.0.0.1 in my /etc/hosts file, so that I do not inadvertently end up visiting them by following a link somewhere else. I think there are very few true social media platforms remaining today, among which I visit only HN and Mastodon.
I am not a professional web developer but I have been using JavaScript since 2001 or so. It is only this month that I realised JavaScript does not have a way to seed the pseudorandom number generator (PRNG). So there was no way to do something like:
srand(Math.floor(Date.now() / 1000 / 3600))
As a result, I had to implement a linear congruential generator (LCG) based on the Knuth parameters: <https://github.com/hnpwd/hnpwd/blob/1e513b1/web/script.js>. When I first came across the LCG algorithm (in K&R with different parameters) in the early 2000s, I felt it was neat but assumed I would never need it, since almost every mainstream language comes with a reasonable PRNG. Little did I know back then that the most ubiquitous language on the web would make that old knowledge useful again, some 25 years later.https://susam.net/invaders.html
Both were pretty well received here on HN. The second one is more popular one among the two with about 90 unique visitors per day on an average, as far as I can tell from the access logs after filtering out bots and scrapers. The first one has about 10 unique visitors per day. Really tiny numbers, but it's a delight that some people out there return to this game regularly. Thank you, whoever you are.
Playing computer games is how I was introduced to computers. I too wanted to develop my own invaders-like game when I was about 8 years old. Unfortunately, I neither had enough access to computers nor sufficient programming skills at the time. The first link (invaders.html) is the result of fulfilling that childhood dream 30 years later.
Inspired by a few computer games from the early 1980s, the first game also includes an autoplay algorithm. If you leave the game idle for 5 seconds after loading, the autoplayer kicks in and starts playing the game automatically.
Each game is implemented in plain HTML and JavaScript as a single, unminified, easily readable HTML page. Anyone can download the page, save it locally, play it offline as well as inspect or tweak the source code.
May I request you to consider moving this project to a community organisation like https://github.com/<your-new-org> so that we, the HN folks, can maintain it as a community? Curated list projects often start with a lot of enthusiasm and I follow several similar ones focused on personal websites and blogs. While some of the curators remain active and maintain their project even years later, some do not. This isn't a complaint. I know life happens and circumstances change. So it is understandable that some of these projects become inactive later.
But it becomes a little problematic when someone wants to have their creation added to the curated list but cannot do so because the maintainer is no longer active. Of course, volunteers can fork the project and maintain it as a community but this is easier said than done. Once a 'Show HN' thread like this becomes successful, future visitors are more likely to end up on the original but no-longer-maintained curated list than the newer community maintained fork. For that reason, when I created my list of curated personal websites, I did so under the organisation <https://github.com/hnpwd> from the very start, and now we have multiple maintainers and contributors helping out with the curation.
Hosting the project under a community org with multiple maintainers could give it a better chance of staying active in the long term. This is only a request. I do not mean to impose or pressure you in any way. Please feel free to ignore the suggestion and thank you again for the work regardless.
The web browsers don't highlight the feed URL information embedded in the HTML anymore, quite unfortunately. But if you go to a YouTube video, say, <https://www.youtube.com/watch?v=9kaIXkImCAM> and then view or inspect the HTML source, you can find the LINK tag for the feed:
<link rel="alternate" type="application/rss+xml" title="RSS" href="https://www.youtube.com/feeds/videos.xml?channel_id=UCi8C7TNs2ohrc6hnRQ5Sn2w">
So the feed URL in this case is: <https://www.youtube.com/feeds/videos.xml?channel_id=UCi8C7TN...>.For anyone else who is interested in taking a look, here is my setup:
* The server-side program that processes the POST requests: https://github.com/susam/susam.net/blob/0.5.0/form.lisp#L254...
* The static site generator reads the comment files and renders them alongside the rest of the website: https://github.com/susam/susam.net/blob/0.5.0/site.lisp#L869...
* End result: https://susam.net/comments/
The last link shows the consolidated comments page that lists all approved comments posted across my entire personal website. The 'View original comment' link under each comment points to the individual comment page for each post.
1. Accept comments via email, CGI scripts, server-side program or by any other means that suits you. A simple hack that requires no server-side scripting: if you run your own web server, you can submit comments as GET query parameters logged in access.log, then extract them using grep, sed, etc. Personally, I use a server-side program to accept POST requests and write comments to a text file on the web server.
2. Review submitted comments. Delete spam.
3. Add comments to your website source repository as .md, .html or whatever format you use, similar to how you add blog posts as content files to your source.
4. Render comments alongside the rest of your site using your static site generator. Depending on the nature of your static site generator, this may require using or creating a template or layout that iterates over the comments and renders them.
It is a fairly hands-on workflow, so it may not suit everybody, but this is how I do it for my personal website. I see two main benefits of this approach. Since the review is manual in step 2, no spam can ever make it to my website. Step 3 ensures comments live entirely under my control, so I never need to worry about migrating them between platforms in the future.
1. Common Lisp, Python.
2. This is not exactly a language feature but more of an attribute of the ecosystems, but I wish Common Lisp had a more comprehensive 'batteries included' standard library. It does have a pretty good standard library [1] for its time, but in the modern day, it fades in comparison to that of mainstream languages like Python or Go. Yes, the availability of Quicklisp compensates for the relatively smaller standard library, but it does not fully replace the value of having a large and cohesive standard library.
For Python, I wish (and this might be controversial) that it used s-expressions instead of whitespace-based delimiter for blocks. I find cutting, pasting, moving around, and in general, manipulating whole s-expressions as individual units very convenient with appropriate editor support (e.g. Paredit). I know there are languages like Racket, Clojure, etc. which fulfil the requirement of extensive batteries included library + s-expressions, but they are much less popular than Python. In my ideal world, one of the top three popular languages would be a Lisp or Lisp-like language with an extensive standard library comparable to Python's.
3. Common Lisp for personal projects. Python for collaborative projects.
[1] https://www.lispworks.com/documentation/HyperSpec/Front/X_Sy...
hello world
4ef69019c65909ffbb470597e3c5afe05ea8a866a0d3b9f950f0bcf057924b52
hello
4358f43b660389eecd435dc2a5f5cee29786245cd2cff27bd4de0b3e8fd53b79
4ef69019c65909ffbb470597e3c5afe05ea8a866a0d3b9f950f0bcf057924b52
406cc6dbc566bf6c672a2167868341e9853f7fbbd2a21eb1caa4d08006abae41
hi
661ce2e5ed28422eb8b51ec2a217c976e05e37713246166e8fcbf67be4824380
test
83d34c0abee918ed3edf585b6cb8ce97fe8286027b012bacdfa71b967924f9b2
a
beef7c4d3141c30ab4f6ebf1f724936c50f609ee1915951d802046ba1d9fa23d
subth.ink
3f3b05abaec959c9950d5a93a64525971c7d9fcabf6436d653edba62f29d5bea
lol
39567a3cc35a4c68d72d01beac88414d0ced5c20b437ff9bc6e2cb20615a47b7
Thanks to Y@Y for 4ef69019c65909ffbb470597e3c5afe05ea8a866a0d3b9f950f0bcf057924b52.