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

I love 1ML, but so far I've failed to see the importance of Tomas' co-effect system. Can you point out why you think it's important? In particular, in what ways is it better than e.g. implicits in Scala?


Have you ever used F#'s type providers? The idea of an external environment (for example, a Web API or a specific SQL database and schema) lifted directly into the type system is pretty powerful. I'm familiar with Slick's typed SQL statements (currently using them in a project) which use a hefty dose of implicits and macros, and it kinda approaches the power of the SQL type provider, but its still incredibly clunky and trying to debug anything is a huge PITA.

A co-effect system is like a type provider on steroids: any aspect of the environment in which a system executes can be lifted onto the type system. This could be anything from GPU or specialty sensor availability to data security requirements.

It would allow for things like code sharing between scala & scalajs without needing to set up complicated SBT code sharing projects. You would have a scalajs main, and a scala main, and any piece of code whose type is permissible in both scalajs and scala is automatically shareable. It would also allow for cross-executable optimization. There is often a lot of code that could be optimized away from current executables if the compiler only knew more about side effects. You could eliminate dead code that goes across a wire between client and server because knowing exactly what the client/server interactions are, the compiler can know what is actually dead code.

Maybe it is possible to do some of the above with some implicit wizardry that I'm just not familiar with, and maybe it could be done with compiler and build system tricks without modifying the base language, but honestly even if it could I would still prefer co-effects. It took me one read of a blog post to really grok co-effects, whereas I've been using Scala for well over two years now and still have trouble understanding how implicits are working in the code I'm using.

For more info, you could read his blog post or academic papers linked in the blog post: http://tomasp.net/blog/2014/why-coeffects-matter/


Why can't F#'s type providers be implemented more generically as macros? Define a piece of code to run on an AST and generate types or whatever? Rust's macros, AFAIK, are powerful enough to do the same thing.

F# type providers sorta seemed like more of an answer to C#'s codegen utils like sqlmetal and xsd.exe. They're cool, but I just don't understand the limitation if we're already gonna run code at compile time.


If the macro can open a connection to a database, query the schema, and use the results to construct/inject types into the source, all at compile time, then yes. That is basically what Slick's type-checked SQL API is doing in Scala.

It sounds like something that might be a practical disaster if you don't have incremental compilation though.


Thanks, I'll read those. Also, I'm absolutely certain that F#'s type providers do provide an additional feature to the language, one that would be quite hard to replicate using macros or other existing constructs.

I'm still not too sure about coeffects, though. I'll read the blog post you linked in more detail, but from a quick glance, it seems that what they provide could more-or-less be replicated by Scala's implicits.

For example, a function requiring the context of a database or GPS module is just a function that has those two as dependencies. This has long been solved using dependency injection, which can be made implicit (but still type-checked) using Scala's implicits.

The security of sensitive information (e.g. a password) is a different manner. I'll have to read the paper, which seems rather technical at first glance (and I couldn't find any additional information about handling of security issues), but I imagine a lot could be done simply by wrapping the password into a monad/object and restricting access to it through the operations the monad allows.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

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

Search: