Suma
Suma

Reputation: 34403

Forward argument list to a function

I have a class implementing some functionality (providing a turtle graphics interface for L-systems, but that is not important here):

abstract class LSystem
{
  def BranchBegin()
  def BranchEnd()
  def Rotate(axis:Vector3f, angle:Float)
  def MoveForward(dist:Float)
  def DrawForward(size:Float, color:ColorRGBA)
  def DrawSphere(size:Float, color:ColorRGBA)
}

I have a a trait prodiving some helpers:

trait LSystemShortcuts {
  def < ()(implicit lsys:LSystem)= lsys.BranchBegin()
  def S(size:Float, color:ColorRGBA)(implicit lsys:LSystem)= lsys.DrawSphere(size,color)
  def > ()(implicit lsys:LSystem)= lsys.BranchEnd()
}

And finally there is an individual L-system, looking like this:

class RoundTree(implicit lsys:LSystem) extends LSystemShortcuts {
  // TODO: move to LSystemShortcuts 
  def F = lsys.DrawForward _
  def R = lsys.Rotate _
  def M = lsys.MoveForward _

  val degree = PI.toFloat/180
  val colorCrown = ColorRGBA.SRGB(0.1f,0.4f,0.05f, 1)
  val colorTrunk = ColorRGBA.SRGB(0.1f,0.1f,0.05f,1)

  def C(size:Float, iterations:Int) = {
    if (iterations>0) {

      F(size*0.5f,colorTrunk)

      <
      C(size*0.5f,iterations-1)
      >

      <
      R(Vector3f(0,0,1),+75*degree)
      C(size*0.3f,iterations-1)
      >

      // some more rendering code here

    }
    else
    {
      F(size,colorTrunk)
      M(size*0.6f)
      S(size*0.7f,colorCrown)
    }
  }
}

Note that currently shortcuts F, R and M are defined directly in the RoundTree class. I would like to move it to the LSystemShortcuts trait, but I would like to avoid having to repeat the argument lists (this is currently done by using partially applied function), like it was done for S shortcut. It would be easy to use LSystemShortcuts as a base class instead, but I do not like such design, trait seems more appropriate.

Is there some way to forward argument lists when defining functions? Something along lines of:

def R(_)(implicit lsys:LSystem) = lsys.Rotate _

Or perhaps some other design, having LSystemShortcuts as a member instead of a trait, which would allow me to achive that?

Upvotes: 0

Views: 118

Answers (2)

tgr
tgr

Reputation: 3608

Well, I can guess of a kind of a dirty workaround. You could alter the definition of your trait with a protected member.

trait A {
  protected var i: Int = 0  // has to be initialized, won't compile otherwise
  def print = println(i)
}

Afterwards you could use that member as follows:

class B extends A {
  i = 10
  print
}

A call of new B() will print 10 to the console.
I hope this answers your question as intended. Otherwise I will be glad to try and work out another solution.

Upvotes: 1

Gabriele Petronella
Gabriele Petronella

Reputation: 108101

To my knowledge this is not possible, since scala does not support point-free style notation as Haskell does.

I'm afraid there's no way of passing the arguments other than explicitly.

Upvotes: 0

Related Questions