HNHacker News
TopNewBestAskShowJobs

klibertp

5,050 karma · joined August 16, 2012

I'm a programmer and a programming language (both in theory and practice) geek. I advocate polyglot programming and have a site dedicated to it: https://klibert.pl/

Contact: The best way to contact me is to send an email to piotrklibert of fastmail.com domain. Or you can leave a comment here: https://klibert.pl/articles/contact.html or ping me on Discord: piotrklibert

Take a look at https://klibert.pl/articles/about.html for more info about me.

submissionscomments
klibertp··on Firewood Splitting Simulator
Well, it's the kind of "meditative" you get when training martial arts forms. It gets good after a few years of preparation; before that, it's not as fun as spars and way less useful than general conditioning.

Coming from a kendo background, when I had to chop firewood for a few years while living in the countryside, I generally focused on accuracy. The swing is completely different than with a sword, and getting the chop to land at the exact spot (I drew lines with a marker) tens of times in a row was very satisfying, but required a lot of conscious effort to get there. It's not trivial to land a chop at the exact spot you want, and it's also quite hard to ensure the axe travels at its fastest exactly at the moment of impact.

It can be fun, but you need to be into things like that in the first place; plus, having to do it no matter the weather and all the other things you need to do can kill all the joy instantly.

klibertp··on OCaml Onboarding: Introduction to the Dune build system
> Because it's really limited and not expressive?

It's neither of those unless you limit yourself to a lowest-common-denominator feature set. GNU Make, for example, is a Turing-complete, dynamic programming language and a CLI task runner. You can build a build system in GNU Make (https://github.com/omercsp/simple-build-system) just like you can do so in any other language.

Make suffers from unfamiliar and somewhat unorthodox syntax, and inconsistent language design. So it's not a good language, and saying it "sucks" is not completely unjustified, but not because it's limited. Looking at SBS, it also seems quite expressive, although I can't say I ever tried building something in it myself.

klibertp··on Building from zero after addiction, prison, and a felony
I'm sorry for your relative, and of course you should always do things like driving (diving, cycling, sailing, climbing - or even cooking and cleaning) as if a tiny mistake could cost you everything: that's because it's actually true. These activities will never be risk-free; the best you can do is bring the risk down to a level comparable to that of alternatives (with "just don't do it" included in the set) and hope no unfortunate incidents occur to you.

It's still worth noting the relative probability: death or life-changing injury is basically what happens in every single accident when you're going 200km/h on a highway surrounded by (what could as well be) steel walls moving at the same speed; in my use case, when not exceeding 40-50 km/h and using roads where other users basically stand still most of the time, you need a pretty specific conditions and a lot of bad luck to even have an accident, much less die or become permanently disabled as a result of one. Still, not a zero probability, but the difference between 100% and 0.01% is kind of noticeable.

klibertp··on LLMs are eroding my software engineering career and I don't know what to do
> Maybe I don't remember how to stitch something together, but i know it can be done.

That's how I use the current AI, too. I never ask them to do something without specifying how it should be done. I ask questions first, use /plan to let the model ask me questions, then I let it execute the plan while reviewing the results. More and more often, I get something close enough to what I would have written. In the opposite case, I at least know exactly how to rewrite the result, if needed.

I observe the same effect as you: while it does sometimes speed up the implementation a bit, it's not very noticeable; however, it frees me from having to recall all the obscure little details up front. Instead, I can describe them, have the model implement them, and then recognize them (and refresh my memory) when reviewing. The effect is that it's easier to start a task because I don't need to prepare as much to execute it. It's especially notable on things that I haven't touched for some time. I know, more or less, how my Elixir projects are set up, but after ~2 years of not working on them, getting back into them had been a hassle - with AI, it's no longer that. I think the biggest difference comes from the AI lowering the cost of context switching for me - I used to have huge problems with that, and AI certainly helped a lot.

klibertp··on Kiki – a tiny homepage construction kit with a small footprint
Ok, but given that there are no license terms anywhere (not in the .zip with the code, and I don't think there is one on the web page), you also can't say that this particular license disallows modification. The terms are simply not specified.

Further, the very operation of this code requires the user to modify it, as described in the usage instructions. You might say that this only gives permission to modify a particular subset of the provided code, to which I don't have an answer (other than that it's unspecified).

You might not be able to fork it and distribute your modified version to others. It's not free/libre. But you can read it and modify it for your own use. To me, that's plenty enough for a project like this. As far as proprietary code goes, this is as harmless as it can get - instead of criticizing it for not being open enough, it would be better to praise it for being this open, to encourage other authors (who would otherwise keep all the code as closed as possible) to follow this model instead.

Yes, FLOSS is good and great, but it's impossible to make all code like that; in reality, where we deal with DRM, app stores, and heaps of unrepairable, uninspectable, obfuscated, phone-home activated code all around, even a bit more openness helps.

klibertp··on Building from zero after addiction, prison, and a felony
> Some US highways

I'm sorry, but from a European perspective, this is the problem, not bikes. If your roads and driving culture encourage driving a tank for safety, that's a bit less than ideal.

I commuted to work for 5 years on a moped. I never used a highway, almost never exceeded 50km/h, and had 2 accidents during that time; both resulted in just a few scratches and bruises.

In another post, you said: "maybe speed was a factor" - actually, it's the only factor. If you never go too fast and never use roads where others may go too fast, you're safe - at least from life-altering tragedies.

If, on the other hand, it's generally impossible to get where you want to without using highways, or the sheer distance forces you to step on it - then yeah, don't buy a motorbike. Just note that it's not the bike's fault!

klibertp··on Building from zero after addiction, prison, and a felony
Probably depends on the locale. In Europe, riding a moped in a big city is a way to drastically cut your commute compared to driving a car. It's not exactly dangerous when all the other road users are moving at 5m/min, and being able to just skip all the traffic jams is a godsend. By car, my trip to the office was about 45min - it was 15min on a moped, a stop at a shop for some snacks included. And that's with riding speed never exceeding 50km/h.

I had two accidents during my 5 years of commuting, and both times I only got minor scratches and had to replace my shoes. Both happened at speeds a determined bicycle rider could achieve, but I suspect I wouldn't be as well protected on a bicycle (both the machine itself and the protective gear tend to be much lighter there than on a moped). If I needed to do that again, I'd buy a model with two wheels at the front, which would have prevented both accidents - though I'm not sure if added stability wouldn't encourage me to ride faster.

So it's pretty specific, but if you're somewhere where driving culture is not too cutthroat, the roads can support single-track vehicles, and the traffic rather than actual distance is the limiting factor - owning a bike can be an objectively better option.

klibertp··on Kiki – a tiny homepage construction kit with a small footprint
I'm not going to blame you _too_ much, since I had similar suspicion, but you could have (as I did) just downloaded the .zip file and examined the contents. In the shareware version, some things are probably missing (I think not all themes are there), but otherwise it's just a bunch of PHP files, no obfuscation or anything. The markup language is configured in a text file, and the parser for that file is just next to it. The configuration is used for configuring the markup parser, which is also present. And so on. It's not open-source only if your definition of OSS is "has to have a Github page".
klibertp··on Elixir v1.20: Now a gradually typed language
> Errors are often simply swallowed.

That's a bit of a misrepresentation. Error handling on the BEAM has a few more layers than in other environments; specifically, the supervision tree can be used to "let things fail". That's not the layer where you should log or handle failures - that's a safety net that ensures your whole system won't go down if your error handling in a single process doesn't work.

For error handling, there are roughly these layers:

    - functions can return {:ok, value} or {:error, error}
    - functions can raise errors (similar to exceptions) that can be caught
    - processes can be monitored from the outside, you get notified when they die
    - processes can be linked and exits can be trapped, also notifying you on failure
    - supervisors can handle process deaths in a configurable manner
    - higher-level behaviours often expose their own error handling callbacks
So there's a bit more to error handling on the BEAM, and I get that becoming familiar with all of them and using them properly can be a challenge. The defaults skew towards high-availability, which is not always what you want in development - sometimes, failing fast and completely (up to stopping the app or the BEAM as a whole) is more convenient. You can have that; you just need to ask for it specifically in your code.
klibertp··on Elixir v1.20: Now a gradually typed language
> Elixir is having to handle (possibly) hundreds of thousands of processes

OMG, why? Why would you ever have so many processes? All of them at the same time? Are you going to animate a 3D scene and run a process for each vertex, or something?

No, I mean, if you're WhatsApp - across all nodes - then somehow maybe yes? At scale. But in normal code, slicing workloads too thinly is counterproductive, and having even tens of thousands of processes is a sign that you're slicing it way too thin. Message passing between processes is cheap, but not free. Schedulers do a good job, but rarely have more than 16 cores to work with. And so on.

You can have that many processes if you want, to be sure. But if you're struggling with it, why would you want it?

Reading your comments in this thread, I have a feeling you just didn't spend enough time reflecting on how you want to use Elixir. In effect, you also failed to consider how exactly you should learn it. For example: Elixir is a perfectly capable procedural language. Start by writing CLI tools, without spawning any processes at all. Then try to parallelize their processing. If the tool accepts a list of files as arguments, use a `Task` to compute return values for each file. Tasks are processes, but with a particular contract that simplifies their usage. Later, you can experiment with error handling and supervision by putting the tasks under a supervisor. And so on. You go from the familiar to the less familiar, with a useful, working tool every step of the way.

klibertp··on Elixir v1.20: Now a gradually typed language
> It's so confusing to build for the BEAM that I ultimately gave up on it.

Every new paradigm is confusing if you don't put in the work to learn it. That's just how the mind works.

What's important is what you get after you don't give up on it long enough. And that, on BEAM, is a hilariously OP superpower of effortlessly[1] parallelizing and distributing workflows. Then there are Elixir macros and the OTP supervision model. The addition of gradual typing is huge, and when the annotation syntax lands, I will definitely switch to Elixir for everything on the backend.

In any case, the only thing I can tell you is that learning Elixir is worth enduring the confusion. From personal experience, it's just a matter of learning it bit by bit over time - there's a finite set of "confusing" ideas in the OTP/Elixir/BEAM mix, and learning about some of them every other day works wonders over a few months.

[1] An exaggeration - I know! But it does make it much easier to implement parallel and distributed workflows. Recently, most of the important languages finally started getting their m-n concurrency models (from Java to Python), so the BEAM is not as much ahead on SMP, but for distribution (you can send closures to execute on different machines transparently!) it is still in a league of its own.

klibertp··on Elixir v1.20: Now a gradually typed language
Smalltalk has no problem at all with accepting that some things are naturally functions: it has always had blocks! The call operator is `value`, not `()`, but it's the same "apply a piece of code to some values" operation.
klibertp··on OpenRidingController – DIY horse riding controller for the PC
Glorious! Next step - find a game where you ride on a flying creature and add the necessary controls. Apparently, you can tame flying creatures in No Man's Sky, for example. You'd probably need to balance with the body? Read through pressure sensors. Might be incredibly cool if well implemented!
klibertp··on Gmail thinks I'm stupid, so I left
The amount of configuration required to rival what's available out of the box in Web clients (especially indexing, searching, filtering, blocking, etc.) is a bit too much for someone who isn't already interested in it. I tried GNUS in Emacs and a few TUI apps; I do like having all my emails accessible locally, but for day-to-day use, web clients are more convenient. I haven't tried Thunderbird or Outlook (if it still has a local version), though, so maybe I'd have all the conveniences I want there - but since I already have them in Fastmail, I just don't have an incentive to switch.
klibertp··on Larry Ellison: "Citizens will be on their best behavior because we’re recording"
It does. It's still a good text. It's also definitely a result of human-AI collaboration (to what extent - hard to say; could be AI edits in human-written text, could be a longer prompt and AI expanding it, something like that).

The it's-not-X-it's-Y formula is the most visible tell. It's overused, being used, I think, 3 times, with 2 being slightly less obvious. This-was-X-and-now-it's-Y is also overrepresented.

It's still not a bad comment. We can discuss it just fine. What we can't do now is assume this is entirely an EastLondonCoder's text, so we can't use it to form an opinion of that person (whether good or bad) based on its content (since we don't know how much of it comes from that person, and how much from the machine). Some will also form an opinion (good or bad) about the poster simply because they used AI.

That's an Internet discourse of 2026, in my experience. I wonder what's next.

klibertp··on Trump signs downsized AI order after weeks of reversals
> I don't think the allowed shapes of formed metal should be regulated either.

I hear you. I collect knives as a hobby, and always have some kind of a cutting tool on me - they solve a surprising amount of little day-to-day problems (unpacking things bought in a shop being a prime example). I lost one of my folders to the UK border guard because, while a 6.5 cm blade was OK, they said its locking mechanism is illegal in the country. What's particularly funny is that I was actually trying to get back to France then - when entering, nobody asked about any knives. I never got that one back. :(

I wish I knew what the people who wrote this law thought. A folder without a locking mechanism is just as dangerous to others in violent scenarios, but way more dangerous for the user in typical EDC tasks. In Poland, there is no limit on the length of the blade nor on the locking mechanism. Technically, carrying an automatic foldable scythe or a zweihander is legal; you can't, however, carry a sword-cane or any other blade that is disguised as another item, like an umbrella. To put that all in perspective: in both countries, just like almost everywhere else in the developed world, the most lethal type of knife is the good old kitchen knife - ubiquitous, solid, with a tip ideal for thrusts, with a handle that protects the user's hand during the thrust, and so on. Such knives are generally not within the scope of knife-related laws.

So yeah, I don't get the logic behind the knife regulations at all. I'm not sure if completely dropping all of them is the way to go, but they would definitely benefit from a rational reevaluation. As an example, making the locking mechanism mandatory, instead of banned, would have no impact on knife-related deaths while allowing quite a few people each year to actually still have all their fingers.

I'm afraid a similar thing will happen with LLMs and later AIs. Regulators will "compromise" and focus on some kind of danger that's not entirely impossible, but also not very probable (assassins with blades in umbrellas...?), will fight for months over semantics, then pass the regulations to absolutely no visible effect - and the really dangerous uses will become either normalized or at least will move to the gray zone. The judiciary will try its best to apply existing laws to new situations, and in some cases, that will inevitably fail. We'll all deal with the consequences of these failures, unfortunately.

klibertp··on The worst job interview I ever had
No. Reread the post. This interview was specifically explained as a non-technical, cultural-fit talk, and the interviewer "gave an impression of this being a safe space". That means they said something specific to hint that this is the case.

Don't blame the poor guy who was subjected to this. You're projecting your understanding of what is normal for the interviewer and assuming that the particular interviewer didn't cross any of the lines you wouldn't. Unless you are the interviewer or know their side of the story, there is literally nothing in the post that would suggest your reading is correct.

A simpler explanation: the interviewer was an amateur psychologist with little experience in either interviewing or therapy. They asked "interesting questions," then were overwhelmed by answers they hadn't expected and couldn't gracefully handle. That's it. Please, unless you know more about that particular instance, don't reflexively blame the candidate for what looks like a series of errors on the interviewer's part.

klibertp··on 7 lines of code, 3 minutes: Implement a programming language (2010)
"Essential" here means something that cannot, in any way, be further removed from consideration. In this view, things that simplify the understanding and make the program more practical are not essential - they are add-ons on top of the most primitive computational model(s). You can drastically simplify the reading of the lambda calculus by giving it direct support for integers, for example - however, you now polluted the model with an additional element that you need to describe and always keep in mind. Using Church encoding lets you get integers without introducing any new elements to the model, keeping the model simpler - but yes, the implementations of programs within that model will get much more complex to read.
klibertp··on 7 lines of code, 3 minutes: Implement a programming language (2010)
You should be familiar with the terms "essential" and "accidental complexity", right?

Lambda calculus, primitive recursion, Brainf*ck (Turing machine) are all models that discard all of the accidental complexity - all of it: syntax, higher-level constructs, abstractions, etc. What's left is the bare computation itself, amenable to analysis.

It's not meant to be practical - it's a research vehicle that shows what's possible and what's not possible in the realm of ideas, without looking at any real-world constraints (you would, in practice, want to see the result of your computation in less than 100 years - that's not the consideration when using one of the models).

So yeah, it's not something you use, it's something you learn to arm your brain with tools that will help you debug and write complex code that works. It's really worth spending a year or two deep-diving into these "pure theory CS" things; considering that you're going to be writing code for 20+ years (AI allowing), spending 10% of that time learning the foundations on which everything else rests is not that big of a task.

klibertp··on AI has suddenly become more useful to open-source developers
I learned (from the second paragraph) that 7 out of 12 is "vast majority". I'm a bit reluctant to read on after that...
klibertp··on Tell HN: Litellm 1.82.7 and 1.82.8 on PyPI are compromised
The NIH syndrome becoming best practice (a commenter below already says they "vibe-coded replacements for many dependencies") would also save quite a few jobs, I suspect. Fun times.
klibertp··on So where are all the AI apps?
But there's no labels on the X axis - and removing the popover with dev tools shows a chart that doesn't really support what OP says. So we might be looking at some sample chart instead of a real one.
klibertp··on Grace Hopper's Revenge
Scala is explicitly multiparadigm and offers a lot of advanced OOP features. It also had a Python-like (though reportedly better handled) 2 -> 3 transition, which deprecated some things, removed others, and added a bunch of new ones. Scala has always been complex, and right now it's also chaotic. It's a wonder the models can get that high a score with it, honestly.

Racket is a similarly large PL, with many abstractions built on the metaprogramming primitives it offers. Without looking at the generated code, it's hard to say anything, but I suspect the high score despite that might be because of the Scheme core of Racket: `racket/base` is a much smaller language than `racket`, so if the LLMs keep to it, it might narrow the solution space enough to show different results.

In general, I think you're half-right: the "solution space" size is a factor, but so is its shape - ie. which features specifically are offered and how they interact. A more compact and cohesive language design should yield better results than just a reduced surface area. C is not a huge language, but the features it offers don't lend themselves to writing correct code much. Elixir is both relatively small and strongly steers a programmer towards safer idioms. Racket is big, but the advanced features are opt-in, while the baseline (immutable bindings, pure functions, expressive contracts) is similar to Elixir. Python is both huge and complex; "there's one obvious way to do it" has always been a bit of a joke. Rust is incredibly complex - the idea is that the tooling should allow you to handle that complexity easily, but that requires agents; one-shotting solutions there won't work as well.

klibertp··on Ask HN: What is it like being in a CS major program these days?
I'm not sure. You'd have to define "level of rigor". TypeScript has a vastly more expressive type system than C, for example, so given their respective prevalence in their domains, you could easily say that coding apps nowadays is actually more rigorous. There's Rust, but somehow people write lots of apps in it. And so on.

I don't think systems programming is inherently harder than writing apps. You deal with different sets of problems (users stubbornly misusing your UI vs. hardware vendors notoriously lying in the manuals; hundreds of dependencies vs. endemic NIH syndrome; etc.), but coding is, for the most part, the same thing everywhere. IME, the "level of rigor" (as in "kinds and pervasiveness of actions taken to ensure correctness") depends much more on actual people or organizations than on the domain.

klibertp··on Ask HN: What is it like being in a CS major program these days?
Drivers, kernels, firmwares, low-level networking, the likes. Some higher-level infrastructure, like compilers, interpreters, runtime systems (Qt/Glib-like code).

I'm not sure where the question comes from? The divide between systems and app programming is almost as old as coding itself; it's not some distinction without difference - it's the difference between writing a TypeScript microservice for handling CRUD on some tables versus contributing to the TypeScript compiler, Node runtime (eg. uv), and PostgreSQL query planner.

Both kinds of programming are needed; both require specific (diverging in places) skills to do well. FWIW, I don't think systems programming is any safer (maybe a little bit) from AI than making apps, but the distinction between the two kinds of programming is real.

klibertp··on Two Years of Emacs Solo
See GToolkit[1] - Lepiter is a bit like that. It's too notebook-y for my taste, but it lets you write and format text and embed any widget. It also uses a native GUI and is not a repackaged browser.

[1] https://gtoolkit.com/

klibertp··on Two Years of Emacs Solo
As much as I love Common Lisp, it's dead. It has 2 orders of magnitude fewer packages in quicklisp than Emacs has in MELPA - and Emacs is an editor, not a general-purpose programming language. SBCL has a handful of devs and moves very slowly - nothing else does at all. Maybe LispWorks, but that's expensive.

CL is also held together - and held back, hugely - by the standard that won't ever be updated. It's good to have it, but there are major omissions (code walkers, MOP) that won't ever be fixed.

As it is now, Elisp is more practical as a scripting language than CL. The gap will only continue to grow. Right now, CL has an edge in parallelism - native threads and mutexes (with all the problems they entail) work there, while with Emacs, the only parallelism you can get is through separate processes. On the other hand, async/await-style concurrency works quite well in Emacs, while in CL you're basically a few macros away from raw promises, and the only real asynchrony is through a pool of threads executing callbacks, and it doesn't play well with conditions and restarts and some other advanced features (notably absent from Elisp).

I love CL, but right now it's aged considerably, lost many of its unique advantages, and has little chance of ever catching up. It's a shame, but using CL in 2026 is not a superpower anymore - it's just one of the similarly-valued propositions, competing with other dynamic languages, still providing a few unique advantages, but even those are being implemented in other languages fast.

klibertp··on Two Years of Emacs Solo
> I just want a GUI that works like what they use.

TL;DR: Emacs is a GUI app and has lots of GUI-related functionality, but it tends to be slightly neglected by the majority of users. You can easily build your ideal GUI using the provided building blocks; the problem is, you have to build it, since most other users are not interested in doing so.

Both Emacs and Vim/NeoVIM have GUIs. I can't even run my Emacs in a terminal without `-q` (omit user config) - I never feel the need, and my config would be much more complex if I tried to make it terminal-friendly.

You don't need baroque keybinds, either. Both Emacs and Vim have always had "Command Palette" - Alt+x in Emacs, : in Vim - and with a few plugins[1], you get fuzzy matching, inline docs, icons showing what type of command you're looking at, etc. Both editors also have GUI buttons and mode-specific (on top of generic) menus (including context menus on click). This provides unmatched discoverability of available functions - you can then bind them to any key combination you find easy to remember. You don't have to, though, since with a few other plugins (Orderless), the frequently used commands bubble to the top of the list.

There are two things Emacs handles a bit poorly: mouse and popups. The former stems from existing users largely ignoring the issue, but the hooks for clicks and even gestures are there. The latter is an unfortunate consequence of wanting TUI to remain first class. There is functionality for creating Emacs "frames" (GUI windows) with given dimensions and a specified position, but it's basically GUI-only. Things like auto-completion popups default to something that can be emulated in the terminal, with frame/window-based implementations provided as extensions. That means that you can have a pop-up with method names starting with a few characters you typed, you can even have another pop-up beside that with docs for a given method, but you generally won't get that doc displayed as rendered markdown (you can't display headers with a bigger font in a terminal). It's 100% social and not a technical limitation - if you accept that you're only going to use Emacs in a GUI, you can get an IntelliJ-level of mouse and popup handling... Though it takes some effort.

That's the real problem, I think. You need to craft many of those features yourself out of available functionality. And it's not even a matter of some (even obscure) configuration, you will need to write your own Lisp to get the most out of Emacs. That's much more of a pain point and a respectable reason for not wanting to touch it. Technically, though, Emacs is not anti-GUI, and there are many packages that make Emacs pretty. Less so with mouse-friendliness, unfortunately, but you can configure it into something half-decent without much effort.

The only environment I know of that is (at least) equally powerful and flexible, but which handles GUI better is GToolkit[2] (VisualWorks was nice before the license change; now it's impossible to use) - a Smalltalk-derived system that uses the host OS (Linux/Windows/Mac) GUI directly through Rust bindings. A step down from there, but still respectable, is Pharo and the browser/Electron. Other than that, you have pre-written GUIs that you can't really change beyond what the developers planned.

[1] Vertico + Marginalia + Embark in my case

[2] https://gtoolkit.com/

klibertp··on Helix: A post-modern text editor
> One thing I remember though, was that the multi-cursor+selection approach only really helps when you can see everything you're about to change on the screen. For large edits, most selections will be out of the scroll window and not really helping.

In Emacs, there's an mc-hide-unmatched-lines command that temporarily hides the lines between the ones with cursors. This makes multiple cursors usable with up to a screen-height number of items (being able to place cursors by searching for a regexp helps).

I agree, though - MCs are most useful for simple, localized edits. They're nice because they don't require you to mentally switch between interactive and batch editing modes, while still giving you some of the batch mode benefits. For larger or more complex edits, a batch-mode tool ("Search and replace", editable occur-mode in Emacs, or even shelling out to sed) is often a better choice.

klibertp··on RE#: how we built the fastest regex engine in F#
If you claim it's the fastest, how does it compare to one-more-re-nightmare?

- https://github.com/telekons/one-more-re-nightmare

- https://applied-langua.ge/posts/omrn-compiler.html

OMRN is a regex compiler that leverages Common Lisp's compiler to produce optimized assembly to match the given regex. It's incredibly fast. It does omit some features to achieve that, though.

← PreviousPage 5 of 34Next →