6 ms·
"This function calculates the minimum of a list of numbers, and subtracts every number in the list by that minimum. This function currently iterates over the li
by bbminner 2y ago
"This function calculates the minimum of a list of numbers, and subtracts every number in the list by that minimum. This function currently iterates over the list twice; once to calculate the minimum, and once to do the subtraction. At a first glance, it looks like there is no way to merge these two loops, because you need to calculate the minimum of all the numbers before you can subtract from any of them. As it turns out, this is possible, using the inverse operator."
https://vine.dev/docs/features/inverse https://vine.dev/docs/features/inverse
I was long curious about interaction nets. Can someone confirm if Vine will automagically derive an algorithm for doing this with a single pass or it will do one pass in "forward mode", but once the minimum is resolved, follow it up with a second implicit "book keeping and variable re-resolution pass" that will be equivalent to an actual full second pass you'd get in an imperative language?
It is all very much reminiscent of programming in tensorflow 0.x.
- tjjfvi 2y ago> it will do one pass in "forward mode", but once the minimum is resolved, follow it up with a second implicit "book keeping and variable re-resolution pass" that will be equivalent to an actual full second pass you'd get in an imperative language Yes, this is correct. Though it's worth noting that this is not some transformation being done by the compiler, but an emergent property of the interaction net.
- chc4 2y agoThat's a very cute feature! Thinking about it in terms of thunks makes it pretty understandable to me.
- bbminner 2y agoYes, thunks with sugar is my thinking as well. Does not explain the "last unassignment" examples though. I don't quite understand why it's needed though :)
- anonzzzies 2y agoI was thinking it must be possible to do something semantically similar in Prolog: find_min_and_subtract([H], [R], Min) :- Min = H, R is H - Min. find_min_and_subtract([H|T], [R|Rs], Min) :- find_min_and_subtract(T, Rs, TailMin), (H < TailMin -> Min = H ; Min = TailMin), R is H - Min,!. Which [9,4,12,2] -> [7, 2, 10, 0]. But this doesn't work for all cases anyway (just the ones where the last value is also the minimum). I feel it can be fully expressed in one pass with miniKanren instead but no time to figure that out now; it can defer the arithmetic by setting up constraints. Always liked the idea of 'using variables in the past' (or creating them in the future) and the first amazement moment was with Prolog (there were quite a lot of wow! moments in Prolog for the young me who only knew basic, pascal & c, like when you have some 'write multiply in prolog', when you deliver f(x,y)=x*y, you can not only do f(2,3) and get 6, but also f(2,y)=6 and get y=3), but, so it made me think of it.
- ngruhn 2y agoProlog also has constraints! You need to import a library called CLP(FD) / CLP(Z) (depending on the Prolog system) and instead of =, <, =<, etc. you need to use #=, #<, #=<, etc. :- use_module(library(clpfd)). min(Min, Y, Min) :- Min #=< Y, !. min(X, Min, Min) :- Min #=< X. find_min_and_subtract_([], [], Min, Min). find_min_and_subtract_([H|T], [R|Rs], TempMin, Min) :- min(TempMin, H, NewTempMin), R #= H - Min, find_min_and_subtract_(T, Rs, NewTempMin, Min). find_min_and_subtract([H|Hs], Rs, Min) :- find_min_and_subtract_([H|Hs], Rs, H, Min). With that (and an additional variable for the temporary minimum) it works for me: ?- find_min_and_subtract([9,2,4,12], Rs, Min). Min = 2, Rs = [7, 0, 2, 10] https://swish.swi-prolog.org/p/qgchfMfB.pl https://swish.swi-prolog.org/p/qgchfMfB.pl
- anonzzzies 2y agoOW! Thanks, I did not know about that. Last I user Prolog was mid 90s, but I really liked it, just did not have any practical use for it after graduation. Thanks for that!
- forgotpwd16 2y agoReading this page made me feel same way when was watching Tenet.
- stuhood 2y agoI think that `inverting` also subsumes async functions/values, which is pretty neat! In the case where asynchrony was actually necessary, it seems like a great alternative to function coloring. But whether you should actually use it for something like their `sub_min` example is highly dependent on how good the performance of their implementation is. Creating a graph of references rather than making two passes over an array of integers is not clearly faster ... or clearer, for that matter.
- jmholla 2y agoI'm a bit confused. How does this not end up as two for loops behind the scenes? The inverse operator still has to be applied to every member after the initial iteration. Or am I missing something?