'Concurrency-by-default' is similar to a notation I've been using to map out async service calls. It's just this: lines are terminated with "," or ";". A comma doesn't block and all comma-separated lines are executed in any order, while a semicolon blocks. Names are only usable when a semicolon is reached, and a semicolon unblocks flow when all preceding names are bound. Probably code is scoped into { } blocks. So a…
Esoteric programming paradigms
141–149 of 149 posts
Re: Esoteric programming paradigms
#142Earlier quoted context omitted.
I can't load the site on my phone. Mind pointing out what makes Eve so special? I'm suspicious of us figuring out anything mind boggling new at this point and assumed Eve was all a gimmick (I hope to be proved wrong :)). Something like Red makes a lot of sense to me as that ahhh language as it is tiny with no install, can be used for high/low level coding, has excellent DSLs such as GUI builders, and can compile to a…
We've certainly taken a lot of inspiration from Smalltalk, but I think the semantics we've arrived at make a really nice programming environment, with some surprising properties you may not think are possible. Eve has a similar philosophy to Red/Rebol - that programming is needlessly complex, and by fixing the model we can make the whole ordeal a lot nicer. We start with a uniform data model - everything in Eve is re…
Quick question: Will it always be online only?
Re: Esoteric programming paradigms
#143Earlier quoted context omitted.
You're correct that I'd not consider these esoteric, just not procedural or OO. Esoteric would be something like Brainf *, the music programming language, or that art language (forget the name). Unusual but still commercial and useful paradigms are logic, array, functional, and concatenative to name a few.
Piet. The Mondrian language I'm guessing
Re: Esoteric programming paradigms
#144Earlier quoted context omitted.
When you say "all open pieces have at least 2 possible values", how can the solution be unique ? Surely for each piece, some values are not admissible, otherwise this would be a contradiction. Sufficiently strong pruning could have eliminated them, either by search or by more reasoning.
First, apologies for going to sleep on you. Huge thanks for sticking with this and opening my eyes to this branch of programming. If you have recommended texts, is appreciate it. For this question, I can really only refer to Knuth. This is exercise 515 of 7.2.2.2. I likely just messed you up on the wording. There are no forced moves for open squares. As soon as you pick one, though, it may force all others.
knuth(a, [[1,_,_,_,_,6,_,8,_],
[5,_,8,7,2,1,4,_,6],
[_,6,_,3,8,_,2,_,1],
[8,4,_,_,_,3,_,_,5],
[_,_,5,_,6,_,8,_,_],
[6,_,_,8,_,_,_,4,2],
[3,_,6,_,4,8,_,2,_],
[4,_,7,6,3,2,1,_,8],
[_,8,_,5,_,_,_,_,4]]).
Consider now a Prolog solution for 9x9 (i.e., "normal") Sudoku puzzles, using integer constraints: sudoku(Rows) :-
length(Rows, 9), maplist(same_length(Rows), Rows),
append(Rows, Vs), Vs ins 1..9,
maplist(all_distinct, Rows),
transpose(Rows, Columns), maplist(all_distinct, Columns),
Rows = [As,Bs,Cs,Ds,Es,Fs,Gs,Hs,Is],
blocks(As, Bs, Cs), blocks(Ds, Es, Fs), blocks(Gs, Hs, Is).
blocks([], [], []).
blocks([N1,N2,N3|Ns1], [N4,N5,N6|Ns2], [N7,N8,N9|Ns3]) :-
all_distinct([N1,N2,N3,N4,N5,N6,N7,N8,N9]),
blocks(Ns1, Ns2, Ns3).
This is indeed exactly a case where search is necessary, because the pruning applied by this concrete constraint solver is not strong enough to deduce the unique solution. If we only post the constraints, we get: ?- knuth(a, Rows),
sudoku(Rows),
maplist(portray_clause, Rows).
[1, _, _, _, _, 6, _, 8, _].
[5, _, 8, 7, 2, 1, 4, _, 6].
[_, 6, _, 3, 8, _, 2, _, 1].
[8, 4, _, _, _, 3, _, _, 5].
[_, _, 5, _, 6, _, 8, _, _].
[6, _, _, 8, _, _, _, 4, 2].
[3, _, 6, _, 4, 8, _, 2, _].
[4, _, 7, 6, 3, 2, 1, _, 8].
[_, 8, _, 5, _, _, _, _, 4].
However, it is exactly as you say: Even assigning a single variable a concrete value automatically enforces the solution by constraint propagation alone: ?- knuth(a, Rows),
sudoku(Rows),
Rows = [[_,Var|_]|_],
indomain(Var),
maplist(portray_clause, Rows).
[1, 2, 3, 4, 5, 6, 7, 8, 9].
[5, 9, 8, 7, 2, 1, 4, 3, 6].
[7, 6, 4, 3, 8, 9, 2, 5, 1].
[8, 4, 2, 1, 9, 3, 6, 7, 5].
[9, 7, 5, 2, 6, 4, 8, 1, 3].
[6, 3, 1, 8, 7, 5, 9, 4, 2].
[3, 1, 6, 9, 4, 8, 5, 2, 7].
[4, 5, 7, 6, 3, 2, 1, 9, 8].
[2, 8, 9, 5, 1, 7, 3, 6, 4].
Note though the general point: A sufficiently strong constraint solver could have deduced the unique solution even without trying any concrete value, exclusively by reasoning about the posted constraints with sufficient sophistication! This concrete solver can't, due to the particular trade-off between efficiency and pruning strength that was chosen by the implementor, and so search must settle the remaining part.One of the other puzzles is:
knuth(d, [[1,_,3,_,5,6,_,8,9],
[6,8,_,3,_,9,1,_,5],
[_,9,5,1,8,_,6,3,_],
[3,_,8,9,6,_,_,5,1],
[_,1,9,5,_,8,3,6,_],
[5,6,_,_,3,1,9,_,8],
[_,5,6,_,9,3,8,1,_],
[8,_,1,6,_,5,_,9,3],
[9,3,_,8,1,_,5,_,6]]).
In this case, the solution is not unique. We can use the constraint solver to count the number of admissible solutions, again using search: ?- knuth(d, Rows),
sudoku(Rows),
findall(., maplist(labeling([ff]), Rows), Ls),
length(Ls, L).
Yielding: L = 12.This indeed shows that search is necessary in general also when applying constraint programming. Still, no such search is applied in the posted article. In the example contained in the article, the constraints alone suffice to determine the unique solution. I leave it as an exercise for the reader to determine whether this is the case for all 4x4 Sudoku puzzles.
Re: Esoteric programming paradigms
#145Earlier quoted context omitted.
First, apologies for going to sleep on you. Huge thanks for sticking with this and opening my eyes to this branch of programming. If you have recommended texts, is appreciate it. For this question, I can really only refer to Knuth. This is exercise 515 of 7.2.2.2. I likely just messed you up on the wording. There are no forced moves for open squares. As soon as you pick one, though, it may force all others.
In the solution of this exercise, 4 example puzzles are given. Here is the first one: knuth(a, [[1,_,_,_,_,6,_,8,_], [5,_,8,7,2,1,4,_,6], [_,6,_,3,8,_,2,_,1], [8,4,_,_,_,3,_,_,5], [_,_,5,_,6,_,8,_,_], [6,_,_,8,_,_,_,4,2], [3,_,6,_,4,8,_,2,_], [4,_,7,6,3,2,1,_,8], [_,8,_,5,_,_,_,_,4]]). Consider now a Prolog solution for 9x9 (i.e., "normal") Sudoku puzzles, using integer constraints: sudoku(Rows) :- length(Rows, 9), m…
I'm curious on how you claim a strong enough solver could have solved this without a "guess."
Also, any thoughts on how treating them as constraint propagation compares to casting it as an exact cover problem?
Re: Esoteric programming paradigms
#146Isn't Lua supposed to be an example of a concatenative language?
Not at all. The definition I like to use of concatenative language is: If "X Y" is a legal program, then "X" is a list of tokens and a legal program and "Y" is a list of tokens and a legal program, and semantically, executing "X Y" is equivalent to executing "X" and then executing "Y". practical implementations often deviate a little from this ideal.
Re: Esoteric programming paradigms
#147Earlier quoted context omitted.
In the solution of this exercise, 4 example puzzles are given. Here is the first one: knuth(a, [[1,_,_,_,_,6,_,8,_], [5,_,8,7,2,1,4,_,6], [_,6,_,3,8,_,2,_,1], [8,4,_,_,_,3,_,_,5], [_,_,5,_,6,_,8,_,_], [6,_,_,8,_,_,_,4,2], [3,_,6,_,4,8,_,2,_], [4,_,7,6,3,2,1,_,8], [_,8,_,5,_,_,_,_,4]]). Consider now a Prolog solution for 9x9 (i.e., "normal") Sudoku puzzles, using integer constraints: sudoku(Rows) :- length(Rows, 9), m…
Thanks for posting. Wasn't sure if folks were interested, but I've found Knuth's fun with Sudoku to be a lot of fun. I'm curious on how you claim a strong enough solver could have solved this without a "guess." Also, any thoughts on how treating them as constraint propagation compares to casting it as an exact cover problem?
As an alternative, we can just as well model Sudoku puzzles as combinatorial tasks over Boolean variables, and hence use CLP(B), constraint logic programming over Booleans.
For example:
sudoku(Rows) :-
length(Rows, 9), maplist(same_length(Rows), Rows),
maplist(row_booleans, Rows, BRows),
maplist(booleans_distinct, BRows),
transpose(BRows, BColumns),
maplist(booleans_distinct, BColumns),
BRows = [As,Bs,Cs,Ds,Es,Fs,Gs,Hs,Is],
blocks(As, Bs, Cs), blocks(Ds, Es, Fs), blocks(Gs, Hs, Is).
blocks([], [], []).
blocks([N1,N2,N3|Ns1], [N4,N5,N6|Ns2], [N7,N8,N9|Ns3]) :-
booleans_distinct([N1,N2,N3,N4,N5,N6,N7,N8,N9]),
blocks(Ns1, Ns2, Ns3).
booleans_distinct(Bs) :-
transpose(Bs, Ts),
maplist(card1, Ts).
card1(Bs) :- sat(card([1],Bs)).
row_booleans(Row, Bs) :-
same_length(Row, Bs),
maplist(cell_boolean, Row, Bs).
cell_boolean(Num, Bs) :-
length(Bs, 9),
sat(card([1],Bs)),
element(Num, Bs, 1).
In this formulation, I use 9 Boolean variables to represent which of the 9 possible integers is assigned to a particular cell.Let us apply this formulation to puzzle (b) that is shown in the solution of this exercise:
knuth(b, [[1,_,3,_,5,6,_,8,9],
[5,9,7,3,8,_,6,1,_],
[6,8,_,1,_,9,3,_,5],
[9,5,6,_,3,1,8,_,7],
[_,3,1,5,_,8,9,6,_],
[2,_,8,9,6,_,1,5,3],
[8,_,9,6,_,5,_,3,1],
[_,6,5,_,1,3,2,9,8],
[3,1,_,8,9,_,5,_,6]]).
Here is the result: ?- knuth(b, Rows),
sudoku(Rows),
maplist(portray_clause, Rows).
[1, 2, 3, 4, 5, 6, 7, 8, 9].
[5, 9, 7, 3, 8, 2, 6, 1, 4].
[6, 8, 4, 1, 7, 9, 3, 2, 5].
[9, 5, 6, 2, 3, 1, 8, 4, 7].
[7, 3, 1, 5, 4, 8, 9, 6, 2].
[2, 4, 8, 9, 6, 7, 1, 5, 3].
[8, 7, 9, 6, 2, 5, 4, 3, 1].
[4, 6, 5, 7, 1, 3, 2, 9, 8].
[3, 1, 2, 8, 9, 4, 5, 7, 6].
For comparison, here is the result of the CLP(FD)-based formulation that I posted earlier: ?- knuth(b, Rows),
sudoku(Rows),
maplist(portray_clause, Rows).
[1, _, 3, _, 5, 6, _, 8, 9].
[5, 9, 7, 3, 8, _, 6, 1, _].
[6, 8, _, 1, _, 9, 3, _, 5].
[9, 5, 6, _, 3, 1, 8, _, 7].
[_, 3, 1, 5, _, 8, 9, 6, _].
[2, _, 8, 9, 6, _, 1, 5, 3].
[8, _, 9, 6, _, 5, _, 3, 1].
[_, 6, 5, _, 1, 3, 2, 9, 8].
[3, 1, _, 8, 9, _, 5, _, 6].
This shows that CLP(B), in contrast to CLP(FD), has determined the unique solution without any search. This is an example of a solver that propagates as strongly as possible, and hence achieves global consistency even across different constraints.It also works for puzzle (a):
?- knuth(a, Rows),
sudoku(Rows),
maplist(portray_clause, Rows).
[1, 2, 3, 4, 5, 6, 7, 8, 9].
[5, 9, 8, 7, 2, 1, 4, 3, 6].
[7, 6, 4, 3, 8, 9, 2, 5, 1].
[8, 4, 2, 1, 9, 3, 6, 7, 5].
[9, 7, 5, 2, 6, 4, 8, 1, 3].
[6, 3, 1, 8, 7, 5, 9, 4, 2].
[3, 1, 6, 9, 4, 8, 5, 2, 7].
[4, 5, 7, 6, 3, 2, 1, 9, 8].
[2, 8, 9, 5, 1, 7, 3, 6, 4].
At this point, you may wonder: Why have I started with (b) instead of (a)? The reason is easy to explain: For puzzle (a), the strong propagation of the CLP(B)-based formulation took so long that it only completed now, after I have finished typing this, a few minutes after I had posted the query, whereas it only took a few seconds for example (b).Both examples have taken considerably longer to solve with CLP(B) instead of CLP(FD). That's not to say that one approach is better than the other in general or even in that particular case - instead, it is more an observation about the solver implementations and the chosen trade-offs between propagation strength and efficiency in both solvers.
CLP(B) achieves this strong consistency by internally considering, in a sense, the totality of all possible assignments, and this may require exponential space and hence also time. But for many important practical cases, the representation used by CLP(B) is very efficient, and indeed allows us to solve tough problems efficiently. Note that still, no search is involved here: Even the internal propagation of CLP(B) proceeds completely deterministically, and at no point in the computation do we have to guess anything.
It must also be said that the CLP(FD)-based formulation, in addition to being faster (despite the necessary search), is also shorter and arguably more natural than the Boolean variant. Casting this as an exact cover or hitting set task can definitely be done, either with CLP(B) or CLP(FD) constraints (since Booleans can also be considered as a special case of integers). However, it takes us even further away from the quite direct and readable "natural" CLP(FD) formulation. For cover problems in general, I recommend you obtain a CLP(B) solver that internally uses Zero Suppressed Binary Decision Diagrams (ZDDs). They let you efficiently represent cases where many of the variables (such as row selection indicators) are zero, which is typical for covering tasks.
Re: Esoteric programming paradigms
#148Aurora looks interesting, but it seems to be .Net/windows only?
That must be a different Aurora. The one mentioned here was never really released, only demo'd at Strange Loop. We subsequently went on to turn that into Eve[1]. [1]: http://witheve.com
Re: Esoteric programming paradigms
#149Earlier quoted context omitted.
A nice demo, but still doesn't show examples of a customer going through an example dataset and building dashboards. The kx site is good at talking about all their customers without giving a whole lot of real info. I wish they had a 64-bit hobbyist license.
I don't know about 64-bit but people in prior HN discussions said you can download a free one off their web site. You should be able to extrapolate some things from that. EDIT: https://kx.com/download/