Returning two variables in SML - return-value

I have a function below that uses variable X and variable A.
How can I return both of these variables to be able to use these values further down the program.
val a = 1000;
val x = 5;
fun test (x,a) =
if (a<1) then(
x)
else(
test(x+1,a-1)
)

You just return a pair:
fun test (x, a) = if a < 1 then (x, a) else test (x+1, a-1)
You receive it by pattern matching:
val (y, z) = test (10, 11)

Related

Reg of Vec of Valid(Vec

I am continually getting an error due to the use of different sized Vecs. Is there a way I could implement this so that b, c, and d would all take just their respective # of Vec elements from a.
val a = Reg(Vec(10, Valid(Vec(32, UInt(8.W)))))
val b = Reg(Vec(10, Valid(Vec(16, UInt(8.W)))))
val c = Reg(Vec(8, Valid(Vec(24, UInt(8.W)))))
val d = Reg(Vec(7, Valid(Vec(32, UInt(8.W)))))
for (i <- 0 to 10) {
b(i).bits := a(i).bits
}
for (i <- 0 to 8) {
c(i).bits := a(i).bits
}
for (i <- 0 to 7) {
d(i).bits := a(i).bits
}
Here is the error message I am receiving.
Connection between sink (UInt<8>[16](Reg in file)) and source (UInt<8>[32](Reg in file)) failed #: Sink and Source are different length Vecs.
You can use the slice method to take a portion of any Scala Seq (Chisel's Vec extends Seq):
val a = Reg(Vec(10, Valid(Vec(32, UInt(8.W)))))
val b = Reg(Vec(10, Valid(Vec(16, UInt(8.W)))))
for (i <- 0 until 10) {
b(i).bits := a(i).bits.slice(0, 16)
}
This all is very index heavy though, relying on knowing the sizes of your Vecs, we could use the Seq method zip which allows you to iterate on corresponding elements in two Seqs. If one is longer than the other, it just truncates to the shorter one. The below is functionally identical to the for loop with the slice:
for ((bb, aa) <- b zip a) { // I'm using infix notation: b zip a == b.zip(a)
for ((x, y) <- bb.bits zip aa.bits) {
x := y
}
}
Note the lack of any indices, this just works no matter the size, so we could use this in a reusable function:
def nestedConnect(x: Vec[Valid[Vec[UInt]]], y: Vec[Valid[Vec[UInt]]]): Unit = {
for ((xx, yy) <- x zip y) {
for ((l, r) <- xx.bits zip yy.bits) {
l := r
}
}
}
We can then do all of your connects by using this function:
nestedConnect(b, a)
nestedConnect(c, a)
nestedConnect(d, a)
Executable example showing that this works: https://scastie.scala-lang.org/SFh1PratTCWhxHc55VGeHg

Matrix Vector multiplication in Scala

I am having a Matrix of size D by D (implemented as List[List[Int]]) and a Vector of size D (implemented as List[Int]). Assuming value of D = 3, I can create matrix and vector in following way.
val Vector = List(1,2,3)
val Matrix = List(List(4,5,6) , List(7,8,9) , List(10,11,12))
I can multiply both these as
(Matrix,Vector).zipped.map((x,y) => (x,Vector).zipped.map(_*_).sum )
This code multiplies matrix with vector and returns me vector as needed. I want to ask is there any faster or optimal way to get the same result using Scala functional style? As in my scenario I have much bigger value of D.
What about something like this?
def vectorDotProduct[N : Numeric](v1: List[N], v2: List[N]): N = {
import Numeric.Implicits._
// You may replace this with a while loop over two iterators if you require even more speed.
#annotation.tailrec
def loop(remaining1: List[N], remaining2: List[N], acc: N): N =
(remaining1, remaining2) match {
case (x :: tail1, y :: tail2) =>
loop(
remaining1 = tail1,
remaining2 = tail2,
acc + (x * y)
)
case (Nil, _) | (_, Nil) =>
acc
}
loop(
remaining1 = v1,
remaining2 = v2,
acc = Numeric[N].zero
)
}
def matrixVectorProduct[N : Numeric](matrix: List[List[N]], vector: List[N]): List[N] =
matrix.map(row => vectorDotProduct(vector, row))

Passing a function to another function as statement

I want to write a function which will return true if given an even number as an argument or false otherwise. additionally, write a function that will filter a list of numbers returning just the even numbers. All done using Scala functional programming. This is what I have:
def isEven(n:Int): Boolean = n % 2 == 0
println(isEven(4))
val filterEven = ( xs :List[Int] ) => {
for( x <- xs; if x % 2 == 0 ) yield x
}
println(filterEven(List(3,2,4,5,6,22,91)))
My question is, how can I pass the first function "isEven" to to the "filterEven" function in order to replace the "if-statement"?
Regards.
You can pass isEven as a parameter to xs.filter
def filterEven(xs: List[Int]) = xs.filter(isEven)
This is functionally equivalent to:
def filterEven(xs: List[Int]) = for { x <- xs if isEven(x) } yield x
First you give it a name when it is passed in.
val filterEven = (xs :List[Int], filterFunc: Int => Boolean) => {
Then you invoke it under its new name.
for(x <- xs; if filterFunc(x)) yield x
Note that now filterEven is not a good name for your function. The parameter passed in as filterFunc will determine whether you filter even, or odd, or less than 100, or .....

Writing a Scala function that returns a function when invoked

Assuming a typical hash function for a value x :
h(x) = ( a * x + b ) % R
I want to write a scala function say buildHashFunction that returns a new hashFunction ( using random values of a and b) every time it is executed. R can be hardcoded to be the same.
The idea is to then use the resulting hashFunction to deterministically calculate hash of a number.
The most obvious way to do this will work fine:
val r = new SecureRandom()
val R = r.nextInt()
def buildHashFunction(): Int => Int = {
val a = r.nextInt()
val b = r.nextInt()
def hashFunction(x: Int) =
( a * x + b ) % R
hashFunction
}

If-statement scoped variables

Often times I have a desire to create variables scoped to an if statement. Some computations only relate to a particular 'if' statement - to pollute the outer scope with temporary variables smells bad.
What I would like to do:
val data = (whatever)
if (val x = data*2+5.4345/2.45; val y = data/128.4; x*y < 10)
x * y
else
x * 2
println(x) //ERROR!
One alternative is rather messy:
val data = (whatever)
if (data*2+5.4345/2.45*data/128.4 < 10)
data*2+5.4345/2.45*data/128.4
else
data*2+5.4345/2.45 * 2
The obvious alternative I'm trying to avoid:
val data = (whatever)
val x = data*2+5.4345/2.45
val y = data/128.4
if (x*y < 10)
x*y
else
x * 2
println(x) //OK
Is something like this possible in Scala? Is there a decent workaround? If not, what other languages support an idea like this?
Since if in Scala is an expression, i.e. it returns a value, normally you'd be setting some value to the result of your if expression. So your third alternative is just fine: put it in a code block, i.e.
val data = (whatever)
val myValue = {
val x = data*2+5.4345/2.45
val y = data/128.4
if (x*y < 10)
x*y
else
x * 2
}
None of the vals declared within the block are available outside it.
You can use a pattern match:
val data = 123
val (result, x) = (data*2+5.4345/2.45, data/128.4) match {
case (x, y) if x * y < 10 => (x * y, x)
case (x, _) => (x * 2, x)
}
println(x)
result contains the result of x * y or x * 2, depending on which computation ran, and x contains the value of data*2+5.4345/2.45 as desired.
You can create a scope for it...
{
val x = data*2+5.4345/2.45
val y = data/128.4;
if ( x*y < 10)
x * y
else
x * 2
}
Or, to make it clearer,
locally {
val x = data*2+5.4345/2.45
val y = data/128.4;
if ( x*y < 10)
x * y
else
x * 2
}