Comments (29)
Thanks for these pointers and for the test-set you provided. It helped me to improve my implementation on the emission of ...
inside lists. NB variables are still not treated differently. Now:
| ?- nth0(I,[A+B+C+D,1+2+3+4,A^B^C^D^E,1^2^3^4^nil,[1,2,3,4],[A,B,C,D],[- -A,- -B,- -C,- -D],[[A,B,C,D]]],T),
between(0,5,M), write(I-M), write(' '),
write_term(T,[variable_names(['A'=A,'B'=B,'C'=C,'D'=D,'E'=E]),max_depth(M)]), nl, false.
SICStus GNU
0-0 A+B+C+D 0-0 A+B+C+D
0-1 ... +D 0-1 ... + ...
0-2 ... +C+D 0-2 ... + ... +D
0-3 A+B+C+D 0-3 ... + ... +C+D
0-4 A+B+C+D 0-4 A+B+C+D
0-5 A+B+C+D 0-5 A+B+C+D
1-0 1+2+3+4 1-0 1+2+3+4
1-1 ... + ... 1-1 ... + ...
1-2 ... + ... +4 1-2 ... + ... +4
1-3 ... + ... +3+4 1-3 ... + ... +3+4
1-4 1+2+3+4 1-4 1+2+3+4
1-5 1+2+3+4 1-5 1+2+3+4
2-0 A^B^C^D^E 2-0 A^B^C^D^E
2-1 A^ ... 2-1 ... ^ ...
2-2 A^B^ ... 2-2 A^ ... ^ ...
2-3 A^B^C^ ... 2-3 A^B^ ... ^ ...
2-4 A^B^C^D^E 2-4 A^B^C^ ... ^ ...
2-5 A^B^C^D^E 2-5 A^B^C^D^E
3-0 1^2^3^4^nil 3-0 1^2^3^4^nil
3-1 ... ^ ... 3-1 ... ^ ...
3-2 1^ ... ^ ... 3-2 1^ ... ^ ...
3-3 1^2^ ... ^ ... 3-3 1^2^ ... ^ ...
3-4 1^2^3^ ... ^ ... 3-4 1^2^3^ ... ^ ...
3-5 1^2^3^4^nil 3-5 1^2^3^4^nil
4-0 [1,2,3,4] 4-0 [1,2,3,4]
4-1 [...|...] 4-1 [1|...]
4-2 [1,2|...] 4-2 [1,2|...]
4-3 [1,2,3|...] 4-3 [1,2,3|...]
4-4 [1,2,3,4] 4-4 [1,2,3,4]
4-5 [1,2,3,4] 4-5 [1,2,3,4]
5-0 [A,B,C,D] 5-0 [A,B,C,D]
5-1 [A|...] 5-1 [A|...]
5-2 [A,B|...] 5-2 [A,B|...]
5-3 [A,B,C|...] 5-3 [A,B,C|...]
5-4 [A,B,C,D] 5-4 [A,B,C,D]
5-5 [A,B,C,D] 5-5 [A,B,C,D]
6-0 [- -A,- -B,- -C,- -D] 6-0 [- -A,- -B,- -C,- -D]
6-1 [...|...] 6-1 [- ...|...]
6-2 [- ...,- ...|...] 6-2 [- - ...,- ...|...]
6-3 [- -A,- -B,- ...|...] 6-3 [- -A,- - ...,- ...|...]
6-4 [- -A,- -B,- -C,- ...] 6-4 [- -A,- -B,- - ...,- ...]
6-5 [- -A,- -B,- -C,- -D] 6-5 [- -A,- -B,- -C,- - ...]
7-0 [[A,B,C,D]] 7-0 [[A,B,C,D]]
7-1 [...] 7-1 [[A|...]]
7-2 [[A|...]] 7-2 [[A,B|...]]
7-3 [[A,B|...]] 7-3 [[A,B,C|...]]
7-4 [[A,B,C|...]] 7-4 [[A,B,C,D]]
7-5 [[A,B,C,D]] 7-5 [[A,B,C,D]]
As mentioned by both of you, 4-1 is not consistent in sicstus thus the "shift" in displays between both systems (which does not appear with vars which are treated differently in sisctus).
from gprolog.
A common issue seems to be counting depth for lists vs other compound terms.
from gprolog.
Results for LVM 6.3.0:
?- member(T,[1+2+3+4,[1,2,3,4],[_,_,_,_]]),between(0,5,D),write(D),write(' '),write_term(T,[max_depth(D)]),nl,false.
0 1+2+3+4
1 ... + ...
2 ... + ... +4
3 ... + ... +3+4
4 1+2+3+4
5 1+2+3+4
0 [1,2,3,4]
1 [1|...]
2 [1,2|...]
3 [1,2,3|...]
4 [1,2,3,4]
5 [1,2,3,4]
0 [_R1,_R2,_R3,_R4]
1 [_R1|...]
2 [_R1,_R2|...]
3 [_R1,_R2,_R3|...]
4 [_R1,_R2,_R3,_R4]
5 [_R1,_R2,_R3,_R4]
false.
Interesting difference between SICStus and LVM: 1 [...|...]
vs 1 [1|...]
. Trealla also outputs 1 [1|...]
.
from gprolog.
Here is another view to understand some of the assumptions present. After all, a list is kind of a right-associative structure. So let's compare them (here Ciao) with 1^2^3^4^nil
?- member(T,[1+2+3+4,1^2^3^4^nil,[1,2,3,4],[_,_,_,_]]),between(0,5,D),write(D),write(' '),write_term(T,[max_depth(D)]),nl,false.
0 1+2+3+4
1 ... + ...
2 ... + ... +4
3 ... + ... +3+4
4 1+2+3+4
5 1+2+3+4
0 1^2^3^4^nil
1 ... ^ ...
2 1^ ... ^ ...
3 1^2^ ... ^ ...
4 1^2^3^ ... ^ ...
5 1^2^3^4^nil
0 [1,2,3,4]
1 [...|...]
2 [1,2|...]
3 [1,2,3|...]
4 [1,2,3,4]
5 [1,2,3,4]
0 [_18139,_18148,_18157,_18166]
1 [_18139|...]
2 [_18139,_18148|...]
3 [_18139,_18148,_18157|...]
4 [_18139,_18148,_18157,_18166]
5 [_18139,_18148,_18157,_18166]
no
While 1+2+3+4
and 1^2^3^4^nil
seem to be uncontroversial, the question is now how this translates (or not) to the list syntax. Taken the example of the ^-list literally, D = 2 would have to be [1,...|...]
. Well, who wants this? But then, why accept [...|...]
in the case of D = 1
?
from gprolog.
The closer I look, the uglier it gets. And also the fewer the systems
I can look at. Now there is only SICStus left...
| ?- nth0(I,[A+B+C+D,1+2+3+4,A^B^C^D^E,1^2^3^4^nil,[1,2,3,4],[A,B,C,D],[- -A,- -B,- -C,- -D],[[A,B,C,D]]],T),
between(0,5,M), write(I-M), write(' '),
write_term(T,[variable_names(['A'=A,'B'=B,'C'=C,'D'=D,'E'=E]),max_depth(M)]), nl, false.
SICStus GNU
0-0 A+B+C+D 0-0 A+B+C+D
0-1 ... +D 0-1 ... + ...
0-2 ... +C+D 0-2 ... + ... +D
0-3 A+B+C+D 0-3 ... + ... +C+D
0-4 A+B+C+D 0-4 A+B+C+D
0-5 A+B+C+D 0-5 A+B+C+D
1-0 1+2+3+4 1-0 1+2+3+4
1-1 ... + ... 1-1 ... + ...
1-2 ... + ... +4 1-2 ... + ... +4
1-3 ... + ... +3+4 1-3 ... + ... +3+4
1-4 1+2+3+4 1-4 1+2+3+4
1-5 1+2+3+4 1-5 1+2+3+4
2-0 A^B^C^D^E 2-0 A^B^C^D^E
2-1 A^ ... 2-1 ... ^ ...
2-2 A^B^ ... 2-2 A^ ... ^ ...
2-3 A^B^C^ ... 2-3 A^B^ ... ^ ...
2-4 A^B^C^D^E 2-4 A^B^C^ ... ^ ...
2-5 A^B^C^D^E 2-5 A^B^C^D^E
3-0 1^2^3^4^nil 3-0 1^2^3^4^nil
3-1 ... ^ ... 3-1 ... ^ ...
3-2 1^ ... ^ ... 3-2 1^ ... ^ ...
3-3 1^2^ ... ^ ... 3-3 1^2^ ... ^ ...
3-4 1^2^3^ ... ^ ... 3-4 1^2^3^ ... ^ ...
3-5 1^2^3^4^nil 3-5 1^2^3^4^nil
4-0 [1,2,3,4] 4-0 [1,2,3,4]
4-1 [...|...] 4-1 [...]
4-2 [1,2|...] 4-2 [1,...]
4-3 [1,2,3|...] 4-3 [1,2,...]
4-4 [1,2,3,4] 4-4 [1,2,3,...]
4-5 [1,2,3,4] 4-5 [1,2,3,4]
5-0 [A,B,C,D] 5-0 [A,B,C,D]
5-1 [A|...] 5-1 [...]
5-2 [A,B|...] 5-2 [A,...]
5-3 [A,B,C|...] 5-3 [A,B,...]
5-4 [A,B,C,D] 5-4 [A,B,C,...]
5-5 [A,B,C,D] 5-5 [A,B,C,D]
6-0 [- -A,- -B,- -C,- -D] 6-0 [- -A,- -B,- -C,- -D]
6-1 [...|...] 6-1 [...]
6-2 [- ...,- ...|...] 6-2 [- ...,...]
6-3 [- -A,- -B,- ...|...] 6-3 [- - ...,- ...,...]
6-4 [- -A,- -B,- -C,- ...] 6-4 [- -A,- - ...,- ...,...]
6-5 [- -A,- -B,- -C,- -D] 6-5 [- -A,- -B,- - ...,- ...]
7-0 [[A,B,C,D]] 7-0 [[A,B,C,D]]
7-1 [...] 7-1 [...]
7-2 [[A|...]] 7-2 [[...]]
7-3 [[A,B|...]] 7-3 [[A,...]]
7-4 [[A,B,C|...]] 7-4 [[A,B,...]]
7-5 [[A,B,C,D]] 7-5 [[A,B,C,...]]
4-1 is problematic in SICStus, not because of 5-1 but because of 4-2.
6-4, I would say (so far), that all elements of a list should be
printed with the same depth. But in any case, these two questions are
a bit open. So for the moment, most relevant is that the terms can
still be used reconstruct a term which has the original term as an
instance.
from gprolog.
Indeed we should see 4-1 [1|...]
for consistency.
from gprolog.
Both CxProlog and LVM output 4-1 [1|...]
.
from gprolog.
A general remark: this option is to help the user to limit large term display by giving it "an idea" of what the term is. The ellipsis meaning "followed by something I suppose you can guess more or less (else increase the depth)".
Keeping this in mind, as I user I prefer [...] to [...|...] which is just more cumbersome and add no information (basically I understand that my term is a list). Similarly, I find [1,...] more intuitive than [1|...] (basically I understand my term is a list whose the first element is 1).
from gprolog.
A general remark: this option is to help the user to limit large term display by giving it "an idea" of what the term is. The ellipsis meaning "followed by something I suppose you can guess more or less (else increase the depth)".
Agree. E.g. I use it in the Logtalk debugger which allows the user to set the max term depth.
Keeping this in mind, as I user I prefer [...] to [...|...] which is just more cumbersome and add no information (basically I understand that my term is a list). Similarly, I find [1,...] more intuitive than [1|...] (basically I understand my term is a list whose the first element is 1).
Both tell the user that it's a list whose the first element is 1. I have no strong preference here other that consistency and ideally a common output for common case among systems.
from gprolog.
I don't find SICStus coherent (with itself) between 0-1,0-2,0-3 and 1-1,1-2,1-3. It seems variables are treated differently (why not all atomics also ?). This seems confirmed by 2-1,2-2,2-3 wrt 3-1,3-2,3-3.
from gprolog.
Yes, variables are treated differently! A ...
stands for a non-variable term. And why not all atomic terms, they can become quite large. Also replacing a variable by a non-variable term like ...
looks rather like an expansion not an abbreviation.
0-1,0-2,0-3 is quite coherent if you count the operators. In 0-3 there are already variables that do not need to be abbreviated.
What is really important is that the abbreviated term can be used to reconstruct (partially) the original term. Think of 4-1 in GNU. This [...]
suggests that there is a one-element list. But this is not the case. In this case it is important to insist that we see only the front of a list. This [...|...]
or [1|...]
. If this property is preserved, such abbreviated terms can be used for testing. Otherwise it is just misdirection for the user. So the very exact depth and the like are less important compared to this property.
from gprolog.
Or see this from another level: Before printing, replace some non-variable subterms by ...
, then print without any depth restriction. That's it. In this manner it is guaranteed that the ...
stands for a non-variable subterm and not, say for several of them.
from gprolog.
A
...
stands for a non-variable term.
Interesting ? Do you have a reference for this definition ?
Yes, variables are treated differently!
On which systems (other than Sicstus) is it the case ?
And why not all atomic terms, they can become quite large.
Variable names can also be rather large, most of the time (in particular in debugging session) they are written as '_addr, e.g.
_35298728` (SWI). Many integers are shorter than this, why not display them too ?
This
[...]
suggests that there is a one-element list.
IMHO [...|...]
does not really bring anything useful for the user but really pollutes the output (if one wants to know more about the content of the list, he simply increases the depth).
from gprolog.
A
...
stands for a non-variable term.Interesting ? Do you have a reference for this definition ?
When a variable is replaced by a non-variable term this is called a substitution. See any textbook.
Yes, variables are treated differently!
On which systems (other than Sicstus) is it the case ?
See above Ciao and XSB. If you find another system, try:
?- (Z=1;Z=2;Z=3),write_term(A+B+C+D,[max_depth(Z)]),nl,false.
And why not all atomic terms, they can become quite large.
Variable names can also be rather large, most of the time (in particular in debugging session) they are written as '_addr
, e.g.
_35298728` (SWI). Many integers are shorter than this, why not display them too ?
You need some consistency in behavior. And, just to reiterate: substitution is a well known operation on variables. So if you are replacing a variable by ...
that looks like a substitution.
And printing a very longish variable like the one you mention is a problem with this system. Also note that printing unnamed variables is a problem in itself. To my knowledge, only SICStus has found a way to handle this. But let's leave that out of the discussion here, since you do not have GC.
This
[...]
suggests that there is a one-element list.IMHO
[...|...]
does not really bring anything useful for the user but really pollutes the output (if one wants to know more about the content of the list, he simply increases the depth).
What do you prefer: a term like [...]
which incorrectly suggests that this is a one-element list. Or an output which contains less-than-you-expect information, but which is accurate?
from gprolog.
Maybe printing atomic terms that are shorter or equal to ...
makes sense. In this manner, one could also print [...]
when there is a one-element list. After all, this does not violate the assumption that ...
stands for a non-variable term.
from gprolog.
Also note that printing unnamed variables is a problem in itself.
To be precise, repeated printing of terms with the same variables is a problem in itself. As for ISO, naming of unnamed shared variables is consistent only within a single invocation of write_term/2
. But even two otherwise identical write_term/2
goals in a row may use such internal variable names differently.
from gprolog.
A ... stands for a non-variable term.
Interesting ? Do you have a reference for this definition ?
When a variable is replaced by a non-variable term this is called a substitution. See any textbook.
My question is not about substitution (which we all know obviously). My question is about "...
stands for non variable term". I never saw the non variable feature explicitly mentioned and thus I'm interested in any pointer (there is generally few info about max_depth
option and ...
).
from gprolog.
That it is used here is Prolog lore. One purpose of standardization is to make these things explicit.
from gprolog.
In very old systems, this feature is only available with the debugger and the option is called printdepth
. The oldest version that prints lists correctly that I can get hold of right now is 3.8.4 of about 2000-07 (or earlier). And the newest version that does the abbreviation incorrect as GNU is 0.7 of 1991-11. The manual of 3.7.1 of 1997-11 has it still incorrect in an example. And in 3.8 of 1999-10 this example is gone.
from gprolog.
I hope you reconsider your decision to go against this treatment of variables. This simply only means that your systems gets tested less. Like for cases you did not consider [[[[[[[[A,B,C,D]]]]]]]]]
nor:
| ?- T=s(T), write_term(T,[max_depth(3)]),false.
s(s(s(...))) % sto, but good
no
| ?- T=[T], write_term(T,[max_depth(3)]),false.
[[[[[[[[[[[[ % sto, unexpected...
from gprolog.
What is the output of the following goal (try to reply before testing any system):
write_term(f(1,2,3),[max_depth(1)]).
All systems I have tried (including ciao, sisctus, ... exception is swi) show f(...)
which is very similar to my initial [...]
for an incomplete list. According to you, they should output f(...,...,...)
. This implies max_depth
option is ineffective on large arity terms, e.g. ILP.
from gprolog.
I agree with your view. Yes, I think that f(...,...,...)
should be the result, or a ...
for it all.
from gprolog.
So maybe replace such very large terms earlier than the indicated depth. But what is most crucial is that all of it is somewhat testable. That is, replace the dots by variables and then subsumes_term(Generalized, Original) must hold.
from gprolog.
or a
...
for it all.
NB: ...
does not respect the "replace the dots by variables and then subsumes_term(Generalized, Original)
must hold". This remains testable (obviously not with a simple subsumes_term
).
But it allows to shorten large arity terms. In that case, an additional possibility is to limit the number of arguments of a structure displayed (as done for lists) as follows:
| ?- write_term(f(1,2,3,4),[max_depth(1)]).
f(1,...)
| ?- write_term(f(1,2,3,4),[max_depth(2)]).
f(1,2,...)
| ?- write_term(f(1,2,3,4),[max_depth(3)]).
f(1,2,3,...)
from gprolog.
SICStus:
| ?- functor(F,f,100),write_term(F,[max_depth(1)]).
f(...)
F = ... ?
yes
| ?- functor(F,f,100),write_term(F,[max_depth(2)]).
f(_1709,_1711,_1713,_1715,_1717,_1719,_1721,_1723,_1725,_1727,_1729,_1731,_1733,_1735,_1737,_1739,_1741,_1743,_1745,_1747,_1749,_1751,_1753,_1755,_1757,_1759,_1761,_1763,_1765,_1767,_1769,_1771,_1773,_1775,_1777,_1779,_1781,_1783,_1785,_1787,_1789,_1791,_1793,_1795,_1797,_1799,_1801,_1803,_1805,_1807,_1809,_1811,_1813,_1815,_1817,_1819,_1821,_1823,_1825,_1827,_1829,_1831,_1833,_1835,_1837,_1839,_1841,_1843,_1845,_1847,_1849,_1851,_1853,_1855,_1857,_1859,_1861,_1863,_1865,_1867,_1869,_1871,_1873,_1875,_1877,_1879,_1881,_1883,_1885,_1887,_1889,_1891,_1893,_1895,_1897,_1899,_1901,_1903,_1905,_1907)
F = ... ?
yes
F = ...
abbreviated by myself
So this only works in one case, and in the other very similar case, the full term is shown.
from gprolog.
NB: ... does not respect the "replace the dots by variables and then subsumes_term(Generalized, Original) must hold". This remains testable (obviously not with a simple subsumes_term).
Why not?
from gprolog.
| ?- write_term(f(1,2,3),[max_depth(1)]).
f(...)
yes
| ?- subsumes_term(f(X),f(1,2,3)).
no
from gprolog.
Ah, sorry. I misunderstood you. No, exactly because of this, I think these wrongly abbreviated terms do not serve much purpose. And as you have seen for SICStus, its use is quite inconsequential.
from gprolog.
Fixed.
| ?- nth0(I,[A+B+C+D,1+2+3+4,A^B^C^D^E,1^2^3^4^nil,[1,2,3,4],[A,B,C,D],[- -A,- -B,- -C,- -D],[[A,B,C,D]]],T),
between(0,5,M), write(I-M), write(' '),
write_term(T,[variable_names(['A'=A,'B'=B,'C'=C,'D'=D,'E'=E]),max_depth(M)]), nl, false.
SICStus GNU
0-0 A+B+C+D 0-0 A+B+C+D
0-1 ... +D 0-1 ... +D
0-2 ... +C+D 0-2 ... +C+D
0-3 A+B+C+D 0-3 A+B+C+D
0-4 A+B+C+D 0-4 A+B+C+D
0-5 A+B+C+D 0-5 A+B+C+D
1-0 1+2+3+4 1-0 1+2+3+4
1-1 ... + ... 1-1 ... + ...
1-2 ... + ... +4 1-2 ... + ... +4
1-3 ... + ... +3+4 1-3 ... + ... +3+4
1-4 1+2+3+4 1-4 1+2+3+4
1-5 1+2+3+4 1-5 1+2+3+4
2-0 A^B^C^D^E 2-0 A^B^C^D^E
2-1 A^ ... 2-1 A^ ...
2-2 A^B^ ... 2-2 A^B^ ...
2-3 A^B^C^ ... 2-3 A^B^C^ ...
2-4 A^B^C^D^E 2-4 A^B^C^D^E
2-5 A^B^C^D^E 2-5 A^B^C^D^E
3-0 1^2^3^4^nil 3-0 1^2^3^4^nil
3-1 ... ^ ... 3-1 ... ^ ...
3-2 1^ ... ^ ... 3-2 1^ ... ^ ...
3-3 1^2^ ... ^ ... 3-3 1^2^ ... ^ ...
3-4 1^2^3^ ... ^ ... 3-4 1^2^3^ ... ^ ...
3-5 1^2^3^4^nil 3-5 1^2^3^4^nil
4-0 [1,2,3,4] 4-0 [1,2,3,4]
4-1 [...|...] 4-1 [1|...]
4-2 [1,2|...] 4-2 [1,2|...]
4-3 [1,2,3|...] 4-3 [1,2,3|...]
4-4 [1,2,3,4] 4-4 [1,2,3,4]
4-5 [1,2,3,4] 4-5 [1,2,3,4]
5-0 [A,B,C,D] 5-0 [A,B,C,D]
5-1 [A|...] 5-1 [A|...]
5-2 [A,B|...] 5-2 [A,B|...]
5-3 [A,B,C|...] 5-3 [A,B,C|...]
5-4 [A,B,C,D] 5-4 [A,B,C,D]
5-5 [A,B,C,D] 5-5 [A,B,C,D]
6-0 [- -A,- -B,- -C,- -D] 6-0 [- -A,- -B,- -C,- -D]
6-1 [...|...] 6-1 [...|...]
6-2 [- ...,- ...|...] 6-2 [- ...|...]
6-3 [- -A,- -B,- ...|...] 6-3 [- -A,- ...|...]
6-4 [- -A,- -B,- -C,- ...] 6-4 [- -A,- -B,- ...|...]
6-5 [- -A,- -B,- -C,- -D] 6-5 [- -A,- -B,- -C,- ...]
7-0 [[A,B,C,D]] 7-0 [[A,B,C,D]]
7-1 [...] 7-1 [...]
7-2 [[A|...]] 7-2 [[A|...]]
7-3 [[A,B|...]] 7-3 [[A,B|...]]
7-4 [[A,B,C|...]] 7-4 [[A,B,C|...]]
7-5 [[A,B,C,D]] 7-5 [[A,B,C,D]]
from gprolog.
Related Issues (20)
- Leak with simple arithmetics HOT 4
- Power not defined HOT 1
- Linking error riscv64
- Problem processing repeated calls HOT 3
- New show_information flag regression HOT 1
- Typo in Load_Math_Expression?
- Insure project web site
- GNU Prolog Parser accepts incomplete clause.
- hand written C code lacks some garbage collection.
- real_file_name does not follow symlinks on Windows HOT 1
- numbervars/3 silently refuses to number vars
- ensure_loaded/1 wants suddently predicate indicator HOT 1
- Ubuntu defaults so that GNU compile result is speedy HOT 1
- Incorrect answers when exceeding domains
- phrase/2 too eager execution HOT 1
- Feature request: format_time
- Ma2Asm for linux x64 with gcc is not generating PIC code (v1.5.0+)
- GNU Prolog crashes when reading long string literals
- GNU Prolog segmentation faults when using read_term/3 on a huge file
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from gprolog.