ceylon / ceylon-spec

DEPRECATED
Apache License 2.0
108 stars 34 forks source link

Allow let clauses in comprehensions (between for/if), not just expressions #1458

Closed ePaul closed 8 years ago

ePaul commented 8 years ago

Comprehensions in argument lists should also allow a let clause beside the for and if clauses.

Example (a bit exaggerated, but from a "real" use case I got, trying to write a (positive) integer as a sum from a power and a remainder):

String? findShortestFormat(Integer n,
                          String formatNumber(Integer root, Integer exp, Integer remainder))
   => { for(exp in 2..5)  // try these exponents
           let(lowerRoot= (n ^ (1.0/exp)).integer)  // \[ sqrt[exp]{n} \] in LaTeX
              for(root in lowerRoot:2)  // lowerRoot, lowerRoot + 1
                 let(power = root ^ exp)
                    if(power - n < n)  // avoid recursion to larger or same number
                       formatNumber(root, exp, n - power)
       } // and now find the shortest formatted string
       .reduce<String>((x, y) => x.size < y.size then x else y);

The syntax and semantics would be analogous to let expressions – the definition would be done once for each outer iteration, and the defined variables would be available in the inner iterations.

This might be slightly ambigous (compared to let expressions) when used this way:

   { for(...)
       let(...)
          x
    }

But the semantics of let expression and let clause would be the same here, no point of confusion.

ePaul commented 8 years ago

Currently my example can be written this way:

String? findShortestFormat(Integer n,
    String formatNumber(Integer root, Integer exp, Integer remainder)) 
    => expand(expand({
         for (exp in 2..5) // try these exponents
            let (lowerRoot = (n ^ (1.0 / exp)).integer) // \[ sqrt[exp]{n} \] in LaTeX
                { for (root in lowerRoot:2) // lowerRoot, lowerRoot + 1
                        let (power = root ^ exp)
                            { if (power-n < n) // avoid recursion to larger or same number
                                    formatNumber(root, exp, n - power)
                            } } }))
        // and now find the shortest formatted string
         .reduce<String>((x, y) => x.size < y.size then x else y);

The proposal would avoid the two expands and the {} inside each let.

jvasileff commented 8 years ago

It's a total abuse of if, but for sake of experimenting, you can introduce values like this:

String? findShortestFormat(Integer n,
   String formatNumber(Integer root, Integer exp, Integer remainder))
   => { for(exp in 2..5)  // try these exponents
           if (exists lowerRoot = true then (n ^ (1.0/exp)).integer)  // \[ sqrt[exp]{n} \] in LaTeX
              for(root in lowerRoot:2)  // lowerRoot, lowerRoot + 1
                 if (exists power = true then root ^ exp)
                    if(power - n < n)  // avoid recursion to larger or same number
                       formatNumber(root, exp, n - power)
       } // and now find the shortest formatted string
       .reduce<String>((x, y) => x.size < y.size then x else y);
gavinking commented 8 years ago

This is a dupe of #377, no?

lucaswerkmeister commented 8 years ago

I guess so, but now that we have let expressions, the syntax and semantics should be obvious. (I haven’t read through that issue – what’s all the discussion about? Perhaps you remember?)

On 02.11.2015 01:05, Gavin King wrote:

This is a dupe of #377 https://github.com/ceylon/ceylon-spec/issues/377, no?

— Reply to this email directly or view it on GitHub https://github.com/ceylon/ceylon-spec/issues/1458#issuecomment-152879482.

gavinking commented 8 years ago

377 proposes exactly the same thing AFAIK, just that we had not yet settled on the let keyword, and so I was (mis)using given in the discussion.

ePaul commented 8 years ago

Yes, it looks like the same as #377. I didn't succeed to find it (I searched for let and comprehension, but that gave me many irrelevant results), sorry.

(#377 has also lots of discussion about using comprehensions and other things as expressions, as well as the syntax of argument lists, which is not relevant to my proposal.)

gavinking commented 8 years ago

I'm going to close this, since it really is a dupe of #377. But I will also change the title of #377.