Joel can your language do this




















Jeez, that is handy. As soon as you start thinking in terms of anonymous functions as arguments, you might notice code all over the place that, say, does something to every element of an array. Doing something to every element of an array is pretty common, and you can write a function that does it for you:. Many older languages simply had no way to do this kind of stuff.

Java required you to create a whole object with a single method called a functor if you wanted to treat a function like a first class object. Combine that with the fact that many OO languages want you to create a whole file for each class, and it gets really klunky fast. See if you can get some of your money back.

How much benefit do you really get out of writting itty bitty functions that do nothing more than iterate through an array doing something to each element? You can run through the array forward or backwards and get the same result, right? It's more like "abstracting away the details". When people talk of the benefits of some practice or programming paradigm, they don't always mention all the work going into it - they just explain the concept.

That's what a good teacher does, IMO. He takes complex concepts and explains the important parts. You are of course correct. I have corrected the parent post. My point is, though, that you almost can't define anonymous functions in Python, either, but you can do nearly all of these clever patterns.

The difference is that Python functions are closures. I agree that that's what a good teacher does, but I don't see this article as doing that. Anonymous inner classes in Java actually are closures. The compiler will force you to declare any closed-over local variables as final. Like everything else in Java, it's verbose but it works.

The problems with using closures in Java is that the type system doesn't play well with function objects and that the standard library doesn't care about functional programming, and it's really only the former that is stopping you from functional programming in Java.

Notice that you need different data structures. You have much less need of these higher level language constructs if the compiler is doing it for you under the hood!

You're missing it. Here's what Joel is saying without saying it: C 4 is "that language. Both his companies are built on the MS stack. Given that the article is from that'd be some prescient writing. Also at the time of this article they had their own custom language Wasabi. While you need a lot of syntactic bullshit to get there, Java does have closures.

Java is just not very conducive to exploratory programming. I think it might be important to note that while the terms map and reduce do come from Lisp, they're not one-to-one with what these functions do in Lisp.

The original MapReduce paper mentions the borrowing, but doesn't really go into specifics. I liked this paper much better and found it the most informative functional explanation to MapReduce note, it's in Haskell. I think MapReduce is really part of a more general pattern where you have an in more Haskell-y terms unfold anamorphism to a foldr catamorphism. It's pretty cool stuff, and really not that complicated when you sit down and think about it. I wish I could upvote you more.

I have never looked into Google's "MapReduce" but if what you say is true then my assumptions on it were completely wrong. I assumed it was with map and reduce. But if it is generating a set of unfolds into 'essentially' fold is it? I only skimmed the first pages due to time then that is a very important detail and makes the name a bit of a misnomer.

Why don't people make a bigger deal about this - unfold, fold is not harder but it requires a different mindset and approach than map fold. This article shows that Javascript is truly the common man's functional programming language. As right as you can get them in an imperative programming language, perhaps, but the semantics of closing over environments containing mutable variables is still confusing to even the smartest of people cf.

SomeCallMeTim on April 23, root parent next [—]. Lua's ability to bind a closure to a mutable variable is a very powerful ability that I use all the time. It WILL create a new instance of the mutable "j" each time "local j" is executed, though, so if the above code is in a function or another block that's executed more than once, then each time those functions will be bound to a new "j". EDIT: Get the code markup right. It is one out of at least two possible semantics. Harmony's new for in construct implicitly introduces a fresh let binding per iteration, yes, but it doesn't fundamentally change the language semantics with regard to the kind of example Eich mentions.

So while one can, in Harmony, write code that behaves in the way that people like Andrej Bauer expect, it doesn't mean that the language's closure semantics have suddenly changed.

It's also hard for me to see how one could have a 'definitive' semantics without having at least one alternative—not that I claimed that either JS's closure semantics were the only ones going. Presumably the alternative you mean is where the variables present in the local environment are copied on creation of a closure.

I'd also resist the idea that I claimed that JavaScript's closure semantics were in some way definitive, although I can see how one might infer that from what I did write. That being said, given the potential problems with the alternative, I would claim that they're a reasonable choice.

Yes, but what are the issues with fresh let-bindings per iteration? No, that's bad -- it leaves you unable to show that objects with mutable state are reducible to closures. JonnieCache on April 23, prev next [—]. Something that I only realised the other day which made me feel kinda embarrassed: in ruby, the reduce method is called inject. For years I've been doing MapReduce functions, without realising it.

MapReduce was in my mental pile of "genius things that cleverer people than me do, must be looked into when there is time. SandB0x on April 23, parent next [—]. In Ruby the reduce method is also called reduce: [1,2,3]. JonnieCache on April 23, root parent next [—]. Reduce is an alias for inject, and depending on which template you use to generate the docs, method aliases are not given the same prominence as full methods.

Some templates simply say "this method is also known as If it were the other way around, and inject was an alias for reduce, I think there would be a lot less confused rubyists. DanielRibeiro on April 23, root parent prev next [—]. Peaker on April 23, root parent prev next [—]. What would it do on an empty list? It should probably take an argument for the empty case What is the history behind the name "inject" here?

The name comes from Smalltalk. By default, inject uses the first element of the array as the argument, so it would use nil on an empty list. It optionally takes an argument to kick off the process. Most likely Ruby takes the name inject from Smalltalk. Smalltalk also uses 'collect' for map, 'select' for filter, 'reject' for an inverse filter. Thank you for pointing out the history! The names inject, collect, select, and reject drive me crazy for some reason.

Maybe it's because they rhyme. At least now I know. Thanks you for your nice words. It probably leads to idiomatically awful Java, but I find it easier to read and write, and nobody else needs to deal with my code. Yup, any language I've worked with, including Java and C, can do that just fine. They just spread the verbosity differently. Organizing large projects is a pain in JavaScript, trivial in Java. Using anonymous functions is a pain in Java, trivial in JavaScript. He gives reduce as an example of "purely functional programs have no side effects and are thus trivially parallelizable.

It is when your reduce operation is associative. Example: sum, or less trivially merge sort. Zaak on April 23, parent prev next [—]. Reduce is trivially parallelizable if you can ensure your operation is associative, but you have to work in languages like Epigram and Agda to guarantee that.

No, you just have to make sure the function you pass is associative. Or, slightly more generally, that the order of reduction is unspecified; in which case only an associative function will produce a totally deterministic result.

Zaak on April 23, root parent prev next [—]. Good point. On a related note, I would like to see a "perverse" compiler and library which exhibits random behavior when undefined behavior is specified by the language. Has anyone else just read this and realised they need to go off an learn some form of functional programming?

I ignored it for such a long time because I felt it wasn't relevant to my current situation but I was wrong. You gain some incredible fundamental knowledge that you would otherwise be completely oblivious to. Is lisp really the way to go though? I would recommend Haskell over Lisp, because Haskell will force you to do functional programming, where-as Lisp is less rigid in that regard. Had about 4 false starts and didn't "get" it until my 5th attempt, at which point I figured out what the type system meant and had a bit of a Matrix "I know kung fu!

You may also have luck learning FP with Erlang. It's also functional, but approaches it from a different direction, focusing on reliability and concurrency rather than types and purity. Between Haskell and Erlang, one of them will probably fit your mind better. I started FP with OCaml, but OCaml makes it too easy to continue writing imperative code when you're actively trying to learn new idioms. I agree Erlang is also very interesting. I think some of the features looks absolutely fascinating hot updatable code!

I just haven't found the the time to learn it yet. And with Wasabi, they can add any language features they want! Just like Lisp, right?

And eventually they'll plug in a. Never mind the fact that your company's flagship application is still written in a freaky custom language based on VBScript that only three people in the world know how to program. But wait!

It gets worse! Now Joel says that a dynamically typed language like Ruby can't possibly be fast enough to run FogBugz : I understand the philosophy that developer cycles are more important than cpu cycles, but frankly that's just a bumper-sticker slogan and not fair to the people who are complaining about performance.

Even though our product, FogBugz, seems like something that should be perfect for Ruby on Rails, we have several parts of code where performance is extremely important. In FogBugz 6 there's one place where we need to do literally millions of calculations to display a single chart on a single web page. We have gotten it down to 3 seconds or so in our current development environment with a lot of optimization, but frankly with a duck-typed function call I really don't think we could do it before the web browser gave up and timed out and the sun cooled down a couple of degrees.

Let me get this straight. Let me make sure I'm understanding this. Because I think I've gone crosseyed.



0コメント

  • 1000 / 1000