- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Adding ARM to Scala's standard library
Mon, 2010-02-08, 17:07
Probably anybody that has written something that needs to be closed after use
has written something like
object With
{
def closeable[C <: java.io.Closeable,R](c: C)
(f: C => R): R =
{
try {
f(c)
}
finally {
try {
c.close()
}
catch {
// #### Log this, but how?
case e =>
}
}
}
}
Then it would be used as
With.closeable(new ByteArrayOutputStream(1024)) { os =>
...
}
This looks like something that would do well in Scala's standard library.
One question is how to deal with the logger for the standard library. I use
slf4j in my projects but not everybody does. I think if this code is in the
standard library then it must provide a way to have the exception from #close()
be logged with the logger of choice. The With object could become an abstract
class with an abstract logging method than projects would instantiate their own
concrete class with their logger of choice.
abstract class With
{
protected def logCloseException(t: Throwable): Unit
}
object MyWith
extends With
{
override protected def logCloseException(t: Throwable): Unit = ...
}
BTW, the reason not to use structural subtyping is performance and it doesn't
work with Oracle's java.sql.ResultSet subclass:
def with_closeable[T <: { def close(): Unit }]
java.lang.IllegalAccessException: Class DatabaseCopy$ can not
access a member of class oracle.jdbc.driver.OracleResultSetImpl
with modifiers "public synchronized"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
at java.lang.reflect.Method.invoke(Method.java:588)
Blair
Mon, 2010-02-08, 17:47
#2
Re: Adding ARM to Scala's standard library
On Feb 8, 2010, at 8:29 AM, Paul Phillips wrote:
> On Mon, Feb 08, 2010 at 08:06:41AM -0800, Blair Zajac wrote:
>> This looks like something that would do well in Scala's standard
>> library.
>
> I thought you were here the last few months.
I've got 19,000 unread messages in my Scala mailbox and not enough time to keep up on everything :(
I found Josh's thread mentioning scalax.io, but the source repository at hg.scalaforge.org is down.
Is the most current discussion at http://groups.google.com/group/scala-incubator/web/arm-questions ?
>
>> BTW, the reason not to use structural subtyping is performance and it
>> doesn't work with Oracle's java.sql.ResultSet subclass:
>
> http://lampsvn.epfl.ch/trac/scala/ticket/2318
> "Structural method is dispatched on non-public member when overriding public member"
Thanks.
Blair
Tue, 2010-02-09, 16:57
#3
Re: Adding ARM to Scala's standard library
Blair, there's actually a project on github here:
http://github.com/jsuereth/scala-arm
I need to get back into it and tweak the thing. I think my experiment with "leaky monads" is failed, but let me know what you think or if you have any questions.
- josh
On Mon, Feb 8, 2010 at 11:41 AM, Blair Zajac <blair@orcaware.com> wrote:
http://github.com/jsuereth/scala-arm
I need to get back into it and tweak the thing. I think my experiment with "leaky monads" is failed, but let me know what you think or if you have any questions.
- josh
On Mon, Feb 8, 2010 at 11:41 AM, Blair Zajac <blair@orcaware.com> wrote:
On Feb 8, 2010, at 8:29 AM, Paul Phillips wrote:
> On Mon, Feb 08, 2010 at 08:06:41AM -0800, Blair Zajac wrote:
>> This looks like something that would do well in Scala's standard
>> library.
>
> I thought you were here the last few months.
I've got 19,000 unread messages in my Scala mailbox and not enough time to keep up on everything :(
I found Josh's thread mentioning scalax.io, but the source repository at hg.scalaforge.org is down.
Is the most current discussion at http://groups.google.com/group/scala-incubator/web/arm-questions ?
>
>> BTW, the reason not to use structural subtyping is performance and it
>> doesn't work with Oracle's java.sql.ResultSet subclass:
>
> http://lampsvn.epfl.ch/trac/scala/ticket/2318
> "Structural method is dispatched on non-public member when overriding public member"
Thanks.
Blair
Tue, 2010-02-09, 17:27
#4
Re: Adding ARM to Scala's standard library
Josh,
Thanks, I'll take a look.
BTW, with my sample "With" object, I later realized that different projects will
want different behavior when close() throws an exception, some will want to
silence it and others will want to propagate it if the try block didn't throw an
exception. So I would need a With.closeable() and With.closeableQuietly().
Blair
Josh Suereth wrote:
> Blair, there's actually a project on github here:
>
> http://github.com/jsuereth/scala-arm
>
> I need to get back into it and tweak the thing. I think my experiment
> with "leaky monads" is failed, but let me know what you think or if you
> have any questions.
>
>
> - josh
>
> On Mon, Feb 8, 2010 at 11:41 AM, Blair Zajac > wrote:
>
> On Feb 8, 2010, at 8:29 AM, Paul Phillips wrote:
>
> > On Mon, Feb 08, 2010 at 08:06:41AM -0800, Blair Zajac wrote:
> >> This looks like something that would do well in Scala's standard
> >> library.
> >
> > I thought you were here the last few months.
>
> I've got 19,000 unread messages in my Scala mailbox and not enough
> time to keep up on everything :(
>
> I found Josh's thread mentioning scalax.io , but
> the source repository at hg.scalaforge.org
> is down.
>
> Is the most current discussion at
> http://groups.google.com/group/scala-incubator/web/arm-questions ?
>
> >
> >> BTW, the reason not to use structural subtyping is performance
> and it
> >> doesn't work with Oracle's java.sql.ResultSet subclass:
> >
> > http://lampsvn.epfl.ch/trac/scala/ticket/2318
> > "Structural method is dispatched on non-public member when
> overriding public member"
>
> Thanks.
>
> Blair
>
>
Tue, 2010-02-09, 20:47
#5
Re: Adding ARM to Scala's standard library
Blair,
The ARM library I was working on actually has the ability to return an Either[List[Throwable],T]. This lets you decide what to do with your exceptions.
Also ->
map and flatMap are assumed to be lazily executed (i.e. you can't acquire/release the resource if you're modifying it)
foreach is assumed to be eagerly executed (you almost have to do this... otherwise when will you run it?)
The final fun was if you pass a function f of Resouce => ? <: Traverable[T], we made the assumption that it would be safe to return a "managed" Traversable. The returned traversable will open the resource, call the mapping function, call foreach on the internal traversable, and then close the resource when done. This was my first attempt to see if I could use the type system to determine when it is safe to extract from a monad. This is the piece that's strange...
basically I wanted this to work:
val lines = for { file <- managed(new java.io.File("some.txt"))
stream <- new java.io.FileInputStream(file)
line <- makeLineIterator(stream) } yield line
Which... does in fact work as I wanted it to... at times. Anyway, I'm still fighting with whether or not the auto-leak feature is useful. If not, the library can be greatly simplified.
Also... one thing I was using this for was RMI/JNDI. In that case I wanted to create a managed resource in a configurable manner... i.e. one that would 'retry" the remote method on failure after some specified timeout. This also required some threading magic and contexts. I'll try to get the code open-source to see if it's of any use to others.
- Josh
On Tue, Feb 9, 2010 at 11:21 AM, Blair Zajac <blair@orcaware.com> wrote:
The ARM library I was working on actually has the ability to return an Either[List[Throwable],T]. This lets you decide what to do with your exceptions.
Also ->
map and flatMap are assumed to be lazily executed (i.e. you can't acquire/release the resource if you're modifying it)
foreach is assumed to be eagerly executed (you almost have to do this... otherwise when will you run it?)
The final fun was if you pass a function f of Resouce => ? <: Traverable[T], we made the assumption that it would be safe to return a "managed" Traversable. The returned traversable will open the resource, call the mapping function, call foreach on the internal traversable, and then close the resource when done. This was my first attempt to see if I could use the type system to determine when it is safe to extract from a monad. This is the piece that's strange...
basically I wanted this to work:
val lines = for { file <- managed(new java.io.File("some.txt"))
stream <- new java.io.FileInputStream(file)
line <- makeLineIterator(stream) } yield line
Which... does in fact work as I wanted it to... at times. Anyway, I'm still fighting with whether or not the auto-leak feature is useful. If not, the library can be greatly simplified.
Also... one thing I was using this for was RMI/JNDI. In that case I wanted to create a managed resource in a configurable manner... i.e. one that would 'retry" the remote method on failure after some specified timeout. This also required some threading magic and contexts. I'll try to get the code open-source to see if it's of any use to others.
- Josh
On Tue, Feb 9, 2010 at 11:21 AM, Blair Zajac <blair@orcaware.com> wrote:
Josh,
Thanks, I'll take a look.
BTW, with my sample "With" object, I later realized that different projects will want different behavior when close() throws an exception, some will want to silence it and others will want to propagate it if the try block didn't throw an exception. So I would need a With.closeable() and With.closeableQuietly().
Blair
Josh Suereth wrote:
Blair, there's actually a project on github here:
http://github.com/jsuereth/scala-arm
I need to get back into it and tweak the thing. I think my experiment with "leaky monads" is failed, but let me know what you think or if you have any questions.
- josh
On Mon, Feb 8, 2010 at 11:41 AM, Blair Zajac <blair@orcaware.com <mailto:blair@orcaware.com>> wrote:
On Feb 8, 2010, at 8:29 AM, Paul Phillips wrote:
> On Mon, Feb 08, 2010 at 08:06:41AM -0800, Blair Zajac wrote:
>> This looks like something that would do well in Scala's standard
>> library.
>
> I thought you were here the last few months.
I've got 19,000 unread messages in my Scala mailbox and not enough
time to keep up on everything :(
I found Josh's thread mentioning scalax.io <http://scalax.io>, but
the source repository at hg.scalaforge.org
<http://hg.scalaforge.org> is down.
Is the most current discussion at
http://groups.google.com/group/scala-incubator/web/arm-questions ?
>
>> BTW, the reason not to use structural subtyping is performance
and it
>> doesn't work with Oracle's java.sql.ResultSet subclass:
>
> http://lampsvn.epfl.ch/trac/scala/ticket/2318
> "Structural method is dispatched on non-public member when
overriding public member"
Thanks.
Blair
On Mon, Feb 08, 2010 at 08:06:41AM -0800, Blair Zajac wrote:
> This looks like something that would do well in Scala's standard
> library.
I thought you were here the last few months.
> BTW, the reason not to use structural subtyping is performance and it
> doesn't work with Oracle's java.sql.ResultSet subclass:
http://lampsvn.epfl.ch/trac/scala/ticket/2318
"Structural method is dispatched on non-public member when overriding public member"