Another 2 day old vibe coded project. The premise is great, but it’s pretty apparent that no thought was put into it. They couldn’t even be bothered to write their own text for the web site.
HN user
mullr
Why would I use this over the existing Proptest library in Rust?
"The Lightning Tamers", by Kathy Joseph, is a wonderful and accessible book about the history of electricity. Her youtube channel is great too: https://www.youtube.com/c/KathyLovesPhysicsHistory
I had the opposite experience. I worked for a company with a bunch of Clojure projects, written by people of varying levels of experience. I had to do some cross-cutting changes and feared the worst. But when I actually got down to it, everything more or less made sense.
Why did this happen?
- We had small common framework that everybody used, at the very highest level (think application lifecycle management). That imposed some amount of consistency at the most basic run-the-program stage.
- The devs communicated openly, a lot, so there was some general consensus on what to do, and what not to do.
- The team at large was very suspicious of introducing new macros. You could do it, but you'd better have a really good reason.
- When I went to make the changes, I didn't have to worry about spooky-action-at-a-distance kinds of consequences anywhere NEAR as much as I do in other languages. Being strict with your state management, as Clojure strongly encourages, REALLY pays off here.
The actual problems I had were entirely related to the overall build system, the fractured nature of the source control, and figuring out who was responsible for what code once we were 3 reorgs deep. The code itself was remarkably resilient to all this nonsense.
I've had no problems with dwarf.
Every Linux C/C++/Rust developer should know about https://github.com/KDAB/hotspot. It's convenient and fast. I use it for Rust all the time, and it provides all of these features on the back of regular old `perf`.
Caveats: I've used nom in anger, chumsky hardly at all, and tree-sitter only for prototyping. I'm using it for parsing a DSL, essentially a small programming language.
The essential difference between nom/chomsky and tree-sitter is that the former are libraries for constructing parsers out of smaller parsers, whereas tree-sitter takes a grammar specification and produces a parser. This may seem small at first, but is a massive difference in practice.
As far as ergonomics go, that's a rather subjective question. On the surface, the parser combinator libraries seem easier to use. They integrate well with the the host language, so you can stay in the same environment. But this comes with a caveat: parser combinators are a functional programming pattern, and Rust is only kind of a functional language, if you treat it juuuuust right. This will make itself known when your program isn't quite right; I've seen type errors that take up an entire terminal window or more. It's also very difficult to decompose a parser into functions. In the best case, you need to write your functions to be generic over type constraints that are subtle and hard to write. (again, if you get this wrong, the errors are overwhelming) I often give up and just copy the code. I have at times believed that some of these types are impossible to write down in a program (and can only exist in the type inferencer), but I don't know if that's actually true.
deep breath
Tree-sitter's user interface is rather different. You write your grammar in a javascript internal dsl, which gets run and produces a json file, and then a code generator reads that and produces C source code (I think the codegen is now written in rust). This is a much more roundabout way of getting to a parser, but it's worth it because: (1) tree-sitter was designed for parsing programming languages while nom very clearly was not, and (2) the parsers it generates are REALLY GOOD. Tree-sitter knows operator precedence, where nom cannot do this natively (there's a PR open for the next version: https://github.com/Geal/nom/pull/1362) Tree-sitter's parsing algorithm (GLR) is tolerant to recursion patterns that will send a parser combinator library off into the weeds, unless it uses special transformations to accommodate them.
It might sound like I'm shitting on nom here, but that's not the goal. It's a fantastic piece of work, and I've gotten a lot of value from it. But it's not for parsing programming languages. Reach for nom when you want to parse a binary file or protocol.
As for chumsky: the fact that it's a parser combinator library in Rust means that it's going to be subject to a lot of the same issues as nom, fundamentally. That's why I'm targeting tree-sitter next.
There's no reason tree-sitter grammars couldn't be written in an internal DSL, perhaps in parser-combinator style (https://github.com/engelberg/instaparse does this). That could smooth over a lot of the rough edges.
Error recovery in nom is left as a very obtuse exercise to the reader. Custom error reporting is difficult at best. That stuff is supposed to be better in chumsky; I don’t know if it actually is.
However, for my own parser which is currently written in nom, my current plan is to port it over to tree-sitter. Its error recovery is completely automatic, and a fair sight better than anything I have time to do by hand.
For Kagi, at least, there's a very well integrated search customization method that they didn't bother to show here. For any search result, you can add a ranking adjustment for the site it came from. This is directly in the results, so it's very accessible, and quite easy. One of the choices is 'pin', which is fantastic for technical work: 'sqlite.org' is now boosted over everything else, for me, and it's exactly what I want. I could just as easily take it out, if it becomes a problem.
If it's not too much to ask, do you mind sharing some of the pain points?
To me, the point of literate programming is that you have a coherent (literate, if you well) document that explains how the program actually works, and the reason it's put together how it is. This is NOT an easy thing to write. It takes as much organization as the program itself. I found the document structure to be continuously in flux, as I updated the program to deal with new requirements. So either document would poorly structured, or I would spend a LOT of time keeping it good.
Yeah, it's really not. You CAN do knuth-style literate programming in org-mode (https://orgmode.org/manual/Extracting-Source-Code.html) I used it to make http://mullr.github.io/micrologic/literate.html.
The experience completely cured me of Knuth-style literate programming, fwiw. It's really great for making a lasting artifact about a program that's completely done. But I can count the number of programs I've worked on like that on zero fingers. Even this one isn't really done, but the cost of updating the essay along with the code discouraged me from working on it any more.
And to really rub salt on it, they have a syntax that looks very much like stock latex for math symbols, and SOME of them are the same, but not all of them! (all / forall is the one that comes to mind, it's been a little while)
you mean like 'u' for micro, and 'lambda'? I think this is pretty common.
Regardless, you're probably doing yourself a disservice if you're allowing things like that to take choices out of your toolbelt. Perhaps the worst offender is TLA+, where you have to write actual ascii art and latex inside your code (yes, I know model/spec). I despise it, to be clear, but it's still a pretty good tool and often the right thing to reach for
What are people doing about this on the client side? The solution that comes to mind is to do all my Rust builds in a sandbox of some kind, but with rust-analyzer involved, I'd likely have to put my editor in there as well.
support for the Wine and Proton compatibility layers on Linux is included
Isn't part of the point of Rust that you don't manage memory yourself, and rather that the compiler is smart enough to manage it for you?
For trivial cases, kind of. But once you start to do anything remotely sophisticated, no. Everything you do in Rust is checked w.r.t. memory management, but you still need to make many choices about it. All the stuff about lifetimes, borrowing, etc: that's memory management. The compiler's checking it for you, but you still need to design stuff sanely, with memory management (and the checking thereof) in mind. It's easy to back yourself into a corner if you ignore this.
As a regular web dev, you are constantly staring a distributed system in the face: it’s made of the program running on the server (back end), and the program running in the web browser (front end). How do those two programs agree on pieces of common information? How does the server deal with communications from other clients? At what cadence? How are the caches invalidated? Regular web dev is anything but simple, if you seriously consider the questions it poses. Tools like this help you think such questions.
Tutoring sessions on our platform are completed using a whiteboard and text-based chat (no audio and video).
Have you found that to be sufficient? I recently tried doing some online tutoring, and I found that even with an audio connection, I had a lot of trouble telling if anything I said was landing at all. I came away from the experience rather disillusioned with the idea of trying to do this online at all.
They are willing to share the dataset, just tell them what you want to do with it.
A truly staggering amount of “scare quotes.”
From the site:
As a conservative watchdog to the nation’s higher education system, Campus Reform exposes liberal bias and abuse on the nation’s college campuses.
The likelihood this is accurate is very low.
To me, Cucumber is a way to write executable specifications that can also be read by non-developers. This can be tremendously powerful if done judiciously, or tremendously pointless if not. This may be because you do not in fact want or need executable specification, or perhaps because there's nobody interested in reading it.
I believe that Cucumber is at its best in situations where it's clear to all parties that a specification is valuable. In that case, making the specification executable is very clearly a massively useful way to spend your time.
Have you ever considered how we could use the predicates in the filters to create Specialized generators that only generate inputs that will be accepted by the filter? You probably need some meta programming or reification of the predicates for that to work.
That's a really nice idea. It doesn't fit into the usual compositional design of the proptest libraries that I've used, but it certainly seems like it should be possible in principle.
We like to run the tests as part of CI with a relatively small number of iterations, and then turn the knob way up in a nightly or weekly scheduled test job.
It certainly seems to be rarely used. It's interesting to look at the concurrency stuff in Clojure and its uptake:
- Atoms: very popular. Usually what people reach for, perhaps overly so.
- STM / refs: Not commonly used, but I wonder if this is because we aren't used to really considering them as an option?
- Agents: I think everybody agrees that you shouldn't use these
- core.async: What many people think you should use instead
- Reducers: I've never seen these used in the wild.
It’s completely correctable. If fb/Twitter wanted to, they could track every person who saw a piece of “wrong” information, and plaster the retraction in front of their face.
It already does.
Emacs 27 includes a native JSON parser (as opposed to one written in elisp, used previously). This matters a lot if you're using `lsp-mode`, since the LSP protocol uses a JSON encoding. I've been using local builds of emacs 27 for quite some time, for this very reason.
My recipe for using twitter in psychologically sustainable way:
1) Follow only people you have met in person, or otherwise directly corresponded with. I make very few exceptions to this.
2) Disable all retweets. Twitter doesn't make this easy, but there are tools that do it in bulk.
3) Make sure you're looking at 'latest tweets' mode, so that you only see the content you chose with (1) and (2). Twitter very frustratingly will put you back in 'top tweets' mode periodically, so you'll have to keep an eye on this. It feels like this happens about every 2 weeks but I haven't measured.
With this setup, nearly all of the viral BS drops away. I only see tweets in which a person I have some relationship with has taken the time to actually type something. 'quote tweets' are still problematic, but it's not nearly as bad.
It does.