List comprehensions: Difference between revisions
Content added Content deleted
Drkameleon (talk | contribs) (Added Arturo implementation) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 21: | Line 21: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="11l">print(cart_product(1..20, 1..20, 1..20).filter((x, y, z) -> x ^ 2 + y ^ 2 == z ^ 2 & y C x .. z))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 30: | Line 30: | ||
=={{header|ABAP}}== |
=={{header|ABAP}}== |
||
<syntaxhighlight lang="abap"> |
|||
<lang ABAP> |
|||
CLASS lcl_pythagorean_triplet DEFINITION CREATE PUBLIC. |
CLASS lcl_pythagorean_triplet DEFINITION CREATE PUBLIC. |
||
PUBLIC SECTION. |
PUBLIC SECTION. |
||
Line 78: | Line 78: | ||
START-OF-SELECTION. |
START-OF-SELECTION. |
||
cl_demo_output=>display( lcl_pythagorean_triplet=>get_triplets( n = 20 ) ). |
cl_demo_output=>display( lcl_pythagorean_triplet=>get_triplets( n = 20 ) ). |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 95: | Line 95: | ||
There is no equivalent construct in Ada. In Ada05, the predefined library Ada.Containers |
There is no equivalent construct in Ada. In Ada05, the predefined library Ada.Containers |
||
implements 3 types of Doubly_Linked_Lists : Basic; Indefinite; Restricted. |
implements 3 types of Doubly_Linked_Lists : Basic; Indefinite; Restricted. |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO; |
||
with Ada.Containers.Doubly_Linked_Lists; |
with Ada.Containers.Doubly_Linked_Lists; |
||
Line 140: | Line 140: | ||
end loop; |
end loop; |
||
end Pythagore_Set; |
end Pythagore_Set; |
||
</syntaxhighlight> |
|||
</lang> |
|||
program output: |
program output: |
||
Line 157: | Line 157: | ||
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386}} |
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386}} |
||
< |
<syntaxhighlight lang="algol68">MODE XYZ = STRUCT(INT x,y,z); |
||
OP +:= = (REF FLEX[]XYZ lhs, XYZ rhs)FLEX[]XYZ: ( |
OP +:= = (REF FLEX[]XYZ lhs, XYZ rhs)FLEX[]XYZ: ( |
||
Line 171: | Line 171: | ||
FOR x TO n DO FOR y FROM x+1 TO n DO FOR z FROM y+1 TO n DO IF x*x + y*y = z*z THEN xyz +:= XYZ(x,y,z) FI OD OD OD; |
FOR x TO n DO FOR y FROM x+1 TO n DO FOR z FROM y+1 TO n DO IF x*x + y*y = z*z THEN xyz +:= XYZ(x,y,z) FI OD OD OD; |
||
xyz), new line |
xyz), new line |
||
))</ |
))</syntaxhighlight> |
||
Output: |
Output: |
||
<div style="width:full;overflow:scroll"><pre> |
<div style="width:full;overflow:scroll"><pre> |
||
Line 182: | Line 182: | ||
{{trans|JavaScript}} |
{{trans|JavaScript}} |
||
< |
<syntaxhighlight lang="applescript">-- List comprehension by direct and unsugared use of list monad |
||
-- pythagoreanTriples :: Int -> [(Int, Int, Int)] |
-- pythagoreanTriples :: Int -> [(Int, Int, Int)] |
||
Line 273: | Line 273: | ||
end script |
end script |
||
end if |
end if |
||
end mReturn</ |
end mReturn</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
< |
<syntaxhighlight lang="applescript">{{3, 4, 5}, {5, 12, 13}, {6, 8, 10}, {7, 24, 25}, {8, 15, 17}, {9, 12, 15}, {12, 16, 20}, {15, 20, 25}}</syntaxhighlight> |
||
=={{header|Arturo}}== |
=={{header|Arturo}}== |
||
< |
<syntaxhighlight lang="rebol">n: 20 |
||
triplets: @[ |
triplets: @[ |
||
loop 1..n 'x [ |
loop 1..n 'x [ |
||
Line 287: | Line 287: | ||
] |
] |
||
] |
] |
||
print triplets</ |
print triplets</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 295: | Line 295: | ||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
{{works with|AutoHotkey_L}} |
{{works with|AutoHotkey_L}} |
||
List Comprehension is not built in. < |
List Comprehension is not built in. <syntaxhighlight lang="autohotkey"> |
||
comprehend("show", range(1, 20), "triples") |
comprehend("show", range(1, 20), "triples") |
||
return |
return |
||
Line 364: | Line 364: | ||
return set |
return set |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Bracmat}}== |
=={{header|Bracmat}}== |
||
Bracmat does not have built-in list comprehension, but nevertheless there is a solution for fixed n that does not employ explicit loop syntax. By their positions in the pattern and the monotonically increasing values in the subject, it is guaranteed that <code>x</code> always is smaller than <code>y</code> and that <code>y</code> always is smaller than <code>z</code>. The combination of flags <code>%@</code> ensures that <code>x</code>, <code>y</code> and <code>z</code> pick minimally one (<code>%</code>) and at most one (<code>@</code>) element from the subject list. |
Bracmat does not have built-in list comprehension, but nevertheless there is a solution for fixed n that does not employ explicit loop syntax. By their positions in the pattern and the monotonically increasing values in the subject, it is guaranteed that <code>x</code> always is smaller than <code>y</code> and that <code>y</code> always is smaller than <code>z</code>. The combination of flags <code>%@</code> ensures that <code>x</code>, <code>y</code> and <code>z</code> pick minimally one (<code>%</code>) and at most one (<code>@</code>) element from the subject list. |
||
< |
<syntaxhighlight lang="bracmat"> |
||
:?py { Initialize the accumulating result list. } |
:?py { Initialize the accumulating result list. } |
||
& ( 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 { This is the subject } |
& ( 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 { This is the subject } |
||
Line 384: | Line 384: | ||
| out$!py { You get here when backtracking has |
| out$!py { You get here when backtracking has |
||
exhausted all combinations of x, y and z } |
exhausted all combinations of x, y and z } |
||
);</ |
);</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> (12,16,20) |
<pre> (12,16,20) |
||
Line 398: | Line 398: | ||
{{works with|GCC}} |
{{works with|GCC}} |
||
The program below is C11 compliant. For C99 compilers change line 57 : |
The program below is C11 compliant. For C99 compilers change line 57 : |
||
<syntaxhighlight lang="c"> |
|||
<lang C> |
|||
for (int i = f + 1; i <= t; i ++) { e = e->nx = listNew(sizeof i, &i); } |
for (int i = f + 1; i <= t; i ++) { e = e->nx = listNew(sizeof i, &i); } |
||
</syntaxhighlight> |
|||
</lang> |
|||
to |
to |
||
<syntaxhighlight lang="c"> |
|||
<lang C> |
|||
int i; |
int i; |
||
for (i = f + 1; i <= t; i ++) { e = e->nx = listNew(sizeof i, &i); } |
for (i = f + 1; i <= t; i ++) { e = e->nx = listNew(sizeof i, &i); } |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output remains unchanged. |
Output remains unchanged. |
||
<syntaxhighlight lang="c"> |
|||
<lang c> |
|||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include <stdio.h> |
#include <stdio.h> |
||
Line 486: | Line 486: | ||
return 0; |
return 0; |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
<pre>3, 4, 5 |
<pre>3, 4, 5 |
||
Line 500: | Line 500: | ||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
===LINQ=== |
===LINQ=== |
||
< |
<syntaxhighlight lang="csharp">using System.Linq; |
||
static class Program |
static class Program |
||
Line 517: | Line 517: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|C++}}== |
=={{header|C++}}== |
||
There is no equivalent construct in C++. The code below uses two nested loops and an ''if'' statement: |
There is no equivalent construct in C++. The code below uses two nested loops and an ''if'' statement: |
||
< |
<syntaxhighlight lang="cpp">#include <vector> |
||
#include <cmath> |
#include <cmath> |
||
#include <iostream> |
#include <iostream> |
||
Line 553: | Line 553: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
This produces the following output: |
This produces the following output: |
||
Line 560: | Line 560: | ||
{{works with|C++11}} |
{{works with|C++11}} |
||
< |
<syntaxhighlight lang="cpp">#include <functional> |
||
#include <iostream> |
#include <iostream> |
||
Line 583: | Line 583: | ||
}); |
}); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
Output: |
Output: |
||
Line 595: | Line 595: | ||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
< |
<syntaxhighlight lang="lisp">(defn pythagorean-triples [n] |
||
(for [x (range 1 (inc n)) |
(for [x (range 1 (inc n)) |
||
y (range x (inc n)) |
y (range x (inc n)) |
||
z (range y (inc n)) |
z (range y (inc n)) |
||
:when (= (+ (* x x) (* y y)) (* z z))] |
:when (= (+ (* x x) (* y y)) (* z z))] |
||
[x y z]))</ |
[x y z]))</syntaxhighlight> |
||
=={{header|CoffeeScript}}== |
=={{header|CoffeeScript}}== |
||
< |
<syntaxhighlight lang="coffeescript">flatten = (arr) -> arr.reduce ((memo, b) -> memo.concat b), [] |
||
pyth = (n) -> |
pyth = (n) -> |
||
Line 612: | Line 612: | ||
)) |
)) |
||
console.dir pyth 20</ |
console.dir pyth 20</syntaxhighlight> |
||
<code>pyth</code> can also be written more concisely as |
<code>pyth</code> can also be written more concisely as |
||
< |
<syntaxhighlight lang="coffeescript">pyth = (n) -> flatten (flatten ([x, y, z] for z in [y..n] when x*x + y*y is z*z for y in [x..n]) for x in [1..n])</syntaxhighlight> |
||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
Line 623: | Line 623: | ||
Here are the Pythagorean triples: |
Here are the Pythagorean triples: |
||
< |
<syntaxhighlight lang="lisp">(defun pythagorean-triples (n) |
||
(loop for x from 1 to n |
(loop for x from 1 to n |
||
append (loop for y from x to n |
append (loop for y from x to n |
||
append (loop for z from y to n |
append (loop for z from y to n |
||
when (= (+ (* x x) (* y y)) (* z z)) |
when (= (+ (* x x) (* y y)) (* z z)) |
||
collect (list x y z)))))</ |
collect (list x y z)))))</syntaxhighlight> |
||
We can also define a new macro for list comprehensions. We can implement them easily with the help of the <code>iterate</code> package. |
We can also define a new macro for list comprehensions. We can implement them easily with the help of the <code>iterate</code> package. |
||
< |
<syntaxhighlight lang="lisp">(defun nest (l) |
||
(if (cdr l) |
(if (cdr l) |
||
`(,@(car l) ,(nest (cdr l))) |
`(,@(car l) ,(nest (cdr l))) |
||
Line 646: | Line 646: | ||
`((iter ,outer ,form) |
`((iter ,outer ,form) |
||
,@(mapcar #'desugar-listc-form forms) |
,@(mapcar #'desugar-listc-form forms) |
||
(in ,outer (collect ,expr)))))</ |
(in ,outer (collect ,expr)))))</syntaxhighlight> |
||
We can then define a function to compute Pythagorean triples as follows: |
We can then define a function to compute Pythagorean triples as follows: |
||
< |
<syntaxhighlight lang="lisp">(defun pythagorean-triples (n) |
||
(listc (list x y z) |
(listc (list x y z) |
||
(for x from 1 to n) |
(for x from 1 to n) |
||
(for y from x to n) |
(for y from x to n) |
||
(for z from y to n) |
(for z from y to n) |
||
(when (= (+ (expt x 2) (expt y 2)) (expt z 2)))))</ |
(when (= (+ (expt x 2) (expt y 2)) (expt z 2)))))</syntaxhighlight> |
||
=={{header|D}}== |
=={{header|D}}== |
||
D doesn't have list comprehensions. One implementation: |
D doesn't have list comprehensions. One implementation: |
||
< |
<syntaxhighlight lang="d">import std.stdio, std.meta, std.range; |
||
TA[] select(TA, TI1, TC1, TI2, TC2, TI3, TC3, TP) |
TA[] select(TA, TI1, TC1, TI2, TC2, TI3, TC3, TP) |
||
Line 692: | Line 692: | ||
iota(y, n + 1), x*x + y*y == z*z); |
iota(y, n + 1), x*x + y*y == z*z); |
||
writeln(r); |
writeln(r); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>[[3, 4, 5], [5, 12, 13], [6, 8, 10], [8, 15, 17], [9, 12, 15], [12, 16, 20]]</pre> |
<pre>[[3, 4, 5], [5, 12, 13], [6, 8, 10], [8, 15, 17], [9, 12, 15], [12, 16, 20]]</pre> |
||
Line 698: | Line 698: | ||
=={{header|E}}== |
=={{header|E}}== |
||
< |
<syntaxhighlight lang="e">pragma.enable("accumulator") # considered experimental |
||
accum [] for x in 1..n { for y in x..n { for z in y..n { if (x**2 + y**2 <=> z**2) { _.with([x,y,z]) } } } }</ |
accum [] for x in 1..n { for y in x..n { for z in y..n { if (x**2 + y**2 <=> z**2) { _.with([x,y,z]) } } } }</syntaxhighlight> |
||
=={{header|EchoLisp}}== |
=={{header|EchoLisp}}== |
||
< |
<syntaxhighlight lang="lisp"> |
||
;; copied from Racket |
;; copied from Racket |
||
Line 712: | Line 712: | ||
(list x y z)) |
(list x y z)) |
||
→ ((3 4 5) (5 12 13) (6 8 10) (8 15 17) (9 12 15) (12 16 20)) |
→ ((3 4 5) (5 12 13) (6 8 10) (8 15 17) (9 12 15) (12 16 20)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Efene}}== |
=={{header|Efene}}== |
||
< |
<syntaxhighlight lang="efene">pythag = fn (N) { |
||
[(A, B, C) for A in lists.seq(1, N) \ |
[(A, B, C) for A in lists.seq(1, N) \ |
||
for B in lists.seq(A, N) \ |
for B in lists.seq(A, N) \ |
||
Line 727: | Line 727: | ||
io.format("~p~n", [pythag(20)]) |
io.format("~p~n", [pythag(20)]) |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Ela}}== |
=={{header|Ela}}== |
||
< |
<syntaxhighlight lang="ela">pyth n = [(x,y,z) \\ x <- [1..n], y <- [x..n], z <- [y..n] | x**2 + y**2 == z**2]</syntaxhighlight> |
||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
Line 745: | Line 745: | ||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
< |
<syntaxhighlight lang="erlang">pythag(N) -> |
||
[ {A,B,C} || A <- lists:seq(1,N), |
[ {A,B,C} || A <- lists:seq(1,N), |
||
B <- lists:seq(A,N), |
B <- lists:seq(A,N), |
||
C <- lists:seq(B,N), |
C <- lists:seq(B,N), |
||
A+B+C =< N, |
A+B+C =< N, |
||
A*A+B*B == C*C ].</ |
A*A+B*B == C*C ].</syntaxhighlight> |
||
=={{header|F Sharp|F#}}== |
=={{header|F Sharp|F#}}== |
||
< |
<syntaxhighlight lang="fsharp">let pyth n = [ for a in [1..n] do |
||
for b in [a..n] do |
for b in [a..n] do |
||
for c in [b..n] do |
for c in [b..n] do |
||
if (a*a+b*b = c*c) then yield (a,b,c)]</ |
if (a*a+b*b = c*c) then yield (a,b,c)]</syntaxhighlight> |
||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
Factor does not support list comprehensions by default. The <code>backtrack</code> vocabulary can make for a faithful imitation, however. |
Factor does not support list comprehensions by default. The <code>backtrack</code> vocabulary can make for a faithful imitation, however. |
||
< |
<syntaxhighlight lang="factor">USING: backtrack kernel locals math math.ranges ; |
||
:: pythagorean-triples ( n -- seq ) |
:: pythagorean-triples ( n -- seq ) |
||
Line 768: | Line 768: | ||
b n [a,b] amb-lazy :> c |
b n [a,b] amb-lazy :> c |
||
a a * b b * + c c * = must-be-true { a b c } |
a a * b b * + c c * = must-be-true { a b c } |
||
] bag-of ;</ |
] bag-of ;</syntaxhighlight> |
||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
Complex numbers simplify the task. However, the reshape intrinsic function along with implicit do loops can generate high rank matrices. |
Complex numbers simplify the task. However, the reshape intrinsic function along with implicit do loops can generate high rank matrices. |
||
<syntaxhighlight lang="fortran"> |
|||
<lang FORTRAN> |
|||
!-*- mode: compilation; default-directory: "/tmp/" -*- |
!-*- mode: compilation; default-directory: "/tmp/" -*- |
||
!Compilation started at Fri Jun 7 23:39:20 |
!Compilation started at Fri Jun 7 23:39:20 |
||
Line 805: | Line 805: | ||
print '(3i4)',d(:,:i) |
print '(3i4)',d(:,:i) |
||
end program list_comprehension |
end program list_comprehension |
||
</syntaxhighlight> |
|||
</lang> |
|||
Line 811: | Line 811: | ||
{{trans|Run BASIC}} |
{{trans|Run BASIC}} |
||
FreeBASIC no tiene listas de comprensión. Una implementación: |
FreeBASIC no tiene listas de comprensión. Una implementación: |
||
< |
<syntaxhighlight lang="freebasic">Dim As Integer x, y, z, n = 25 |
||
For x = 1 To n |
For x = 1 To n |
||
For y = x To n |
For y = x To n |
||
Line 819: | Line 819: | ||
Next y |
Next y |
||
Next x |
Next x |
||
Sleep</ |
Sleep</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 834: | Line 834: | ||
=={{header|FunL}}== |
=={{header|FunL}}== |
||
< |
<syntaxhighlight lang="funl">def triples( n ) = [(a, b, c) | a <- 1..n-2, b <- a+1..n-1, c <- b+1..n if a^2 + b^2 == c^2] |
||
println( triples(20) )</ |
println( triples(20) )</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 845: | Line 845: | ||
=={{header|GAP}}== |
=={{header|GAP}}== |
||
< |
<syntaxhighlight lang="gap"># We keep only primitive pythagorean triples |
||
pyth := n -> |
pyth := n -> |
||
Filtered(Cartesian([1 .. n], [1 .. n], [1 .. n]), |
Filtered(Cartesian([1 .. n], [1 .. n], [1 .. n]), |
||
Line 854: | Line 854: | ||
# [ [ 3, 4, 5 ], [ 5, 12, 13 ], [ 7, 24, 25 ], [ 8, 15, 17 ], [ 9, 40, 41 ], [ 11, 60, 61 ], [ 12, 35, 37 ], |
# [ [ 3, 4, 5 ], [ 5, 12, 13 ], [ 7, 24, 25 ], [ 8, 15, 17 ], [ 9, 40, 41 ], [ 11, 60, 61 ], [ 12, 35, 37 ], |
||
# [ 13, 84, 85 ], [ 16, 63, 65 ], [ 20, 21, 29 ], [ 28, 45, 53 ], [ 33, 56, 65 ], [ 36, 77, 85 ], [ 39, 80, 89 ], |
# [ 13, 84, 85 ], [ 16, 63, 65 ], [ 20, 21, 29 ], [ 28, 45, 53 ], [ 33, 56, 65 ], [ 36, 77, 85 ], [ 39, 80, 89 ], |
||
# [ 48, 55, 73 ], [ 65, 72, 97 ] ]</ |
# [ 48, 55, 73 ], [ 65, 72, 97 ] ]</syntaxhighlight> |
||
=={{header|Go}}== |
=={{header|Go}}== |
||
Go doesn't have special syntax for list comprehensions but we can build a function which behaves similarly. |
Go doesn't have special syntax for list comprehensions but we can build a function which behaves similarly. |
||
< |
<syntaxhighlight lang="go">package main |
||
import "fmt" |
import "fmt" |
||
Line 919: | Line 919: | ||
pt = pt.listComp(in, expr, pred) |
pt = pt.listComp(in, expr, pred) |
||
fmt.Println(pt) |
fmt.Println(pt) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 927: | Line 927: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
< |
<syntaxhighlight lang="haskell">pyth :: Int -> [(Int, Int, Int)] |
||
pyth n = |
pyth n = |
||
[ (x, y, z) |
[ (x, y, z) |
||
Line 933: | Line 933: | ||
, y <- [x .. n] |
, y <- [x .. n] |
||
, z <- [y .. n] |
, z <- [y .. n] |
||
, x ^ 2 + y ^ 2 == z ^ 2 ]</ |
, x ^ 2 + y ^ 2 == z ^ 2 ]</syntaxhighlight> |
||
List-comprehensions and do notation are two alternative and equivalent forms of syntactic sugar in Haskell. |
List-comprehensions and do notation are two alternative and equivalent forms of syntactic sugar in Haskell. |
||
Line 939: | Line 939: | ||
The list comprehension above could be re-sugared in Do notation as: |
The list comprehension above could be re-sugared in Do notation as: |
||
< |
<syntaxhighlight lang="haskell">pyth :: Int -> [(Int, Int, Int)] |
||
pyth n = do |
pyth n = do |
||
x <- [1 .. n] |
x <- [1 .. n] |
||
Line 946: | Line 946: | ||
if x ^ 2 + y ^ 2 == z ^ 2 |
if x ^ 2 + y ^ 2 == z ^ 2 |
||
then [(x, y, z)] |
then [(x, y, z)] |
||
else []</ |
else []</syntaxhighlight> |
||
and both of the above could be de-sugared to: |
and both of the above could be de-sugared to: |
||
< |
<syntaxhighlight lang="haskell">pyth :: Int -> [(Int, Int, Int)] |
||
pyth n = |
pyth n = |
||
[1 .. n] >>= |
[1 .. n] >>= |
||
Line 959: | Line 959: | ||
case x ^ 2 + y ^ 2 == z ^ 2 of |
case x ^ 2 + y ^ 2 == z ^ 2 of |
||
True -> [(x, y, z)] |
True -> [(x, y, z)] |
||
_ -> []</ |
_ -> []</syntaxhighlight> |
||
which can be further specialised (given the particular context of the list monad, |
which can be further specialised (given the particular context of the list monad, |
||
Line 965: | Line 965: | ||
in which (>>=) is flip concatMap, pure is flip (:) [], and empty is []) to: |
in which (>>=) is flip concatMap, pure is flip (:) [], and empty is []) to: |
||
< |
<syntaxhighlight lang="haskell">pyth :: Int -> [(Int, Int, Int)] |
||
pyth n = |
pyth n = |
||
concatMap |
concatMap |
||
Line 981: | Line 981: | ||
main :: IO () |
main :: IO () |
||
main = print $ pyth 25</ |
main = print $ pyth 25</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>[(3,4,5),(5,12,13),(6,8,10),(7,24,25),(8,15,17),(9,12,15),(12,16,20),(15,20,25)]</pre> |
<pre>[(3,4,5),(5,12,13),(6,8,10),(7,24,25),(8,15,17),(9,12,15),(12,16,20),(15,20,25)]</pre> |
||
Line 987: | Line 987: | ||
Finally an alternative to the list comprehension from the beginning. First introduce all triplets: |
Finally an alternative to the list comprehension from the beginning. First introduce all triplets: |
||
< |
<syntaxhighlight lang="haskell">triplets n = [(x, y, z) | x <- [1 .. n], y <- [x .. n], z <- [y .. n]]</syntaxhighlight> |
||
If we apply this to our list comprehension we get this tidy line of code: |
If we apply this to our list comprehension we get this tidy line of code: |
||
< |
<syntaxhighlight lang="haskell">[(x, y, z) | (x, y, z) <- triplets n, x^2 + y^2 == z^2]</syntaxhighlight> |
||
=={{header|Hy}}== |
=={{header|Hy}}== |
||
< |
<syntaxhighlight lang="clojure">(defn triples [n] |
||
(list-comp (, a b c) [a (range 1 (inc n)) |
(list-comp (, a b c) [a (range 1 (inc n)) |
||
b (range a (inc n)) |
b (range a (inc n)) |
||
Line 1,003: | Line 1,003: | ||
(print (triples 15)) |
(print (triples 15)) |
||
; [(3, 4, 5), (5, 12, 13), (6, 8, 10), (9, 12, 15)]</ |
; [(3, 4, 5), (5, 12, 13), (6, 8, 10), (9, 12, 15)]</syntaxhighlight> |
||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
Line 1,011: | Line 1,011: | ||
expression: |
expression: |
||
< |
<syntaxhighlight lang="unicon"> |
||
|(x := seq(), x^2 > 3, x*2) |
|(x := seq(), x^2 > 3, x*2) |
||
</syntaxhighlight> |
|||
</lang> |
|||
is capable of producing successive elements from the infinite list described in the |
is capable of producing successive elements from the infinite list described in the |
||
Wikipedia article. For example, to produce the first 100 elements: |
Wikipedia article. For example, to produce the first 100 elements: |
||
< |
<syntaxhighlight lang="unicon"> |
||
procedure main() |
procedure main() |
||
every write(|(x := seq(), x^2 > 3, x*2) \ 100 |
every write(|(x := seq(), x^2 > 3, x*2) \ 100 |
||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
While result sequences are lexically bound to the code that describes them, |
While result sequences are lexically bound to the code that describes them, |
||
Line 1,029: | Line 1,029: | ||
with (works in both languages): |
with (works in both languages): |
||
< |
<syntaxhighlight lang="unicon">procedure main(a) |
||
n := integer(!a) | 20 |
n := integer(!a) | 20 |
||
s := create (x := 1 to n, y := x to n, z := y to n, x^2+y^2 = z^2, [x,y,z]) |
s := create (x := 1 to n, y := x to n, z := y to n, x^2+y^2 = z^2, [x,y,z]) |
||
while a := @s do write(a[1]," ",a[2]," ",a[3]) |
while a := @s do write(a[1]," ",a[2]," ",a[3]) |
||
end</ |
end</syntaxhighlight> |
||
Sample output: |
Sample output: |
||
Line 1,048: | Line 1,048: | ||
=={{header|Ioke}}== |
=={{header|Ioke}}== |
||
< |
<syntaxhighlight lang="ioke">for( |
||
x <- 1..20, |
x <- 1..20, |
||
y <- x..20, |
y <- x..20, |
||
Line 1,054: | Line 1,054: | ||
x * x + y * y == z * z, |
x * x + y * y == z * z, |
||
[x, y, z] |
[x, y, z] |
||
)</ |
)</syntaxhighlight> |
||
=={{header|J}}== |
=={{header|J}}== |
||
< |
<syntaxhighlight lang="j">require'stats' |
||
buildSet=:conjunction def '(#~ v) u y' |
buildSet=:conjunction def '(#~ v) u y' |
||
triples=: 1 + 3&comb |
triples=: 1 + 3&comb |
||
isPyth=: 2&{"1 = 1&{"1 +&.:*: 0&{"1 |
isPyth=: 2&{"1 = 1&{"1 +&.:*: 0&{"1 |
||
pythTr=: triples buildSet isPyth</ |
pythTr=: triples buildSet isPyth</syntaxhighlight> |
||
The idiom here has two major elements: |
The idiom here has two major elements: |
||
Line 1,077: | Line 1,077: | ||
Example use: |
Example use: |
||
< |
<syntaxhighlight lang="j"> pythTr 20 |
||
3 4 5 |
3 4 5 |
||
5 12 13 |
5 12 13 |
||
Line 1,083: | Line 1,083: | ||
8 15 17 |
8 15 17 |
||
9 12 15 |
9 12 15 |
||
12 16 20</ |
12 16 20</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
Line 1,089: | Line 1,089: | ||
Using list-of-arrays made the syntax easier than list-of-lists, but meant that you need the "output expression" part to get to something easily printable. |
Using list-of-arrays made the syntax easier than list-of-lists, but meant that you need the "output expression" part to get to something easily printable. |
||
< |
<syntaxhighlight lang="java">// Boilerplate |
||
import java.util.Arrays; |
import java.util.Arrays; |
||
import java.util.List; |
import java.util.List; |
||
Line 1,122: | Line 1,122: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre>[[3, 4, 5], [5, 12, 13], [6, 8, 10], [8, 15, 17], [9, 12, 15]]</pre> |
<pre>[[3, 4, 5], [5, 12, 13], [6, 8, 10], [8, 15, 17], [9, 12, 15]]</pre> |
||
Line 1,132: | Line 1,132: | ||
ES5 does not provide built-in notation for list comprehensions. The list monad pattern which underlies list comprehension notation can, however, be used in any language which supports the use of higher order functions. The following shows how we can achieve the same result by directly using a list monad in ES5, without the abbreviating convenience of any specific syntactic sugar. |
ES5 does not provide built-in notation for list comprehensions. The list monad pattern which underlies list comprehension notation can, however, be used in any language which supports the use of higher order functions. The following shows how we can achieve the same result by directly using a list monad in ES5, without the abbreviating convenience of any specific syntactic sugar. |
||
< |
<syntaxhighlight lang="javascript">// USING A LIST MONAD DIRECTLY, WITHOUT SPECIAL SYNTAX FOR LIST COMPREHENSIONS |
||
(function (n) { |
(function (n) { |
||
Line 1,163: | Line 1,163: | ||
} |
} |
||
})(100);</ |
})(100);</syntaxhighlight> |
||
Output: |
Output: |
||
Line 1,176: | Line 1,176: | ||
See [https://developer.mozilla.org/en/New_in_JavaScript_1.7#Array_comprehensions here] for more details |
See [https://developer.mozilla.org/en/New_in_JavaScript_1.7#Array_comprehensions here] for more details |
||
< |
<syntaxhighlight lang="javascript">function range(begin, end) { |
||
for (let i = begin; i < end; ++i) |
for (let i = begin; i < end; ++i) |
||
yield i; |
yield i; |
||
Line 1,192: | Line 1,192: | ||
for each(var triple in triples(20)) |
for each(var triple in triples(20)) |
||
print(triple);</ |
print(triple);</syntaxhighlight> |
||
outputs: |
outputs: |
||
Line 1,210: | Line 1,210: | ||
by using <code>concatMap</code> (the monadic bind function for lists), and <code>x => [x]</code> (monadic pure/return for lists): |
by using <code>concatMap</code> (the monadic bind function for lists), and <code>x => [x]</code> (monadic pure/return for lists): |
||
< |
<syntaxhighlight lang="javascript">(n => { |
||
'use strict'; |
'use strict'; |
||
Line 1,240: | Line 1,240: | ||
enumFromTo(x, n)), |
enumFromTo(x, n)), |
||
enumFromTo(1, n)); |
enumFromTo(1, n)); |
||
})(20);</ |
})(20);</syntaxhighlight> |
||
Or, expressed in terms of bind (>>=) |
Or, expressed in terms of bind (>>=) |
||
< |
<syntaxhighlight lang="javascript">(n => { |
||
'use strict'; |
'use strict'; |
||
Line 1,284: | Line 1,284: | ||
))); |
))); |
||
})(20);</ |
})(20);</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
< |
<syntaxhighlight lang="javascript">[[3, 4, 5], [5, 12, 13], [6, 8, 10], [8, 15, 17], [9, 12, 15], [12, 16, 20]]</syntaxhighlight> |
||
=={{header|jq}}== |
=={{header|jq}}== |
||
'''Direct approach''':< |
'''Direct approach''':<syntaxhighlight lang="jq">def triples(n): |
||
range(1;n+1) as $x | range($x;n+1) as $y | range($y;n+1) as $z |
range(1;n+1) as $x | range($x;n+1) as $y | range($y;n+1) as $z |
||
| select($x*$x + $y*$y == $z*$z) |
| select($x*$x + $y*$y == $z*$z) |
||
| [$x, $y, $z] ; |
| [$x, $y, $z] ; |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Using listof(stream; criterion)''' |
'''Using listof(stream; criterion)''' |
||
< |
<syntaxhighlight lang="jq"># listof( stream; criterion) constructs an array of those |
||
# elements in the stream that satisfy the criterion |
# elements in the stream that satisfy the criterion |
||
def listof( stream; criterion): [ stream|select(criterion) ]; |
def listof( stream; criterion): [ stream|select(criterion) ]; |
||
Line 1,305: | Line 1,305: | ||
.[0] * .[0] + .[1] * .[1] == .[2] * .[2] ) ; |
.[0] * .[0] + .[1] * .[1] == .[2] * .[2] ) ; |
||
listof_triples(20)</ |
listof_triples(20)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,315: | Line 1,315: | ||
Array comprehension: |
Array comprehension: |
||
<syntaxhighlight lang="julia"> |
|||
<lang Julia> |
|||
julia> n = 20 |
julia> n = 20 |
||
20 |
20 |
||
Line 1,327: | Line 1,327: | ||
(9,12,15) |
(9,12,15) |
||
(12,16,20) |
(12,16,20) |
||
</syntaxhighlight> |
|||
</lang> |
|||
A Julia generator comprehension (note the outer round brackets), returns an iterator over the same result rather than an explicit array: |
A Julia generator comprehension (note the outer round brackets), returns an iterator over the same result rather than an explicit array: |
||
<syntaxhighlight lang="julia"> |
|||
<lang Julia> |
|||
julia> ((x, y, z) for x = 1:n for y = x:n for z = y:n if x^2 + y^2 == z^2) |
julia> ((x, y, z) for x = 1:n for y = x:n for z = y:n if x^2 + y^2 == z^2) |
||
Base.Flatten{Base.Generator{UnitRange{Int64},##33#37}}(Base.Generator{UnitRange{Int64},##33#37}(#33,1:20)) |
Base.Flatten{Base.Generator{UnitRange{Int64},##33#37}}(Base.Generator{UnitRange{Int64},##33#37}(#33,1:20)) |
||
Line 1,343: | Line 1,343: | ||
(9,12,15) |
(9,12,15) |
||
(12,16,20) |
(12,16,20) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Array comprehensions may also be N-dimensional, not just vectors: |
Array comprehensions may also be N-dimensional, not just vectors: |
||
<syntaxhighlight lang="julia"> |
|||
<lang Julia> |
|||
julia> [i + j for i in 1:5, j in 1:5] |
julia> [i + j for i in 1:5, j in 1:5] |
||
5×5 Array{Int64,2}: |
5×5 Array{Int64,2}: |
||
Line 1,371: | Line 1,371: | ||
5 6 7 8 9 |
5 6 7 8 9 |
||
6 7 8 9 10 |
6 7 8 9 10 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
< |
<syntaxhighlight lang="scala">// version 1.0.6 |
||
fun pythagoreanTriples(n: Int) = |
fun pythagoreanTriples(n: Int) = |
||
Line 1,387: | Line 1,387: | ||
fun main(args: Array<String>) { |
fun main(args: Array<String>) { |
||
println(pythagoreanTriples(20)) |
println(pythagoreanTriples(20)) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,396: | Line 1,396: | ||
=={{header|Lasso}}== |
=={{header|Lasso}}== |
||
Lasso uses query expressions for list manipulation. |
Lasso uses query expressions for list manipulation. |
||
< |
<syntaxhighlight lang="lasso">#!/usr/bin/lasso9 |
||
local(n = 20) |
local(n = 20) |
||
Line 1,406: | Line 1,406: | ||
select (:#x, #y, #z) |
select (:#x, #y, #z) |
||
) |
) |
||
#triples->join('\n')</ |
#triples->join('\n')</syntaxhighlight> |
||
Output: |
Output: |
||
< |
<syntaxhighlight lang="lasso">staticarray(3, 4, 5) |
||
staticarray(5, 12, 13) |
staticarray(5, 12, 13) |
||
staticarray(6, 8, 10) |
staticarray(6, 8, 10) |
||
staticarray(8, 15, 17) |
staticarray(8, 15, 17) |
||
staticarray(9, 12, 15) |
staticarray(9, 12, 15) |
||
staticarray(12, 16, 20)</ |
staticarray(12, 16, 20)</syntaxhighlight> |
||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
Lua doesn't have list comprehensions built in, but they can be constructed from chained coroutines: |
Lua doesn't have list comprehensions built in, but they can be constructed from chained coroutines: |
||
< |
<syntaxhighlight lang="lua"> |
||
LC={} |
LC={} |
||
LC.__index = LC |
LC.__index = LC |
||
Line 1,453: | Line 1,453: | ||
return self:add_iter(function(arg) if pred(arg) then coroutine.yield(arg) end end) |
return self:add_iter(function(arg) if pred(arg) then coroutine.yield(arg) end end) |
||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
We can then define a function to compute Pythagorean triples as follows: |
We can then define a function to compute Pythagorean triples as follows: |
||
< |
<syntaxhighlight lang="lua"> |
||
function get(key) |
function get(key) |
||
return (function(arg) return arg[key] end) |
return (function(arg) return arg[key] end) |
||
Line 1,473: | Line 1,473: | ||
print(arg.x, arg.y, arg.z) |
print(arg.x, arg.y, arg.z) |
||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
< |
<syntaxhighlight lang="mathematica">Select[Tuples[Range[100], 3], #1[[1]]^2 + #1[[2]]^2 == #1[[3]]^2 &]</syntaxhighlight> |
||
< |
<syntaxhighlight lang="mathematica">Pick[#, (#^2).{1, 1, -1}, 0] &@Tuples[Range[100], 3]</syntaxhighlight> |
||
=={{header|MATLAB}} / {{header|Octave}}== |
=={{header|MATLAB}} / {{header|Octave}}== |
||
In Matlab/Octave, one does not think much about lists rather than vectors and matrices. Probably, the find() operation comes closes to the task |
In Matlab/Octave, one does not think much about lists rather than vectors and matrices. Probably, the find() operation comes closes to the task |
||
< |
<syntaxhighlight lang="matlab">N = 20 |
||
[a,b] = meshgrid(1:N, 1:N); |
[a,b] = meshgrid(1:N, 1:N); |
||
c = sqrt(a.^2 + b.^2); |
c = sqrt(a.^2 + b.^2); |
||
[x,y] = find(c == fix(c)); |
[x,y] = find(c == fix(c)); |
||
disp([x, y, sqrt(x.^2 + y.^2)])</ |
disp([x, y, sqrt(x.^2 + y.^2)])</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,511: | Line 1,511: | ||
''Solutions'' behaves like list comprehension since compound goals resemble set-builder notation. |
''Solutions'' behaves like list comprehension since compound goals resemble set-builder notation. |
||
< |
<syntaxhighlight lang="mercury"> |
||
:- module pythtrip. |
:- module pythtrip. |
||
:- interface. |
:- interface. |
||
Line 1,536: | Line 1,536: | ||
solutions((pred(Triple::out) is nondet :- pythTrip(20,Triple)),Result), |
solutions((pred(Triple::out) is nondet :- pythTrip(20,Triple)),Result), |
||
write(Result,!IO). |
write(Result,!IO). |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Nemerle}}== |
=={{header|Nemerle}}== |
||
Demonstrating a list comprehension and an iterator. List comprehension adapted from Haskell example, iterator adapted from C# example. |
Demonstrating a list comprehension and an iterator. List comprehension adapted from Haskell example, iterator adapted from C# example. |
||
< |
<syntaxhighlight lang="nemerle">using System; |
||
using System.Console; |
using System.Console; |
||
using System.Collections.Generic; |
using System.Collections.Generic; |
||
Line 1,578: | Line 1,578: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
List comprehension is done in the standard library with the collect() macro (which uses for-loop macros) from the sugar package: |
List comprehension is done in the standard library with the collect() macro (which uses for-loop macros) from the sugar package: |
||
< |
<syntaxhighlight lang="nim">import sugar, math |
||
let n = 20 |
let n = 20 |
||
Line 1,592: | Line 1,592: | ||
if x^2 + y^2 == z^2: |
if x^2 + y^2 == z^2: |
||
(x,y,z) |
(x,y,z) |
||
echo triplets</ |
echo triplets</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>@[(3, 4, 5), (5, 12, 13), (6, 8, 10), (8, 15, 17), (9, 12, 15), (12, 16, 20)]</pre> |
<pre>@[(3, 4, 5), (5, 12, 13), (6, 8, 10), (8, 15, 17), (9, 12, 15), (12, 16, 20)]</pre> |
||
A special syntax for list comprehensions in Nim can be implemented thanks to the strong metaprogramming capabilities: |
A special syntax for list comprehensions in Nim can be implemented thanks to the strong metaprogramming capabilities: |
||
< |
<syntaxhighlight lang="nim">import macros |
||
type ListComprehension = object |
type ListComprehension = object |
||
Line 1,645: | Line 1,645: | ||
const n = 20 |
const n = 20 |
||
echo lc[(x,y,z) | (x <- 1..n, y <- x..n, z <- y..n, x*x + y*y == z*z), tuple[a,b,c: int]]</ |
echo lc[(x,y,z) | (x <- 1..n, y <- x..n, z <- y..n, x*x + y*y == z*z), tuple[a,b,c: int]]</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>@[(a: 3, b: 4, c: 5), (a: 5, b: 12, c: 13), (a: 6, b: 8, c: 10), (a: 8, b: 15, c: 17), (a: 9, b: 12, c: 15), (a: 12, b: 16, c: 20)]</pre> |
<pre>@[(a: 3, b: 4, c: 5), (a: 5, b: 12, c: 13), (a: 6, b: 8, c: 10), (a: 8, b: 15, c: 17), (a: 9, b: 12, c: 15), (a: 12, b: 16, c: 20)]</pre> |
||
Line 1,657: | Line 1,657: | ||
For instance, |
For instance, |
||
< |
<syntaxhighlight lang="ocaml"># [? 2 * x | x <- 0 -- max_int ; x * x > 3];; |
||
- : int Enum.t = <abstr></ |
- : int Enum.t = <abstr></syntaxhighlight> |
||
or, to compute a list, |
or, to compute a list, |
||
< |
<syntaxhighlight lang="ocaml"># [? List: 2 * x | x <- 0 -- 100 ; x * x > 3];; |
||
- : int list = [2; 4; 6; 8; 10]</ |
- : int list = [2; 4; 6; 8; 10]</syntaxhighlight> |
||
or, to compute a set, |
or, to compute a set, |
||
< |
<syntaxhighlight lang="ocaml"># [? PSet: 2 * x | x <- 0 -- 100 ; x * x > 3];; |
||
- : int PSet.t = <abstr></ |
- : int PSet.t = <abstr></syntaxhighlight> |
||
etc.. |
etc.. |
||
A standard OCaml distribution also includes a number of camlp4 extensions, including one that provides list comprehensions: |
A standard OCaml distribution also includes a number of camlp4 extensions, including one that provides list comprehensions: |
||
< |
<syntaxhighlight lang="ocaml"># #camlp4o;; |
||
# #require "camlp4.listcomprehension";; |
# #require "camlp4.listcomprehension";; |
||
/home/user//.opam/4.06.1+trunk+flambda/lib/ocaml/camlp4/Camlp4Parsers/Camlp4ListComprehension.cmo: loaded |
/home/user//.opam/4.06.1+trunk+flambda/lib/ocaml/camlp4/Camlp4Parsers/Camlp4ListComprehension.cmo: loaded |
||
Line 1,675: | Line 1,675: | ||
- : int list = [2; 4; 6; 8] |
- : int list = [2; 4; 6; 8] |
||
# [ x * 2 | x <- [1;2;3;4]; x > 2 ];; |
# [ x * 2 | x <- [1;2;3;4]; x > 2 ];; |
||
- : int list = [6; 8]</ |
- : int list = [6; 8]</syntaxhighlight> |
||
=={{header|Oz}}== |
=={{header|Oz}}== |
||
Line 1,682: | Line 1,682: | ||
However, there is a list comprehension package available [http://oz-code.googlecode.com/files/ListComprehension.zip here]. It uses the <em>unofficial and deprecated</em> macro system. Usage example: |
However, there is a list comprehension package available [http://oz-code.googlecode.com/files/ListComprehension.zip here]. It uses the <em>unofficial and deprecated</em> macro system. Usage example: |
||
< |
<syntaxhighlight lang="oz">functor |
||
import |
import |
||
LazyList |
LazyList |
||
Line 1,701: | Line 1,701: | ||
{Application.exit 0} |
{Application.exit 0} |
||
end</ |
end</syntaxhighlight> |
||
=={{header|PARI/GP}}== |
=={{header|PARI/GP}}== |
||
GP 2.6.0 added support for a new comprehension syntax: |
GP 2.6.0 added support for a new comprehension syntax: |
||
{{works with|PARI/GP|2.6.0 and above}} |
{{works with|PARI/GP|2.6.0 and above}} |
||
< |
<syntaxhighlight lang="parigp">f(n)=[v|v<-vector(n^3,i,vector(3,j,i\n^(j-1)%n)),norml2(v)==2*v[3]^2]</syntaxhighlight> |
||
Older versions of GP can emulate this through <code>select</code>: |
Older versions of GP can emulate this through <code>select</code>: |
||
{{PARI/GP select}} |
{{PARI/GP select}} |
||
< |
<syntaxhighlight lang="parigp">f(n)=select(v->norml2(v)==2*v[3]^2,vector(n^3,i,vector(3,j,i\n^(j-1)%n)))</syntaxhighlight> |
||
Version 2.4.2 (obsolete, but widespread on Windows systems) requires inversion: |
Version 2.4.2 (obsolete, but widespread on Windows systems) requires inversion: |
||
{{works with|PARI/GP|2.4.2}} |
{{works with|PARI/GP|2.4.2}} |
||
< |
<syntaxhighlight lang="parigp">f(n)=select(vector(n^3,i,vector(3,j,i\n^(j-1)%n)),v->norml2(v)==2*v[3]^2)</syntaxhighlight> |
||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
Line 1,720: | Line 1,720: | ||
Perl 5 does not have built-in list comprehension syntax. The closest approach are the list <code>map</code> and <code>grep</code> (elsewhere often known as filter) operators: |
Perl 5 does not have built-in list comprehension syntax. The closest approach are the list <code>map</code> and <code>grep</code> (elsewhere often known as filter) operators: |
||
< |
<syntaxhighlight lang="perl">sub triples ($) { |
||
my ($n) = @_; |
my ($n) = @_; |
||
map { my $x = $_; map { my $y = $_; map { [$x, $y, $_] } grep { $x**2 + $y**2 == $_**2 } 1..$n } 1..$n } 1..$n; |
map { my $x = $_; map { my $y = $_; map { [$x, $y, $_] } grep { $x**2 + $y**2 == $_**2 } 1..$n } 1..$n } 1..$n; |
||
}</ |
}</syntaxhighlight> |
||
<code>map</code> binds <code>$_</code> to each element of the input list and collects the results from the block. <code>grep</code> returns every element of the input list for which the block returns true. The <code>..</code> operator generates a list of numbers in a specific range. |
<code>map</code> binds <code>$_</code> to each element of the input list and collects the results from the block. <code>grep</code> returns every element of the input list for which the block returns true. The <code>..</code> operator generates a list of numbers in a specific range. |
||
< |
<syntaxhighlight lang="perl">for my $t (triples(10)) { |
||
print "@$t\n"; |
print "@$t\n"; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Line 1,741: | Line 1,741: | ||
Thinking laterally, Phix also does not have any special syntax for dictionaries, instead they are supported |
Thinking laterally, Phix also does not have any special syntax for dictionaries, instead they are supported |
||
via an autoinclude with the following standard hll routines: |
via an autoinclude with the following standard hll routines: |
||
<!--< |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #008080;">global</span> <span style="color: #008080;">function</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">pool_only</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> |
<span style="color: #008080;">global</span> <span style="color: #008080;">function</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">pool_only</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> |
||
<span style="color: #008080;">global</span> <span style="color: #008080;">procedure</span> <span style="color: #7060A8;">destroy_dict</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">tid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">justclear</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> |
<span style="color: #008080;">global</span> <span style="color: #008080;">procedure</span> <span style="color: #7060A8;">destroy_dict</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">tid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">justclear</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> |
||
Line 1,752: | Line 1,752: | ||
<span style="color: #008080;">global</span> <span style="color: #008080;">procedure</span> <span style="color: #7060A8;">traverse_dict</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000000;">user_data</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">tid</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> |
<span style="color: #008080;">global</span> <span style="color: #008080;">procedure</span> <span style="color: #7060A8;">traverse_dict</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000000;">user_data</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">tid</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> |
||
<span style="color: #008080;">global</span> <span style="color: #008080;">function</span> <span style="color: #7060A8;">dict_size</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">tid</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> |
<span style="color: #008080;">global</span> <span style="color: #008080;">function</span> <span style="color: #7060A8;">dict_size</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">tid</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
Clearly it would be relatively trivial for the compiler, just like it does with s[i], to map some other new |
Clearly it would be relatively trivial for the compiler, just like it does with s[i], to map some other new |
||
dictionary syntax to calls to these routines (not that it would ever use the default tid of 1, and admittedly |
dictionary syntax to calls to these routines (not that it would ever use the default tid of 1, and admittedly |
||
Line 1,759: | Line 1,759: | ||
With all that in mind, the following (which works just fine as it is) might be a first step to formal list comprehension support: |
With all that in mind, the following (which works just fine as it is) might be a first step to formal list comprehension support: |
||
<!--< |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #000080;font-style:italic;">-- demo\rosetta\List_comprehensions.exw</span> |
<span style="color: #000080;font-style:italic;">-- demo\rosetta\List_comprehensions.exw</span> |
||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
||
Line 1,784: | Line 1,784: | ||
<span style="color: #0000FF;">?</span><span style="color: #000000;">list_comprehension</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">20</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"triangle"</span><span style="color: #0000FF;">),</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span> |
<span style="color: #0000FF;">?</span><span style="color: #000000;">list_comprehension</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">20</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"triangle"</span><span style="color: #0000FF;">),</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,792: | Line 1,792: | ||
=={{header|Picat}}== |
=={{header|Picat}}== |
||
===List comprehensions=== |
===List comprehensions=== |
||
< |
<syntaxhighlight lang="picat">pyth(N) = [[A,B,C] : A in 1..N, B in A..N, C in B..N, A**2 + B**2 == C**2].</syntaxhighlight> |
||
===Array comprehensions=== |
===Array comprehensions=== |
||
Picat also has array comprehensions. Arrays are generally used for faster access (using <code>{}</code> instead of <code>[]</code>). |
Picat also has array comprehensions. Arrays are generally used for faster access (using <code>{}</code> instead of <code>[]</code>). |
||
< |
<syntaxhighlight lang="picat">pyth(N) = {{A,B,C} : A in 1..N, B in A..N, C in B..N, A**2 + B**2 == C**2}.</syntaxhighlight> |
||
===findall/2=== |
===findall/2=== |
||
A related construct is <code>findall/2</code> to get all solutions for the specific goal at the second parameter. Here this is shown with <code>member/2</code> for generating the numbers to test (which for this task is fairly inefficient). |
A related construct is <code>findall/2</code> to get all solutions for the specific goal at the second parameter. Here this is shown with <code>member/2</code> for generating the numbers to test (which for this task is fairly inefficient). |
||
<lang>pyth(N) = findall([A,B,C], (member(A,1..N), member(B,1..N), member(C,1..N), A < B, A**2 + B**2 == C**2)).</ |
<syntaxhighlight lang="text">pyth(N) = findall([A,B,C], (member(A,1..N), member(B,1..N), member(C,1..N), A < B, A**2 + B**2 == C**2)).</syntaxhighlight> |
||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
Line 1,807: | Line 1,807: | ||
We might use a generator function, pipe, coroutine or pilog predicate. |
We might use a generator function, pipe, coroutine or pilog predicate. |
||
===Using a generator function=== |
===Using a generator function=== |
||
< |
<syntaxhighlight lang="picolisp">(de pythag (N) |
||
(job '((X . 1) (Y . 1) (Z . 0)) |
(job '((X . 1) (Y . 1) (Z . 0)) |
||
(loop |
(loop |
||
Line 1,819: | Line 1,819: | ||
(while (pythag 20) |
(while (pythag 20) |
||
(println @) )</ |
(println @) )</syntaxhighlight> |
||
===Using a pipe=== |
===Using a pipe=== |
||
< |
<syntaxhighlight lang="picolisp">(pipe |
||
(for X 20 |
(for X 20 |
||
(for Y (range X 20) |
(for Y (range X 20) |
||
Line 1,828: | Line 1,828: | ||
(pr (list X Y Z)) ) ) ) ) |
(pr (list X Y Z)) ) ) ) ) |
||
(while (rd) |
(while (rd) |
||
(println @) ) )</ |
(println @) ) )</syntaxhighlight> |
||
===Using a coroutine=== |
===Using a coroutine=== |
||
Coroutines are available only in the 64-bit version. |
Coroutines are available only in the 64-bit version. |
||
< |
<syntaxhighlight lang="picolisp">(de pythag (N) |
||
(co 'pythag |
(co 'pythag |
||
(for X N |
(for X N |
||
Line 1,840: | Line 1,840: | ||
(while (pythag 20) |
(while (pythag 20) |
||
(println @) )</ |
(println @) )</syntaxhighlight> |
||
Output in all three cases: |
Output in all three cases: |
||
Line 1,851: | Line 1,851: | ||
===Using Pilog=== |
===Using Pilog=== |
||
{{works with|PicoLisp|3.0.9.7}} |
{{works with|PicoLisp|3.0.9.7}} |
||
< |
<syntaxhighlight lang="picolisp">(be pythag (@N @X @Y @Z) |
||
(for @X @N) |
(for @X @N) |
||
(for @Y @X @N) |
(for @Y @X @N) |
||
Line 1,857: | Line 1,857: | ||
(^ @ |
(^ @ |
||
(let (X (-> @X) Y (-> @Y) Z (-> @Z)) |
(let (X (-> @X) Y (-> @Y) Z (-> @Z)) |
||
(= (+ (* X X) (* Y Y)) (* Z Z)) ) ) )</ |
(= (+ (* X X) (* Y Y)) (* Z Z)) ) ) )</syntaxhighlight> |
||
Test: |
Test: |
||
< |
<syntaxhighlight lang="picolisp">: (? (pythag 20 @X @Y @Z)) |
||
@X=3 @Y=4 @Z=5 |
@X=3 @Y=4 @Z=5 |
||
@X=5 @Y=12 @Z=13 |
@X=5 @Y=12 @Z=13 |
||
Line 1,866: | Line 1,866: | ||
@X=9 @Y=12 @Z=15 |
@X=9 @Y=12 @Z=15 |
||
@X=12 @Y=16 @Z=20 |
@X=12 @Y=16 @Z=20 |
||
-> NIL</ |
-> NIL</syntaxhighlight> |
||
=={{header|Prolog}}== |
=={{header|Prolog}}== |
||
SWI-Prolog does not have list comprehension, however we can simulate it. |
SWI-Prolog does not have list comprehension, however we can simulate it. |
||
< |
<syntaxhighlight lang="prolog">% We need operators |
||
:- op(700, xfx, <-). |
:- op(700, xfx, <-). |
||
:- op(450, xfx, ..). |
:- op(450, xfx, ..). |
||
Line 1,903: | Line 1,903: | ||
Vs <- {Var & Dec} :- |
Vs <- {Var & Dec} :- |
||
findall(Var, maplist(call, [Dec]), Vs). |
findall(Var, maplist(call, [Dec]), Vs). |
||
</syntaxhighlight> |
|||
</lang> |
|||
Examples of use :<BR> |
Examples of use :<BR> |
||
List of Pythagorean triples : |
List of Pythagorean triples : |
||
Line 1,931: | Line 1,931: | ||
List comprehension: |
List comprehension: |
||
< |
<syntaxhighlight lang="python">[(x,y,z) for x in xrange(1,n+1) for y in xrange(x,n+1) for z in xrange(y,n+1) if x**2 + y**2 == z**2]</syntaxhighlight> |
||
A Python generator expression (note the outer round brackets), returns an iterator over the same result rather than an explicit list: |
A Python generator expression (note the outer round brackets), returns an iterator over the same result rather than an explicit list: |
||
< |
<syntaxhighlight lang="python">((x,y,z) for x in xrange(1,n+1) for y in xrange(x,n+1) for z in xrange(y,n+1) if x**2 + y**2 == z**2)</syntaxhighlight> |
||
A slower but more readable version: |
A slower but more readable version: |
||
< |
<syntaxhighlight lang="python">[(x, y, z) for (x, y, z) in itertools.product(xrange(1,n+1),repeat=3) if x**2 + y**2 == z**2 and x <= y <= z]</syntaxhighlight> |
||
Or as an iterator: |
Or as an iterator: |
||
< |
<syntaxhighlight lang="python">((x, y, z) for (x, y, z) in itertools.product(xrange(1,n+1),repeat=3) if x**2 + y**2 == z**2 and x <= y <= z)</syntaxhighlight> |
||
Alternatively we shorten the initial list comprehension but this time without compromising on speed. First we introduce a generator which generates all triplets: |
Alternatively we shorten the initial list comprehension but this time without compromising on speed. First we introduce a generator which generates all triplets: |
||
< |
<syntaxhighlight lang="python">def triplets(n): |
||
for x in xrange(1, n + 1): |
for x in xrange(1, n + 1): |
||
for y in xrange(x, n + 1): |
for y in xrange(x, n + 1): |
||
for z in xrange(y, n + 1): |
for z in xrange(y, n + 1): |
||
yield x, y, z</ |
yield x, y, z</syntaxhighlight> |
||
Apply this to our list comprehension gives: |
Apply this to our list comprehension gives: |
||
< |
<syntaxhighlight lang="python">[(x, y, z) for (x, y, z) in triplets(n) if x**2 + y**2 == z**2]</syntaxhighlight> |
||
Or as an iterator: |
Or as an iterator: |
||
< |
<syntaxhighlight lang="python">((x, y, z) for (x, y, z) in triplets(n) if x**2 + y**2 == z**2)</syntaxhighlight> |
||
More generally, the list comprehension syntax can be understood as a concise syntactic sugaring of a use of the list monad, in which non-matches are returned as empty lists, matches are wrapped as single-item lists, and concatenation flattens the output, eliminating the empty lists. |
More generally, the list comprehension syntax can be understood as a concise syntactic sugaring of a use of the list monad, in which non-matches are returned as empty lists, matches are wrapped as single-item lists, and concatenation flattens the output, eliminating the empty lists. |
||
Line 1,965: | Line 1,965: | ||
The monadic 'bind' operator for lists is concatMap, traditionally used with its first two arguments flipped. The following three formulations of a '''pts''' (pythagorean triangles) function are equivalent: |
The monadic 'bind' operator for lists is concatMap, traditionally used with its first two arguments flipped. The following three formulations of a '''pts''' (pythagorean triangles) function are equivalent: |
||
< |
<syntaxhighlight lang="python">from functools import (reduce) |
||
from operator import (add) |
from operator import (add) |
||
Line 2,023: | Line 2,023: | ||
main()</ |
main()</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>[(3, 4, 5), (5, 12, 13), (6, 8, 10), (8, 15, 17), (9, 12, 15), (12, 16, 20)] |
<pre>[(3, 4, 5), (5, 12, 13), (6, 8, 10), (8, 15, 17), (9, 12, 15), (12, 16, 20)] |
||
Line 2,031: | Line 2,031: | ||
=={{header|R}}== |
=={{header|R}}== |
||
R has inherent list comprehension: |
R has inherent list comprehension: |
||
<syntaxhighlight lang="r"> |
|||
<lang R> |
|||
x = (0:10) |
x = (0:10) |
||
> x^2 |
> x^2 |
||
Line 2,039: | Line 2,039: | ||
> x[x[(0:length(x))] %% 2==0] |
> x[x[(0:length(x))] %% 2==0] |
||
[1] 0 2 4 6 8 10 |
[1] 0 2 4 6 8 10 |
||
</syntaxhighlight> |
|||
</lang> |
|||
R's "data frame" functions can be used to achieve the same code clarity (at the cost of expanding the entire grid into memory before the filtering step) |
R's "data frame" functions can be used to achieve the same code clarity (at the cost of expanding the entire grid into memory before the filtering step) |
||
<syntaxhighlight lang="r"> |
|||
<lang R> |
|||
subset(expand.grid(x=1:n, y=1:n, z=1:n), x^2 + y^2 == z^2) |
subset(expand.grid(x=1:n, y=1:n, z=1:n), x^2 + y^2 == z^2) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
(for*/list ([x (in-range 1 21)] |
(for*/list ([x (in-range 1 21)] |
||
Line 2,055: | Line 2,055: | ||
#:when (= (+ (* x x) (* y y)) (* z z))) |
#:when (= (+ (* x x) (* y y)) (* z z))) |
||
(list x y z)) |
(list x y z)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
(formerly Perl 6) |
(formerly Perl 6) |
||
Raku has single-dimensional list comprehensions that fall out naturally from nested modifiers; multidimensional comprehensions are also supported via the cross operator; however, Raku does not (yet) support multi-dimensional list comprehensions with dependencies between the lists, so the most straightforward way is currently: |
Raku has single-dimensional list comprehensions that fall out naturally from nested modifiers; multidimensional comprehensions are also supported via the cross operator; however, Raku does not (yet) support multi-dimensional list comprehensions with dependencies between the lists, so the most straightforward way is currently: |
||
<lang |
<syntaxhighlight lang="raku" line>my $n = 20; |
||
gather for 1..$n -> $x { |
gather for 1..$n -> $x { |
||
for $x..$n -> $y { |
for $x..$n -> $y { |
||
Line 2,067: | Line 2,067: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Note that <tt>gather</tt>/<tt>take</tt> is the primitive in Raku corresponding to generators or coroutines in other languages. It is not, however, tied to function call syntax in Raku. We can get away with that because lists are lazy, and the demand for more of the list is implicit; it does not need to be driven by function calls. |
Note that <tt>gather</tt>/<tt>take</tt> is the primitive in Raku corresponding to generators or coroutines in other languages. It is not, however, tied to function call syntax in Raku. We can get away with that because lists are lazy, and the demand for more of the list is implicit; it does not need to be driven by function calls. |
||
=={{header|Rascal}}== |
=={{header|Rascal}}== |
||
<syntaxhighlight lang="rascal"> |
|||
<lang Rascal> |
|||
public list[tuple[int, int, int]] PythTriples(int n) = [<a, b, c> | a <- [1..n], b <- [1..n], c <- [1 .. n], a*a + b*b == c*c]; |
public list[tuple[int, int, int]] PythTriples(int n) = [<a, b, c> | a <- [1..n], b <- [1..n], c <- [1 .. n], a*a + b*b == c*c]; |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
Line 2,081: | Line 2,081: | ||
===vertical list=== |
===vertical list=== |
||
< |
<syntaxhighlight lang="rexx">/*REXX program displays a vertical list of Pythagorean triples up to a specified number.*/ |
||
parse arg n . /*obtain optional argument from the CL.*/ |
parse arg n . /*obtain optional argument from the CL.*/ |
||
if n=='' | n=="," then n= 100 /*Not specified? Then use the default.*/ |
if n=='' | n=="," then n= 100 /*Not specified? Then use the default.*/ |
||
Line 2,099: | Line 2,099: | ||
end /*j*/ /* [↑] list the members vertically. */ |
end /*j*/ /* [↑] list the members vertically. */ |
||
say |
say |
||
say # ' members listed.' /*stick a fork in it, we're all done. */</ |
say # ' members listed.' /*stick a fork in it, we're all done. */</syntaxhighlight> |
||
{{out|output|text= when using the default input:}} |
{{out|output|text= when using the default input:}} |
||
<pre style="height:45ex"> |
<pre style="height:45ex"> |
||
Line 2,160: | Line 2,160: | ||
===horizontal list=== |
===horizontal list=== |
||
< |
<syntaxhighlight lang="rexx">/*REXX program shows a horizontal list of Pythagorean triples up to a specified number. */ |
||
parse arg n . /*obtain optional argument from the CL.*/ |
parse arg n . /*obtain optional argument from the CL.*/ |
||
if n=='' | n=="," then n= 100 /*Not specified? Then use the default.*/ |
if n=='' | n=="," then n= 100 /*Not specified? Then use the default.*/ |
||
Line 2,187: | Line 2,187: | ||
end /*j*/ |
end /*j*/ |
||
say strip($); say |
say strip($); say |
||
say # ' members listed.' /*stick a fork in it, we're all done. */</ |
say # ' members listed.' /*stick a fork in it, we're all done. */</syntaxhighlight> |
||
{{out|output|text= when using the following input: <tt> 35 </tt>}} |
{{out|output|text= when using the following input: <tt> 35 </tt>}} |
||
<pre> |
<pre> |
||
Line 2,198: | Line 2,198: | ||
=={{header|Ring}}== |
=={{header|Ring}}== |
||
< |
<syntaxhighlight lang="ring"> |
||
for x = 1 to 20 |
for x = 1 to 20 |
||
for y = x to 20 |
for y = x to 20 |
||
Line 2,207: | Line 2,207: | ||
next |
next |
||
next |
next |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
Line 2,223: | Line 2,223: | ||
{{works with|Ruby|1.9.2}} |
{{works with|Ruby|1.9.2}} |
||
< |
<syntaxhighlight lang="ruby">n = 20 |
||
# select Pythagorean triplets |
# select Pythagorean triplets |
||
Line 2,231: | Line 2,231: | ||
[[x, y, z]].keep_if { x * x + y * y == z * z }}}}) |
[[x, y, z]].keep_if { x * x + y * y == z * z }}}}) |
||
p r # print the array _r_</ |
p r # print the array _r_</syntaxhighlight> |
||
Output: <tt>[[3, 4, 5], [5, 12, 13], [6, 8, 10], [8, 15, 17], [9, 12, 15], [12, 16, 20]]</tt> |
Output: <tt>[[3, 4, 5], [5, 12, 13], [6, 8, 10], [8, 15, 17], [9, 12, 15], [12, 16, 20]]</tt> |
||
Line 2,245: | Line 2,245: | ||
Illustrating a way to avoid all loops (but no list comprehensions) : |
Illustrating a way to avoid all loops (but no list comprehensions) : |
||
< |
<syntaxhighlight lang="ruby">n = 20 |
||
p (1..n).to_a.combination(3).select{|a,b,c| a*a + b*b == c*c} |
p (1..n).to_a.combination(3).select{|a,b,c| a*a + b*b == c*c} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Run BASIC}}== |
=={{header|Run BASIC}}== |
||
< |
<syntaxhighlight lang="runbasic">for x = 1 to 20 |
||
for y = x to 20 |
for y = x to 20 |
||
for z = y to 20 |
for z = y to 20 |
||
Line 2,256: | Line 2,256: | ||
next z |
next z |
||
next y |
next y |
||
next x</ |
next x</syntaxhighlight>Output: |
||
<pre>[3,4,5] |
<pre>[3,4,5] |
||
[5,12,13] |
[5,12,13] |
||
Line 2,273: | Line 2,273: | ||
First using the built-in iterator trait, we can simply flat-map and then filter-map: |
First using the built-in iterator trait, we can simply flat-map and then filter-map: |
||
< |
<syntaxhighlight lang="rust">fn pyth(n: u32) -> impl Iterator<Item = [u32; 3]> { |
||
(1..=n).flat_map(move |x| { |
(1..=n).flat_map(move |x| { |
||
(x..=n).flat_map(move |y| { |
(x..=n).flat_map(move |y| { |
||
Line 2,285: | Line 2,285: | ||
}) |
}) |
||
}) |
}) |
||
}</ |
}</syntaxhighlight> |
||
* Using <code>flat_map</code> we can map and flatten an iterator. |
* Using <code>flat_map</code> we can map and flatten an iterator. |
||
Line 2,299: | Line 2,299: | ||
Using the above and <code>macro_rules!</code> we can implement comprehension with a reasonably sized macro: |
Using the above and <code>macro_rules!</code> we can implement comprehension with a reasonably sized macro: |
||
< |
<syntaxhighlight lang="rust">macro_rules! comp { |
||
($e:expr, for $x:pat in $xs:expr $(, if $c:expr)?) => {{ |
($e:expr, for $x:pat in $xs:expr $(, if $c:expr)?) => {{ |
||
$xs.filter_map(move |$x| if $($c &&)? true { Some($e) } else { None }) |
$xs.filter_map(move |$x| if $($c &&)? true { Some($e) } else { None }) |
||
Line 2,306: | Line 2,306: | ||
$xs.flat_map(move |$x| comp!($e, $(for $y in $ys),+ $(, if $c)?)) |
$xs.flat_map(move |$x| comp!($e, $(for $y in $ys),+ $(, if $c)?)) |
||
}}; |
}}; |
||
}</ |
}</syntaxhighlight> |
||
The way to understand a Rust macro is it's a bit like regular expressions. The input matches a type of token, and expands it into the block, for example take the follow pattern: |
The way to understand a Rust macro is it's a bit like regular expressions. The input matches a type of token, and expands it into the block, for example take the follow pattern: |
||
< |
<syntaxhighlight lang="rust">($e:expr, for $x:pat in $xs:expr $(, if $c:expr)?)</syntaxhighlight> |
||
# matches an <code>expr</code> expression, defines it to <code>$e</code> |
# matches an <code>expr</code> expression, defines it to <code>$e</code> |
||
Line 2,323: | Line 2,323: | ||
This makes the two following blocks equivalent: |
This makes the two following blocks equivalent: |
||
< |
<syntaxhighlight lang="rust">comp!(x, for x in 0..10, if x != 5)</syntaxhighlight> |
||
< |
<syntaxhighlight lang="rust">(0..10).filter_map(move |x| { |
||
if x != 5 && true { |
if x != 5 && true { |
||
Some(x) |
Some(x) |
||
Line 2,331: | Line 2,331: | ||
None |
None |
||
} |
} |
||
})</ |
})</syntaxhighlight> |
||
The most interesting part of <code>comp!</code> is that it's a recursive macro (it expands within itself), and that means it can handle any number of iterators as inputs. |
The most interesting part of <code>comp!</code> is that it's a recursive macro (it expands within itself), and that means it can handle any number of iterators as inputs. |
||
Line 2,339: | Line 2,339: | ||
The pythagorean function could as such be defined as the following: |
The pythagorean function could as such be defined as the following: |
||
< |
<syntaxhighlight lang="rust">fn pyth(n: u32) -> impl Iterator<Item = [u32; 3]> { |
||
comp!( |
comp!( |
||
[x, y, z], |
[x, y, z], |
||
Line 2,347: | Line 2,347: | ||
if x.pow(2) + y.pow(2) == z.pow(2) |
if x.pow(2) + y.pow(2) == z.pow(2) |
||
) |
) |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
< |
<syntaxhighlight lang="scala">def pythagoranTriangles(n: Int) = for { |
||
x <- 1 to 21 |
x <- 1 to 21 |
||
y <- x to 21 |
y <- x to 21 |
||
z <- y to 21 |
z <- y to 21 |
||
if x * x + y * y == z * z |
if x * x + y * y == z * z |
||
} yield (x, y, z)</ |
} yield (x, y, z)</syntaxhighlight> |
||
which is a syntactic sugar for: |
which is a syntactic sugar for: |
||
< |
<syntaxhighlight lang="scala"> def pythagoranTriangles(n: Int) = (1 to n) flatMap (x => |
||
(x to n) flatMap (y => |
(x to n) flatMap (y => |
||
(y to n) filter (z => x * x + y * y == z * z) map (z => |
(y to n) filter (z => x * x + y * y == z * z) map (z => |
||
(x, y, z))))</ |
(x, y, z))))</syntaxhighlight> |
||
Alas, the type of collection returned depends on the type of the collection |
Alas, the type of collection returned depends on the type of the collection |
||
Line 2,372: | Line 2,372: | ||
To get a <code>List</code> out of it, just pass a <code>List</code> to it: |
To get a <code>List</code> out of it, just pass a <code>List</code> to it: |
||
< |
<syntaxhighlight lang="scala">def pythagoranTriangles(n: Int) = for { |
||
x <- List.range(1, n + 1) |
x <- List.range(1, n + 1) |
||
y <- x to 21 |
y <- x to 21 |
||
z <- y to 21 |
z <- y to 21 |
||
if x * x + y * y == z * z |
if x * x + y * y == z * z |
||
} yield (x, y, z)</ |
} yield (x, y, z)</syntaxhighlight> |
||
Sample: |
Sample: |
||
Line 2,389: | Line 2,389: | ||
Scheme has no native list comprehensions, but SRFI-42 [http://srfi.schemers.org/srfi-42/srfi-42.html] provides them: |
Scheme has no native list comprehensions, but SRFI-42 [http://srfi.schemers.org/srfi-42/srfi-42.html] provides them: |
||
< |
<syntaxhighlight lang="scheme"> |
||
(list-ec (:range x 1 21) |
(list-ec (:range x 1 21) |
||
(:range y x 21) |
(:range y x 21) |
||
Line 2,395: | Line 2,395: | ||
(if (= (* z z) (+ (* x x) (* y y)))) |
(if (= (* z z) (+ (* x x) (* y y)))) |
||
(list x y z)) |
(list x y z)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
<pre> |
<pre> |
||
Line 2,403: | Line 2,403: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans|Raku}} |
{{trans|Raku}} |
||
< |
<syntaxhighlight lang="ruby">var n = 20 |
||
say gather { |
say gather { |
||
for x in (1 .. n) { |
for x in (1 .. n) { |
||
Line 2,412: | Line 2,412: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,420: | Line 2,420: | ||
=={{header|Smalltalk}}== |
=={{header|Smalltalk}}== |
||
{{works with|Pharo|1.3-13315}} |
{{works with|Pharo|1.3-13315}} |
||
< |
<syntaxhighlight lang="smalltalk"> |
||
| test | |
| test | |
||
Line 2,437: | Line 2,437: | ||
#(9 12 15) |
#(9 12 15) |
||
#(12 16 20)" |
#(12 16 20)" |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Stata}}== |
=={{header|Stata}}== |
||
Line 2,443: | Line 2,443: | ||
Stata does no have list comprehensions, but the Mata matrix language helps simplify this task. |
Stata does no have list comprehensions, but the Mata matrix language helps simplify this task. |
||
< |
<syntaxhighlight lang="stata">function grid(n,p) { |
||
return(colshape(J(1,p,1::n),1),J(n,1,1::p)) |
return(colshape(J(1,p,1::n),1),J(n,1,1::p)) |
||
} |
} |
||
Line 2,450: | Line 2,450: | ||
a = grid(n,n) |
a = grid(n,n) |
||
a = a,sqrt(a[.,1]:^2+a[.,2]:^2) |
a = a,sqrt(a[.,1]:^2+a[.,2]:^2) |
||
a[selectindex(floor(a[.,3]):==a[.,3] :& a[.,3]:<=n),]</ |
a[selectindex(floor(a[.,3]):==a[.,3] :& a[.,3]:<=n),]</syntaxhighlight> |
||
'''Output''' |
'''Output''' |
||
Line 2,471: | Line 2,471: | ||
=={{header|SuperCollider}}== |
=={{header|SuperCollider}}== |
||
< |
<syntaxhighlight lang="supercollider"> |
||
var pyth = { |n| |
var pyth = { |n| |
||
all {: [x,y,z], |
all {: [x,y,z], |
||
Line 2,481: | Line 2,481: | ||
}; |
}; |
||
pyth.(20) // example call</ |
pyth.(20) // example call</syntaxhighlight> |
||
returns |
returns |
||
< |
<syntaxhighlight lang="supercollider">[ [ 3, 4, 5 ], [ 5, 12, 13 ], [ 6, 8, 10 ], [ 8, 15, 17 ], [ 9, 12, 15 ], [ 12, 16, 20 ] ]</syntaxhighlight> |
||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
{{incorrect|Swift|They should be distinct from (nested) for loops and the use of map and filter functions within the syntax of the language.}} |
{{incorrect|Swift|They should be distinct from (nested) for loops and the use of map and filter functions within the syntax of the language.}} |
||
< |
<syntaxhighlight lang="swift">typealias F1 = (Int) -> [(Int, Int, Int)] |
||
typealias F2 = (Int) -> Bool |
typealias F2 = (Int) -> Bool |
||
Line 2,501: | Line 2,501: | ||
} |
} |
||
print(pythagoreanTriples(n: 20))</ |
print(pythagoreanTriples(n: 20))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,509: | Line 2,509: | ||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
Tcl does not have list comprehensions built-in to the language, but they can be constructed. |
Tcl does not have list comprehensions built-in to the language, but they can be constructed. |
||
< |
<syntaxhighlight lang="tcl">package require Tcl 8.5 |
||
# from http://wiki.tcl.tk/12574 |
# from http://wiki.tcl.tk/12574 |
||
Line 2,553: | Line 2,553: | ||
set range {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20} |
set range {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20} |
||
puts [lcomp {$x $y $z} x $range y $range z $range {$x < $y && $x**2 + $y**2 == $z**2}]</ |
puts [lcomp {$x $y $z} x $range y $range z $range {$x < $y && $x**2 + $y**2 == $z**2}]</syntaxhighlight> |
||
<pre>{3 4 5} {5 12 13} {6 8 10} {8 15 17} {9 12 15} {12 16 20}</pre> |
<pre>{3 4 5} {5 12 13} {6 8 10} {8 15 17} {9 12 15} {12 16 20}</pre> |
||
Line 2,560: | Line 2,560: | ||
TI-89 BASIC does not have a true list comprehension, but it has the seq() operator which can be used for some similar purposes. |
TI-89 BASIC does not have a true list comprehension, but it has the seq() operator which can be used for some similar purposes. |
||
< |
<syntaxhighlight lang="ti89b">{1, 2, 3, 4} → a |
||
seq(a[i]^2, i, 1, dim(a))</ |
seq(a[i]^2, i, 1, dim(a))</syntaxhighlight> |
||
produces {1, 4, 9, 16}. When the input is simply a numeric range, an input list is not needed; this produces the same result: |
produces {1, 4, 9, 16}. When the input is simply a numeric range, an input list is not needed; this produces the same result: |
||
< |
<syntaxhighlight lang="ti89b">seq(x^2, x, 1, 4)</syntaxhighlight> |
||
=={{header|Visual Basic .NET}}== |
=={{header|Visual Basic .NET}}== |
||
Line 2,571: | Line 2,571: | ||
{{trans|C#}} |
{{trans|C#}} |
||
< |
<syntaxhighlight lang="vbnet">Module ListComp |
||
Sub Main() |
Sub Main() |
||
Dim ts = From a In Enumerable.Range(1, 20) _ |
Dim ts = From a In Enumerable.Range(1, 20) _ |
||
Line 2,583: | Line 2,583: | ||
Next |
Next |
||
End Sub |
End Sub |
||
End Module</ |
End Module</syntaxhighlight> |
||
Output: |
Output: |
||
Line 2,599: | Line 2,599: | ||
VP7 has explicit list comprehension syntax. |
VP7 has explicit list comprehension syntax. |
||
<syntaxhighlight lang="visualprolog"> |
|||
<lang visualProlog> |
|||
implement main |
implement main |
||
open core, std |
open core, std |
||
Line 2,626: | Line 2,626: | ||
goal |
goal |
||
mainExe::run(main::run). |
mainExe::run(main::run). |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Wrapl}}== |
=={{header|Wrapl}}== |
||
< |
<syntaxhighlight lang="wrapl">ALL WITH x <- 1:to(n), y <- x:to(n), z <- y:to(n) DO (x^2 + y^2 = z^2) & [x, y, z];</syntaxhighlight> |
||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
Using a generator. |
Using a generator. |
||
< |
<syntaxhighlight lang="ecmascript">var pythTriples = Fiber.new { |n| |
||
(1..n-2).each { |x| |
(1..n-2).each { |x| |
||
(x+1..n-1).each { |y| |
(x+1..n-1).each { |y| |
||
Line 2,645: | Line 2,645: | ||
var res = pythTriples.call(n) |
var res = pythTriples.call(n) |
||
res && System.print(res) |
res && System.print(res) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,658: | Line 2,658: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
< |
<syntaxhighlight lang="zkl">var n=20; |
||
[[(x,y,z); [1..n]; {[x..n]}; {[y..n]},{ x*x + y*y == z*z }; _]] |
[[(x,y,z); [1..n]; {[x..n]}; {[y..n]},{ x*x + y*y == z*z }; _]] |
||
//-->L(L(3,4,5),L(5,12,13),L(6,8,10),L(8,15,17),L(9,12,15),L(12,16,20))</ |
//-->L(L(3,4,5),L(5,12,13),L(6,8,10),L(8,15,17),L(9,12,15),L(12,16,20))</syntaxhighlight> |
||
Lazy: |
Lazy: |
||
< |
<syntaxhighlight lang="zkl">var n=20; |
||
lp:=[& (x,y,z); // three variables, [& means lazy/iterator |
lp:=[& (x,y,z); // three variables, [& means lazy/iterator |
||
[1..n]; // x: a range |
[1..n]; // x: a range |
||
Line 2,672: | Line 2,672: | ||
// with values x,y,z, or just _ (which means return arglist) |
// with values x,y,z, or just _ (which means return arglist) |
||
]]; |
]]; |
||
lp.walk(2) //-->L(L(3,4,5),L(5,12,13))</ |
lp.walk(2) //-->L(L(3,4,5),L(5,12,13))</syntaxhighlight> |
||