News for hackers. Stuff that matters.
Re:Cap'n Web: a new RPC system for browsers and web servers by mdasen on Monday September 22, 2025 @03:22PM (#45338228)
In C#, there's expression trees which handle things like this and it's how Entity Framework is able to convert the lambdas it's given into SQL. This means that you can pass around code that can be inspected or transformed instead of being executed. Take this EntityFramework snippet:

    db.People.Where(p => p.Name == "Joe")
`Where` takes an `Expression<Func<T, bool>> predicate`. It isn't taking the `Func` itself, but an `Expression` of it so that it can look at the code rather than execute it. It can see that it's trying to match the `Name` field to the value "Joe" and translate that into a SQL WHERE clause.

Since JS doesn't have this, they have to pass in a special placeholder value and try to record what the code is doing to that value.

Re:Cap'n Web: a new RPC system for browsers and web servers by drysart on Monday September 22, 2025 @04:07PM (#45338784)
There are inherent limitations with the "execute it once and see what happens" approach; namely that any conditional logic that might be in the mapping function is going to silently get ignored. For example, `db.people.map(p => p.IsPerson ? (p.FirstName + ' ' + p.LastName) : p.EntityName)` would either be seen as reading `(IsPerson, FirstName, LastName)` or `(p.IsPerson, p.EntityName)` depending on the specific behavior of the placeholder value ... and neither of those sets is fully correct.

I wonder why they don't just do `.toString()` on the mapping function and then parse the resulting Javascript into an AST and figure out property accesses from that. At the very least, that'd allow the code to properly throw an error in the event the callback contains any forbidden or unsupported constructs.

Re:Cap'n Web: a new RPC system for browsers and web servers by kentonv on Monday September 22, 2025 @04:13PM (#45338852)
The placeholder value is an RpcPromise. Which means that all its properties are also RpcPromises. So `p.IsPerson` is an RpcPromise. I guess that's truthy, so the expression will always evaluate to `(p.FirstName + ' ' + p.LastName)`. But that's going to evaluate to '[object Object] [object Object]'. So your mapper function will end up not doing anything with the input at all, and you'll get back an array full of '[object Object] [object Object]'.

Unfortunately, "every object is truthy" and "every object can be coerced to a string even if it doesn't have a meaningful stringifier" are just how JavaScript works and there's not much we can do about it. If not for these deficiencies in JS itself, then your code would be flagged by the TypeScript compiler as having multiple type errors.

Re:Cap'n Web: a new RPC system for browsers and web servers by skybrian on Monday September 22, 2025 @06:19PM (#45340318)
Another way to screw this up would be to have an index counter and do something different based on the index. I think the answer is "don't do that."
Re:Cap'n Web: a new RPC system for browsers and web servers by kentonv on Monday September 22, 2025 @06:42PM (#45340519)
Hmm, but I should make it so the map callback can take the index as the second parameter probably. Of course, it would actually be a promise for the index, so you couldn't compute on it, but there might be other uses...
Re:Cap'n Web: a new RPC system for browsers and web servers by drysart on Monday September 22, 2025 @06:45PM (#45340546)
Yeah I'll definitely chalk this up to my not having more than a very very passing idea of the API surface of your library based on a quick read over just the blog post.

On a little less trivial skim over it looks like the intention here isn't to map property-level subsets returned data (e.g., only getting the `FirstName` and `LastName` properties of a larger object); as much as it is to do joins and it's not data entities being provided to the mapping function but RpcPromises so individual property values aren't even available anyway.

So I guess I might argue that map() isn't a good name for the function because it immediately made me think it's for doing a mapping transformation and not for basically just specifying a join (since you can't really transform the data) since that's what map() can do everywhere else in Javascript. But for all I know that's more clear when you're actually using the library, so take what I think with a heaping grain of salt. ;)

Re:Cap'n Web: a new RPC system for browsers and web servers by Aeolun on Monday September 22, 2025 @06:53PM (#45340618)
Couldn’t you make this safer by passing the map something that’s not a plain JS function? I confess to that being the only thing that had me questioning the logic. If I can express everything, then everything should work. If it’s not going to work, I don’t want to be able to express it.
Re:Cap'n Web: a new RPC system for browsers and web servers by kentonv on Monday September 22, 2025 @07:25PM (#45340881)
I think any other syntax would likely be cumbersome. What we actually want to express here is function-shaped: you have a parameter, and then you want to substitute it into one or more RPC calls, and then compute a result. If you're going to represent that with a bunch of data structures, you end up with a DSL-in-JSON type of thing and it's going to be unwieldy.
Re:Cap'n Web: a new RPC system for browsers and web servers by pcthrowaway on Tuesday September 23, 2025 @12:08AM (#45342747)
I suspect there is prior work to draw from that could make this feasible for you... Have a look at how something like MongoDB handles conditional logic for example.
Re:Cap'n Web: a new RPC system for browsers and web servers by kentonv on Tuesday September 23, 2025 @08:46AM (#45346266)
Yeah that's what I mean by DSL-in-JSON. I think it's pretty clunky. It's also (at least in Mongo's formulation, at least when I last used it ~10 years ago) very vulnerable to query injection.
Re:Cap'n Web: a new RPC system for browsers and web servers by kentonv on Monday September 22, 2025 @04:18PM (#45338910)
> I wonder why they don't just do `.toString()` on the mapping function and then parse the resulting Javascript into an AST and figure out property accesses from that.

That sounds incredibly complicated, and not something we could do in a <10kB library!

Re:Cap'n Web: a new RPC system for browsers and web servers by actionfromafar on Monday September 22, 2025 @06:21PM (#45340336)
Maybe Fabrice Bellard could spare an afternoon.
Re:Cap'n Web: a new RPC system for browsers and web servers by sonthonax on Tuesday September 23, 2025 @03:37AM (#45343936)
To the contrary, a simple expression language is one of those things that can easily be done in that size.
Re:Cap'n Web: a new RPC system for browsers and web servers by kentonv on Tuesday September 23, 2025 @09:35AM (#45346836)
But the suggestion wasn't to design a simple expression language.

The suggestion was to parse _JavaScript_. (That's what `.toString()` on a function does... gives you back the JavaScript.)

Re:Cap'n Web: a new RPC system for browsers and web servers by javier2 on Monday September 22, 2025 @04:57PM (#45339355)
It dont think C# looks at the code? I suspect it can track that you called p.Name, then generate sql with this information?
Re:Cap'n Web: a new RPC system for browsers and web servers by adzm on Monday September 22, 2025 @05:01PM (#45339397)
The lambda is converted into an Expression, basically a syntax tree, which is then analyzed to see what is accessed.
Re:Cap'n Web: a new RPC system for browsers and web servers by javier2 on Wednesday September 24, 2025 @05:33AM (#45358057)
Ok, so its a step in the compile that rewrites and analyzes it?
Re:Cap'n Web: a new RPC system for browsers and web servers by adzm on Wednesday September 24, 2025 @10:12PM (#45368548)
It's actually really neat. Normally a lambda would just be a function but if it gets cast to an Expression then you get the AST at runtime. Entity Framework analyzes these at runtime to generate the SQL and logic/mapping etc. You can get the AST at compile time in some situations with a Roslyn plug-in or etc I believe as well.
Re:Cap'n Web: a new RPC system for browsers and web servers by ziml77 on Monday September 22, 2025 @06:11PM (#45340228)
The C# compiler is looking at that code. It sees that the lambda is being passed into a function which accepts an Expression as a parameter, so it compiles the lambda as an expression tree rather than behaving like it's a normal delegate.
Re:Cap'n Web: a new RPC system for browsers and web servers by squirrellous on Monday September 22, 2025 @08:32PM (#45341444)
Is there anything C# _doesn’t_ have? :-)

It feels like C# has an answer to every problem I’ve ever had with other languages - dynamic loading, ADTs with pattern matching, functional programming, whatever this expression tree is, reflection, etc etc. Yet somehow it’s still a niche language that isn't widely used (outside of particular ecosystems).

Re:Cap'n Web: a new RPC system for browsers and web servers by rjbwork on Monday September 22, 2025 @09:22PM (#45341771)
It's one of the most widely used languages out there actually. But it's primarily used at buttoned up and boring SMB's/enterprise backoffices. We're not out here touting our new framework of the month to kafloogle the whatzit. We're just building systems with a good language and ecosystem that's getting better every year.

I've worked only at startups/small businesses since I graduated university and it's all been in C#.

Re:Cap'n Web: a new RPC system for browsers and web servers by brainzap on Tuesday September 23, 2025 @06:26AM (#45345117)
getting better? many packages we been using did a license swap on us xD

fucking nice ecosystem

Re:Cap'n Web: a new RPC system for browsers and web servers by rjbwork on Tuesday September 23, 2025 @12:02PM (#45348904)
Fork it. End of the day some guys decided they wanted to make money and the corporations profiting off their labor weren't paying up. These things don't happen in a vacuum. Does your company have a multi-thousand dollar a year budget to make sure your dependencies are sustainable?
Re:Cap'n Web: a new RPC system for browsers and web servers by uzerfcwn on Tuesday September 23, 2025 @12:11AM (#45342768)
> Is there anything C# _doesn’t_ have?

Pi types, existential types and built-in macros to name a few.

Re:Cap'n Web: a new RPC system for browsers and web servers by moomin on Tuesday September 23, 2025 @05:21AM (#45344675)
Sum types are the ones I really miss. The others would be nice but processing heterogeneous streams is my biggest practical issue.
Re:Cap'n Web: a new RPC system for browsers and web servers by vaylian on Tuesday September 23, 2025 @03:32AM (#45343904)
It's funny how C# started out as a Java clone and then added a ton of features while Java stayed very conservative with new language features. And both languages are fine.
Re:Cap'n Web: a new RPC system for browsers and web servers by garblegarble on Tuesday September 23, 2025 @06:52AM (#45345289)
>Is there anything C# _doesn’t_ have?

You were maybe already getting at it, but as a kitchen sink language the answer is "simplicity". All these diverse language features increase cognitive load when reading code, so it's a complexity/utility tradeoff

Re:Cap'n Web: a new RPC system for browsers and web servers by dominicrose on Tuesday September 23, 2025 @08:14AM (#45345905)
As someone who dislikes clutter, in my experience it's just easier to read and write with these languages: Perl, PHP, Ruby, Python, Javascript, Smalltalk.

If you dare leave the safety of a compiler you'll find that Sublime Merge can still save you when rewriting a whole part of an app. That and manual testing (because automatic testing is also clutter).

If you think it's more professional to have a compiler I'd like to agree but then why did I run into a PHP job when looking for a Typescript one? Not an uncommon unfolding of events.

Re:Cap'n Web: a new RPC system for browsers and web servers by FungalRaincloud on Tuesday September 23, 2025 @12:36PM (#45349404)
I'm a bit surprised that you put PHP in that list. My current workload is in it, and a relatively modern version of it, so maybe that surprise will turn around soon, but I've always felt that PHP was more obnoxious than even C to read and write.

Granted, I started out on LISP. My version of "easy to read and write" might be slightly masochistic. But I love Perl and Python and Javascript are definitely "you can jump in and get shit done if you have worked in most languages. It might not be idiomatic, but it'll work"...

Re:Cap'n Web: a new RPC system for browsers and web servers by dominicrose on Wednesday September 24, 2025 @08:45AM (#45359531)
PHP is easy to get into because of the simple (and tolerant) syntax and extremely simple static typing system. The weak typing also means it's easier for beginners.

It does require twice the lines of PHP code to make a Ruby or Python program equivalent, or more if you add phpdoc and static types though, so it is easier to read/write Ruby or Python, but only after learning the details of the language. Ruby's syntax is very expressive but very complex if you don't know it by heart.

Re:Cap'n Web: a new RPC system for browsers and web servers by gwbas1c on Tuesday September 23, 2025 @08:46AM (#45346270)
Good abstractions around units (Apologies if there is a specific terminology that I should use.)

Specifically, I'd like to be able to have "inches" as a generic type, where it could be an int, long, float, double. Then I'd also like to have "length" as a generic type where it could be inches as a double, millimeters as a long, ect, ect.

I know they added generic numbers to the language in C# 7, so maybe there is a way to do it?

Re:Cap'n Web: a new RPC system for browsers and web servers by evntdrvn on Tuesday September 23, 2025 @10:03AM (#45347209)
Check out F# "units of measure" ;)
Re:Cap'n Web: a new RPC system for browsers and web servers by notpushkin on Monday September 22, 2025 @10:13PM (#45342073)
PonyORM does something similar in Python:

    select(c for c in Customer if sum(c.orders.total_price) > 1000)
I love the hackiness of it.
Re:Cap'n Web: a new RPC system for browsers and web servers by porridgeraisin on Monday September 22, 2025 @10:29PM (#45342183)
PonyORM is my favourite python ORM.

Along with https://pypi.org/project/pony-stubs/, you get decent static typing as well. It's really quite something.

Re:Cap'n Web: a new RPC system for browsers and web servers by rafaelgoncalves on Tuesday September 23, 2025 @01:15AM (#45343054)
whoa, didn't know PonyORM, looks really neat! thanks for showing
Re:Cap'n Web: a new RPC system for browsers and web servers by keyle on Monday September 22, 2025 @11:23PM (#45342501)
C#, Swift, Dart, Rust... Python. Many languages take lambda/predicate/closure as filter/where.

It generally unrolls as a `for loop` underneath, or in this case LINQ/SQL.

C# was innovative for doing it first in the scope of SQL. I remember the arrival of LINQ... Good times.

Re:Cap'n Web: a new RPC system for browsers and web servers by sobani on Tuesday September 23, 2025 @03:14AM (#45343784)
How many of those languages can take an expression instead of a lambda?

Func<..> is lambda that can only be invoked.

Expression<Func..>> is an AST of a lambda that can be transformed by your code/library.

Re:Cap'n Web: a new RPC system for browsers and web servers by Tyr42 on Tuesday September 23, 2025 @07:58AM (#45345731)
R let's you do that, and it gets used by the tidy verse libraries to do things like change the scope variables in the functions are looked up in.