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

杨博 (Yang Bo, Dev) <[email protected]>
Newsgroups gmane.comp.lang.scala,gmane.spam.detected
Message-ID <CAMsCQ5fLyP=huBevVRRJucW+SbjAuNngwjYyFip4Vc-jTpcy0A@mail.gmail.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.
<https://gist.github.com/Atry/220227cd6ce48ae49280#current-situation>Current
situation

Currently, our project is named scalaz-monad-factory
<https://github.com/ThoughtWorksInc/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
<https://github.com/ThoughtWorksInc/scalaz-monad-factory/blob/1f4d8727d0e0c86541b50a738f5f7d609ded7e70/src/test/scala/com/thoughtworks/scalazMonadFactory/TransformerTest.scala>
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))

<https://gist.github.com/Atry/220227cd6ce48ae49280#the-name-for-the-macro>The
name for the macro <https://gist.github.com/Atry/220227cd6ce48ae49280#async>
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.
<https://gist.github.com/Atry/220227cd6ce48ae49280#do>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))

<https://gist.github.com/Atry/220227cd6ce48ae49280#apply>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))

<https://gist.github.com/Atry/220227cd6ce48ae49280#other-candidates>Other
candidates

Other candidate names are: monadic, transform
<https://gist.github.com/Atry/220227cd6ce48ae49280#the-name-for-the-fake-method-currently-named-await>The
name for the fake method, currently namedawait
<https://gist.github.com/Atry/220227cd6ce48ae49280#await>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.
<https://gist.github.com/Atry/220227cd6ce48ae49280#-><-

<- 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.
<https://gist.github.com/Atry/220227cd6ce48ae49280#postfix-method>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.
<https://gist.github.com/Atry/220227cd6ce48ae49280#survey>Survey

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

We need you.

Thanks!
-- 
Regards,
*杨博 Yang Bo*
*Consultant, ThoughtWorks*
[image: ThroughtWorks] <http://www.thoughtworks.com/>
<https://github.com/Atry> [image: Blog]
<http://www.ac.net.blog.163.com/> [image:
知乎] <http://www.zhihu.com/people/atry>

-- 
You received this message because you are subscribed to the Google Groups "scala-language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.