Live data from Hacker News

Learn from Haskell - Functional, Reusable JavaScript

seanhess.github.com

1–10 of 50 posts

Re: Learn from Haskell - Functional, Reusable JavaScript

#4
One bit of trouble I have with functional style programming is something like the following example: if I have an array of people with firstName and lastName properties, how would I go about returning the person with the longest full name without adding any properties directly to the objects? It is a simple map then reduce to return the maximum length, a fairly trivial modification thereof to return the full name, but when I want to return the original object, I can't think of a good way to do this.

The best I can figure is first mapping to a nested array where the first element is the object and the second is the computed property but that seems really messy. Thoughts?

Re: Learn from Haskell - Functional, Reusable JavaScript

#5
post #4

One bit of trouble I have with functional style programming is something like the following example: if I have an array of people with firstName and lastName properties, how would I go about returning the person with the longest full name without adding any properties directly to the objects? It is a simple map then reduce to return the maximum length, a fairly trivial modification thereof to return the full name, bu…

You wouldn't use map or reduce, you'd just use recursion with an accumulator.

If you absolutely insist on map/reduce, you can just use reduce, where your binary function returns whichever object has a longer full name.

Re: Learn from Haskell - Functional, Reusable JavaScript

#6
post #4

One bit of trouble I have with functional style programming is something like the following example: if I have an array of people with firstName and lastName properties, how would I go about returning the person with the longest full name without adding any properties directly to the objects? It is a simple map then reduce to return the maximum length, a fairly trivial modification thereof to return the full name, bu…

The map is unnecessary. Just reduce:

    (* assuming: val total_len : string -> int *)

    List.reduce seq ~f:(fun a b ->
      if (total_len a) > (total_len b) then a else b)
It's not necessary in this case, but fold is often a lot more useful than reduce. At least the way I think of it, the type of reduce is 'a list -> ('a -> 'a -> 'a) -> 'a, whereas the type of fold is 'a list -> init:'b -> ('b -> 'a -> 'b) -> 'b. The upside is that you can construct basically any type of thing you'd like, since 'b is a completely different type. The downside is that if 'a is different than 'b, you need some sort of initial value to give it.

edit: Yes, this does require you to compute string length multiple times...but keep in mind that getting string length is very cheap in languages with good strings. (That is, basically everything except C's null-terminated strings.) 99% of the time it's not going not going to matter at all. If you do care, you can map to a tuple of (original_struct,total_len) and then do the reduce and then another map to get back to your original structure, or use a fold, as I mentioned, or write a (tail-)recursive function that does it in slightly fewer operations. (Although I don't think JS has tail-call optimizations, so that's probably a bad idea if you're doing it in JS.)

Re: Learn from Haskell - Functional, Reusable JavaScript

#7
post #4

One bit of trouble I have with functional style programming is something like the following example: if I have an array of people with firstName and lastName properties, how would I go about returning the person with the longest full name without adding any properties directly to the objects? It is a simple map then reduce to return the maximum length, a fairly trivial modification thereof to return the full name, bu…

You wouldn't use map or reduce, you'd just use recursion with an accumulator. If you absolutely insist on map/reduce, you can just use reduce, where your binary function returns whichever object has a longer full name.

In hindsight the second solution was obvious :) But can you explain your ideal solution more? Is it something that can be accomplished in Javascript?

Re: Learn from Haskell - Functional, Reusable JavaScript

#8
post #4

One bit of trouble I have with functional style programming is something like the following example: if I have an array of people with firstName and lastName properties, how would I go about returning the person with the longest full name without adding any properties directly to the objects? It is a simple map then reduce to return the maximum length, a fairly trivial modification thereof to return the full name, bu…

The pattern you mention of using a tuple of key-value pairs is not that bad and it even has a name. The Perl people call it the Swartzian transform.

An alternative if you don't like that would be having the maximum-finding function receive an additional comparator argument, similarly to qsort.

Re: Learn from Haskell - Functional, Reusable JavaScript

#9
post #6
post #4

One bit of trouble I have with functional style programming is something like the following example: if I have an array of people with firstName and lastName properties, how would I go about returning the person with the longest full name without adding any properties directly to the objects? It is a simple map then reduce to return the maximum length, a fairly trivial modification thereof to return the full name, bu…

The map is unnecessary. Just reduce: (* assuming: val total_len : string -> int *) List.reduce seq ~f:(fun a b -> if (total_len a) > (total_len b) then a else b) It's not necessary in this case, but fold is often a lot more useful than reduce . At least the way I think of it, the type of reduce is 'a list -> ('a -> 'a -> 'a) -> 'a , whereas the type of fold is 'a list -> init:'b -> ('b -> 'a -> 'b) -> 'b . The upside…

Aren't I then computing the value of total_len for my largest object numerous times? That was why I went for the map, it made some sense to pre-compute the lengths and then find the largest one. Certainly I could implement some caching mechanism but that would come with some implementation complexity?

Re: Learn from Haskell - Functional, Reusable JavaScript

#10
post #4

One bit of trouble I have with functional style programming is something like the following example: if I have an array of people with firstName and lastName properties, how would I go about returning the person with the longest full name without adding any properties directly to the objects? It is a simple map then reduce to return the maximum length, a fairly trivial modification thereof to return the full name, bu…

You don't need a map, just a reduce (foldl, really). Using underscore, no double calculation:

    _.reduce(arr, function(p1, p2) {
        var len = p2.firstName.length + p2.lastName.length;
        return (len > p1[1]) ? [p2, len] : p1;  
    }, 
    [null, -1]);
Post reply on HN