toolkit icon indicating copy to clipboard operation
toolkit copied to clipboard

Opinionated default implementations of common tasks in scripts.

Open KristianAN opened this issue 2 years ago • 9 comments

Languages like python provide really fast and simple ways to perform most operations, which lends itself very well to scripting. I think that Scala fails at this, while it's better than Java it's still not great. I don't think this is a problem for most situations.

I do however think it would be very nice if toolkit could provide default implementations of some common tasks in a referential transparent and resource-safe way. An example would be reading and writing files.

I'm pretty new to using CE so I ended up writing this, which I'm not even sure is the correct way to do this.

def fileWriter(path: String): Resource[IO, FileWriter] = 
    Resource.make(IO.blocking(new FileWriter(new File(name))))(file => IO.blocking(file.close()))
def openFile(path: String) : Resource[IO, Source] = 
    Resource.make(IO.blocking(Source.fromFile(path)))(file => IO.blocking(file.close()))

def writeToFile(path: String, content: String) =
    fileWriter(path).use(writer => IO.blocking(writer.write(content)))

if instead similar operations were already implemented for me I think that would be really great. It would at least make it a lot easier to convince other people to use this :)

All of this might obviously be outside of the scope of toolkit as it's a collection of libraries, but it would certainly make it easier to pick up for people who just want something to write small tools with.

KristianAN avatar Mar 10 '23 17:03 KristianAN

For referentially-transparent, resource-safe APIs for working with files you can look at fs2.io.file.Files.

  • https://fs2.io/#/io?id=files
  • https://www.javadoc.io/doc/co.fs2/fs2-docs_2.13/latest/fs2/io/file/Files.html

I think the quickest way to read a file to a string is:

Files[IO].readUtf8(Path(...)).compile.string

Unfortunately, I think writing currently needs more boilerplate.

Stream.emit(str)
  .through(fs2.text.utf8.encode)
  .through(Files[IO].writeAll(Path(...)))
  .compile.drain

Maybe we need a helper for writing in FS2, and some examples in this area.

armanbilge avatar Mar 10 '23 17:03 armanbilge

Btw: another possibility is that we need a new lib, similar to os-lib, that provides a bunch of helpers on top of fs2.io.file and fs2.io.process that make it easy to do stuff in a non-streaming way. Streaming is awesome, but it's probably unnecessary boilerplate for many scripts.

armanbilge avatar Mar 10 '23 17:03 armanbilge

I think creating another lib is probably the best idea. tos-lib? I'm sure it would be useful in a lot of projects.

KristianAN avatar Mar 10 '23 19:03 KristianAN

Feel free to pick and choose from what I put together a while ago https://github.com/davenverse/shellfish

ChristopherDavenport avatar Mar 10 '23 22:03 ChristopherDavenport

Maybe we need a helper for writing in FS2, and some examples in this area.

A helper? Btw, examples are a great idea, I'll write some of them for sure

[EDIT] ah, that helper! :D

TonioGela avatar Mar 11 '23 16:03 TonioGela

Maybe we need a helper for writing in FS2, and some examples in this area.

A helper? Btw, examples are a great idea, I'll write some of them for sure

[EDIT] ah, that helper! :D

I wrote that helpers and they got published here

Also, to revive this issue, are we considering writing an os-lib?

TonioGela avatar May 12 '23 14:05 TonioGela

Also, to revive this issue, are we considering writing an os-lib?

I have no experience in writing OS abstraction stuff, but I'll gladly contribute whereever possible! But wouldn't it be better to improve shellfish?

zetashift avatar May 24 '23 10:05 zetashift

But wouldn't it be better to improve shellfish?

Yes, I believe that's what we should do. If anyone has time to work on this, I can review / merge PRs 🙂

The first step can be rewriting what's already there with FS2 I/O so that it's cross-platform (it's currently JVM only).

armanbilge avatar May 24 '23 11:05 armanbilge

The first step can be rewriting what's already there with FS2 I/O so that it's cross-platform (it's currently JVM only).

It looks like it uses fs2.io in some places no? https://github.com/typelevel/toolkit/issues/15#issuecomment-1560950790

Though I see it uses some JVM only APIs as well: https://github.com/davenverse/shellfish/blob/main/core/src/main/scala/io/chrisdavenport/shellfish/Shell.scala#L158

I'll try to see what currently can be made cross-platform

zetashift avatar May 24 '23 11:05 zetashift