Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #32193 > unrolled thread

Functional Programming needs some real world use cases

Started byjustaguy <lichunshen84@gmail.com>
First post2017-01-18 20:09 -0800
Last post2017-01-20 05:02 +0000
Articles 20 — 6 participants

Back to article view | Back to comp.lang.javascript


Contents

  Functional Programming needs some real world use cases justaguy <lichunshen84@gmail.com> - 2017-01-18 20:09 -0800
    Re: Functional Programming needs some real world use cases Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-19 20:10 +0000
      Re: Functional Programming needs some real world use cases Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2017-01-19 21:16 +0100
        Re: Functional Programming needs some real world use cases Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-19 21:24 +0000
      Re: Functional Programming needs some real world use cases justaguy <lichunshen84@gmail.com> - 2017-01-19 12:34 -0800
        Re: Functional Programming needs some real world use cases justaguy <lichunshen84@gmail.com> - 2017-01-19 12:41 -0800
          Re: Functional Programming needs some real world use cases justaguy <lichunshen84@gmail.com> - 2017-01-19 13:01 -0800
            Re: Functional Programming needs some real world use cases justaguy <lichunshen84@gmail.com> - 2017-01-19 17:26 -0800
      Re: Functional Programming needs some real world use cases Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-19 21:23 +0000
        Re: Functional Programming needs some real world use cases Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-19 21:50 +0000
      Re: [Firefox]"print" Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2017-01-24 01:52 +0100
        Re: [Firefox]"print" Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2017-01-24 05:45 +0100
    Re: Functional Programming needs some real world use cases Scott Sauyet <scott@sauyet.com> - 2017-01-20 04:28 +0000
      Re: Functional Programming needs some real world use cases justaguy <lichunshen84@gmail.com> - 2017-01-19 21:18 -0800
      Re: Functional Programming needs some real world use cases John Harris <niam@jghnorth.org.uk.invalid> - 2017-01-20 10:22 +0000
        Re: Functional Programming needs some real world use cases Scott Sauyet <scott@sauyet.com> - 2017-01-21 01:29 +0000
      Re: Functional Programming needs some real world use cases Scott Sauyet <scott@sauyet.com> - 2017-01-21 01:15 +0000
      Re: Functional Programming needs some real world use cases "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2017-01-21 15:00 -0800
    Re: Functional Programming needs some real world use cases Scott Sauyet <scott@sauyet.com> - 2017-01-20 05:00 +0000
    Re: Functional Programming needs some real world use cases Scott Sauyet <scott@sauyet.com> - 2017-01-20 05:02 +0000

#32193 — Functional Programming needs some real world use cases

Fromjustaguy <lichunshen84@gmail.com>
Date2017-01-18 20:09 -0800
SubjectFunctional Programming needs some real world use cases
Message-ID<8b2dc802-a0d2-4ae0-ba75-98ecf5989e64@googlegroups.com>
Hi,

I'm starting to read about Functional Programming.  The following is some sample code, which seems concise.  In the meantime, I wonder if you have some idea of using other "action" other than "print", and of course, feel free to use other array "values" where appropriate.  

function forEach(array, action) {
  for (var i = 0; i < array.length; i++)
    action(array[i]);
}

forEach(["Wampeter", "Foma", "Granfalloon"], print);


Thanks.

[toc] | [next] | [standalone]


#32198

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-01-19 20:10 +0000
Message-ID<87bmv2erpx.fsf@bsb.me.uk>
In reply to#32193
justaguy <lichunshen84@gmail.com> writes:

> I'm starting to read about Functional Programming.  The following is
> some sample code, which seems concise.  In the meantime, I wonder if
> you have some idea of using other "action" other than "print", and of
> course, feel free to use other array "values" where appropriate.
>
> function forEach(array, action) {
>   for (var i = 0; i < array.length; i++)
>     action(array[i]);
> }
>
> forEach(["Wampeter", "Foma", "Granfalloon"], print);

As an exercise, what expression can you write in place of "..." to print
all seven strings (and just those):

  forEach([["a","b","c"],["q","r"],["z"]], ...);

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#32199

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2017-01-19 21:16 +0100
Message-ID<3131945.LM0AJKV5NW@PointedEars.de>
In reply to#32198
Ben Bacarisse wrote:

> justaguy <lichunshen84@gmail.com> writes:
>> function forEach(array, action) {
>>   for (var i = 0; i < array.length; i++)
>>     action(array[i]);
>> }
>>
>> forEach(["Wampeter", "Foma", "Granfalloon"], print);
> 
> As an exercise, what expression can you write in place of "..." to print
> all seven strings (and just those):
> 
>   forEach([["a","b","c"],["q","r"],["z"]], ...);

Seven?

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#32207

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-01-19 21:24 +0000
Message-ID<87r33yd9pp.fsf@bsb.me.uk>
In reply to#32199
Thomas 'PointedEars' Lahn <PointedEars@web.de> writes:

> Ben Bacarisse wrote:
>
>> justaguy <lichunshen84@gmail.com> writes:
>>> function forEach(array, action) {
>>>   for (var i = 0; i < array.length; i++)
>>>     action(array[i]);
>>> }
>>>
>>> forEach(["Wampeter", "Foma", "Granfalloon"], print);
>> 
>> As an exercise, what expression can you write in place of "..." to print
>> all seven strings (and just those):
>> 
>>   forEach([["a","b","c"],["q","r"],["z"]], ...);
>
> Seven?

Thanks, I meant six.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#32201

Fromjustaguy <lichunshen84@gmail.com>
Date2017-01-19 12:34 -0800
Message-ID<6b8d9806-b427-4b74-b74f-b582cf1ceba1@googlegroups.com>
In reply to#32198
On Thursday, January 19, 2017 at 3:10:25 PM UTC-5, Ben Bacarisse wrote:
> justaguy writes:
> 
> > I'm starting to read about Functional Programming.  The following is
> > some sample code, which seems concise.  In the meantime, I wonder if
> > you have some idea of using other "action" other than "print", and of
> > course, feel free to use other array "values" where appropriate.
> >
> > function forEach(array, action) {
> >   for (var i = 0; i < array.length; i++)
> >     action(array[i]);
> > }
> >
> > forEach(["Wampeter", "Foma", "Granfalloon"], print);
> 
> As an exercise, what expression can you write in place of "..." to print
> all seven strings (and just those):
> 
>   forEach([["a","b","c"],["q","r"],["z"]], ...);
> 
> -- 
> Ben.

console.log

you have three arrays inside an array

[toc] | [prev] | [next] | [standalone]


#32203

Fromjustaguy <lichunshen84@gmail.com>
Date2017-01-19 12:41 -0800
Message-ID<a8be0d39-6f93-4051-9fc9-1827446a02d0@googlegroups.com>
In reply to#32201
On Thursday, January 19, 2017 at 3:35:09 PM UTC-5, justaguy wrote:
> On Thursday, January 19, 2017 at 3:10:25 PM UTC-5, Ben Bacarisse wrote:
> > justaguy writes:
> > 
> > > I'm starting to read about Functional Programming.  The following is
> > > some sample code, which seems concise.  In the meantime, I wonder if
> > > you have some idea of using other "action" other than "print", and of
> > > course, feel free to use other array "values" where appropriate.
> > >
> > > function forEach(array, action) {
> > >   for (var i = 0; i < array.length; i++)
> > >     action(array[i]);
> > > }
> > >
> > > forEach(["Wampeter", "Foma", "Granfalloon"], print);
> > 
> > As an exercise, what expression can you write in place of "..." to print
> > all seven strings (and just those):
> > 
> >   forEach([["a","b","c"],["q","r"],["z"]], ...);
> > 
> > -- 
> > Ben.
> 
> console.log
> 
> you have three arrays inside an array

console.log is another action, that does not solve your problem. Yours seems tricky.

[toc] | [prev] | [next] | [standalone]


#32205

Fromjustaguy <lichunshen84@gmail.com>
Date2017-01-19 13:01 -0800
Message-ID<dd1317b4-8b1e-4594-bb85-6834f47d477c@googlegroups.com>
In reply to#32203
On Thursday, January 19, 2017 at 3:41:27 PM UTC-5, justaguy wrote:
> On Thursday, January 19, 2017 at 3:35:09 PM UTC-5, justaguy wrote:
> > On Thursday, January 19, 2017 at 3:10:25 PM UTC-5, Ben Bacarisse wrote:
> > > justaguy writes:
> > > 
> > > > I'm starting to read about Functional Programming.  The following is
> > > > some sample code, which seems concise.  In the meantime, I wonder if
> > > > you have some idea of using other "action" other than "print", and of
> > > > course, feel free to use other array "values" where appropriate.
> > > >
> > > > function forEach(array, action) {
> > > >   for (var i = 0; i < array.length; i++)
> > > >     action(array[i]);
> > > > }
> > > >
> > > > forEach(["Wampeter", "Foma", "Granfalloon"], print);
> > > 
> > > As an exercise, what expression can you write in place of "..." to print
> > > all seven strings (and just those):
> > > 
> > >   forEach([["a","b","c"],["q","r"],["z"]], ...);
> > > 
> > > -- 
> > > Ben.
> > 
> > console.log
> > 
> > you have three arrays inside an array
> 
> console.log is another action, that does not solve your problem. Yours seems tricky.


function forEach(array, action) { 
  for (var i = 0; i < array.length; i++) 
	// if (Array.isArray(i)) {
	if ( i === Array ) {
		 for (var i2 = 0; i2 < i.length; i2++)
		 action(i[i2]); 
		}	 
	else {
		action(array[i]); 
	}
} 

I'm a bit puzzled, the above code executes the else portion for 
[["a","b","c"],["q","r"],["z"]] data

Probably we should stick with the original code but use another "action", but what's that?  Thanks.

[toc] | [prev] | [next] | [standalone]


#32212

Fromjustaguy <lichunshen84@gmail.com>
Date2017-01-19 17:26 -0800
Message-ID<2904795a-c86f-4a52-be28-e4f7bb8efbfe@googlegroups.com>
In reply to#32205
On Thursday, January 19, 2017 at 4:01:31 PM UTC-5, justaguy wrote:
> On Thursday, January 19, 2017 at 3:41:27 PM UTC-5, justaguy wrote:
> > On Thursday, January 19, 2017 at 3:35:09 PM UTC-5, justaguy wrote:
> > > On Thursday, January 19, 2017 at 3:10:25 PM UTC-5, Ben Bacarisse wrote:
> > > > justaguy writes:
> > > > 
> > > > > I'm starting to read about Functional Programming.  The following is
> > > > > some sample code, which seems concise.  In the meantime, I wonder if
> > > > > you have some idea of using other "action" other than "print", and of
> > > > > course, feel free to use other array "values" where appropriate.
> > > > >
> > > > > function forEach(array, action) {
> > > > >   for (var i = 0; i < array.length; i++)
> > > > >     action(array[i]);
> > > > > }
> > > > >
> > > > > forEach(["Wampeter", "Foma", "Granfalloon"], print);
> > > > 
> > > > As an exercise, what expression can you write in place of "..." to print
> > > > all seven strings (and just those):
> > > > 
> > > >   forEach([["a","b","c"],["q","r"],["z"]], ...);
> > > > 
> > > > -- 
> > > > Ben.
> > > 
> > > console.log
> > > 
> > > you have three arrays inside an array
> > 
> > console.log is another action, that does not solve your problem. Yours seems tricky.
> 
> 
> function forEach(array, action) { 
>   for (var i = 0; i < array.length; i++) 
> 	// if (Array.isArray(i)) {
> 	if ( i === Array ) {
> 		 for (var i2 = 0; i2 < i.length; i2++)
> 		 action(i[i2]); 
> 		}	 
> 	else {
> 		action(array[i]); 
> 	}
> } 
> 
> I'm a bit puzzled, the above code executes the else portion for 
> [["a","b","c"],["q","r"],["z"]] data
> 
> Probably we should stick with the original code but use another "action", > but what's that?  Thanks.

function forEach(array, action) { 
  for (var i = 0; i < array.length; i++) 
	action(array[i]); 
	// if (Array.isArray(i)) {
	/*
	if ( i === Array ) {
		 for (var i2 = 0; i2 < i.length; i2++)
		 action(i[i2]); 
		}	 
	else {
		action(array[i]); 
	}
	*/
	} 
	
	var recurse = function (i) {
	if ( i === Array ) {
			 for (var i2 = 0; i2 < i.length; i2++)
			 // print(i[i2]); 
			 // console.log('element is array:' + i[i2]);
			 return document.getElementById('output').innerHTML += 'element is array:' + i[i2] + ',';
			}	 
		else {
			// print([i]); 
			return document.getElementById('output').innerHTML += [i] + ',';
		}	
	}	
	

caller = forEach([["a","b","c"],["q","r"],["z"]], recurse);

it puts a, b, c, q, r, z on the page.  Hmm, I'll see if I can manage to get the browser print function in as well later ...
 

[toc] | [prev] | [next] | [standalone]


#32206

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-01-19 21:23 +0000
Message-ID<87ziimd9rr.fsf@bsb.me.uk>
In reply to#32198
ram@zedat.fu-berlin.de (Stefan Ram) writes:

> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>As an exercise, what expression can you write in place of "..." to print
>>all seven strings (and just those):
>>forEach([["a","b","c"],["q","r"],["z"]], ...);
>
>   Ok, the easy part is:

Why would you post the answer to an exercise?

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#32209

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-01-19 21:50 +0000
Message-ID<87lgu6d8hv.fsf@bsb.me.uk>
In reply to#32206
ram@zedat.fu-berlin.de (Stefan Ram) writes:

> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>ram@zedat.fu-berlin.de (Stefan Ram) writes:
>>>Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>>>As an exercise, what expression can you write in place of "..." to print
>>>>all seven strings (and just those):
>>>>forEach([["a","b","c"],["q","r"],["z"]], ...);
>>>Ok, the easy part is:
>>Why would you post the answer to an exercise?
>
>   If it was an exercise made especially for justaguy:
>   He does not seem to have read my answer.
>
>   Otherwise, if it was an exercise made for everybody:
>   Then it would have been appropriate for me to answer.

Anyone who posts an answer should add a spoiler alert (unless some
significant time has elapsed).  I should have said "why post the answer
to an exercise without a spoiler alert or some obfuscation".  You can
post answers all you like, but it does not help others if they see them
immediately.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#32283 — Re: [Firefox]"print"

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2017-01-24 01:52 +0100
SubjectRe: [Firefox]"print"
Message-ID<42447262.MN2xkq1pzW@PointedEars.de>
In reply to#32198
Stefan Ram kept talking to himself:

> ram@zedat.fu-berlin.de (Stefan Ram) writes:
>> Let's look at the property:
>> Object.getOwnPropertyDescriptor( this, print )
>> undefined
> 
>   Ok, I should have written:
> 
> Object.getOwnPropertyDescriptor( this, "print" )

“print” in Mozilla JavaScript is still something else than
“this.print” (in global browser context equivalent to “window.print”):

| $ dpkg -l libmozjs-24-bin | grep ^.i
| ii  libmozjs-24-bin 24.2.0-2     amd64       Spidermonkey JavaScript shell
| 
| $ dpkg -L libmozjs-24-bin 
| /.
| /usr
| /usr/bin
| /usr/bin/js24
| /usr/share
| /usr/share/doc
| /usr/share/doc/libmozjs-24-bin
| /usr/share/doc/libmozjs-24-bin/changelog.Debian.gz
| /usr/share/doc/libmozjs-24-bin/copyright 
| 
| $ js24
| js> help(print);
| JavaScript-C24.2.0
| print([exp ...])
|   Evaluate and print expressions to stdout.
| js> 

By contrast,

| $ js --help | head -n 1
| Usage: node [options] [ -e script | script.js ] [arguments] 
| 
| $ js -v
| v0.10.38

Node.js 0.10.38, …

| $ js -e 'console.log(process.versions.v8);'
| 3.14.5.8

based on Google V8 JavaScript 3.14.5.8):

| $ js -e 'print(42);'
| 
| [eval]:1
| print(42);
| ^
| ReferenceError: print is not defined
|     at [eval]:1:1
|     at Object.<anonymous> ([eval]-wrapper:6:22)
|     at Module._compile (module.js:456:26)
|     at evalScript (node.js:536:25)
|     at startup (node.js:80:7)
|     at node.js:906:3

So this has nothing to do with Firefox and its Web Console, everything with 
the ECMAScript implementation (provided by the Gecko layout engine) that is 
used by it.

It is most obvious in the result of what you have *not* tried so far:

,-[Iceweasel 38.1.0 Web Console]
| 
| 01:28:04.562 > print();
| 01:28:04.569 < "undefined"
| 01:28:09.221 > print
| 01:28:09.230 < function JSTH_print()
| 01:28:16.522 > this.print
| 01:28:16.538 < function print()
| 01:31:00.768 > window.print
| 01:31:00.775 < function print()
| 01:31:13.967 > this.print === window.print
| 01:31:13.974 < true
| 01:31:49.429 > print(42);
| 01:31:49.436 < "42"

(Exercise: Try the same in Chromium or Chrome.)

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#32291 — Re: [Firefox]"print"

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2017-01-24 05:45 +0100
SubjectRe: [Firefox]"print"
Message-ID<2500325.yaVYbkx8dN@PointedEars.de>
In reply to#32283
Thomas 'PointedEars' Lahn wrote:

> ,-[Iceweasel 38.1.0 Web Console]
> | 
> | 01:28:04.562 > print();
> | 01:28:04.569 < "undefined"
> | 01:28:09.221 > print
> | 01:28:09.230 < function JSTH_print()
> | 01:28:16.522 > this.print
> | 01:28:16.538 < function print()
> | 01:31:00.768 > window.print
> | 01:31:00.775 < function print()
> | 01:31:13.967 > this.print === window.print
> | 01:31:13.974 < true
> | 01:31:49.429 > print(42);
> | 01:31:49.436 < "42"
> 
> (Exercise: Try the same in Chromium or Chrome. […]

… What happens and why does it happen?)

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#32213

FromScott Sauyet <scott@sauyet.com>
Date2017-01-20 04:28 +0000
Message-ID<o5s3l1$ahq$1@dont-email.me>
In reply to#32193
justaguy wrote:

> I'm starting to read about Functional Programming.  The following is
> some sample code, which seems concise.  

Concise, even elegant, code is one of the hallmarks of functional 
programming.  But I would suggest that you don't seek it as an initial 
goal.  Look to other main facets: immutability, referential transparency, 
systems built by composing smaller functions.

As you learn functional techniques, concise code will likely emerge on 
its own.


> In the meantime, I wonder if you
> have some idea of using other "action" other than "print", and of
> course, feel free to use other array "values" where appropriate.
> 
> function forEach(array, action) {
>   for (var i = 0; i < array.length; i++)
>     action(array[i]);
> }
> 
> forEach(["Wampeter", "Foma", "Granfalloon"], print);


`forEach` is not really an example of functional programming.  One of the 
key tenets of functional programming is that code must be referentially 
transparent.  This means that any expression could be replaced with its 
value with no change to the behavior of the system.  For functions this 
means that they must be *pure* (their results must depend only on their 
parameters) and that they must have no side effects (all they can do is 
to return a result.)  Your `print` statement fails the last, as do any 
reasonable uses of `forEach`.

Note that by this definition, no useful programs can be entirely 
functional, since they could never take any input nor return any output.  
Although this is often glossed over, the main point is that side effects 
should be limited to a very thin shell of your system, leaving a 
functional core.

-----

Examples with `map`, `filter`, or `reduce` would demonstrate functional 
behavior significantly better.  `map` is especially interesting, as it 
can expand into discussions of Functors and from there into other 
Algebraic Data Types.

Such functions do not have to be considered only as methods of 
`Array.prototype`.  You can write your own:

    function map1(fn, list) {
      const result = new Array(list.length);
      for (let i = 0; i < list.length; i++) {
        result[i] = fn(list[i]);
      }
      return result;
    }

which might be used like this:

    const toUpper = (str) => str.toUpperCase();
    const square = (n) => n * n;

    map1(toUpper, ['foo', 'bar', 'baz']); 
    //=> ["FOO", "BAR", "BAZ"]

    map1(square, [1, 2, 3, 4, 5])
    //=> [1, 4, 9, 16, 25]

Or you might make a somewhat more sophisticated version such as this:

    function map2(fn, list) {
      const m = function(list) {
        const result = new Array(list.length);
        for (let i = 0; i < list.length; i++) {
          result[i] = fn(list[i]);
        }
        return result;
      };
      return arguments.length > 1 ?  m(list) : m;
    }

    // works the same for two arguments:

    map2(toUpper, ['foo', 'bar', 'baz']); 
    //=> ["FOO", "BAR", "BAZ"] 
    map2(square, [1, 2, 3, 4, 5])
    //=> [1, 4, 9, 16, 25]

    // returns a new function when supplied only the first argument:

    const squareAll = map2(square);
    squareAll([1, 2, 3, 4, 5]); 
    //=> [1, 4, 9, 16, 25]

You might wonder why we shouldn't write it like this:

    function map3(fn, list) {
      return list.map(fn);
    }

    map3(parseFloat, ['1.1', '2.2', '3.3']);
    //=> [1.1, 2.2, 3.3]

We could.  But we might run into some unfortunate situations caused by 
Array.prototype.map that we don't want to deal with [1]:

    map3(parseInt, ['1', '2', '3']);
    //=> [1, NaN, NaN]

Or you could use one of the many libraries available to help with 
functional programming in JS.  I'm one of the principle authors of Ramda 
[2], which has become quite a popular library for doing FP in JS.  It 
provides several hundred functions for working with lists, functions, 
objects, strings, and algebraic data types.  Sanctuary [3] stated as a 
companion library to Ramda, but is growing beyond that.  It is a more 
principled, and more opinionated library than Ramda, perhaps less 
accessible to the beginner, but more aligned with pure FP languages.  
Underscore [4] and lodash [5] are more general-purpose libraries, similar 
in scope to Ramda: overall more popular, but much less focused on pure FP. 
And there are many more.

-----

There are two excellent books online that help teach functional 
programming using Javascript.  Reg Braithewaite's _JavaScript Allongé_ 
[6] and Brian Lonsdorf's _Professor Frisby's Mostly Adequate Guide to 
Functional Programming_. [7] Braithewaite simply reimagines programming 
with the function as its key element and derives some very powerful, and 
surprisingly eloquent, principles from that.  Lonsdorf builds up much of 
the standard functional programming arsenal using nothing but basic 
Javascript; although it moves logically, and very clearly, once he builds 
up steam, it begins to become challenging to keep up; but the first two 
thirds of the book should be accessible to anyone.


_____

  [1]: There are many explanations of this around.  Here's one: <http://
stackoverflow.com/questions/262427/javascript-arraymap-and-parseint>

  [2]: <http://ramdajs.com>

  [3]: <https://sanctuary.js.org/>

  [4]: http://underscorejs.org/

  [5]: https://lodash.com/

  [6]: I'm partial to the first edition of this book because of its 
simplicity: <https://leanpub.com/javascript-allonge>, but the ES6 edition 
may be more practical these days:  <https://leanpub.com/
javascriptallongesix/>

  [7]: <https://github.com/MostlyAdequate/mostly-adequate-guide>

  -- Scott

[toc] | [prev] | [next] | [standalone]


#32216

Fromjustaguy <lichunshen84@gmail.com>
Date2017-01-19 21:18 -0800
Message-ID<42e9d095-5f91-420c-b0a7-4371cce24f8b@googlegroups.com>
In reply to#32213
On Thursday, January 19, 2017 at 11:30:01 PM UTC-5, Scott Sauyet wrote:
> justaguy wrote:
> 
> > I'm starting to read about Functional Programming.  The following is
> > some sample code, which seems concise.  
> 
> Concise, even elegant, code is one of the hallmarks of functional 
> programming.  But I would suggest that you don't seek it as an initial 
> goal.  Look to other main facets: immutability, referential transparency, 
> systems built by composing smaller functions.
> 
> As you learn functional techniques, concise code will likely emerge on 
> its own.
> 
> 
> > In the meantime, I wonder if you
> > have some idea of using other "action" other than "print", and of
> > course, feel free to use other array "values" where appropriate.
> > 
> > function forEach(array, action) {
> >   for (var i = 0; i < array.length; i++)
> >     action(array[i]);
> > }
> > 
> > forEach(["Wampeter", "Foma", "Granfalloon"], print);
> 
> 
> `forEach` is not really an example of functional programming.  One of the 
> key tenets of functional programming is that code must be referentially 
> transparent.  This means that any expression could be replaced with its 
> value with no change to the behavior of the system.  For functions this 
> means that they must be *pure* (their results must depend only on their 
> parameters) and that they must have no side effects (all they can do is 
> to return a result.)  Your `print` statement fails the last, as do any 
> reasonable uses of `forEach`.
> 
> Note that by this definition, no useful programs can be entirely 
> functional, since they could never take any input nor return any output.  
> Although this is often glossed over, the main point is that side effects 
> should be limited to a very thin shell of your system, leaving a 
> functional core.
> 
> -----
> 
> Examples with `map`, `filter`, or `reduce` would demonstrate functional 
> behavior significantly better.  `map` is especially interesting, as it 
> can expand into discussions of Functors and from there into other 
> Algebraic Data Types.
> 
> Such functions do not have to be considered only as methods of 
> `Array.prototype`.  You can write your own:
> 
>     function map1(fn, list) {
>       const result = new Array(list.length);
>       for (let i = 0; i < list.length; i++) {
>         result[i] = fn(list[i]);
>       }
>       return result;
>     }
> 
> which might be used like this:
> 
>     const toUpper = (str) => str.toUpperCase();
>     const square = (n) => n * n;
> 
>     map1(toUpper, ['foo', 'bar', 'baz']); 
>     //=> ["FOO", "BAR", "BAZ"]
> 
>     map1(square, [1, 2, 3, 4, 5])
>     //=> [1, 4, 9, 16, 25]
> 
> Or you might make a somewhat more sophisticated version such as this:
> 
>     function map2(fn, list) {
>       const m = function(list) {
>         const result = new Array(list.length);
>         for (let i = 0; i < list.length; i++) {
>           result[i] = fn(list[i]);
>         }
>         return result;
>       };
>       return arguments.length > 1 ?  m(list) : m;
>     }
> 
>     // works the same for two arguments:
> 
>     map2(toUpper, ['foo', 'bar', 'baz']); 
>     //=> ["FOO", "BAR", "BAZ"] 
>     map2(square, [1, 2, 3, 4, 5])
>     //=> [1, 4, 9, 16, 25]
> 
>     // returns a new function when supplied only the first argument:
> 
>     const squareAll = map2(square);
>     squareAll([1, 2, 3, 4, 5]); 
>     //=> [1, 4, 9, 16, 25]
> 
> You might wonder why we shouldn't write it like this:
> 
>     function map3(fn, list) {
>       return list.map(fn);
>     }
> 
>     map3(parseFloat, ['1.1', '2.2', '3.3']);
>     //=> [1.1, 2.2, 3.3]
> 
> We could.  But we might run into some unfortunate situations caused by 
> Array.prototype.map that we don't want to deal with [1]:
> 
>     map3(parseInt, ['1', '2', '3']);
>     //=> [1, NaN, NaN]
> 
> Or you could use one of the many libraries available to help with 
> functional programming in JS.  I'm one of the principle authors of Ramda 
> [2], which has become quite a popular library for doing FP in JS.  It 
> provides several hundred functions for working with lists, functions, 
> objects, strings, and algebraic data types.  Sanctuary [3] stated as a 
> companion library to Ramda, but is growing beyond that.  It is a more 
> principled, and more opinionated library than Ramda, perhaps less 
> accessible to the beginner, but more aligned with pure FP languages.  
> Underscore [4] and lodash [5] are more general-purpose libraries, similar 
> in scope to Ramda: overall more popular, but much less focused on pure FP. 
> And there are many more.
> 
> -----
> 
> There are two excellent books online that help teach functional 
> programming using Javascript.  Reg Braithewaite's _JavaScript Allongé_ 
> [6] and Brian Lonsdorf's _Professor Frisby's Mostly Adequate Guide to 
> Functional Programming_. [7] Braithewaite simply reimagines programming 
> with the function as its key element and derives some very powerful, and 
> surprisingly eloquent, principles from that.  Lonsdorf builds up much of 
> the standard functional programming arsenal using nothing but basic 
> Javascript; although it moves logically, and very clearly, once he builds 
> up steam, it begins to become challenging to keep up; but the first two 
> thirds of the book should be accessible to anyone.
> 
> 
> _____
> 
>   [1]: There are many explanations of this around.  Here's one: <http://
> stackoverflow.com/questions/262427/javascript-arraymap-and-parseint>
> 
>   [2]: <http://ramdajs.com>
> 
>   [3]: <https://sanctuary.js.org/>
> 
>   [4]: http://underscorejs.org/
> 
>   [5]: https://lodash.com/
> 
>   [6]: I'm partial to the first edition of this book because of its 
> simplicity: <https://leanpub.com/javascript-allonge>, but the ES6 edition 
> may be more practical these days:  <https://leanpub.com/
> javascriptallongesix/>
> 
>   [7]: <https://github.com/MostlyAdequate/mostly-adequate-guide>
> 
>   -- Scott

Thank you.

[toc] | [prev] | [next] | [standalone]


#32221

FromJohn Harris <niam@jghnorth.org.uk.invalid>
Date2017-01-20 10:22 +0000
Message-ID<l5p38cd873umflfgl2l2r6b50oa4kpsi5i@4ax.com>
In reply to#32213
On Fri, 20 Jan 2017 04:28:17 -0000 (UTC), Scott Sauyet
<scott@sauyet.com> wrote:


  <snip>
>Note that by this definition, no useful programs can be entirely 
>functional, since they could never take any input nor return any output.  

Just like ECMAScript, the core language, then :-)


>Although this is often glossed over, the main point is that side effects 
>should be limited to a very thin shell of your system, leaving a 
>functional core.
  <snip>

Are the DOM and similar environments a "thin" shell ?

  John

[toc] | [prev] | [next] | [standalone]


#32224

FromScott Sauyet <scott@sauyet.com>
Date2017-01-21 01:29 +0000
Message-ID<o5udgu$obk$2@dont-email.me>
In reply to#32221
John Harris wrote:
> Scott Sauyet wrote:

>   <snip>
>> Note that by this definition, no useful programs can be entirely
>> functional, since they could never take any input nor return any 
>> output.
> 
> Just like ECMAScript, the core language, then :-)

Exactly.  :-)

>> Although this is often glossed over, the main point is that side 
>> effects should be limited to a very thin shell of your system, leaving 
>> a functional core.
> 
> Are the DOM and similar environments a "thin" shell ?

No, but if you're going to write functional Javascript for a DOM 
environment, the idea would be to keep all the core data transformations, 
all the fundamental logic, together and central, and relegate your code 
that actually interacts with the DOM to the edges of your program.

In compile-to-JS languages like PureScript, this may actually be 
enforced, requiring you to use Monads to encapsulate side effects.  (I'm 
guessing; I have yet to try PureScript, but given it's close ties with 
Haskell, it seems a likely guess.)  In Javascript, you would have to 
manage this yourself.  I've seen people simply physically separate and 
comment as such the pure code and impure code.  Or it could be done via 
naming conventions, file layout conventions, whatever...

  -- Scott

[toc] | [prev] | [next] | [standalone]


#32223

FromScott Sauyet <scott@sauyet.com>
Date2017-01-21 01:15 +0000
Message-ID<o5uco5$obk$1@dont-email.me>
In reply to#32213
Stefan Ram wrote:
> Scott Sauyet writes:

>> key tenets of functional programming is that code must be referentially
>> transparent.  This means that any expression could be replaced with its
>> value with no change to the behavior of the system.
> 
>   »2« is an example of an expression. An expression is part of the
>   source code.
> 
>   A value is abstract, it is not source text like an expression.
> 
>   Therefore, an expression cannot be replaced by a value in the source
>   code.

Have you been hanging out with the pedants again?

"an expression could be replaced with a representation of its value with 
no change to the behavior of the system."  Does that satisfy you?



>   An expression, however, can be replaced by another expression equal in
>   value. If this can be done without changing the meaning of a program
>   it is what Søndergaard and Sestof call »substitutivity of identity«.
>   [ ... ]

Thank you for that reference.  I had not read their paper although I'd 
read many of their sources, including Landin, Strachey, and even Quine (I 
just knew that philosophy course would come in handy!)  I never quite 
made it through the _Principia_ (ok, I never quite made it through the 
first 20 pages of the _Principia_; I bore easily!) But I find the meaning 
as commonly used in computing perfectly reasonable, and don't need to go 
back to Quine to infer a deeper meaning for the phrase/


>   Other concepts that sometimes are used as definitions of »referential
>   transparency« are extensionality, definiteness and unfoldability, all
>   independed properties! See also
> 
> http://www.purl.org/stefan_ram/pub/referential_transparency


Sure, but I think that for most of us, the definition above has come to 
dominate the alternatives.  At least for the uses in computer science.  I 
know nothing about linguistics or the other such places.

  -- Scott

[toc] | [prev] | [next] | [standalone]


#32244

From"Michael Haufe (TNO)" <tno@thenewobjective.com>
Date2017-01-21 15:00 -0800
Message-ID<66b6ed25-01ad-4ada-aa6d-f08bc69eee7e@googlegroups.com>
In reply to#32213
Scott Sauyet wrote:

> Note that by this definition, no useful programs can be entirely 
> functional, since they could never take any input nor return any output.  
> Although this is often glossed over, the main point is that side effects 
> should be limited to a very thin shell of your system, leaving a 
> functional core.

Hardly. That is what Codata is all about.

Reading from I/O can be represented by a Stream<T> or Observable<T> depending on whether it is an Interactive (List of all prime numbers) or Reactive (The current system time)

Writing to I/O can be represented by a dual which doesn't have a return type 
Sink<T>

Imagine:

interface Console {
    write(value: String): Nothing
}

[toc] | [prev] | [next] | [standalone]


#32214

FromScott Sauyet <scott@sauyet.com>
Date2017-01-20 05:00 +0000
Message-ID<o5s5h9$ahq$2@dont-email.me>
In reply to#32193
Stefan Ram wrote:
> justaguy  writes:

>> In the meantime, I wonder if you have some idea of using other "action"
>> other than "print", and of course, feel free to use other array 
>> "values" where appropriate.
> 
>   I do not proceed in that way. I do not like the tool-
>   looking-for-a-job approach. Rather I am used to start with
>   requirements and then search for appropriate tools. 
>   [ ... ]

ACK

>> function forEach(array, action) {
>>   for (var i = 0; i < array.length; i++)
>>     action(array[i]);
>> }
> 
>   To me, pure functional programming (independent of JavaScript) does
>   not involve changing state such as »i« above. So I do not deem the
>   above to be purely functional. 

I think you need to be able to compromise on this a bit in Javascript, at 
least until proper tail call optimization is widespread.  [1] The 
alternative to such iteration is managed with recursion, but that is not 
practical for anything but relatively small data structures in JS.

My take, and that of the FP library I help maintain (Ramda [2]) is that 
such reassignment must happen inside a function, and ideally inside a 
function that's buried in a library, rather than in a user's code.



>   Of course, most procedural programs
>   contain some parts of functional programming, but in this sense
>   "everything" is functional a bit.

I don't follow this.  The reverse is clear enough.  Any FP program, in 
order to interact with the world, must contain some part that is not 
entirely pure.  But why do you say everything must have functional 
sections?  I don't see that at all.

 
>   For example, they say C is procedural, not functional. Yet you can
>   write
> static void foreach( void( * const f )( char const * const )t
> , ... )
> { va_list ap;
>   va_start( ap, f );
>   while( 1 )
>   { char const * const s = va_arg( ap, char const * const );
                        ^^^^^
>     if( s )f( s ); else break; }
>   va_end( ap ); }

AFAICT, by reassigning `s` on each iteration, this has the same sort of 
behavior.  (My always weak C is pretty rusty, though.)  I believe you 
would need a recursive solution to avoid this.
 

>   Go and read a book about Haskell!

While this is good advice, it doesn't really help answer questions about 
how much and what kind of FP one can do in JS.

 
_____

  [1]: Kangax's ES6 tables don't give much hope.  At the time of this 
writing, they show only the most recent Safari (desktop and iOS 10) and 
the Kinoma XS6 server meeting the specification for proper tail calls: 
<https://kangax.github.io/compat-table/es6/#test-proper_tail_calls_%
28tail_call_optimisation%29>


  -- Scott
  [2]: <http://ramdajs.com>

[toc] | [prev] | [next] | [standalone]


#32215

FromScott Sauyet <scott@sauyet.com>
Date2017-01-20 05:02 +0000
Message-ID<o5s5li$ahq$3@dont-email.me>
In reply to#32193
Stefan Ram wrote:

>     Can Programming Be Liberated from the von Neumann Style? A
>     Functional Style and Its Algebra of Programs - John Backus (1978-08)
> 
>   And IIRC, this is the work that usually is said to have triggered the
>   interest in functional programming.

It may have accelerated interest.  But LISP, which is mostly used as a 
functional language, had already been around two decades by the time 
Backus published this pager.

  -- Scott

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web