4 ms·
No ifs…alternatives to statement branching in JavaScript
- donpdonp 16y agoAn alternative to 'if' that I like but havent seriously used before is <expression>.true? {block}. an example in ruby: (3==3).true?{'Yes'} => "Yes" (4==4).true?{'Yes'} => nil using this implementation: class Object def true? yield end end class FalseClass def true? end end class NilClass def true? end end
- Xuzz 16y agoSort of like how Smalltalk replaces 'if' statements with ifTrue: messages?
- danudey 16y agoI'm only familiar with Ruby syntax, and not 100% fluent in it, but it seems to me like this kind of shortcut could make your code much less readable for not a whole lot of gain. I'm curious what the major benefit is over doing it 'the old fashioned way'.
- jules 16y agoI thought this was going to be about booleans from nothing at all: true = function(x,y){ return x; } false = function(x,y){ return y; } ifelse = function(x,a,b){ x(a,b)(); } not = function(x){ return x(false,true); } and = function(x,y){ return x(y,false); } or = function(x,y){ return x(true,y); } bool = and(not(true),or(true,false)) ifelse(bool, function(){ alert("true!") }, function(){ alert("false!") } ) Amazing, isn't it? It gets better. Pairs: pair = function(x,y){ return function(f){ return f(x,y); } } fst = function(p){ return p(function(x,y){ return x; }); } snd = function(p){ return p(function(x,y){ return y; }); } Unions: left = function(x){ return function(f,g){ return f(x); } } right = function(x){ return function(f,g){ return g(x); } } Pairs combined with unions make lists: cons = function(x,y){ return left(pair(x,y)); } head = function(l){ return l(function(p){ return fst(p); }, function(n){ alert("Can't take head of nil"); }) } tail = function(l){ return l(function(p){ return snd(p); }, function(n){ alert("Can't take tail of nil"); }) } nil = right(false) isnil = function(l){ return l(function(p){ return false; }, function(n){ return true; }) } map = function(f,l){ return ifelse(isnil(l), function(){ return nil; }, function(){ return cons(f(head(l)),map(f,tail(l))); }) } filter = function(f,l){ return ifelse(isnil(l), function(){ return nil; }, function(){ return ifelse(f(head(l)), function(){ return cons(head(l),filter(f,tail(l))); }, function(){ return filter(f,tail(l)); }) }); } Isn't it neat how you can build everything, including conditionals, booleans, pairs and lists from functions? Note that this code was not tested in any way, so it likely contains bugs.
- freyrs3 16y agoYou really can build everything out of anonymous functions, including all of arithmetic: zero = function(x,y){ return y; } succ = function (f) { return function (x) {return f(n(f(x)));};} one = succ(zero); two = succ(one); Look up lambda calculus if anyone is interested.
- jules 16y agoThe only problem then is, how do you do pred the inverse of succ? ;)
- mathgladiator 16y agoThe same way you build the integers. Built it out of pairs. a --> (a,0) -a --> (0,a) succ((a,0)) = (a+1,0) pred((a,0)) = (a,0+1)
- mathgladiator 16y agovia something like: http://news.ycombinator.com/item?id=2030649 http://news.ycombinator.com/item?id=2030649
- freyrs3 16y agoYou need to construct integers with a tuple type, in lambda calculus its: pair = λ x. λ y. λ z. x. y. z Or if you are willing to let pred(0) = 0 then you can use: pred = λ x. λy. λ z. x . (λ i. λ j. j. i. y (λ k. z) (λ k. k)
- mathgladiator 16y agoI recommend the Numbers Book ( http://www.amazon.com/Numbers-Graduate-Texts-Mathematics-Readings/dp/0387974970 http://www.amazon.com/Numbers-Graduate-Texts-Mathematics-Rea... ): I just did a construction of the integers assuming either sets or arrays. I could equally have used your list definition. http://pastie.org/1397123 http://pastie.org/1397123 and http://news.ycombinator.com/item?id=2030649 http://news.ycombinator.com/item?id=2030649 I've very tempted to combine your work with this and then go on to define rationals and then the reals. The reals would be very interesting since it would be a sequence that takes an epsilon and gets a rational number that is close enough. It's kind of crazy to think that all these real numbers are infinite cauchy sequences. If I define a real as function(eps) { return some_rational; } then I could define it piece_wise and say function mult_real(a,b) { return function(eps) { return a(eps/2) * b(eps/2); } }
- telemachos 16y agoA previous round of comments: http://news.ycombinator.com/item?id=1581830 http://news.ycombinator.com/item?id=1581830
- deleted 16y ago[deleted]
- jvoorhis 16y agoThis seems to boil down to a preference for expressions over statements. It's easier to reason about the meaning of a value than a listing of commands, and more insightful to recombine subexpressions to make values than to recombine statements to get side-effects and void.
- johnthedebs 16y agoIt's worth noting that these techniques also work in other languages - I've been doing this more and more often in the Python code I write. If you aren't used to it, it looks a bit unusual (of course) but it makes for much cleaner, and therefore more maintainable, code.