HN user

Bogdanp

10,780 karma

https://defn.io/page/about

Submissions are not endorsements.

Posts927
Comments188
View on HN
blog.racket-lang.org 8mo ago

Parallel Threads in Racket v9.0

Bogdanp
66pts1
microsoft.github.io 8mo ago

Skeena Indigenous Typeface

Bogdanp
72pts12
zapstore.dev 8mo ago

Zapstore

Bogdanp
3pts0
github.com 8mo ago

Concise explanation of why a cycle-accurate 6502 emulator is easier than not

Bogdanp
3pts0
uni-watch.com 8mo ago

Uni Watch: 1999–2025

Bogdanp
2pts0
www.jaho.com 8mo ago

Jaho Coffee Roaster

Bogdanp
2pts0
www.phoronix.com 8mo ago

Linux Kernel Ported to WebAssembly – Demo Lets You Run It in Your Web Browser

Bogdanp
14pts1
words.filippo.io 8mo ago

Claude Code can debug low-level cryptography

Bogdanp
473pts208
blog.adacore.com 8mo ago

Open-Source Ada: From Gateware to Application

Bogdanp
63pts11
mattermost.com 8mo ago

A deep dive into deeply recursive Go

Bogdanp
1pts0
typesanitizer.com 8mo ago

The purported benefits of effect systems

Bogdanp
7pts0
www.tbray.org 8mo ago

Tim Bray on Grokipedia

Bogdanp
177pts215
support.apple.com 8mo ago

What's New in Shortcuts for the Apple OS 26 Releases

Bogdanp
1pts0
www.washingtonpost.com 8mo ago

Kennedy Center Ticket Sales Have Plummeted Since Trump Takeover

Bogdanp
12pts1
www.theverge.com 8mo ago

October Is over and the Gold Trump Phone Still Hasn't Shipped

Bogdanp
17pts0
www.honeybadger.io 8mo ago

Deep dive into the Elixir Logger module

Bogdanp
2pts0
michael.stapelberg.ch 8mo ago

My Impressions of the MacBook Pro M4

Bogdanp
2pts0
obeli.sk 8mo ago

Challenging the Fastest OSS Workflow Engine

Bogdanp
1pts0
eaton-works.com 8mo ago

Hacking India's largest automaker: Tata Motors

Bogdanp
4pts0
wingolog.org 8mo ago

Wastrel, a Profligate Implementation of WebAssembly

Bogdanp
15pts0
discourse.haskell.org 8mo ago

GHC now runs in the browser

Bogdanp
7pts0
anirudh.fi 8mo ago

Building for the Future

Bogdanp
2pts0
blog.goose.love 8mo ago

The (rust) Clippy Changelog Cat Contest, a brief retrospective

Bogdanp
3pts0
joe-steel.com 8mo ago

CarPlay Seems Essential for Rental Fleets

Bogdanp
10pts2
xdgbasedirectoryspecification.com 8mo ago

Use the XDG Base Directory Specification

Bogdanp
1pts2
prolog.univie.ac.at 8mo ago

Traveling Salesman Game

Bogdanp
4pts0
www.inquirer.com 8mo ago

Local Note: WMMR's Pierre Robert Found Dead at 70

Bogdanp
4pts1
visualrambling.space 8mo ago

Dithering – Part 1

Bogdanp
461pts96
mastodon.social 8mo ago

PCalc 4.11.1 for Mac

Bogdanp
5pts0
lgug2z.com 8mo ago

Normalize Identifying Corporate Devices in Your Software

Bogdanp
72pts61

I have a custom harness that runs in a macOS VM. It has e-mail and its own accounts. I assign it tasks in Linear, it does them and spins up PRs for me to review. This works pretty well, generally. I have to spend time writing stories and doing code review, but I don’t have to follow its (their — I have 3 of them) every move.

Rhombus Language 1 year ago

Web: create an executable distribution[1] and ship it to a server.

Windows/Linux/macOS: same as web, using cross-compilation[5]. Additionally for macOS, embedded in a Swift app and distributed as a .dmg[2] and on the Mac App Store[3]

iOS: embedded in a Swift app and distributed on the App Store[4].

[1] https://docs.racket-lang.org/raco/exe-dist.html

[2] https://franz.defn.io/

[3] https://apps.apple.com/us/app/franz-apache-kafka-client/id64...

[4] https://apps.apple.com/us/app/podcatcher-podcast-player/id67...

[5] https://docs.racket-lang.org/raco-cross/index.html

Rhombus Language 1 year ago

I’ve used it for all kinds of production stuff over the years, from web to desktop and mobile apps.

Notification names are arbitrary strings. It's convention to use "fully-qualified" names like that to avoid collisions. In this case, I imagine that just happens to be what the developer chose as a prefix.

3. from what I understand, shell syntax is available only at REPL top level. Once you switch to Lisp syntax with `(`, you can return to shell syntax only with `)`. Thus means you cannot embed shell syntax inside Lisp syntax, i.e. you cannot do `(define j {find -type f | less})`

It's possible I misunderstand what you mean because I'm not sure what piping to less is supposed to accomplish here, but this is not true. The following program works just fine:

    #lang rash

    (require racket/port
             racket/string)

    (define (echo!!! message)
      (define output {echo $message |> port->string |> string-trim})
      (string-append output "!!!"))

    (echo!!! "Hello")

Nice! Yeah, using protobufs seems reasonable. Re. GC, Racket has support for "freezing" values in place to prevent the GC from moving them, but freezing too many values can impact the GC's operation so I'd watch out for that if that's possible in OCaml.

No worries! I like talking about this stuff.

Yes, the app uses Noise under the hood, and the way to think about it is a request-response model[1]. Swift makes an async request to the Racket backend, it constructs some data (either by querying SQLite, or making a request to the backend, etc.) and returns a response. If it doesn't retain any of the data, then it gets GC'd. The ser/de is relatively low overhead -- if you try the app and go to Settings -> Support and take a look at the logs after using it a little, that should give you an idea of how long the requests take. The lines that start with `#` refer to Swift->Racket RPCs. Here's an example from my logs:

    2025-01-28 13:04:32 +0000 [io.defn.NoiseBackend.Backend] [debug] #006381: waitForAllDownloads()
    2025-01-28 13:04:32 +0000 [io.defn.NoiseBackend.Backend] [debug] #006381: took 319µs to fulfill
    2025-01-28 13:04:32 +0000 [io.defn.Podcatcher.AppDelegate] [debug] didBecomeActive: finished downloading pending episodes
    2025-01-28 13:04:33 +0000 [io.defn.NoiseBackend.Backend] [debug] #006382: getStats()
    2025-01-28 13:04:33 +0000 [io.defn.NoiseBackend.Backend] [debug] #006382: took 2ms to fulfill
Some things on the Racket side are long running, like the download manager. It's like an actor that keeps track of what's being downloaded and the progress of each download. Whenever a download makes progress, it notifies the Swift side by making a callback from Racket->Swift. In this example, there is some duplication since both the Swift and Racket sides each have a view of the same data, but it's negligible.

What's not as great from a memory use perspective is how large Racket's baseline memory use is. Loading the Racket runtime and all the app code takes up about 180MB of RAM, but then anything the app does is marginal on top of that (unless there's a bug, of course).

[1]: I did this precisely because, as you say, keeping keeping data in sync in memory between the two languages would be very hard, especially since the Racket GC is allowed to move values in memory. A value you grab at t0 might no longer be available at t1 if the Racket VM was given a chance to run between t0 and t1, so it's better to just let Racket run in its own thread and communicate with it via pipes. Probably, the same would be true for OCaml.

Thanks for the feedback. Subscribing in particular is slow, especially for podcasts with lots of episodes, because it tries to save all the episode metadata locally, to avoid roundtripping later. So, it’s slow initially so it can be fast later and work offline, but I understand how that can be annoying!

Ultimately, you end up calling some system API for I/O, so the only difference is how efficient the implementations of those Frameworks are compared to the embedded language's implementations. On iOS, embedding Racket requires using an interpreted mode (as opposed to Racket's usual native compilation mode), so there is a small hit, but it's not one that is really noticeable in battery or CPU consumption. In fact, Podcatcher seems to do better in battery consumption compared to the competition in my (and my friend's) testing, but I would guess that's not necessarily _because_ of Racket; it probably has more to do with how the system as a whole pays attention to perf.

A botched deploy that I didn't notice ended up crashing the server, which then failed to recover when the systemd unit tried to restart it (it couldn't bind the port and ran out of retries quickly) overnight, so that's why that was failing. It's back up now and I'll put a fix in today.

That's right, the UI and the Audio Engine bits are in Swift, because it's easier to interface with those Frameworks directly from Swift (and not fight the platform). Everything else (the Database management & the models, the download manager, ID3 parsing, parsing release notes, syncing with the backend server, etc.) is implemented in Racket and is portable.

Yup, unfortunately Podcatcher works the same way and that explains why you'd be getting that error, since the server can't access your feed. That's certainly something that it could support though, but you would obviously not get any push notifications for that feed.

Thanks! I used Pixelmator Pro to put the images together. I just made one long image that I cropped at the end into the screenshots you see on the App Store. For the iPhone templates, I think I exported a template from Sketch, but I later found out that Pixelmator also has them (you can find them under the Mockups category in the New dialog).

Thanks! That makes a lot of sense. It actually only downloads at most 2 episodes per podcast at a time, but that's still not great for your use case. I do plan to add per-podcast settings in probably the release after next, so stay tuned for that!