8 replaced http://programmers.stackexchange.com/ with https://softwareengineering.stackexchange.com/
source | link

As YannisYannis pointed out, there are a number of factors that have influenced the adoption of high-order functions in languages that were previously without. One of the important items he only touched lightly on is the proliferation of multi-core processors and, with that, the desire for more parallel and concurrent processing.

The map/filter/reduce style of functional programming is very friendly to parallelization, allowing the programmer to easily make use of multiple cores, without writing any explicit threading code.

As Giorgio notes, there is more to functional programming than just high-order functions. Functions, plus a map/filter/reduce programming pattern, and immutability are the core of functional programming. Together these things make for powerful tools of parallel and concurrent programming. Thankfully, many languages already support some notion of immutability, and, even if they don't, programmers can treat things as immutable allowing the libraries and compiler to create and manage asynchronous or parallel operations.

Adding high-order functions to a language is an important step to simplifying concurrent programming.

Update

I'll add a couple more detailed examples in order to address the concerns Loki noted.

Consider the following C# code which traverses a collection of widgets, creating a new list of widget prices.

List<float> widgetPrices;
    float salesTax = RetrieveLocalSalesTax();
foreach( Widget w in widgets ) {
    widgetPrices.Add( CalculateWidgetPrice( w, salesTax ) );
}

For a large collection of widgets, or a computationally intensive CalculateWidgetPrice(Widget) method, this loop would not make good use of any available cores. To do the price calculations on different cores would require the programmer to explicitly create and manage threads, passing work around, and collecting the results together.

Consider a solution once high-order functions have been added to C#:

var widgetPrices = widgets.Select( w=> CalculateWidgetPrice( w, salesTax ) );

The foreach loop has been moved into the Select method, hiding its implementation details. All that remains to the programmer is to tell Select what function to apply to each element. This would allow the Select implementation to run the calculations in parellel, handling all the synchronization and thread management concerns without the programmer's involvement.

But, of course, Select does not do it's work in parallel. That's where immutability comes in. The implementation of Select does not know that the provided function (CalculateWidgets above) does not have side effects. The function could change the state of the program outside the view of Select and its synchronization, breaking everything. For example, in this case the value of salesTax could be changed in error. Pure functional languages provide immutability, so the Select (map) function can know for sure that no state is changing.

C# addresses this by providing PLINQ as an alternative to Linq. That would look like:

var widgetPrices = widgets.AsParallel().Select(w => CalculateWidgetPrice( w, salesTax) );

Which makes full use of all the cores of your system without explicit management of those cores.

As Yannis pointed out, there are a number of factors that have influenced the adoption of high-order functions in languages that were previously without. One of the important items he only touched lightly on is the proliferation of multi-core processors and, with that, the desire for more parallel and concurrent processing.

The map/filter/reduce style of functional programming is very friendly to parallelization, allowing the programmer to easily make use of multiple cores, without writing any explicit threading code.

As Giorgio notes, there is more to functional programming than just high-order functions. Functions, plus a map/filter/reduce programming pattern, and immutability are the core of functional programming. Together these things make for powerful tools of parallel and concurrent programming. Thankfully, many languages already support some notion of immutability, and, even if they don't, programmers can treat things as immutable allowing the libraries and compiler to create and manage asynchronous or parallel operations.

Adding high-order functions to a language is an important step to simplifying concurrent programming.

Update

I'll add a couple more detailed examples in order to address the concerns Loki noted.

Consider the following C# code which traverses a collection of widgets, creating a new list of widget prices.

List<float> widgetPrices;
    float salesTax = RetrieveLocalSalesTax();
foreach( Widget w in widgets ) {
    widgetPrices.Add( CalculateWidgetPrice( w, salesTax ) );
}

For a large collection of widgets, or a computationally intensive CalculateWidgetPrice(Widget) method, this loop would not make good use of any available cores. To do the price calculations on different cores would require the programmer to explicitly create and manage threads, passing work around, and collecting the results together.

Consider a solution once high-order functions have been added to C#:

var widgetPrices = widgets.Select( w=> CalculateWidgetPrice( w, salesTax ) );

The foreach loop has been moved into the Select method, hiding its implementation details. All that remains to the programmer is to tell Select what function to apply to each element. This would allow the Select implementation to run the calculations in parellel, handling all the synchronization and thread management concerns without the programmer's involvement.

But, of course, Select does not do it's work in parallel. That's where immutability comes in. The implementation of Select does not know that the provided function (CalculateWidgets above) does not have side effects. The function could change the state of the program outside the view of Select and its synchronization, breaking everything. For example, in this case the value of salesTax could be changed in error. Pure functional languages provide immutability, so the Select (map) function can know for sure that no state is changing.

C# addresses this by providing PLINQ as an alternative to Linq. That would look like:

var widgetPrices = widgets.AsParallel().Select(w => CalculateWidgetPrice( w, salesTax) );

Which makes full use of all the cores of your system without explicit management of those cores.

As Yannis pointed out, there are a number of factors that have influenced the adoption of high-order functions in languages that were previously without. One of the important items he only touched lightly on is the proliferation of multi-core processors and, with that, the desire for more parallel and concurrent processing.

The map/filter/reduce style of functional programming is very friendly to parallelization, allowing the programmer to easily make use of multiple cores, without writing any explicit threading code.

As Giorgio notes, there is more to functional programming than just high-order functions. Functions, plus a map/filter/reduce programming pattern, and immutability are the core of functional programming. Together these things make for powerful tools of parallel and concurrent programming. Thankfully, many languages already support some notion of immutability, and, even if they don't, programmers can treat things as immutable allowing the libraries and compiler to create and manage asynchronous or parallel operations.

Adding high-order functions to a language is an important step to simplifying concurrent programming.

Update

I'll add a couple more detailed examples in order to address the concerns Loki noted.

Consider the following C# code which traverses a collection of widgets, creating a new list of widget prices.

List<float> widgetPrices;
    float salesTax = RetrieveLocalSalesTax();
foreach( Widget w in widgets ) {
    widgetPrices.Add( CalculateWidgetPrice( w, salesTax ) );
}

For a large collection of widgets, or a computationally intensive CalculateWidgetPrice(Widget) method, this loop would not make good use of any available cores. To do the price calculations on different cores would require the programmer to explicitly create and manage threads, passing work around, and collecting the results together.

Consider a solution once high-order functions have been added to C#:

var widgetPrices = widgets.Select( w=> CalculateWidgetPrice( w, salesTax ) );

The foreach loop has been moved into the Select method, hiding its implementation details. All that remains to the programmer is to tell Select what function to apply to each element. This would allow the Select implementation to run the calculations in parellel, handling all the synchronization and thread management concerns without the programmer's involvement.

But, of course, Select does not do it's work in parallel. That's where immutability comes in. The implementation of Select does not know that the provided function (CalculateWidgets above) does not have side effects. The function could change the state of the program outside the view of Select and its synchronization, breaking everything. For example, in this case the value of salesTax could be changed in error. Pure functional languages provide immutability, so the Select (map) function can know for sure that no state is changing.

C# addresses this by providing PLINQ as an alternative to Linq. That would look like:

var widgetPrices = widgets.AsParallel().Select(w => CalculateWidgetPrice( w, salesTax) );

Which makes full use of all the cores of your system without explicit management of those cores.

7 Added a link for the linked to answer.
source | link

As YannisYannis pointed out, there are a number of factors that have influenced the adoption of high-order functions in languages that were previously without. One of the important items he only touched lightly on is the proliferation of multi-core processors and, with that, the desire for more parallel and concurrent processing.

The map/filter/reduce style of functional programming is very friendly to parallelization, allowing the programmer to easily make use of multiple cores, without writing any explicit threading code.

As Giorgio notes, there is more to functional programming than just high-order functions. Functions, plus a map/filter/reduce programming pattern, and immutability are the core of functional programming. Together these things make for powerful tools of parallel and concurrent programming. Thankfully, many languages already support some notion of immutability, and, even if they don't, programmers can treat things as immutable allowing the libraries and compiler to create and manage asynchronous or parallel operations.

Adding high-order functions to a language is an important step to simplifying concurrent programming.

Update

I'll add a couple more detailed examples in order to address the concerns Loki noted.

Consider the following C# code which traverses a collection of widgets, creating a new list of widget prices.

List<float> widgetPrices;
    float salesTax = RetrieveLocalSalesTax();
foreach( Widget w in widgets ) {
    widgetPrices.Add( CalculateWidgetPrice( w, salesTax ) );
}

For a large collection of widgets, or a computationally intensive CalculateWidgetPrice(Widget) method, this loop would not make good use of any available cores. To do the price calculations on different cores would require the programmer to explicitly create and manage threads, passing work around, and collecting the results together.

Consider a solution once high-order functions have been added to C#:

var widgetPrices = widgets.Select( w=> CalculateWidgetPrice( w, salesTax ) );

The foreach loop has been moved into the Select method, hiding its implementation details. All that remains to the programmer is to tell Select what function to apply to each element. This would allow the Select implementation to run the calculations in parellel, handling all the synchronization and thread management concerns without the programmer's involvement.

But, of course, Select does not do it's work in parallel. That's where immutability comes in. The implementation of Select does not know that the provided function (CalculateWidgets above) does not have side effects. The function could change the state of the program outside the view of Select and its synchronization, breaking everything. For example, in this case the value of salesTax could be changed in error. Pure functional languages provide immutability, so the Select (map) function can know for sure that no state is changing.

C# addresses this by providing PLINQ as an alternative to Linq. That would look like:

var widgetPrices = widgets.AsParallel().Select(w => CalculateWidgetPrice( w, salesTax) );

Which makes full use of all the cores of your system without explicit management of those cores.

As Yannis pointed out, there are a number of factors that have influenced the adoption of high-order functions in languages that were previously without. One of the important items he only touched lightly on is the proliferation of multi-core processors and, with that, the desire for more parallel and concurrent processing.

The map/filter/reduce style of functional programming is very friendly to parallelization, allowing the programmer to easily make use of multiple cores, without writing any explicit threading code.

As Giorgio notes, there is more to functional programming than just high-order functions. Functions, plus a map/filter/reduce programming pattern, and immutability are the core of functional programming. Together these things make for powerful tools of parallel and concurrent programming. Thankfully, many languages already support some notion of immutability, and, even if they don't, programmers can treat things as immutable allowing the libraries and compiler to create and manage asynchronous or parallel operations.

Adding high-order functions to a language is an important step to simplifying concurrent programming.

Update

I'll add a couple more detailed examples in order to address the concerns Loki noted.

Consider the following C# code which traverses a collection of widgets, creating a new list of widget prices.

List<float> widgetPrices;
    float salesTax = RetrieveLocalSalesTax();
foreach( Widget w in widgets ) {
    widgetPrices.Add( CalculateWidgetPrice( w, salesTax ) );
}

For a large collection of widgets, or a computationally intensive CalculateWidgetPrice(Widget) method, this loop would not make good use of any available cores. To do the price calculations on different cores would require the programmer to explicitly create and manage threads, passing work around, and collecting the results together.

Consider a solution once high-order functions have been added to C#:

var widgetPrices = widgets.Select( w=> CalculateWidgetPrice( w, salesTax ) );

The foreach loop has been moved into the Select method, hiding its implementation details. All that remains to the programmer is to tell Select what function to apply to each element. This would allow the Select implementation to run the calculations in parellel, handling all the synchronization and thread management concerns without the programmer's involvement.

But, of course, Select does not do it's work in parallel. That's where immutability comes in. The implementation of Select does not know that the provided function (CalculateWidgets above) does not have side effects. The function could change the state of the program outside the view of Select and its synchronization, breaking everything. For example, in this case the value of salesTax could be changed in error. Pure functional languages provide immutability, so the Select (map) function can know for sure that no state is changing.

C# addresses this by providing PLINQ as an alternative to Linq. That would look like:

var widgetPrices = widgets.AsParallel().Select(w => CalculateWidgetPrice( w, salesTax) );

Which makes full use of all the cores of your system without explicit management of those cores.

As Yannis pointed out, there are a number of factors that have influenced the adoption of high-order functions in languages that were previously without. One of the important items he only touched lightly on is the proliferation of multi-core processors and, with that, the desire for more parallel and concurrent processing.

The map/filter/reduce style of functional programming is very friendly to parallelization, allowing the programmer to easily make use of multiple cores, without writing any explicit threading code.

As Giorgio notes, there is more to functional programming than just high-order functions. Functions, plus a map/filter/reduce programming pattern, and immutability are the core of functional programming. Together these things make for powerful tools of parallel and concurrent programming. Thankfully, many languages already support some notion of immutability, and, even if they don't, programmers can treat things as immutable allowing the libraries and compiler to create and manage asynchronous or parallel operations.

Adding high-order functions to a language is an important step to simplifying concurrent programming.

Update

I'll add a couple more detailed examples in order to address the concerns Loki noted.

Consider the following C# code which traverses a collection of widgets, creating a new list of widget prices.

List<float> widgetPrices;
    float salesTax = RetrieveLocalSalesTax();
foreach( Widget w in widgets ) {
    widgetPrices.Add( CalculateWidgetPrice( w, salesTax ) );
}

For a large collection of widgets, or a computationally intensive CalculateWidgetPrice(Widget) method, this loop would not make good use of any available cores. To do the price calculations on different cores would require the programmer to explicitly create and manage threads, passing work around, and collecting the results together.

Consider a solution once high-order functions have been added to C#:

var widgetPrices = widgets.Select( w=> CalculateWidgetPrice( w, salesTax ) );

The foreach loop has been moved into the Select method, hiding its implementation details. All that remains to the programmer is to tell Select what function to apply to each element. This would allow the Select implementation to run the calculations in parellel, handling all the synchronization and thread management concerns without the programmer's involvement.

But, of course, Select does not do it's work in parallel. That's where immutability comes in. The implementation of Select does not know that the provided function (CalculateWidgets above) does not have side effects. The function could change the state of the program outside the view of Select and its synchronization, breaking everything. For example, in this case the value of salesTax could be changed in error. Pure functional languages provide immutability, so the Select (map) function can know for sure that no state is changing.

C# addresses this by providing PLINQ as an alternative to Linq. That would look like:

var widgetPrices = widgets.AsParallel().Select(w => CalculateWidgetPrice( w, salesTax) );

Which makes full use of all the cores of your system without explicit management of those cores.

6 Returning to lambdas specifically, I hope. I'll get this right yet, dang it!
source | link

As Yannis pointed out, there are a number of factors that have influenced the adoption of high-order functions in languages that were previously without. One of the important items he only touched lightly on is the proliferation of multi-core processors and, with that, the desire for more parallel and concurrent processing.

The map/filter/reduce style of functional programming is very friendly to parallelization, allowing the programmer to easily make use of multiple cores, without writing any explicit threading code.

As Giorgio notes, there is more to functional programming than just high-order functions. Functions, plus a map/filter/reduce programming pattern, and immutability are the core of functional programming. Together these things make for powerful tools of parallel and concurrent programming. Thankfully, many languages already support some notion of immutability, and, even if they don't, programmers can treat things as immutable allowing the libraries and compiler to create and manage asynchronous or parallel operations.

Adding high-order functions to a language is an important step to simplifying concurrent programming.

Update

I'll add a couple more detailed examples in order to address the concerns Loki noted.

Consider the following C# code which traverses a collection of widgets, creating a new list of widget prices.

List<float> widgetPrices;
    float salesTax = RetrieveLocalSalesTax();
foreach( Widget w in widgets ) {
    widgetPrices.Add( CalculateWidgetPrice( w, salesTax ) );
}

For a large collection of widgets, or a computationally intensive CalculateWidgetPrice(Widget) method, this loop would not make good use of any available cores. To do the price calculations on different cores would require the programmer to explicitly create and manage threads, passing work around, and collecting the results together.

Consider a solution once high-order functions have been added to C#:

var widgetPrices = widgets.Select( w=> CalculateWidgetPrice( w, salesTax ) );

The foreach loop has been moved into the Select method, hiding its implementation details. All that remains to the programmer is to tell Select what function to apply to each element. This would allow the Select implementation to run the calculations in parellel, handling all the synchronization and thread management concerns without the programmer's involvement.

But, of course, Select does not do it's work in parallel. That's where immutability comes in. The implementation of Select does not know that the provided function (CalculateWidgets above) does not have side effects. The function could change the state of the program outside the view of Select and its synchronization, breaking everything. For example, in this case the value of salesTax could be changed in error. Pure functional languages provide immutability, so the Select (map) function can know for sure that no state is changing.

C# addresses this by providing PLINQ as an alternative to Linq. That would look like:

var widgetPrices = widgets.AsParallel().Select(w => CalculateWidgetPrice( w, salesTax) );

Which makes full use of all the cores of your system without explicit management of those cores.

As Yannis pointed out, there are a number of factors that have influenced the adoption of high-order functions in languages that were previously without. One of the important items he only touched lightly on is the proliferation of multi-core processors and, with that, the desire for more parallel and concurrent processing.

The map/filter/reduce style of functional programming is very friendly to parallelization, allowing the programmer to easily make use of multiple cores, without writing any explicit threading code.

As Giorgio notes, there is more to functional programming than just high-order functions. Functions, plus a map/filter/reduce programming pattern, and immutability are the core of functional programming. Together these things make for powerful tools of parallel and concurrent programming. Thankfully, many languages already support some notion of immutability, and, even if they don't, programmers can treat things as immutable allowing the libraries and compiler to create and manage asynchronous or parallel operations.

Adding high-order functions to a language is an important step to simplifying concurrent programming.

Update

I'll add a couple more detailed examples in order to address the concerns Loki noted.

Consider the following C# code which traverses a collection of widgets, creating a new list of widget prices.

List<float> widgetPrices;
foreach( Widget w in widgets ) {
    widgetPrices.Add( CalculateWidgetPrice( w ) );
}

For a large collection of widgets, or a computationally intensive CalculateWidgetPrice(Widget) method, this loop would not make good use of any available cores. To do the price calculations on different cores would require the programmer to explicitly create and manage threads, passing work around, and collecting the results together.

Consider a solution once high-order functions have been added to C#:

var widgetPrices = widgets.Select( CalculateWidgetPrice );

The foreach loop has been moved into the Select method, hiding its implementation details. All that remains to the programmer is to tell Select what function to apply to each element. This would allow the Select implementation to run the calculations in parellel, handling all the synchronization and thread management concerns without the programmer's involvement.

But, of course, Select does not do it's work in parallel. That's where immutability comes in. The implementation of Select does not know that the provided function (CalculateWidgets above) does not have side effects. The function could change the state of the program outside the view of Select and its synchronization, breaking everything. Pure functional languages provide immutability, so the Select (map) function can know for sure that no state is changing.

C# addresses this by providing PLINQ as an alternative to Linq. That would look like:

var widgetPrices = widgets.AsParallel().Select( CalculateWidgetPrice );

Which makes full use of all the cores of your system without explicit management of those cores.

As Yannis pointed out, there are a number of factors that have influenced the adoption of high-order functions in languages that were previously without. One of the important items he only touched lightly on is the proliferation of multi-core processors and, with that, the desire for more parallel and concurrent processing.

The map/filter/reduce style of functional programming is very friendly to parallelization, allowing the programmer to easily make use of multiple cores, without writing any explicit threading code.

As Giorgio notes, there is more to functional programming than just high-order functions. Functions, plus a map/filter/reduce programming pattern, and immutability are the core of functional programming. Together these things make for powerful tools of parallel and concurrent programming. Thankfully, many languages already support some notion of immutability, and, even if they don't, programmers can treat things as immutable allowing the libraries and compiler to create and manage asynchronous or parallel operations.

Adding high-order functions to a language is an important step to simplifying concurrent programming.

Update

I'll add a couple more detailed examples in order to address the concerns Loki noted.

Consider the following C# code which traverses a collection of widgets, creating a new list of widget prices.

List<float> widgetPrices;
    float salesTax = RetrieveLocalSalesTax();
foreach( Widget w in widgets ) {
    widgetPrices.Add( CalculateWidgetPrice( w, salesTax ) );
}

For a large collection of widgets, or a computationally intensive CalculateWidgetPrice(Widget) method, this loop would not make good use of any available cores. To do the price calculations on different cores would require the programmer to explicitly create and manage threads, passing work around, and collecting the results together.

Consider a solution once high-order functions have been added to C#:

var widgetPrices = widgets.Select( w=> CalculateWidgetPrice( w, salesTax ) );

The foreach loop has been moved into the Select method, hiding its implementation details. All that remains to the programmer is to tell Select what function to apply to each element. This would allow the Select implementation to run the calculations in parellel, handling all the synchronization and thread management concerns without the programmer's involvement.

But, of course, Select does not do it's work in parallel. That's where immutability comes in. The implementation of Select does not know that the provided function (CalculateWidgets above) does not have side effects. The function could change the state of the program outside the view of Select and its synchronization, breaking everything. For example, in this case the value of salesTax could be changed in error. Pure functional languages provide immutability, so the Select (map) function can know for sure that no state is changing.

C# addresses this by providing PLINQ as an alternative to Linq. That would look like:

var widgetPrices = widgets.AsParallel().Select(w => CalculateWidgetPrice( w, salesTax) );

Which makes full use of all the cores of your system without explicit management of those cores.

5 Adding examples in response to comments
source | link
4 Corrected my note about Yannis post.
source | link
3 Corrected typo.
source | link
2 Minor grammar correction, but I left the run-on sentence.
source | link
1
source | link