Here's what I'd like to do
# Ruby
class Foo
def bar
#bar ||= []
end
end
Here's what I'm starting with:
// Pony pseudocode
class Foo
var _bar: Optional(Array(I32))
fun ref bar(): Array(I32) ref =>
if _bar == None then
_bar = Some([])
end
_bar.unbox()
Pony does not have a built option type. Instead, you can write a sum type (…. | None), with a None alternative. Pattern matching can be used to recover the alternatives, based on their types:
class Foo
var _bar: (Array[I32] ref | None) = None
fun ref bar(): Array[I32] ref =>
match _bar
| let bar': Array[I32] => bar'
| None =>
let bar'' = Array[I32]
_bar = bar''
bar''
end
Note that Pony use […] around type arguments, not parentheses.
Related
Is there a way in Scala to explicity tell a function that you want to use the default arguments?
Example
def myFunction(default : Int = 0) { /* logic */ }
myFunction(number match {
case 5 => 5
case _ => ???
})
Is it possible to replace ??? with something that will act as calling the function with the default? (Of course, I could replace with 0, but assume this example for simplicity)
Thanks
number match {
case 5 => myFunction(5)
case _ => myFunction()
}
I think You can do it by using pattern match with function call.
The right way is what #chengpohi suggests. The only way to do exactly what you asked is to mess with how scalac implements default arguments under the hood:
myFunction(number match {
case 5 => 5
case _ => myFunction$default$1
})
But that is very much not recommended.
Also mind that this will probably not work when pasted without adaptation in the REPL, because the REPL wraps things in additional objects and you'll have to know the absolute path to myFunction$default$1. To test it in the REPL you'll have to wrap it in an object or class:
scala> object Foo {
| def myFunction(a: Int = 0) = println(a)
|
| val number = 42
| myFunction(number match {
| case 5 => 5
| case _ => myFunction$default$1
| })
| }
defined object Foo
scala> Foo
0
res5: Foo.type = Foo$#2035f1f0
I am composing function literals, though unlike most examples I've seen I'm starting with a multi-argument function that is then curried.
I have:
//types
case class Thing1(v: Double)
case class Thing2(v: Double)
case class Thing3(v: Double)
type Multiplier = Double
//functions
val f1 = (t: Thing1, m: Multiplier) => Thing2(m * t.v)
val f2 = (t: Thing2) => Thing3(t.v)
I want to compose f1 and f2 to get a combined function
Thing1 => (Multiplier => Thing3)
As expected, the following doesn't compile:
val fcomposed1 = f1.curried.andThen(f2) // does not compile
By experimentation, I was able to work out that the following does compile and has the right signature for fcomposed:
val fcomposed2 = f1.curried(_:Thing1).andThen(f2)
I've read various sources like What are all the uses of an underscore in Scala? and possibly relevant Why does Scala apply thunks automatically, sometimes? but unfortunately I still cannot work out exactly step-by-step what is happening here and why it works.
Furthermore, I would expect the above separated into two expressions to work identically to fcomposed2, however instead the second does not compile:
val f1partial = f1.curried(_:Thing1)
val fcomposed3 = f1partial.andThen(f2) // does not compile - same error as fcomposed1
Looks like f1partial returns the same signature as f1.curried, which makes me wonder further how the earlier fcomposed2 works.
Could someone please explain both behaviours step by step?
Here, the _ is acting as syntactical sugar for a lambda expression, but at a level you might not expect.
f1.curried has type Thing1 => Multiplier => Thing2
f1.curried(_:Thing1) is the same as { x: Thing1 => f1.curried(x) }. Since the result of f1.curried(x) has type Multiplier => Thing2, the final type of the whole expression is still Thing1 => Multiplier => Thing2. So it is not valid to call andThen(f2) on the result (f1partial) because the input type of function f2 (Thing2) is not the same as the output of the previous function (Multiplier => Thing2).
By contrast, f1.curried(_:Thing1).andThen(f2) expands to { x: Thing1 => f1.curried(x).andThen(f2) }. f1.curried(x) evaluates to type Multiplier => Thing2, like stated earlier, so you can call andThen(f2) on that, resulting in a Multiplier => Thing3. So then the entire expression evaluates to a Thing1 => Multiplier => Thing3
Perhaps it's more clear if you think about the differences between these two expressions:
val fcomposed1 = { x: Thing1 => f1.curried(x).andThen(f2) } // valid
val fcomposed2 = { x: Thing1 => f1.curried(x) }.andThen(f2) // error
Why is this function giving me the following error:
recursive value listHuman needs type
def setHumanResources(physicalResources: List[Physical], totalHumanResources: List[Human]): List[Human] = {
val listHuman = physicalResources.map{pr => totalHumanResources.find(_.handles.contains(pr.post)).filterNot(a=>listHuman.contains(a))}
return listHuman
}
I tried to do this, but it gives me another error:
val listHuman: List[Human] = physicalResources.map{pr => totalHumanResources.find(_.handles.contains(pr.post)).get}.filterNot(human=>listHuman.contains(human))
forward reference extends over definition of value listHuman
This error means that constant value or variable is used before its declaration. For example
val y = x + 2
val x = 5
What wrong with your code is you try to define constant value with itself. It's impossible by definition of constant. To build recursion use def.
It seems like you want to do a foldLeft, does this work?
def setHumanResources(physicalResources: List[Physical], totalHumanResources: List[Human]): List[Human] = {
physicalResources.foldLeft(Set.empty[Human]) { (l, pr) =>
val applicableHuman = totalHumanResources.find(_.handles.contains(pr.post))
l ++ applicableHuman
}.toList
}
The premises here is to have setHumanResourcesreturn a unique/distint list of Human objects. The code tries this by doing filterNot(a=>listHuman.contains(a)) in definition of listHuman and thus recursively referring to listHuman while defining listHuman in semantically illegal way. This de-duping can be achieved properly by the following ways.
convert the List to Set and convert it back to List to remove duplicates like listHuman.toSet.ToList. for this method to work the Human object have property identity defined by overriding equals method. so the code will now look like
def setHumanResources(physicalResources: List[Physical], totalHumanResources: List[Human]): List[Human] = {
val listHuman = physicalResources.map{pr => totalHumanResources.find(_.handles.contains(pr.post))
listHuman.toSet.toList
}
A Demo for a sample class of Human is shown below.
scala> class Human(val firstName: String, val lastName: String) {
| override def toString = this.firstName
| override def equals(that: Any): Boolean = that match {
| case that: Human if that.firstName == this.firstName => true
| case _ => false
| }
| }
defined class Human
scala> List(new Human("Peter", "Parker"), new Human("Peter", "Quill")).toSet.toList
res14: List[Human] = List(Peter)
If the class Human cannot have object equality defined in it by overriding equals method then follow this approach. considering each Human can be uniquely identified by say two properties property1 and property2. the listHuman can be deduped by the following expression. For our previously defined Human class if we want to de-dupe on both firstName and lastName properties, the code would be like below.
listHuman.groupBy(x => (x.firstName, x.lastName)).map(_._2.head)
so the new method definition becomes
def setHumanResources(physicalResources: List[Physical], totalHumanResources: List[Human]): List[Human] = {
val listHuman = physicalResources.map{pr =>
totalHumanResources.find(_.handles.contains(pr.post))
listHuman.groupBy(x => (x.property1, x.property2) ).map(_._2.head)
}
This works:
scala> def test(name: String = "joe"): Boolean = true
test: (name: String)Boolean
I expected this to work in the same way:
scala> val test: String => Boolean = { (name: String = "joe") => true }
console>:1: error: ')' expected but '=' found.
The boring, correct answer is no, you can't, but actually you kind of can, with the experimental single abstract method (SAM) synthesis in 2.11.
First you need to define your own SAM type with the default value for the apply method's parameter:
trait Func {
def apply(name: String = "joe"): Boolean
}
Now you can use the function literal notation to define a Func (note that you'll need to have started the REPL with -Xexperimental for this step to work):
val f: Func = { (name: String) => name == "joe" }
Or just:
val f: Func = _ == "joe"
And then the usual stuff:
scala> f("joe")
res0: Boolean = true
scala> f("eoj")
res1: Boolean = false
And the punchline:
scala> f()
res2: Boolean = true
It's not exactly the syntax you're asking for, and there are no promises that this will ever leave experimental status, and even if it does, default arguments may not be supported—but I still think it's pretty neat that it works now.
To expand on "The boring, correct answer is no" in Travis Brown's answer:
Functions (i.e. objects of FunctionN[...] type) can't have default arguments in Scala, only methods can. Since anonymous function expressions produce functions (and not methods), they can't have default arguments.
This is bit dirty solution I think, using currying
def testDef(nameDef: String)(name2: String): Boolean = {
val name3 = if ( name2 != "") name2 else nameDef
//use name3 for your logic
true
}
//> testDef: (name: String)(name2: String)Boolean
Curry the testDef method to hold default value as shown below.
var test = test("joe")_ //> test : String => Boolean=function1
test("fun") //"fun" will be used as name3
test("") // "joe" will be used as name3
I have a variable obj: Option[MyObject] and want to extract multiple variables from it - if the object is not set, default values should be used.
Currently I do it like this:
val var1 = obj match {
case Some(o) => e.var1
case _ => "default1"
}
val var2 = obj match {
case Some(o) => e.var2
case _ => "default2"
}
...
which is extremely verbose. I know I could do it like this:
val var1 = if (obj.isDefined) obj.get.var1 else "default1"
val var2 = if (obj.isDefined) obj.get.var2 else "default2"
which still seems strange. I know I could use one big match and return a value object or tuple.
But what I would love is something similar to this:
val var1 = obj ? _.var1 : "default1"
val var2 = obj ? _.var2 : "default2"
Is this possible somehow?
How about this?
obj.map(_.var1).getOrElse("default1")
or, if you prefer this style:
obj map (_ var1) getOrElse "default"
Another variation would be to use a version of the Null Object Pattern and use the object directly
//could also be val or lazy val
def myDefault = new MyObject {
override val var1 = "default1"
override val var2 = "default2"
}
val myObj = obj getOrElse myDefault
use(myObj.var1)
use(myObj.var2)
To extract multiple values from an Option I'd recommend returning a tuple and using the extractor syntax:
val (val1, val2) = obj.map{o => (o.var1, o.var2)}.getOrElse(("default1", "default2"))