Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to use non-scalar values in functions with where clauses in Chapel?

Tags:

chapel

I've been trying out Chapel off and on over the past year or so. I have used C and C++ briefly in the past, but most of my experience is with dynamic languages such as Python, Ruby, and Erlang more recently.

After some exposure to Erlang and its function clauses, I was excited to find out about where clauses in Chapel. However, I've run into a barrier with their use. Learn Chapel in Y minutes contains the following code demonstrating a use of the where clause:

proc whereProc(param N : int): void
  where (N > 0) {
    writeln("N is greater than 0");
}

proc whereProc(param N : int): void
  where (N < 0) {
    writeln("N is less than 0");
}

whereProc(10);
whereProc(-1);

This produces the expected output for each of the two scalar values, 10 and -1. However, I have tried to write similar programs that iterate over a range or an array. I've even tried recursion. In all cases I get essentially the same error:

whereproc2.chpl:12: error: unresolved call 'whereProc(int(64))'
whereproc2.chpl:1: note: candidates are: whereProc(param N: int)
whereproc2.chpl:6: note:                 whereProc(param N: int)

The code that produced this particular error is:

proc whereProc(param N : int): void
  where (N > 0) {
    writeln("N is greater than 0");
}

proc whereProc(param N : int): void
  where (N <= 0) {
    writeln("N is less than or equal to 0");
}

for n in 1..10 do
  whereProc(n);

Is there something I'm missing that will cause this to work, or is this not expected to work? I noticed that on Learn Chapel in Y minutes it says all information needs to be known at compile time. Are the contents of a finite range or initialized array not known at compile time? It seems to me that the usefulness of the where clause is limited if it only works with scalar values.

like image 282
anglus Avatar asked Apr 23 '18 23:04

anglus


People also ask

Can we use scalar function in where clause?

You should never use a scalar function in a where clause as indexes can't be used and frequently a full table scan is required.

Can we use function anywhere that we can use a scalar value or a table?

We can use a function anywhere that we can use a scalar value or a table. Functions can be used in constraints, computed columns, joins, WHERE clauses, or even in other functions. Functions are an incredibly powerful part of SQL Server.

Can we use select statement in scalar function?

"Select statements included within a function cannot return data to a client."

How do you select a scalar valued function in SQL Server?

If you want to use select function() you must use a scalar function. Show activity on this post. Make sure you have the correct database selected. You may have the master database selected if you are trying to run it in a new query window.


1 Answers

Is there something I'm missing that will cause this to work...?

Yes, the problem is that in your for loop:

for n in 1..10 do
  whereProc(n);

when iterating over ranges, the loop index variable n is an execution-time constant, which prevents the compiler from reasoning about it. In order to get the behavior you want, you need to request that the compiler make it a param (a compile-time constant). This can be done using the syntax:

for param n in 1..10 do
  whereProc(n);

This has the effect of making n a param value which gives the compiler the ability to reason about its value. Try this version of the code online (with a slightly more interesting range).

Using a param index expression like this can be viewed as fully unrolling the loop:

{
  param n = 1;
  whereProc(n);
}
{
  param n = 2;
  whereProc(n);
}
...
{
  param n = 10;
  whereProc(n);
}

As such, this can be a useful idiom for iterating over things when types might vary from one iteration to the next (like a heterogeneous tuple).

like image 143
Brad Avatar answered Sep 28 '22 02:09

Brad