HNHacker News
TopNewBestAskShowJobs

hayley-patton

628 karma · joined November 13, 2021

https://applied-langua.ge/
submissionscomments
hayley-patton··on Pine64 Ox64 $6 RISC-V Linux hybrid SBC
Thanks. I didn't mention IoT nor wearables though; and it would be nice to source that information from the manufacturer too.
hayley-patton··on Pine64 Ox64 $6 RISC-V Linux hybrid SBC
Does anyone know if the two cores share memory? The datasheet and manual suggest the same memory map, but the block diagram suggests some kind of distinction between the two cores. Would be an interesting thing to target.
hayley-patton··on Zero Feet: a proposal for a systems-free Lisp
There is also the requirement in this counter argument that the interpreter design substantially affects runtime performance. Generally, when there is a JIT compiler and an interpreter, my understanding is that one attempts to spend most cycles running in compiled code. Does LuaJIT not do that?

HotSpot also uses an interpreter, but its performance comes from the C2 compiler, for example. Quoth Cliff Click [1]:

> if you are spending any amount of time beyond e.g. 5% in the interpreter / stage-0 JIT you need to adjust your JIT'ing strategy. Not saying "no-gain" in a stage-0-only, but definitely should not be a super high payoff if there's a stage-1 following you.

[1] https://old.reddit.com/r/Compilers/comments/sae1iy/compiler_...

hayley-patton··on Zero Feet: a proposal for a systems-free Lisp
If LuaJIT is the example, is Lua being interpreted? I know that there is a bytecode interpreter hand-coded in assembly, but isn't the JIT used for hot code?

Edit: perhaps this is about missing the word "primarily", that performance in such an implementation is bound by interpretation speed.

hayley-patton··on Zero Feet: a proposal for a systems-free Lisp
The difference here is that Zero Feet uses the same language and implementation framework for all code, but with capabilities and restraints chosen per module, rather than in a sub-language.

Indeed ZF relies on stack allocation, but this is done "optimistically" and for all code.

hayley-patton··on Zero Feet: a proposal for a systems-free Lisp
This exact comment was asked on Reddit some time ago - I mean the exact same characters. [1]

Nonetheless I'll provide the same answer; the compiler technology should be orthogonal to how it is implemented, so it should absolutely be possible. The proposal of using (monomorphic) inline caches is only the bare minimum to avoid crashing.

[1] https://old.reddit.com/r/lisp/comments/wlafgn/zero_feet_a_pr...

hayley-patton··on Zero Feet: a proposal for a systems-free Lisp
Indeed it doesn't mention the instruction set. The closest would be Self, which only has instructions to do message sends and read particular VM registers; which boil down to calls and pushes respectively. That part of the semantics of the proposed language are closer to Smalltalk heritage than Lisp; the expression orientation, syntax and, at lack of a better term, "nesting" are the Lisp influence. Say, Smalltalk provides variable declarations at the start of a method, we intend to provide LET/LETREC forms instead.

I would agree that CLISP bytecode would be heavier; this approach ("template compiler"?) has been used as a baseline JIT in e.g. Jalepeño for the JVM with some success, but being a baseline JIT it is not intended to be that fast either.

hayley-patton··on Zero Feet: a proposal for a systems-free Lisp
Co-author here; the first goal is to work at all, not to be awfully fast. But the branches that appear would most likely be due to inline caching, which are very predictable in practice; [1] claims a 95% hit rate for a simple inline cache. And given that there is little to inline, this scheme probably does approximate subroutine threading.

[1] https://bibliography.selflanguage.org/_static/pics.pdf

hayley-patton··on Common Lisp names all sixteen binary logic gates
Perhaps so, and I've cracked a similar joke (where's the hardware and compiler writers?) but no one brought up a "full stack", so it wasn't obvious what the leaky abstraction was.
hayley-patton··on Common Lisp names all sixteen binary logic gates
How so?
hayley-patton··on Zig VP of community comments on Rust
RC scans dead memory and changes things, and the GC would appear in a binary. But it is indeed a dual <https://dl.acm.org/doi/10.1145/1035292.1028982>
hayley-patton··on Big Ideas from 8 Programming Languages
> In LISP, everything is a linked list

Atoms are linked lists?

hayley-patton··on Jonathan Blow on Societal Collapse (2019)
> I wonder if this is a factor for the decline in software quality Jonathan Blow talks about in his video.

Wouldn't hold my breath; I recall a tangent on programmers being "afraid of pointers". Depending on your favourite not-C-pointer way of managing memory, that's saying that use-after-free bugs are a sign of bad programmers, or shunning substructural/region/etc types for verifying that explicit memory management is correct.

hayley-patton··on Rob Pike's simple C regex matcher in Go
> And yes, derivatives build full DFAs. Those are a no-go in a general purpose regex engine.

Lazily compute derivatives? From memory Rust regex computes and caches a DFA lazily from the NFA, for comparison.

hayley-patton··on Lively Linear Lisp – 'Look Ma, No Garbage!' (1992) [pdf]
Right.
hayley-patton··on Lively Linear Lisp – 'Look Ma, No Garbage!' (1992) [pdf]
Careful - push is a macro which modifies the value bound to "list", but doesn't modify any of the cons cells in that list.
hayley-patton··on Reference count, don't garbage collect
Backup compaction can be useful, like backup tracing can be, but you can also use all the initial increments in a coalescing RC collector to determine which pointers need to be fixed up for copying, without tracing. See http://users.cecs.anu.edu.au/~steveb/pubs/papers/rcix-oopsla... pages 8 and 9 on "Defragmentation with Opportunistic Copying" e.g.
hayley-patton··on Reference count, don't garbage collect
> That is a ridiculous statement.

If you do use limited counts, you will need a backup tracing collector; and limited counts are appealing because they save space (and most objects tend to only have a few references [1]).

> In fact! I just realized we do have data for which is more performant: this article describes how Instagram turned of GC for Python and just relied on reference counting. They gained 10% increase in performance:

...because generations in the GC are represented as linked lists, and modifying those linked lists reduces the number of page faults, in turn because pages are shared by copy-on-write between process. That representation isn't the best idea already, and shared structure should be in the oldest generation anyway, as you don't want to collect it (as SBCL does for images, which are loaded with copy-on-write).

[1] http://users.cecs.anu.edu.au/~steveb/pubs/papers/rc-ismm-201... page 4

hayley-patton··on Reference count, don't garbage collect
https://users.cecs.anu.edu.au/~steveb/pubs/papers/lxr-pldi-2... is the most recent publication in this lineage of high-performance RC systems.
hayley-patton··on Reference count, don't garbage collect
You'd get very different results doing atomic operations on counters shared between multiple threads, and with other stuff to do that causes your CPU to serialise and run less out-of-order. That single-threaded benchmark is data, but it doesn’t appear awfully relevant to how naive RC barriers perform versus barriers for coalesced RC or tracing.

Indeed the issue with measuring barriers is that measuring the barrier doesn't suffice; one wants to measure how the barrier affects the rest of execution. This entails coming up with programs that are much less trivial than repeatedly incrementing a counter.

hayley-patton··on Treadmill garbage collector by H. Baker
The Dijkstra, Lamport, Martin, Scholten and Steffens "on-the-fly" collector [0] is the most inspirational, I think, with its analogy of "colors" for objects. Baker first designed a serial "real-time" copying collector [1], showing that three areas in copying are equivalent to the colors; then I think the lists of objects in the Treadmill are supposed to correspond to those areas in the copying collector. Instead of moving objects and advancing a scan pointer to change the color of objects, objects are rearranged in the doubly linked-list.

[0] https://lamport.azurewebsites.net/pubs/garbage.pdf

[1] https://plover.com/~mjd/misc/hbaker-archive/RealTimeGC.html

hayley-patton··on Ask HN: What are some cool but obscure data structures you know about?
Decent JS engines will use "hidden classes" to dedupe keys for you already, so this isn't necessary to save space; the technique is pretty old and dates to Self. Still, the arrangement may help with locality of reference.
hayley-patton··on Some Thoughts on Zig
Borrowing, in a way, looks a bit like the anchored pointers suggested by Henry Baker in [1]. I recall reading someone did a static analysis to detect what pointers could be anchored, but forgot which someone. However the "deferral" suggested is very different to the Deutsch-Bobrow deferral; what makes me think it is more like borrowing is that anchoring avoids destruction due to linear types, like borrowing avoids moving or copying. (Regions in Cyclone would be somewhere in between, too.)

[1] https://plover.com/~mjd/misc/hbaker-archive/LRefCounts.html

hayley-patton··on Making Code Faster
> I had to pay real money to get the Java profiler I used at AWS and while it worked, it was klunky, not fun to use.

VisualVM <https://visualvm.github.io/> is quite good for Java/JVM profiling.

hayley-patton··on Rust without the async (hard) part
> imho the issue isn't function coloring, threads, whatever. It's a compiler that defaults to async code in the calling convention and then optimization passes to de-async-ify (remove unnecessary yield points) the code at compile time. The result would be code that looks synchronous but is async where it matters (i/o).

Safepoints for garbage collection are somewhat similar, but for preemption one wants to interrupt threads on a timer, rather than before the collector takes over. Despite occurring very frequently (at around 100 _million_ checks per second), the time overhead is only about 2.5% or so, according to a study by Blackburn et al [0]. It appears, I think, that as long as the fast not-interrupting path is fast enough, eliminating safepoints isn't too important.

[0] Stop and Go: Understanding Yieldpoint Behaviour <https://users.cecs.anu.edu.au/~steveb/pubs/papers/yieldpoint...>

hayley-patton··on The true cost of linked lists
On a 64-bit machine where everything is aligned to two words (like SBCL), you get 4 bits for tags.
hayley-patton··on What is a programmable programming language? (2019)
Macros do reduce the surface area for mistakes, by removing redundant expressions that can be typoed. Say, you cannot forget to close a file if you use WITH-OPEN-FILE, but you can if you call OPEN and CLOSE yourself. There are other ways to not leak resources, but macros are just another way to not repeat oneself.

> But the main argument is that Lisp is hyperproductive if you’re an individual brain genius who’s memorized every emacs key combo.

I certainly haven't, though I suspect this is a bit of an exaggeration.

hayley-patton··on Why does this code execute more slowly after strength-reducing multiplications?
Does the Go compiler auto-vectorise? Vectorisation appears to have been the cause of the weird performance.
hayley-patton··on Ask HN: What does a developer need to know to build their own Lisp from scratch?
I can't recommend Build Your Own Lisp - if there's anything particularly "profound" about Lisp, the book misses it by miles. For example, the book claims that adding a new feature requires "syntax, representation, parsing and semantics" [0], whereas one of the nice things about Lisp is that adding most sorts of features doesn't require new syntax or new representations (and "syntax" and "parsing" are fairly redundant).

The example also indicates how the book conflates language and implementation. It's perhaps not the most important thing to know if one is learning how to design and implement programming languages, but unfortunate as CL and Scheme have independent standards; and separating semantics and implementation makes it possible to discuss how differing implementation techniques can be used for the same language. The language implemented also uses dynamic scoping, which is plain weird nowadays.

The C code is of questionable quality, and the author doesn't cover how to improve your chances of writing working C (e.g. using a debugger, testing with sanitizers, etc). This is more of an issue, because the interpreter copies and mutates in a weird way which appears quite easy to mess up, rather than using a garbage collector. The book uses a parser library by the author, so using e.g. the Boehm GC library doesn't seem too bad, but arguably doing your own memory management is more representative of C code that isn't a language implementation. The approach also makes mutation hard to reason about; it's hard to say what a particular update is actually going to affect.

[0] https://buildyourownlisp.com/chapter10_q_expressions

hayley-patton··on We're choosing Rust, and not Go, C++, or Node.js (Feb 2022)
There is a list of benchmarks used; including the Mandelbrot and pidigits benchmarks I cite. They also claim "they gathered the most efficient (i.e. fastest) version of the source code"; and I cited the fastest programs.

This is legitimately painful to discuss, as this information is readily available in the paper, and seemingly we are getting nowhere by picking at how I made my observations; so I am going to do something more enjoyable, somewhere very far away from you.

← PreviousPage 8 of 10Next →