frontpage.
newsnewestaskshowjobs

Made with ♥ by @iamnishanth

Open Source @Github

fp.

Show HN: AI generated personal affirmations playing when your phone is locked

https://MyAffirmations.Guru
1•alaserm•47s ago•0 comments

Show HN: GTM MCP Server- Let AI Manage Your Google Tag Manager Containers

https://github.com/paolobietolini/gtm-mcp-server
1•paolobietolini•1m ago•0 comments

Launch of X (Twitter) API Pay-per-Use Pricing

https://devcommunity.x.com/t/announcing-the-launch-of-x-api-pay-per-use-pricing/256476
1•thinkingemote•2m ago•0 comments

Facebook seemingly randomly bans tons of users

https://old.reddit.com/r/facebookdisabledme/
1•dirteater_•3m ago•1 comments

Global Bird Count

https://www.birdcount.org/
1•downboots•3m ago•0 comments

What Is Ruliology?

https://writings.stephenwolfram.com/2026/01/what-is-ruliology/
2•soheilpro•5m ago•0 comments

Jon Stewart – One of My Favorite People – What Now? With Trevor Noah Podcast [video]

https://www.youtube.com/watch?v=44uC12g9ZVk
1•consumer451•8m ago•0 comments

P2P crypto exchange development company

1•sonniya•21m ago•0 comments

Vocal Guide – belt sing without killing yourself

https://jesperordrup.github.io/vocal-guide/
1•jesperordrup•26m ago•0 comments

Write for Your Readers Even If They Are Agents

https://commonsware.com/blog/2026/02/06/write-for-your-readers-even-if-they-are-agents.html
1•ingve•27m ago•0 comments

Knowledge-Creating LLMs

https://tecunningham.github.io/posts/2026-01-29-knowledge-creating-llms.html
1•salkahfi•27m ago•0 comments

Maple Mono: Smooth your coding flow

https://font.subf.dev/en/
1•signa11•34m ago•0 comments

Sid Meier's System for Real-Time Music Composition and Synthesis

https://patents.google.com/patent/US5496962A/en
1•GaryBluto•42m ago•1 comments

Show HN: Slop News – HN front page now, but it's all slop

https://dosaygo-studio.github.io/hn-front-page-2035/slop-news
5•keepamovin•43m ago•1 comments

Show HN: Empusa – Visual debugger to catch and resume AI agent retry loops

https://github.com/justin55afdfdsf5ds45f4ds5f45ds4/EmpusaAI
1•justinlord•45m ago•0 comments

Show HN: Bitcoin wallet on NXP SE050 secure element, Tor-only open source

https://github.com/0xdeadbeefnetwork/sigil-web
2•sickthecat•47m ago•1 comments

White House Explores Opening Antitrust Probe on Homebuilders

https://www.bloomberg.com/news/articles/2026-02-06/white-house-explores-opening-antitrust-probe-i...
1•petethomas•48m ago•0 comments

Show HN: MindDraft – AI task app with smart actions and auto expense tracking

https://minddraft.ai
2•imthepk•52m ago•0 comments

How do you estimate AI app development costs accurately?

1•insights123•54m ago•0 comments

Going Through Snowden Documents, Part 5

https://libroot.org/posts/going-through-snowden-documents-part-5/
1•goto1•54m ago•0 comments

Show HN: MCP Server for TradeStation

https://github.com/theelderwand/tradestation-mcp
1•theelderwand•57m ago•0 comments

Canada unveils auto industry plan in latest pivot away from US

https://www.bbc.com/news/articles/cvgd2j80klmo
3•breve•58m ago•1 comments

The essential Reinhold Niebuhr: selected essays and addresses

https://archive.org/details/essentialreinhol0000nieb
1•baxtr•1h ago•0 comments

Rentahuman.ai Turns Humans into On-Demand Labor for AI Agents

https://www.forbes.com/sites/ronschmelzer/2026/02/05/when-ai-agents-start-hiring-humans-rentahuma...
1•tempodox•1h ago•0 comments

StovexGlobal – Compliance Gaps to Note

1•ReviewShield•1h ago•1 comments

Show HN: Afelyon – Turns Jira tickets into production-ready PRs (multi-repo)

https://afelyon.com/
1•AbduNebu•1h ago•0 comments

Trump says America should move on from Epstein – it may not be that easy

https://www.bbc.com/news/articles/cy4gj71z0m0o
7•tempodox•1h ago•4 comments

Tiny Clippy – A native Office Assistant built in Rust and egui

https://github.com/salva-imm/tiny-clippy
1•salvadorda656•1h ago•0 comments

LegalArgumentException: From Courtrooms to Clojure – Sen [video]

https://www.youtube.com/watch?v=cmMQbsOTX-o
1•adityaathalye•1h ago•0 comments

US moves to deport 5-year-old detained in Minnesota

https://www.reuters.com/legal/government/us-moves-deport-5-year-old-detained-minnesota-2026-02-06/
9•petethomas•1h ago•3 comments
Open in hackernews

Row Polymorphic Programming

https://www.stranger.systems/posts/by-slug/row-polymorphic-programming.html
52•todsacerdoti•6mo ago

Comments

skybrian•6mo ago
What could you do with row polymorphism that you couldn’t do with generic functions that take slices in Go?
tines•6mo ago
I think Go interfaces are row-polymorphic aren't they? I'm also wondering what the difference between row-polymorphism and ad-hoc polymorphism (a la C++ templates) is.
wavemode•6mo ago
Yes, Go interfaces are row-polymorphic, in the sense that they allow you to write functions that operate on any struct which has a field with a certain name and type.

This utilizes the fact that structs implement interfaces implicitly in Go, rather than explicitly.

> I'm also wondering what the difference between row-polymorphism and ad-hoc polymorphism (a la C++ templates) is

C++ templates can also be row-polymorphic. They're a lot more flexible than just row polymorphism, though, because they essentially allow you to be polymorphic over any type for which a given expression is valid syntax.

Concepts were an attempt to allow developers to rein in some of that flexibility, since it actually became a pain.

skybrian•6mo ago
Is this new with generics? I thought Go interfaces were just method sets?
jerf•6mo ago
"Go interfaces are row-polymorphic, in the sense that they allow you to write functions that operate on any struct which has a field with a certain name and type."

It doesn't have it yet. Go is headed strongly in that direction which is why I add the "yet", but see https://github.com/golang/go/issues/70128 , especially the "future directions" note about issue #48522 which is not implemented. Prepatory work has been done but the change is not in yet.

You can embed something like compile-time row types into Go if you implement it in terms of accessor methods that can be included in an interface, rather than direct struct field access, which has its pros and cons.

But if you're reading this in 2026 or beyond, check in with Go, this may not be true anymore.

aatd86•6mo ago
When you want to abstract on structs "having" a given field (by name) of a given type, I think. Although that may come in Go at some point.
tines•6mo ago
I'm not a Go expert but that's exactly what interfaces are, aren't they? In Go a struct automatically implements an interface if it contains all the required fields (duck-typing).
sparkie•6mo ago
They're both a form of structural typing - the static equivalent of duck typing.

A difference with row types is that they don't have to be declared up front like an interface - they're basically anonymous types. You declare the row types in the type signature.

For example, a function taking some structural subtype of `Foo` and returning some structural subtype of `Bar` would be written in Go as:

    type Foo interface {
        baz Baz
    }
    
    type Bar interface {
        qux Qux
    }
    
    func (x Foo) f() Bar {
        ...
    }
In OCaml, you'd just inline the row types - there are no `Foo` or `Bar`:

    val f : < baz : Baz.t; .. > -> < qux : Qux.t; .. > 
    let f x = ...
You can typedef row types though

    type foo = < baz : Baz.t; .. >
    type bar = < qux : Qux.t; .. >
    val f : foo -> bar
Rows can be declared to have an exact set of members. For example, the types `< bar : Baz.t >` and `< bar : Baz.t; ..>` are two different types. The latter can have members besides `bar`, but the former can only have the member `bar`. A type containing the fields `bar` and `qux` would be a subtype of `< bar : Bar.t; .. >`, but it would not be a subtype of `< bar : Bar.t >`.

OCaml has another form of structural typing in its module system, closer to interfaces where a `module type` is declared up-front, and can be specified as the argument for a functor (parameterized module) - but this is incompatible with the row types in the object system.

logicchains•6mo ago
Go also supports inline/unnamed interfaces.
aatd86•6mo ago
It's not fields but methods.
moron4hire•6mo ago
Also called Nominal Typing. I generally consider it a mistake. Interfaces aren't just a bag of fields and methods. They encode semantics, too. Otherwise, you could dismiss employees with a gun or by loading them into a kiln.
tines•6mo ago
Nominal typing is the opposite, I think you're thinking of structural typing, no?
moron4hire•6mo ago
Yep, sorry
taeric•6mo ago
I am not entirely sure I disagree. I think context is often a big factor in semantics, though? The problem with interfaces is often that people think they do all of the work by themselves. But, that is only true within the context of how you use some data. And people tend to accidentally constrain themselves too heavily.

You can make the same argument for numbers, for an easy exploration. Just look at all of the tools that you can have at your disposal by thinking of things as numbers.

michael1999•6mo ago
In the original relational papers, column names were basically types. In a OO world, that doesn't make sense, but in a relational world, it does.
pxeger1•6mo ago
I think you mean structural typing; nominal typing is the opposite, where field names are lexically scoped.

Anyway, row polymorphism can technically be used with nominal typing, it's just that it usually makes sense to use structural typing instead.

The key benefit of row polymorphism is a bit of an implementation detail - it lets you get something resembling (a limited form of) subtyping in your language, without needing as complicated a type inference algorithm as fully-general subtyping requires.

Row polymorphism can be (IMO should usually be) made opt-in, so you can avoid problems like the scenario you describe.

daxfohl•6mo ago
The only thing is I wish there was a way to safely lift a row-polymorphic record to a named record type if the compiler can determine it has all the required fields. Haven't seen any languages that offer this yet though.
continuational•6mo ago
Firefly can construct any named record from any other record (named or anonymous):

    let point = (x = 5, y = 7)
    let point3d = point.Point3d(z = 0)
We included this feature specifically to make it easy to use named and unnamed records together.

More here: https://www.firefly-lang.org/

owlstuffing•6mo ago
The manifold project[1] for Java provides that feature as "Structural Interfaces" which supports polymorphic variants.

The project also supports tuples that behave similarly.

    var person = (name: "Joe", age: 35);
    . . .
    Person p = person; // tuple's name, age properties satisfy Person record
1. https://github.com/manifold-systems/manifold
gsliepen•6mo ago
When is it "safe" though? What if the row-polymorphic record has more fields than the named record? Should those just be discarded? If it has exactly the same fields, then in C++ at least you can use std::get<NamedRecordType>(row_polymorphic_record) if you are using static polymorphism, and dynamic_cast<NamedRecordType*>(row_polymorphic_record) in case of dynamic polymorphism. Note that the compiler cannot determine anything at compile time when you have polymorphic objects, so it's just going to emit code that at runtime will throw an exception.
owlstuffing•6mo ago
I hadn't come across the "Row" polymorphism term before, but it sounds more like structural typing -- for example TypeScript, and to a lesser degree Go, have structural interfaces that provide "row polymorphic" programming.

You could go further with variant structural typing, basically this is a broader form of type checking based on call compatibility, which answers the question -- is B#foo() callable as an A#foo()?

For instance, your `area` example requires `double` result types, otherwise a row type having `width` and `length` defined as `integer` columns doesn't satisfy `area`. But, result types are naturally covariant -- `integer` is a subset of `double` -- which permits us to accept `integer` in the implementation of `area`.

Similarly, parameter types are naturally contravariant -- `Shape` is contravariant to `Triangle`, thus `B#foo(Shape)` is call-compatible as a `A#foo(Triangle)`, therefore I can pass a Triangle to `B#foo(Shape)`.

The manifold project[1] for Java is one example where the type system is enhanced with this behavior using structural interfaces.

Note, this goes further with parametric types where function result types and parameter types define variance and other constraints.

1. https://github.com/manifold-systems/manifold

aerzen•6mo ago
Someone help me, a rust programmer , understand this: is this like having a function be generic over structs with some fields?

Like having `<T: {width: f64, depth: f64}>`?

I have such a hard time understanding the multiple arrows notation of ML family languages.

malcolmgreaves•6mo ago
Yes! The idea is that we just care that it’s something with the named & typed fields. It can have more fields, but we’re really setting a lower bound on what we need to exist for our function to work.
maegul•6mo ago
Hmmm … my beginner’s rust is getting too rusty.

Is this valid rust (it’d be new to me)?!

If not, I’m guessing, from memory, the only way at this in rust is to through traits?

malcolmgreaves•6mo ago
> In my personal experience I have found that when an experienced programmer who really seems like they should know better is making some weird sounding arguments about how type systems decrease their productivity and don't prevent enough bugs to be worth it, they seem to usually be complaining about the lack of row polymorphism (or the closely related structural subtyping) in popular statically typed languages, just without having the technical vocabulary for it.
constantcrying•6mo ago
Interestingly Matlab has a specific data type for this, the cell array, as far as I am aware the only language to provide a specific data type for storing 2D arbitrarily typed data. Exactly the use case described here.
1-more•6mo ago
This is roughly how records and extensible record arguments work in Elm. A `type alias` is a structural type, and a function argument specified as an extensible record `{ a | … }` can be read as "any record a having at least the fields …"

    type alias Furniture = { name : String, length : Float, width : Float, height : Float}
    type alias Room = { name : String, length : Float, width : Float}

    floorArea : { a | length : Float, width : Float} -> Float
    floorArea {length, width} = length * width
This is just an example for brevity. In practice, I'd probably recommend the dimensions be stored as `Length.Length` from the package elm-units. I'd modify the extensible record argument of `floorArea` to expect the same, and I'd have `floorArea` return an `Area.Area`.

You can also use nominal typing to prohibit this via opacity. You can then wrap up construction in a function that fails for invalid states. Here we export the type Furniture but not its only constructor Furniture1.

    module Furniture exposing (Furniture, width, length, height, name)
    type Furniture = Furniture1 { name : String, length : Float, width : Float, height : Float}
    
    name : Furniture -> String
    name (Furniture1 {name}) = name -- etc for width, length, height

    type Dimension = Width | Length | Height
    type Error = NameCannotBeBlank | DimensionMustBePositive Dimension

    safeConstruct : {width, height, name, length} -> Result Error Furniture
    safeConstruct params =
        if params.name == "" then
            Err NameCannotBeBlank

        else if (params.width <= 0) then
            Err (DimensionsMustBePositive Width)
        -- repeat for length and height
        else
            Ok (Furniture1 input)

then in a different module (i.e. a different file) (assume I also wrote safe constructors and accessors)

    module Room exposing (Room, width, length, name)
    type Room = Room1 { name : String, length : Float, width : Float}
Finally, your floor area function would not be able to inspect values of these types because we did not expose the Floor1 and Room1 constructors (in practice those would be named Floor and Room but that's confusing in this example). It would need accessors for the properties.

    floorArea : { toWidth : a -> Float, toLength : a -> Float } -> a -> Float
    floorArea {toWidth, toLength} = (toWidth a) * (toLength a)

    floorAreaRoom : Room -> Float
    floorAreaRoom = floorArea { toWidth = Room.width, length = Room.length }

    floorAreaFurniture : Furniture -> Float
    floorAreaFurniture = floorArea { toWidth = Furniture.width, length = Furniture.length }
Also in practice I'd maybe have `safeConstruct` have a shorter name and return a non-empty list of errors rather than just the first error, but that would cloud this example.