roc-lang / book-of-examples

Software Design by Example in Roc
Other
27 stars 15 forks source link

topic proposal: logging framework #13

Open gvwilson opened 3 months ago

gvwilson commented 3 months ago

Original proposal:

  • discovering tests
  • running them
  • mocking external dependencies

Revised proposal (see thread below): implement a logging framework on top of two different platforms to compare/contrast the ways those platforms affect design.

Anton-4 commented 3 months ago

We decided to include testing in the language with expect to make testing easy and light-weight. So using a unit testing framework in Roc is not something (I believe) we would recommend. For mocking we plan to introduce "effect interpreters", @rtfeldman may have a google doc that talks about that proposal.

gvwilson commented 3 months ago

Thanks for the background - even if Roc-the-project uses expect, is it possible to built a small xUnit-style testing framework to show people things like "how to discover test functions automatically" and "how to capture errors for reporting"? (By analogy, I don't expect anyone will use the text editor that's built for this book in real life, but it's worth having to explain ideas.)

Anton-4 commented 3 months ago

"how to discover test functions automatically"

I believe the only way that could be done is by relying on the platform in e.g. Rust. I would expect the Rust code for that to be very hacky.

"how to capture errors for reporting"

Roc does not capture errors like for example try/except in python. A function that can error would typically return a Result like Ok "<html>...</html>" orErr UrlNotFound. It could also return aTaskwhich can be converted to aResult` to perform error handling. We do this to force the user to handle their errors, in python it's easy to forget about them.

gvwilson commented 3 months ago

OK, this is great: "here's why and how testing in Roc is different from testing in other languages you may already know, illustrated by working code" would be a great chapter.

Anton-4 commented 3 months ago

It is interesting to learn about for sure, although I have trouble imagining how it could be long enough. We included testing in the language because it makes for the best user experience and that's about it :smile:

"Error handling in Roc" on the other hand could definitely be a chapter. It is not focused on making a tool but I noticed the python book also has some chapters that are not about tools.

gvwilson commented 3 months ago

What about a logging library? I think this is another place where OOP does well: loggers all implement the same interface but have different back ends, etc., so seeing how to achieve the same thing in Roc would help people coming from imperative/OOP translate their mental models.

Anton-4 commented 3 months ago

Ergonomic logging is currently a pain point in Roc, although I think we're nearly done with the module parameters implementation, which would make this easier. What do you think about a chapter on a logging library @rtfeldman?

rtfeldman commented 3 months ago

It's a tricky question given the goals of the book to showcase idiomatic Roc designs without relying on unusual Roc-specific language features.

The way I expect most people will want to do logging in Roc is to have platforms to provide logging Tasks (and potentially involve dbg in logging too, since platforms are in charge of what that does), and then expose ways for applications to set the log level at runtime (or based on a config file, env var, etc.)

Implementing a log library in that way would mostly involve doing platform-specific things, and platforms are a language feature unique to Roc. That means anyone reading a chapter about how to implement that logging design wouldn't be able to translate it to other languages.

Someone could intentionally implement a different logging design, that was more geared toward being language-agnostic (even if it made less sense in Roc), but that would have some friction with the goal of showcasing idiomatic ways to do things in Roc.

gvwilson commented 3 months ago

On the other hand, this could be a place to deliberately show Roc's dependence on platforms: is it possible to implement two logging libraries, each on a different platform, and then compare and contrast the way those dependencies shape their designs? By analogy, there's a chapter in the JavaScript book that shows how promises actually work, and another showing how to implement classes and objects in Python using dictionaries; both are very language-specific, but both show how the way a language is implemented shapes what is easy and hard to do with it.

rtfeldman commented 3 months ago

That would certainly work, yeah!

noelrivasc commented 3 months ago

I would like to take this topic. Roughly, the approach I'm thinking is:

— Implement a logging library in Roc that writes to a file and uses only the features of the basic-cli platform. This allows us to demonstrate, at a basic level, the interaction between platform and Roc. — Integrate a simple, open source logging framework with a NodeJS-based platform. This allows us to demonstrate using from Roc tools that exist in the platform language, and could be a good context to discuss why one would want to use Roc at all —considering that whatever the Roc part of the example is, could be written in NodeJS too.

Does this align with your vision for the chapter, @gvwilson @rtfeldman ?

gvwilson commented 3 months ago

Hi @noelrivasc - thanks for your interest in this topic. The first part definitely aligns; I'll defer to @rtfeldman but my preference based on experience with earlier books is to stick to one language: as soon as we require Node, Python, Go, or anything else, we make the book inaccessible (or less accessible) to a large number of readers. The only place I broke this rule in the JS and Python books was a little bit of Unix shell to launch jobs, but even then I thought long and hard. Thoughts @rtfeldman ?

noelrivasc commented 3 months ago

@gvwilson I understand your concern. Another downside of the approach I proposed for the second part is that the JS (or whatever other language) could be lengthy. This is why I thought of just writing a wrapper for an existing library, but I'm not sure how thin the wrapper would be.

Let's see what @rtfeldman 's opinion is, but another approach would be to write the second logging library for the webserver platform, using SQLite.

gvwilson commented 3 months ago

doing the second one on the webserver platform would be a great opportunity to compare & contrast to show how the platform influences design