Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I've been kind of curious why tricks like this aren't used more to make sql and such. Heck, you could do similar tricks for shell execution. Or any general "string that is parseable." Seems we always take the route of not parsing the string as much as we can?


This is a pretty neat application, but most embedded languages like SQL have a way more complicated grammar that would require a really complicated set of types to parse. This can tank the performance of your type checking step and it also means that the error messages you get out of the parser-in-types are going to be nearly useless.

A more common solution is to parse the string at runtime with a proper parser with decent error handling and then have the parser return a branded type [0] which you can use elsewhere to ensure your strings are well formed.

[0] https://egghead.io/blog/using-branded-types-in-typescript


I'd expect that for most SQL that is being inlined in code, you could get by with only supporting a subset of what is possible. I also have no doubt you could easily sabotage the effort by trying to support every dialect of sql in a smart way. :D

I'm also curious on the idea of having a string parsed at runtime and why that is necessarily better? Sounds like this is essentially dynamic typing? Where they are calling it branded, instead of dynamic? At first, I confess the idea sounded close to a tagged union. You have to have something in the data to indicate the tag; but I guess it is missing the union part? Definitely looks close to the idea of treating "objects" as maps.

Neat idea, thanks for sharing!


I can't find it now, but someone actually built that for SQL in Typescript as an experiment. The problem folks run into is IDE and compiler performance. These sorts of features are what make your system turing complete, so they start stressing the compiler pretty quickly


I think, from having it used recently, that supabase's TS library does this. I had to write a wrapper around it a few months ago at $dayjob and was really surprised when select/from parts of a "query" (not really a SQL query, because it's just a postgrest query) actually got parsed at compile time and spit out the right types. And since our code is pretty type heavy, I was gonna have to do that anyway, so I really appreciated it


There is actually efforts in the Typescript community attempting to do just that. Personally I think it'll end up being a waste, but these sorts of experiments, even when they fail, often can help along new discoveries.

And on the off-chance they get it right, then damn that's pretty great.


Fully agreed that failure is expected! I think it can still make great learning for all involved. And, 100% agreed that proving us wrong on this would be great!


There is an implementation of SQL that operates on a table shaped type, entirely at type level. For your amusement: https://github.com/codemix/ts-sql

There are a bunch of more practical takes that codegen types from your database and generate types for your queries, eg: https://github.com/adelsz/pgtyped

To me the second approach seems much more pragmatic because you don’t need to run a SQL parser in your typechecker interpreter on every build


Cool! I'm not sure how I feel on the idea of keeping it out of the "typechecker." At large, the amount of work being done by what we call the compiler nowadays is already far more than folks would have called for decades ago. I don't know that I think there is a solid line of "this should never happen during compilation."

Your implication that it is a tradeoff, btw, I fully endorse/agree with. And I know there will be pathological projects out there where the code gen will take ages to complete. I'd hazard a guess that most people wouldn't notice the codegen happening on every build for most projects. Especially on modern build machines.


> why tricks like this aren't used more

Some languages don't support this.

The languages that do would require extensive systems to implement this feature. It may simply not be a priority over other requirements like thread safety, atomicity, etc.

> similar tricks for shell execution

Shell only supports strings, integers and lists. The type system is too limited for this level of type-checking.

This works in typescript due to the advanced type operations built into the language.


Apologies, I meant the equivalent of `os.popen` in python. You'd almost certainly only support a subset of what a shell actually supports, but that would almost certainly be for the best.

Basic point being that the equivalent of named/delimited parameters with pretty much forced support for escaping such that you have to go out of your way to send raw strings.

I think, bottom line, it bemuses me that the default "convenience" methods are almost always "send this string over to another process to evaluate it" instead of any processing locally on it. That feels it would be far better as the power "escape hatch" instead of the "convenience method" that it is often pitched as.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: