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.