Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
sarehu
Apr 20, 2007

(call/cc call/cc)
Yup.

Adbot
ADBOT LOVES YOU

KernelSlanders
May 27, 2013

Rogue operating systems on occasion spread lies and rumors about me.
Yeah, square brackets in scala are basically the same as angle brackets in java. asInstanceOf acts as a cast.

KernelSlanders
May 27, 2013

Rogue operating systems on occasion spread lies and rumors about me.
Has anyone used Ammonite? What did you think of it?

Steve French
Sep 8, 2003

KernelSlanders posted:

Has anyone used Ammonite? What did you think of it?

The creator of it gave a (really good, entertaining) talk about it at Scala by the Bay a few months ago and I have been meaning to try it since then (the repl, not the shell), but haven't gotten around to it yet. Looks really promising. I'm on vacation for the rest of the month but plan to give it a shot afterwards; I will report back.

KICK BAMA KICK
Mar 2, 2009

I think the intentions of this are pretty clear; a case class (more just to convey the intention of immutability and for the free equals and hashCode than for pattern matching) that is only constructed from the companion's parameterless factories.
code:
case class Foo private(arg: Seq[Bar]) {/* stuff */}

object Foo {
  apply(): Foo = new Foo(someDefaultArgument)
  otherFactory(): Foo = new Foo(differentArgument)
}
When I defined apply without the parentheses and tested it in the REPL, val f = Foo() threw an error because it couldn't resolve the ambiguity between the helper's apply method and the class's constructor. This doesn't make any sense to me, since a) if I don't supply an argument, isn't it obvious that I'm calling the one that doesn't take an argument? and b) that constructor is supposed to be private anyway.

So my questions are 1) why? 2) is that how you implement what I'm trying to do? and 3) I guess whatever the convention is on factory methods that take no arguments and otherwise have no side effects, would you define and call otherFactory with parentheses just to match the apply version? I know it doesn't make a difference but it would bug me.

KernelSlanders
May 27, 2013

Rogue operating systems on occasion spread lies and rumors about me.

KICK BAMA KICK posted:

I think the intentions of this are pretty clear; a case class (more just to convey the intention of immutability and for the free equals and hashCode than for pattern matching) that is only constructed from the companion's parameterless factories.

When I defined apply without the parentheses and tested it in the REPL, val f = Foo() threw an error because it couldn't resolve the ambiguity between the helper's apply method and the class's constructor. This doesn't make any sense to me, since a) if I don't supply an argument, isn't it obvious that I'm calling the one that doesn't take an argument? and b) that constructor is supposed to be private anyway.

So my questions are 1) why? 2) is that how you implement what I'm trying to do? and 3) I guess whatever the convention is on factory methods that take no arguments and otherwise have no side effects, would you define and call otherFactory with parentheses just to match the apply version? I know it doesn't make a difference but it would bug me.

It's hard to know precisely what's going on, but I suspect you overloaded a factory method with the same number of arguments as the one created for you with the case keyword. This code works fine for me:

code:
case class Foo private (name: String, value: Int) {
  def plusInt(n: Int): Int = value + n
}

object Foo {
  def apply(): Foo = new Foo("zero", 0)
}
Then:
code:
scala> val foo = Foo("three", 3)
foo: Foo = Foo(three,3)

scala> val foo = Foo()
foo: Foo = Foo(zero,0)
Don't forget that if you're using default arguments or the _* operator, then the case class syntactic sugar is defining more factory methods than you probably realize. Of course in my case Foo.zero would probably have been more idiomatic than Foo().

KICK BAMA KICK
Mar 2, 2009

Didn't have any default arguments and I don't even know what the _* operator does. When I compile:
code:
case class Foo private(arg: Seq[Int]) {}

object Foo {
  def apply: Foo = new Foo(Seq())
  def otherFactory: Foo = new Foo(Seq(0))
}
and then try it at the SBT console I get:
code:
scala> val f = Foo()
<console>:10: error: overloaded method value apply with alternatives:
  (arg: Seq[Int])Foo <and>
  => Foo
 cannot be applied to ()
       val f = Foo()
and when I add parentheses to def apply(): Foo = new Foo(Seq()) it works as expected. I get that it synthesizes a companion that doesn't require new but is it also synthesizing a factory with no arguments for this class? No big deal cause as you suggested there's a perfectly appropriate name for the default factory rather than apply but that behavior seemed weird to me.

Sedro
Dec 31, 2008
Foo() is short for Foo.apply(), but there's no function with that signature. There's a Foo.apply and a Foo.apply(Seq[Int]).

KICK BAMA KICK
Mar 2, 2009

Sedro posted:

Foo() is short for Foo.apply(), but there's no function with that signature. There's a Foo.apply and a Foo.apply(Seq[Int]).
OK, thanks. Got confused by how you can omit the parentheses sometimes.

Cabbage Disrespect
Apr 24, 2009

ROBUST COMBAT
Leonard Riflepiss
Soiled Meat

KICK BAMA KICK posted:

I don't even know what the _* operator does. When I compile:

_* (the one-eyed man operator) is mildly useful:

code:
def foo(someStrings: String*) = someStrings mkString " "
foo(Seq("some", "dumb", "goon"):_*) // some dumb goon, liked you'd called foo("some", "dumb", "goon") instead
It only works with varargs, though, so if you

code:
def foo(a: String, b: String, c: String) = s"$a $b $c"
foo(Seq("some", "dumb", "goon"):_*)

not enough arguments for method foo: (a: String, b: String, c: String)String.
Unspecified value parameters b, c.
foo(Seq("some", "dumb", "goon"):_*);}
   ^

Opulent Ceremony
Feb 22, 2012
Is Seq[] the Scala equivalent of C#'s IEnumerable<> or is there a more high-level interface for iterable things?

VVV cool thanks

Opulent Ceremony fucked around with this message at 18:46 on Nov 4, 2015

Sedro
Dec 31, 2008
The equivalent to IEnumerable<T> is probably TraversableOnce[T]. You generally don't deal with TraversableOnce though because collections APIs return the same type of collection (in C# you always get IEnumerable). If you want the lazy LINQ behavior from C# you can call .view on your collection.

Seq[T] has an ordering and a length, and it might be mutable (unless you use immutable.Seq[T]). It's closer to IList<T>.

Sedro fucked around with this message at 17:52 on Nov 4, 2015

FamDav
Mar 29, 2008
might be a coding horror, but is there a programmatic way to get the concrete parent class of an anonymous class?

i.e. given

val x = new Thing with SomeTraitAndNowImAnonymous

is there a method on x I can call that will return Thing?

Sedro
Dec 31, 2008
Plain old Java reflection will work: x.getClass.getSuperclass

KernelSlanders
May 27, 2013

Rogue operating systems on occasion spread lies and rumors about me.

FamDav posted:

might be a coding horror, but is there a programmatic way to get the concrete parent class of an anonymous class?

i.e. given

val x = new Thing with SomeTraitAndNowImAnonymous

is there a method on x I can call that will return Thing?

When I first started learning scala I found myself constantly at war with the type system. I've learned to really appreciate it's power since. In general if you find yourself fighting the type checker, you made a mistake earlier on in your design. It's hard to know what exactly the best solution for you is without the use case (implicit ClassTags?). That said, here is almost certainly something better than java reflection, especially given that once your class goes in a container, type erasure breaks reflection.

Sedro posted:

Plain old Java reflection will work: x.getClass.getSuperclass

This works for the simple case FamDav described, but for an ad hoc anonymous class it's likely to be much less useful:

code:
scala> val x = new Iterator[Int] {
     |   var count = 0
     |   def hasNext = true
     |   def next = { count += 1; count }
     | }
x: Iterator[Int]{def count: Int; def count_=(x$1: Int): Unit} = non-empty iterator

scala> x.getClass
res0: Class[_ <: Iterator[Int]] = class $anon$1

scala> x.getClass.getSuperclass
warning: there were 1 feature warning(s); re-run with -feature for details
res1: Class[?0] forSome { type ?0 >: ?0; type ?0 <: Iterator[Int] } = class java.lang.Object

FamDav
Mar 29, 2008
it is for the dumbest of reasons - providing a className to a logger instance that is mixed in as a trait.

edit: the logger trait isnt the trait being mixed in at instantiation time.

Steve French
Sep 8, 2003

FamDav posted:

it is for the dumbest of reasons - providing a className to a logger instance that is mixed in as a trait.

edit: the logger trait isnt the trait being mixed in at instantiation time.

If whatever logging library you're using works the way I'd expect, it seems like the right thing to do is to just mix the logging trait in with the parent class. If you're using the class name as the identifier for the logger, any anonymous class that extends the parent class is going to use the same logger anyway. Instead of:

code:
class Foo

new Foo extends Thing with Logging {
  ...
}
do:

code:
class Foo extends Logging {
  ...
}

new Foo extends Thing {
  ...
}

Hughlander
May 11, 2005

I'm working in an existing code base with a horrible method with 18 arguments, along the lines of:

code:
def Foo(bar: Bar,
        moo: Moo=null,
        zoo: String=null,
        bleh: String = null,
        <repeat 15 times>)
I'd like to partially apply the function so that you specify the Bar as expected, but the zoo is fixed, while the callers could still apply moo/bleh et al. IE something like:

code:
val myFoo = Foo(_: Bar, zoo="gently caress you")
val Something = myFoo(thisBar, bleh="Such poo poo")
Is there a way to do so or what would the approach be if I can't touch Foo?

Steve French
Sep 8, 2003

Hughlander posted:

I'm working in an existing code base with a horrible method with 18 arguments, along the lines of:

code:
def Foo(bar: Bar,
        moo: Moo=null,
        zoo: String=null,
        bleh: String = null,
        <repeat 15 times>)
I'd like to partially apply the function so that you specify the Bar as expected, but the zoo is fixed, while the callers could still apply moo/bleh et al. IE something like:

code:
val myFoo = Foo(_: Bar, zoo="gently caress you")
val Something = myFoo(thisBar, bleh="Such poo poo")
Is there a way to do so or what would the approach be if I can't touch Foo?

I don't think there's a way to do that without either losing or repeating the default values of null.

Sedro
Dec 31, 2008
Right, you would have to repeat all the parameters. You baked in all the defaults as soon as you partially applied Foo. Only methods (Foo) can have default arguments; functions (myFoo) can't.

I think you could write a macro.

Cryolite
Oct 2, 2006
sodium aluminum fluoride
I wrote a small Scala app to try to find anagrams on Twitter. It uses Twitter4j to get a streaming sample of tweets and Slick with an embedded H2 database to save tweets and potential matches.

It's using a lot more memory than I expected and I'd like to learn why, if that's good or bad, or if I should even care. I'm coming from .NET and don't have very much experience with the JVM or JVM memory usage.

The code isn't special and is mostly copied from examples on the internet. However, after a few seconds the process starts using more than 2GB of memory. I didn't expect it to be that big. I used jmap to create a heap dump and jvisualvm to look at it. There's over a gig of just char[], byte[], and java.lang.String. From looking through the instances it looks like there are quite a few duplicates but otherwise there doesn't seem to be much out of the ordinary.

Is this normal or expected? CPU usage starts out around 40% but then seems to drop to a steady state of 5%. I'm handling about 50 tweets a second and saving about 5% of them to the database.

If I use -Xmx256m -Xms64m then the memory usage stays low but CPU usage stays high around 40% instead of 5%. Maybe this is due to all the extra garbage collecting it has to do for the heap to stay under 256MB?

I had the thought of running this on a cheap Digital Ocean or Linode instance and maybe turning it into a bot but it seems to be a lot more resource-intensive than I imagined.

Does anyone have any tips or resources for researching/minimizing memory usage in Scala apps? I'm kind of tempted to try the same thing in .NET or Python to see how the performance compares.

Sedro
Dec 31, 2008
Are you storing the database in memory? Try using H2 in persistent mode, or use sqlite.

Cryolite
Oct 2, 2006
sodium aluminum fluoride
I am using it in persistent mode (db is about 225MB of candidate tweets and found matches now). I tried using SQLite in the beginning but had a lot of trouble getting Slick to generate the schema DDL for it so I switched to H2, but it wouldn't be too hard just to write it myself if I needed to switch. However I'm starting to get some actual anagrams so if I put this on a server and have multiple processes trying to access the database (like a Play application to manage which tweets get posted if I actually turn this into a bot) I'm worried SQLite wouldn't be a good choice since only one process can update SQLite at a time. H2 has a server mode so I figured it was a better choice if that happened. Maybe this isn't a concern at all.

Cryolite
Oct 2, 2006
sodium aluminum fluoride
I'm an idiot. I was trying to perform a certain type of query about every 500ms to try to find anagrams and the query was taking over 1200ms. Since Slick is non-blocking and just returns futures, it was very easy to bombard the database with more queries than it could keep up with.

I added an index on one column and my queries went from 1200ms to <20ms. There's no problem now and it uses <1% CPU and only 480MB of memory after running for over a day.

Zasze
Apr 29, 2009
O man a scala thread neat, I was a java programmer for about 4 years after graduating college and a scala dev for about a year at my current job which is a start up. Slick is awesome and terrible at the same time constantly!

Ganondork
Dec 26, 2012

Ganondork

Cryolite posted:

I'm an idiot. I was trying to perform a certain type of query about every 500ms to try to find anagrams and the query was taking over 1200ms. Since Slick is non-blocking and just returns futures, it was very easy to bombard the database with more queries than it could keep up with.

I added an index on one column and my queries went from 1200ms to <20ms. There's no problem now and it uses <1% CPU and only 480MB of memory after running for over a day.

If it's a read-heavy table, it's almost always worth creating an index for whatever high frequency queries you're running, provided you have the disk space.

But yea, that moment when you realize the table never had an index...:dance:

Cryolite
Oct 2, 2006
sodium aluminum fluoride
Has anyone here gotten Play projects in a multi-project SBT setup running in Intellij?

I'm trying to build an Intellij project that has some common code shared between a Play project and some other executables, so to figure out how to do this I'm trying to run some activator templates that have multi-project SBT setups with one or more Play projects and some common code shared between them. For example, this one and this one. However whenever I try to run the Play apps through Intellij like shown here I get a "No main class detected." error. I can't seem to find a solution to this by googling. Doing sbt, project x, ~run through the command line works, but debugging seems like a pain that way.

Does everyone do everything through the command line anyway? I really wish I could right-click and select "Run Play 2 App" but it only seems to work for the out-of-the-box single project template.

Cryolite fucked around with this message at 07:04 on Dec 10, 2015

Sedro
Dec 31, 2008
You can do sbt x/run -jvm-debug 5005 then attach your remote debugger from Intellij.

Cryolite
Oct 2, 2006
sodium aluminum fluoride

Sedro posted:

You can do sbt x/run -jvm-debug 5005 then attach your remote debugger from Intellij.

Thanks, I eventually got this working and it works great.

I'm using Windows and had a lot of trouble initially getting it to listen. I ended up needing to do this to set SBT_OPTS before sbt myproject/run to get it to listen. Then connecting from Intellij was no problem.

Now I can run and even debug multiple Play apps at a time. Neat!

KernelSlanders
May 27, 2013

Rogue operating systems on occasion spread lies and rumors about me.
I commonly have to match on an Option of an instance of a sealed trait. It ends up being an awkward pattern and it really seems like there should be a cleaner way to do it. Supposed I have some code like:

code:
sealed trait Light
case class RedLight(timeLeft: Double) extends Light
case class GreenLight(timeLeft: Double) extends Light

def timeToNextGreen(light: Option[Light]) = light match {
  case Some(RedLight(t)) => t
  case Some(GreenLight(t)) => t + 5.0
  case None => 0.0
}
This nested unapply works perfectly fine. However, sometimes you don't want to run an extractor, you need the object itself. I end up doing something like:

code:
def doStuff(light: Option[Light]) = {
  val something = light.map {
    case rl: RedLight => doSomething(rl)
    case gl: GreenLight => doSomethingElse(gl)
  }

  something.getOrElse(thatOtherThing)
}
or

code:
def doStuff(light: Option[Light]) = light match {
  case Some(x) => 
    x match {
      case rl: RedLight => doSomething(rl)
      case gl: GreenLight => doSomethingElse(gl)
    }
  case None => thatOtherThing 
}
Neither of those are particularly satisfying.

Sedro
Dec 31, 2008
You can use @ to get the whole object for the thing matching the pattern-- the "have your cake and eat it too operator"
code:
def doStuff(light: Option[Light]) = light match {
  case Some(rl @ RedLight(t)) => doSomething(rl)
  case Some(gl @ GreenLight(t)) if t > 0 => doSomethingElse(gl)
  case _ => thatOtherThing
}

Cabbage Disrespect
Apr 24, 2009

ROBUST COMBAT
Leonard Riflepiss
Soiled Meat
edit: :saddowns:

code:
sealed trait Light
case class RedLight(timeLeft: Double) extends Light
case class GreenLight(timeLeft: Double) extends Light

def whatever(light: Option[Light]) = light match {
  case Some(r@RedLight(t)) => redLightStuff(r, t)
  case Some(g@GreenLight(t)) => greenLightStuff(g, t)
  case None => fuckOff
}

KernelSlanders
May 27, 2013

Rogue operating systems on occasion spread lies and rumors about me.
Ah of course. I've used @ but didn't realize you could nest it.

Tarion
Dec 1, 2014
After using scala for about a year...

The good:

1. for comprehensions definitely can make using futures for async programming nice.

The bad:

1. Linked List as the default data structure.
2. Implicits make reasoning about things hard.
3. Cake really should be called spaghetti.

The ugly:

1. 'return' statement.
2. Collections libraries.

Overall, my impression is that it's a nice research language that various people at big companies decided to use in production because it was cool rather than because it was ready.

Asymmetrikon
Oct 30, 2009

I believe you're a big dork!
What's wrong with lists?

Cryolite
Oct 2, 2006
sodium aluminum fluoride
Coming from C# where the List type is backed by an array (like ArrayList in Java) I know I was surprised to learn Scala's List is really a linked list. I expected a type named List to have the performance characteristics of an array-backed data structure.

For idiomatic Scala (immutable and functional) I guess it makes sense for it to be a linked list. It's just different and I have to change my thinking when going back and forth.

Steve French
Sep 8, 2003

Tarion posted:

After using scala for about a year...

The good:

1. for comprehensions definitely can make using futures for async programming nice.

The bad:

1. Linked List as the default data structure.
2. Implicits make reasoning about things hard.
3. Cake really should be called spaghetti.

The ugly:

1. 'return' statement.
2. Collections libraries.

Overall, my impression is that it's a nice research language that various people at big companies decided to use in production because it was cool rather than because it was ready.

You mean linked lists as the default ordered collection. I don't see that as much of a negative. It's quite easy to use something different if need be, though there are a lot of warts (hidden or otherwise) in the collections library. I still prefer it to any other language's standard collections though.

Implicits, if used excessively or improperly, can be tough, but it also enables some really great general patterns and simplifications if used well (see: typeclasses)

I agree about the cake pattern. Gave it a try, do not like it. I much prefer the gradual and pragmatic approach outlined here: http://di-in-scala.github.io/

What about the return statement? You don't like that it exists? (I rarely use/encounter it)

For what it is worth, I fully believe it is a production ready language, and use it as such. There are a lot of really high quality tools built with/for it. Finagle, in particular, I find to be excellent.

Tarion
Dec 1, 2014

Asymmetrikon posted:

What's wrong with lists?

This is ultimately a great summary: http://cglab.ca/~abeinges/blah/too-many-lists/book/#an-obligatory-public-service-announcement

For me, it's mostly performance and the fact that working with non-linked sequences in scala just seems harder because every interface uses List, so I end up having to convert to a List anyways.

Cryolite posted:

Coming from C# where the List type is backed by an array (like ArrayList in Java) I know I was surprised to learn Scala's List is really a linked list. I expected a type named List to have the performance characteristics of an array-backed data structure.

For idiomatic Scala (immutable and functional) I guess it makes sense for it to be a linked list. It's just different and I have to change my thinking when going back and forth.

Idiomatic Scala is pseudo-functional. The fact that it's running on the JVM (and much of the time ends up needing to call Java code) and various other things make it way harder to actually benefit from the purity of functional programming, so I'm just left with poorly performing Lists everywhere.

Steve French posted:

You mean linked lists as the default ordered collection. I don't see that as much of a negative. It's quite easy to use something different if need be, though there are a lot of warts (hidden or otherwise) in the collections library. I still prefer it to any other language's standard collections though.

Implicits, if used excessively or improperly, can be tough, but it also enables some really great general patterns and simplifications if used well (see: typeclasses)

I agree about the cake pattern. Gave it a try, do not like it. I much prefer the gradual and pragmatic approach outlined here: http://di-in-scala.github.io/

What about the return statement? You don't like that it exists? (I rarely use/encounter it)

For what it is worth, I fully believe it is a production ready language, and use it as such. There are a lot of really high quality tools built with/for it. Finagle, in particular, I find to be excellent.

I've never seen that di link before, but that's basically what I did for a codebase I'm working on that I got to write from scratch. Much nicer.

And my point about production vs research language is more about the language than the tools and even more specifically about the design of the language and approach to it's design. The tools are fine.

Steve French
Sep 8, 2003

Where have you found that every interface uses lists? (what libraries, etc)

That has not been my experience.

Adbot
ADBOT LOVES YOU

Fullets
Feb 5, 2009
Most of the stuff I've seen uses Seq or F[_]: Whatever depending on whether it's functional or not. I wouldn't be enormously surprised though to discover that requiring lists had be come an idiom somewhere.

  • Locked thread