Re: Need help: naming for a new library that creates scalar monadic expressions

38 views
Skip to first unread message

杨博 (Yang Bo)

unread,
Jun 8, 2015, 1:16:34 PM6/8/15
to scala-l...@googlegroups.com, sca...@googlegroups.com, scala...@googlegroups.com
This project is like effectful, except we support all Scala expressions, while effectful does not support var, while, try, catch.

在 2015年6月8日星期一 UTC+8下午11:38:24,Nick Stanchenko写道:

杨博 (Yang Bo, Dev)

unread,
Jun 8, 2015, 1:16:34 PM6/8/15
to scala...@googlegroups.com, scala-l...@googlegroups.com, sca...@googlegroups.com

Hello, all,

We, some people from ThoughtWorks China, have created a macro library that converts native imperative syntax to scalaz's monadic expression. But, before we release the first version of this library, we found a very tough problem: what is the best name for the project, the source file and the methods.

Current situation

Currently, our project is named scalaz-monad-factory. I guess the name is inappropriate, because this project does not create monads, instead, it uses scalaz's monad to create functional expressions.

The current usage is very simple:

import scalaz.std.list._

val transformer = com.thoughtworks.scalazMonadFactory.Transformer[List]

val list1 = List("foo", "bar", "baz")
val list2 = List("Hello", "World!")

val concatList = transformer.async(transformer.await(list1).substring(0, 2) + " " + transformer.await(list2).substring(1, 4))

Assert.assertEquals(List("fo ell", "ba ell", "ba ell", "fo orl", "ba orl", "ba orl"), concatList)

The method transformer.async is a macro and transformer.await is a fake method to fetch the result of a monadic value. You can put any Scala expressions in the async macro and it will magically turn your code into monadic expressions. You can visit the test cases for more information

So, the code val concatList = transformer.async(transformer.await(list1).substring(0, 2) + " " + transformer.await(list2).substring(1, 4)) will be translated to monadic expression:

val concatList = Monad[List].bind(list2) { (string2: String) =>
  Monad[List].map(list1) { (string1: String) =>
    string1.substring(0, 2) + " " + string2.substring(1, 4)
  }
}

Which also equals to list comprehension supported by Scala Standard Library:

val concatList = for {
  string1 <- list1
  string2 <- list2
} yield (string1.substring(0, 2) + " " + string2.substring(1, 4))

Currently, the await method is implicit, so we can also write like this:

import transformer._
val concatList = async(list1.substring(0, 2) + " " + list2.substring(1, 4))

The name for the macro

async

Everything is good until now, except the macro name async.

async is a C# 4.5 keyword to perform CPS transformation. When our macro works with some kind of Cont monad, it will do the same thing as C# async, but it also cooperates well with other monads, e.g. IO monad, Option monad, and List monad shown before. So I think the name should be more general than async.

do

Another candidate name for the macro is do, because there is a similiar do notation in Haskell. Unfortunately do is a keyword in Scala, so we must quoted it like this:

val concatList = transformer.`do`(transformer.await(list1).substring(0, 2) + " " + transformer.await(list2).substring(1, 4))

apply

I also thought about simply use apply as the macro name, this will allow users treatingtransformer itself as a function:

val concatList = transformer(transformer.await(list1).substring(0, 2) + " " + transformer.await(list2).substring(1, 4))

Other candidates

Other candidate names are: monadictransform

The name for the fake method, currently namedawait

await

In C# 4.5, await is a keyword to wait a Task, which must be nested in a async method. OurTransformer.await, which is used to get the result from a monadic value, evaluates immediately forOption monad and List monad, and may only blocking wait for IO monad or other asynchronous monads. So it is also good to have a more general name.

<-

<- is the syntax in Haskell. Haskell's x <- action corresponds to current val x = transformer.await(action) in our project. Unfortunately <- is a keyword in Scala, so we must quoted it like this:

val concatList = transformer.`do`(transformer.`<-`(list1).substring(0, 2) + " " + transformer.`<-`(list2).substring(1, 4))

This is a less annoying problem than do, because we may use implicit call for most time.

Postfix method

Another option is providing a implicit class with a postfix await method, so we can writeaction.await. This syntax is less trivial than transformer.await(action), and also more explicit and more clear than implicit calls.

Survey

I created a survey to gather your opinion: https://jinshuju.net/f/TUZeAO.

We need you.

Thanks!

-- 
Regards,
杨博 Yang Bo
Consultant, ThoughtWorks
ThroughtWorks   Blog 知乎

Jean-Rémi Desjardins

unread,
Jun 8, 2015, 2:27:24 PM6/8/15
to sca...@googlegroups.com, scala...@googlegroups.com, scala-l...@googlegroups.com
I very much sympathize with your problem as I have my own project which aims to solve the same problem:


I will add your project to the Similar Projects section

Cheers!
Reply all
Reply to author
Forward
0 new messages