4 ms·
It's somewhat funny that this article seems to miss the very practical rise of functional programming style in JavaScript, especially with the rise of libraries
by Homunculiheaded 15y ago
It's somewhat funny that this article seems to miss the very practical rise of functional programming style in JavaScript, especially with the rise of libraries like underscore.js
Of course JavaScript has some pretty severe limitations as far as functional programming goes, the biggest being really cumbersome lambdas, and a lack of implicit return. If you try to program in a functional style in JavaScript you'll be fighting the language more than you'd like. However both of these issues are remedied in CoffeeScript.
As someone who was a lisper before getting into web development I'm really surprised to see lambdas, closures, pattern matching/de-structuring bind, let statement equivalents and more be part of a language that is not even talked about too much as being lisp-like or functional. Also important is that CoffeeScript's main selling point is that it's practical and more sane then JavaScript, not that it's functional or lisp-like. At the same time CoffeeScript is probably the closest thing I've seen to a (potentially) successful lisp-without-parens
Functional languages will gain serious traction, but I think it will be when their users find their features convenient and helpful (coffeeScript) rather than interesting/mind-blowing/etc (scala, haskell, erlang..)
- davidhollander 15y ago> Also important is that CoffeeScript's main selling point is that it's practical and more sane then JavaScript, not that it's functional or lisp-like. At the same time CoffeeScript is probably the closest thing I've seen to a (potentially) successful lisp-without-parens Have you tried Lua? It has full lexical scoping like Scheme (so you don't have to (function(){})() all over your code to create closures) and has saner built in types than vanilla JS, while also being much faster (around SBCL\Java speed with LuaJIT). I'm writing a basic functional library for it here if you need some stuff like map, foldl, foldr, partial, filter to get started: https://github.com/davidhollander/fn https://github.com/davidhollander/fn
- silentbicycle 15y agoUnfortunately, Lua has statement- rather than expression-oriented semantics (i.e., no "implicit returns"). It's quite nice otherwise, though, and its integration with C is hard to beat. I wrote a library for pattern-matching in Lua, btw (http://github.com/silentbicycle/tamale http://github.com/silentbicycle/tamale). May be of interest.
- davidhollander 15y ago> Unfortunately, Lua has statement- rather than expression-oriented semantics (i.e., no "implicit returns"). This is largely irrelevant for anything related to developing asynchronous services such as web or servers. Asynchronous web development using callbacks is a form of continuation passing style, where control is often explicitly passed using a callback. Since you are explicitly passing control, you usually never have to return values anyway. The 'return' keyword just becomes a bonus feature for convenient error handling. Having a language with good closure support just works phenomenally well for asynchronous web development. For instance, sending an entire message asynchronously can be a pain because it can fail at any point in the message and require restarting at that point and keeping track of when it has finished. It's a piece of cake in Lua though, due to its excellent support for closures: -- SendAll -- Start sending a message on connection [c] -- Close when done. function SendAll(c, msg) local n=0 OnWrite(c, function(c) n=n + c.fd:send(msg, n) if n>=#msg then c.fd:close() return 'close' -- just for kicks end end) end The variable "n" is a counter for the number of bytes sent to the file descriptor "fd". The write callback lambda assigned with OnWrite can always access the appropriate counter "n" based on its creation location. No extra work was needed to create the closure, unlike in languages such as JavaScript.
- anonymoushn 15y agoIn Lua, unlike in JavaScript, you don't need to use closures for async programming most of the time. -- SendAll -- Start sending a message on connection [c] -- Close when done. function SendAll(c, msg) local n=0 while n<#msg do yield() n=n + c.fd:send(msg, n) end c.fd:close() yield('close') -- just for kicks end
- davidhollander 15y agoCoroutines aren't as flexible as continuation passing style and add significant overhead for the non-vital syntactic sugar they give you. I'd much rather explicitly set an OnWrite event that has a one-to-one correspondence to a socket write event from a poll() system call, than create a ton of coroutines and juggle "resumes". This is especially true if you have a usecase where you want to start sending while you are still reading, this would require the creation of 2 coroutines per each context. While Lua coroutines are significantly better than Python generators by having a more functional than syntactical "yield", I still feel it does more harm than good for structuring asynchronous applications.
- mb21 15y agoI think I'm currently in the "I just don't get it camp" when a significant deficit of a language is the lack of implicit returns. Is typing return that bad? I quite like the readability. Is it that you can only return once per function? I already do that, but recognize that some developers don't. If that's part of it then a lot about these languages is to keep the riff-raff out? If that's true then I think we can probably all agree they will never be mainstream since in most cases mainstream == rif-raff.
- Homunculiheaded 15y agoI know this is 10 days late, but the big factor is not whether you type 'return', it's knowing that everybody else has. When you have implicit returns you can always know that a call to a function will return a value, this is essential to proper functional programming technique.
- gaius 15y agoIt's because it makes it harder to prove that a function does one of only two things: returns a known type, or throws and exception. In Python it's legal to have a function that can return 0 or return "hello" or nothing at all.
- mb21 15y agoI don't understand. I can't tell if you are arguing for or against explicit returns. Can you elaborate?
- silentbicycle 15y agoI suspect he read "typing return" as "return having one specific type" (i.e., "return an int (not string, float, etc.)". That's a different (but related) issue.
- silentbicycle 15y agoIt's not about readability or "keeping the riff-raff out". Needing to type "return" itself is a minor detail, but explicit returns are a strong sign of having statement-oriented semantics, rather than expression-oriented semantics. In languages based around statements, things are done for their side-effects. Returning a value is itself a kind of side-effect, hence an explicit return statement. In languages based around expressions (Lisp, ML & Haskell, APL, etc.), the language itself gently encourages side-effect-free programming. In Scheme, for example, you usually use a begin block when you need to do things for their side-effects. While it doesn't prevent side-effects entirely, it does make them stand out, and adds a subtle pressure against their overuse.