News for hackers. Stuff that matters.

slightknack

The minimaxir/gemimg repo is pretty cool, fwiw.

Going further, one thing you can do is give Gemini 2.5 a system prompt like the following:

https://goto.isaac.sh/image-prompt

And then pass Gemini 2.5's output directly to Nano-Banana. Doing this yields very high-quality images. This is also good for style transfer and image combination. For example, if you then give Gemini 2.5 a user prompt that looks something like this:

    I would like to perform style transfer. I will provide the image generation model a photograph alongside your generated prompt. Please write a prompt to transfer the following style: {{ brief style description here }}.
You can get aesthetic consistently-styled images, like these:

https://goto.isaac.sh/image-style-transfer

Re:About using Nix in my development workflow on Thursday July 21, 2022 @02:43AM (#32176487)
In my opinion, writing derivations in Guile Scheme, using Guix[0], is a breath of fresh air[1]. If only the ecosystem were as large as Nix's...

[0]: https://en.wikipedia.org/wiki/GNU_Guix

[1]: https://goto.isaac.sh/guix

> He identified the four forces which act on a heavier-than-air flying vehicle: weight, lift, drag and thrust. [...] He also designed the first glider reliably reported to carry a human aloft. He correctly predicted that sustained flight would not occur until a lightweight engine was developed to provide adequate thrust and lift. The Wright brothers acknowledged his importance to the development of aviation.

— https://en.wikipedia.org/wiki/George_Cayley

I think by the time the Wright brothers came around, the general theory for powered flight was in place. The Wright Flyer was precision engineered, compared to most 'kites' that came before it. It's not every day you see an internal combustion engine on a kite.

Re:Rust without the async (hard) part on Thursday June 09, 2022 @02:15PM (#31684811)
A language with a function-color-agnostic effect system, generic over asynchronicity?
I mocked up a prototype for something similar to this using TreeSitter and its query language the other day for some heavy refactoring I had to do. This looks like a really cool project, will have to try it out!
Re:Sliderland – Creative coding with 64 HTML sliders on Saturday May 14, 2022 @12:53PM (#31379844)
I had a little too much fun...

    x>0.2-abs(sin(t*2))*0.05&&x<0.8+abs(sin(t*2))*0.05?(i%2?(min((x-sin(t%1.57)*0.3-0.5)*tan(-t%1.57)+cos(t%1.57)*0.3+0.5,(x-sin(t%1.57-1.57)*0.3-0.5)*tan(-t%1.57-1.57)+cos(t%1.57-1.57)*0.3+0.5)*0.4+0.5):(1-(min((-x-sin(t%1.57)*0.3+0.5)*tan(-t%1.57)+cos(t%1.57)*0.3+0.5,(-x-sin(t%1.57-1.57)*0.3+0.5)*tan(-t%1.57-1.57)+cos(t%1.57-1.57)*0.3+0.5)*0.4+0.5))):0.5
https://sliderland.blinry.org/#x%3E0.2-abs%28sin%28t*2%29%29...
Re:Actual is going open-source on Friday April 29, 2022 @12:02PM (#31206909)
I love Actual, one of the best local-first apps I've used. I'm excited that it's been open sourced, but I also understand that this release is a bit bittersweet. Awesome work James, best of luck in your future endeavors :)
Re:I bought a short domain name. What should I do with it? on Tuesday April 12, 2022 @06:09AM (#31000638)
Thanks for the link to the guidelines: I removed the 'Show HN' prefix as this project isn't anything quantifiable yet. I'll be sure to post a proper Show HN when I've got something to show.

I bought a short domain name. What should I do with it?

https://hb.sbs

In the spirit of 'Tiny Projects' by Ben Stokes, I'd like to start a small little side project. A while back I registered https://hb.sbs, but soon realized that I had no idea what project I wanted to make. I have a few ideas, but would love to hear if y'all have any cool project ideas.I plan to document my process in selecting, building, and releasing the project. I'll release the project...

( Read More... | 15 comments | 11 points | on HN )
Re:Fuchsia IDL Overview on Thursday March 17, 2022 @02:28AM (#30708243)
Don't forget the built-in chat in google docs that nobody uses! (Yes, the one other than the commenting system).
Re:Plasticity Is CAD for Artists on Wednesday March 16, 2022 @08:25AM (#30697879)
We shouldn't have to live in a culture when being called out for making a 'choice with tenuous political relevancy' is socially expected, and something someone is 'guilty of'.
Re:TermKit: A Rich Graphical Terminal (2011) on Wednesday March 02, 2022 @01:25AM (#30524386)
Like you, I am not a huge fan of JS, but I'd like to say that the ideas behind TermKit — namely having a shell with richer graphical interaction (e.g. cat works for images too), semantic awareness and tokenization of commands, rich autocomplete, etc. — were ahead of their time.

Maybe it's expected that TermKit-the-project died, but I don't think that TermKit-the-idea should: whether it be bringing features from the project as extensions to existing terminals (cat for images would be nice), or building a new TermKit built on modern graphics libraries powered by WASM/Lua/bring-your-own scripting language.

Re:Show HN: Spade, A simple programming language with a TUI IDE on Saturday January 15, 2022 @12:33PM (#29948346)
Just letting you know, it's also the name of a pretty well-known suit of cards present in decks of playing cards.

https://en.m.wikipedia.org/wiki/Spades_(suit)

This is a neat idea. Would love to run some queries against this with a larger index. Here's one instance of the question just going over the transformer's head, I guess:

My question:

> how does google work

The response:

> A decentralized autonomous organization (DAO) is a software running on a distributed ledger that offers users a built-in model for the collective management of its code. To become a member of a DAO, users need to first join the DAO by buying its currency. Unlike traditional organizations, there is no hierarchy in DAOs. One of the key features of DAOS is the internal capital that is used to incentivize these actors and ensure that the organization runs smoothly.

Re:Show HN: Looptap – A minimal game to waste your time on Thursday January 13, 2022 @02:43PM (#29925739)
Yes, but this almost seems intentionally genius at the same time.
A snapshot is a the entire state of a program at a single moment in time. Continuations are basically exposed snapshots, i.e. taking a snapshot, storing it in a variable, doing some work, and then 'calling' the snapshot to return to an earlier point. Continuations allow you to implement a naive version of single-shot delimited continuations - coroutines! This can be very useful for modeling concurrency.

Aside from coroutines and continuations, snapshots are neat for distributed computing: spin up a vm, take a snapshot, and replicate it over the network. You could also send snapshots of different tasks to other computers to execute. In the context of edge computing, you could snapshot the program once it's 'warm' to cut back on VM startup time.

Snapshots allow you to peek into your program. Imagine a debugger that takes snapshots on breakpoints, lets you to inspect the stack and heap, and replay the program forward from a given point in a deterministic manner. You could also send a snapshot to a friend so they can run an application from a given point on their machine. If you do snapshots + live reloading there are tons of other things you can do (e.g. live patching and replaying of functions while debugging).

I've written some documentation for it in the past, but had to scrap it because things tend to move so quickly that it's better to read the code and ask Shaw than use incorrect documentation. As things stabilize, these issues will be resolved, but it's very bleeding-edge right now.
Re:The joy of building a ray tracer, for fun, in Rust on Tuesday January 04, 2022 @04:46AM (#29793062)
Oh, I did something like this a while back as well! Aside from ray tracing, my renderer also supports ray marching, so it can render some cool fractals[1]. Writing path tracers is so much fun, love the write-up!

[1]: https://github.com/slightknack/keikan#readme

Re:Scripting languages of the future on Monday November 08, 2021 @06:12AM (#29148130)
> Tossing my hat in for Passerine [1]. Gorgeous ML inspired syntax.

I work on Passerine, cool to see the language mentioned in the wild, glad you like it!

> Written in Rust, and I suspect scripting Rust libraries is in the cards.

We have a rudimentary FFI to Rust already in place. We're also working on a proc macro lib for creating high-level bindings to Rust types/functions/crates (currently unreleased). Also working on an algebraic-effect-based system-injection engine, which will replace the FFI in the 0.10.0 or 0.11.0 release :)

Hey HN,

Isaac Clayton again[0]! This summer I worked as an intern at tonari[1] where I developed algorithms for real-time 3D scene construction on the GPU. As a part of my research, I developed a library / tool for prototyping shader-based graphical pipelines on the GPU. This tool, Shadergarden[2], uses GLSL[3] for shaders, but introduces a lisp-like configuration language[4] for chaining shaders (and other transformations) into directed acyclic graphical pipelines. We've been using it for both art and research, kinda like a local Shadertoy.

Hope you enjoy the write up, have a nice day!

PS — If your browser automatically pauses videos, you might need to 'show video controls' to play some of the visualizations.

[0]: https://news.ycombinator.com/item?id=25347140 / https://news.ycombinator.com/item?id=26212491

[1]: https://tonari.no

[2]: https://github.com/tonarino/shadergarden

[3]: https://thebookofshaders.com/

[4]: https://github.com/tonarino/shadergarden/blob/master/LISP.md (When all you have is a compiler, everything's a DSL)

Re:Rome's Pizza Vending Machine on Thursday August 26, 2021 @12:46PM (#28317329)
As someone who lives in Rome, it's about as quick to order a fresh pizza to go from a local restaurant as it is to get one from this vending machine. Alice Pizza is a popular pizza-to-go chain, but the place with what I think has the best pizza is Sementi la Pizza.

Just my own 2¢, I digress.

Because Passerine is pass-by-value, it only allows each reference to be owned by one object.

> So if some code somewhere hands me a list that contains references to some heap data, how do you track this?

Passerine is a high-level language, so it does not give the programmer control over whether something is a list of references to data on the heap or a list of values. Assuming `a`, `b`, and `c` have been defined, If I write this:

    list = [a, b, c]
`a`, `b`, and `c` will be moved into the list upon construction. If I do something like:

    list = [a, b, c]
    print (foo a c)
`b` will be moved into the list, and copies of `a` and `c` will be moved into the list.

So, to now answer your question:

    list = [a, b, c]
    list = drop_first list
> We lost/dropped/gave up a. How do we know how a was tied to the stack?

`a` was tied to the stack because it's in `[a, b, c]`, which is tied to the stack via `list`.

> How many other references might point at the object previously referenced by a? Can we collect that object now?

By definition, none - `a` is a unique value. Now that we dropped `a`, there are guaranteed to be no other references of `a`, so we can collect that object now.

> Is this the case where reference counting kicks in?

No, the reference counting is a small optimization for sharing immutable values in closures. If a closure captures a value, say a large list, we don't want to go around copying this willy-nilly:

    big_list = [...]
    c = () -> {
        -- big list is copied when the closure is made
        -- this happens because the reference in the closure can outlive local stack frame
        a -> first big_list
    }

    -- these calls to c do not copy big_list again
    a_outer = c ()
    a_another = c ()
Closures need to copy values immutably to prevent the construction of cycles. I wrote a long explanation on why this is the case, but I've decided to move it to the blog post when I publish it. I thought of a way to efficiently count references acyclically, but I need to work it out before I made any more claims.

Hope this helps!

Thanks for your excellent questions. They're really helping me fuzz through my approach - I wish I had people I could do this with more often, haha. :P

Anyway, something I realized after I posted that question is that assignment doesn't have to force a copy; for instance, this could just take a CoW slice reference to the original list:

    [head & tail] = &rem'
The only requirement is that the value returned from a function is an owned value, not CoW. To avoid talking myself into circles, I'll show that `append` still works under this rule. It just moves the copy to the point where we construct the new list, rather that at the point where we de-structure it:

    loop [head' & acc'] tail'
So in `[head' & acc']`.

For the code sample you provided, a reference would be passed down, rather than a copy of the entire list, so just the first two elements would be copied. Do you have any further questions regarding this? I'd like to be able to prove the soundness of this system, but I'm not sure going back and forth on example after example is the best strategy in the long run.

> In a functional language, insertion into a binary tree only copies nodes along one path in the tree. Would your language copy the entire tree instead, at potentially exponentially higher cost?

Most functional languages use persistent data-types, because all data in those languages are immutable. I haven't thought about how they'd work into Passerine, but if you mutate data that will be used later, a copy of that data will be made. So yes, mutating a tree makes a copy of it if the original tree is used later.

This is less of a problem then you'd think. It's common to write programs as series of transformations on data, so note that if you do something like this on a big million-element list children .map { child -> (child.name, child.age, child.hobby) } .filter { (_, age, _) -> age > 10 } .map { (name, _, hobby) -> (first_name name, hobby) } .filter { (_, hobby) -> is_fun hobby } .fold "" { (string, (name, hobby)) -> string + name + " enjoys " + hobby + "\n" } .print

No copies will be made, because each step is the last usage of the data-structure produced in the previous step.

> (I'm also slightly confused by your definition of append -- the accumulator seems to be a list, but then the initial call of loop would need to use [value] instead of value, no?)

Once again, correct.

> Regarding "tying references to the stack" I had another question here: https://news.ycombinator.com/item?id=26228961

I wrote a long response, to this, but it ended up being a couple thousand words, so I'm trying to trim it down. (I went off the deep end, with stack diagrams, explaining how cycles get created, etc, etc.) TL;DR for now is that you can't have a list of references, each object is only mutably 'owned' by one other. Once I trim down the response, I'll post it - should be sometime later today.

It's loosely based on Proust ASAP, but without the explicit quadratic-time construction of paths (in a sense, this is done 'dynamically' at runtime with the CoW strategy we've discussed). When you think about it, Vaporization is really just an extension to escape analysis. It's not a perfect system though, namely, It required immutable closures. But if you're coming from a functional programming language, that's a small sacrifice to make, given that mutability is generally frowned upon.

> I think I'll have at least one more question about how the "tying of references to the stack" works, but I need to think things through a bit more.

I tried to answer your sibling comment on appending a CoW xs. I hope that clears some things up so you can ask any questions you have!

Older »