where clause

spir denis.spir at gmail.com
Mon Mar 7 03:56:45 PST 2011


On 03/07/2011 02:23 AM, bearophile wrote:
> The "where" allows to write an expression where some parts of it are defined below it. In the where you are allowed to put one or more variables (immutable values in Haskell) and functions (values again).
>
> So first of all some usage examples from random Haskell code (Haskell uses significant indentation, almost as Python):
>
>
> median xs | even len  = (mean . take 2 . drop (mid - 1)) ordered
>            | otherwise = ordered !! mid
>    where len = length xs
>          mid = len `div` 2
>          ordered = sort xs

Hello Bearophile,

I also find this feature very nice (to the point of having asked for its 
introduction in Python, one day --without success). I like it because it makes 
the reasoning clear. There are 2 kinds of statement sequences in declarative 
programming:
* (chrono)logical sequences (*)
* expression sequences
The latter define sub-expressions of a more complex super-expression -- if only 
to make it clear -- using temporary variables.

In functional programming, using temp that way vars in at best awkward; rather 
unnatural and unpractical. Thus, 'where' (also 'let' in scheme/Lisp) constructs 
really fulfill a need.
In imperative programming, you don't have such a need. But conceptualy, a way 
to express that sub-expressions are part of a higher one would be very helpful, 
at least to make a difference with logical sequences of statements. This would 
also encourage people writing clearer code instead of constructing unlegible 
expressions (esp. in C-like languages).

But there is a simple workaround: just use a comment, saying the following 
statements construct a super expression.


import std.algorithm, std.array;

T[][2] halves (T) (T[] a) {
     // find median index (artificial example, indeed)
     auto len = a.length;
     auto median = len / 2;
     // a logical step: allows not computing 'sorted' twice
     auto sorted = array(a.sort());
     // get halves slices
     auto smalls = sorted[0..median];
     auto bigs = sorted[median..sorted.length];
     return [smalls,bigs];
}

unittest {
     int[] ints = [3,0,4,9,6,5,8,7,1,2];
     assert( halves(ints) == [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]] );
}
void main () {}


Denis

(*) typically, ordered because they change program state --but there are other 
reasons: see example
-- 
_________________
vita es estrany
spir.wikidot.com



More information about the Digitalmars-d mailing list