jeff_ciesielski

Joined 7 years ago

Karma
105
Submissions
14
Member since
Feb 9
View on Hacker News

Recent submissions

Comment · 14 days ago
Rather than salty comments, I just decided to give it a try.

Ported a couple of algorithms from my quite large commercial rust codebase and they were significantly faster in goose. Was wow'd, but the big gain was actually that goose just led the LLM to use more efficient (though admittedly slightly less rust-ideomatic but still safe) data structures, so porting them back kept nearly all of the gain (and in one case, even more).

The obvious 'no shit' comment is 'well your code just wasn't optimized', which is partially true, there was obviously a fair bit left on the table. What I find more interesting is that for darn near zero cost, having an an LLM explore in different languages led to a better outcome than me sitting here running perf and squeezing for cycles.

I'm sure that as I build up a cookbook for my codebase this will be less useful over time, but for now, this is going to be how I approach first order performance optimization.

Nice work, cool tool, plz de-ai the docs :D

Comment · 1 month ago
Howdy folks.

I was inspired by the really neat "Jev in 25 lines of Python" post a few days ago (and System One models in general), and after playing with the idea I tried whipping up something a little more complex, and Lichen is what popped out: https://github.com/Mushroom-Systems/lichen

My question after reading that post (and I know I wasn't the only one; antirez came right out and said it in the comments) was whether Google Research's prompt repetition paper for non-reasoning models (https://arxiv.org/abs/2512.14982) would improve the outcomes. Turns out it did a fair bit. After some experimentation I added two more tricks: the options are listed a second time in a rotated order to wash out the model's preference for position, and a letter remapping sums the probabilities over each option's letters. Both help on the harder and more ambiguous questions.

After testing several models I had lying around, I settled on gemma-4-26B-A4B as my daily driver. On public JevBench, Google's QAT build scores 207/231 against Jev 1.13's 200 (not statistically significant yet; I'll be submitting it for evaluation on the withheld items soon). Served from vLLM with the NVFP4 build, it scores 204 with a median response time of about 56 ms on my laptop 5090. For folks without that much VRAM to spare, the smaller Gemma 4 models also perform well: E4B fits in about 5 GB, though it does suffer on the harder queries. Qwen also works (my colleague has reported good results with Qwen3.8), but on my setup I found it a bit slow for my use case, and the benefits weren't strong enough to outweigh the slowdown.

Because Gemma 4 is multimodal, Lichen also extends the query format so images can be part of the state (served from vLLM), with answers in about 190 ms. The results are good but not perfect. On 125 Wikimedia Commons photos that I checked by hand, it got every one right. On 98 road-sign photos drawn at random from Commons, it named the right sign 92 times when it had to pick one. When I added "another sign, or no road sign" as an option, it dropped to 73: it tends to decide that a small, distant or vandalized sign isn't there, and it's confident about those misses. The confidence on images isn't well calibrated in either direction, and a separate temperature for images didn't fix it. The README has the numbers and a couple of the failures.

I've been using this as a partial replacement for the backbone of our company's context graph for a few days now, and it's performed excellently so far. Hopefully folks will find some use for it.

(Sidenote: Big thanks to my friend and colleague Jacob M for his vLLM support patch)

Comment · 1 month ago
Comment · 1 year ago
We do a fair bit of FPGA design in SpinalHDL, and have taped out several ASICs with parts of the design done in SpinalHDL at my dayjob.

In general: No, alternative HDLs don't see a lot of use, and I'd argue that we qualify as 'academia' since the ASICs are NIH funded and we tend to work with a lot of academic partners and on low-quantity R&D projects.

Having said that, every time we've deployed SpinalHDL for a commercial client they've been blown away by the results. The standard library, developer ergonomics, test capabilities, and little things like having clock domains as a part of the type system make development so much faster and less error prone that the NRE for doing it in verilog just doesn't make sense.

You get access to the entire Java and Scala ecosystem at elaboration and test time. We deploy ScalaCheck in our test harnesses to automatically generate test cases that can reduce inputs to identify edge cases. It's incredibly powerful.

Comment · 2 years ago
Like any time you get off the beaten path, there are rough patches, but to paraphrase another comment in this thread "Nim is just C", so anything that felt a little awkward just meant using an `importc` pragma and doing whatever I needed to do in an environment I felt more comfortable (you can also have C code compiled with a {.compile: "foo.c"} pragma, so if a module required something be done in C, you didn't have to monkey about with the build system to include it, it 'just worked')

The biggest negative I ever hit was that early on, Nim didn't have support for `volatile`, which meant it was a non-starter for doing anything with MMIO (I ended up being the one who added volatileLoad/volatileStore to Nim's stdlib so I could use it on a Cortex-M without having to drop into C so much).

For the most part though, if you're reasonably comfortable with embedded toolchains (i.e. you understand how to write linker scripts, understand what happens between a reset and actually getting into `main()`, etc), it's not much of a hurdle to set up a simple build system to compile your Nim code to C, link appropriately, and then sort of forget about it.

It's been a while, but IIRC I also got step-through debugging working with OpenOCD by having the nim compiler generate `#line` pragmas and including debug symbols, which was pretty neat.

This was all pre ARC/ORC, so I did have to make sure to be careful not to use ref objects, but ultimately it felt pretty seamless. I still tend towards fully manually managed memory on embedded projects, but I'd be curious to give it a go.

Comment · 2 years ago
> In what way? Comptime should be generally capable of anything macros are.

I started to reply to this with 'Comptime is generally capable of doing anything that Nim's templates can accomplish (but not it's macros)', but I stopped myself because even though Zig's comptime is more akin to Nim's templates than its macros (in my opinion), Nim templates are more powerful as they allow you to embed arbitrary blocks of code to implement constructs similar to python's context managers (which I'm fairly certain you can't do with comptime).

W/R/T Macros vs Comptime, you can't create arbitrarily complex DSLs with comptime the way you can with a Nim's macros as you don't have full control over AST generation.

All that said, the power you'd get from a Macro or Template system like Nim's don't really jive with Zig's whole "no hidden control flow" thing.

>Terribly difficult to implement without breaking a major language tenant of “no hidden control flow”.

I dunno if I agree with that, even very simple rust-like traits that simply enforce that a struct implemented a given interface at compile time (static dispatch only) would go a long way without compromising obvious control flow IMO.

>But I found that once I left behind OO style of thinking, I haven’t missed this all that much. For the rare time I do generalize like this, you can literally just check at comptime that the passed in type provides the necessary decls. It’s not terribly complex or hostile (although tooling could use some work around it)

Respectfully, I don't view it as OO thinking (I think typeclasses come from SML...). Making polymorphism reasonably ergonomic goes a long way towards code reuse and (again, only my humble opinion here) would help with what some of the folks in this comment section are talking about w/r/t code re-use and generalizing a HAL layer in a consistent way without forcing users (or library authors) to write a bunch of ad-hoc code to check that functions exist on a given struct, or manually implementing dispatch tables.

Comment · 2 years ago
I used Zig (not MicroZig, just rolled my own HAL) for the bootloader and firmware on a soft RISC-V SOC + custom peripherals recently and had somewhat mixed, though positive feelings about it.

On the positive side:

- As a 'safer c', getting things up and running was a breeze, writing code largely felt intuitive.

- The additions to C (slices/iterators, enhanced structs, arbitrarily sized integers) are excellent

- It produces fairly small firmware images (useful when stuffing a boot rom in logic/EBRAM)

- Easier (than C IMO) to get up and running with formatted IO vs retargeting libc

- Comptime is neat, and you can build some decent low-cost abstractions with it (ex: I built a comptime heavy write-through cache for key-value storage that required very little overhead and largely self-generated based on a simple struct)

- I really enjoy the use of structs for function+data organization. It maps well to hardware instances, giving you an 'object' like feeling without OOP ick.

On the negative side:

- The compiler is still a seriously moving target. Upgrading sometimes meant rather large refactors.

- Documentation is somewhat poor IMO.

- As a long time user of Nim (including on really lean embedded targets), compared to hygienic macros, comptime falls way short.

- The lack of first class interfaces/traits/typeclasses is not my favorite. The currently suggested alternatives are so un-ergonomic I'd almost call them hostile.

All-in-all, I'm excited to see where Zig ends up. After nearly 20 years writing embedded code I'm really (really really really) tired of C. The embedded systems community really needs to embrace better tools.

Comment · 5 years ago
Comment · 5 years ago
I hate to give an 'it depends', but it depends.

Typically, no. In SPI all lines are actively driven high or low rather than an open drain configuration. The bus master drives SCK (SPI clock), MOSI (master out, slave in) and CS (chip select), and the slave device(s) drive the MISO (master in, slave out) line(s). From an operating perspective, pullup/pulldown resistors are not required.

Now having said that, in some cases it's considered appropriate to add weak pullup/pulldown resistors to the data lines to ensure that they're in the expected state on power up and to prevent glitches from putting slave devices into weird states.

Comment · 5 years ago
(From someone who is working on a rv32im implementation in Clash)

I really love writing RTL in haskell when compared to verilog/vhdl, but as a language I think it suffers from the same thing a lot of other languages do: too many ways to do the same thing. Mix that with a language that encourages meta-programming and you've got yourself a recipe for every complex haskell project basically becoming it's own little DSL. It's also often made worse because so much haskell is written by type-theorists and mathematicians churning out symbol-soup without a thought for the rest of us plebs.

IMO this is actually pretty readable and the implementation is stitched together nicely. There are some haskell/ml-isms like lenses/monad transformers/partial functions sprinkled in there that complicate a casual read-through, but if you've got a grasp on those most of this is reasonably clear.

It isn't the most complex beast (as others have pointed out, it skips things like the Zicsr and M extensions which add significant complexity) but it could serve very well as say, a companion core to some more complex piece of hardware. Perhaps one that requires reconfigurable logic that would be impractical in silicon but doesn't require realtime interrupts or fast math?

Comment · 7 years ago
I wrote something similar a while back (also in nim): https://github.com/Jeff-Ciesielski/synesthesia

When I stop being so darn busy, I do want to revisit my original project of doing the same thing for a FORTH derivative.

Comment · 7 years ago

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton