I myself am interested in functional languages and visit various sites Some sites carefully describe the merits of functional languages and make you think "functional languages are good", while others say "well, this doesn't make you feel the merits of functional languages". This time, I would like to write about the features of "a site that does not make you feel the merits of functional languages".
The sample is Code IQ site. The purpose of the above site seems to be that array processing is written in imperative language (C language) and functional language (Haskell), and functional language (Haskell) is easy to understand by comparing both.
I sincerely agree that the description of functional languages (Haskell) is very concise, but I personally think that there are some problems with the logic of C, which is given as an example of imperative languages. .. So I'm not sure if what is said to be the benefit of the last functional language (Haskell) on the site really benefits. For example, if reduce and map, which are said to be the merits of functional languages on this site, do not take a lot of time and effort when implemented in imperative languages, they cannot be said to have real merits.
Below, I will list the problems of the sample program that I personally felt.
What does i or N in the sample program really mean? I didn't know what the variable names meant, so I couldn't figure out what the logic was for just by reading the program. At the very least, i should be counter and N should be ARRAY_LIMITTED_NUMBER to clarify the role of the variable.
If you use an initializer when you initialize an array, why not set the number of elements in the array?
There may be some misunderstandings when it comes to strange things, but isn't it easier to write the process by using pointers instead of subscripts to access arrays? If you access it with a pointer, at least the variable i should be unnecessary
Isn't this better than a problem? It is a proposal. It seems better to introduce NULL to represent the end of the array That way, you don't have to compare the subscripts with the maximum number of elements in the array when determining the loop exit condition. Well, in this case, there is a problem of what to do if NULL is inserted in the middle of the array, but as long as you use C language, you need to make some rules for the end of the array. The sample program also uses define to secretly define the maximum number of elements in the array as 5.
In the original program, data control (loop processing) and data processing (snake and frog simulation) are performed in one place. But isn't this contrary to structured programming, which has been said for decades before functional languages? If you're doing modern development, no matter what language you use, data control and data processing should be cut into separate functions.
Below, I will post the C language code that I improved
sample.c
#include "stdafx.h"
//Calculate the number of surviving frogs
int calc(int snakes, int flogs) {
if (flogs >= snakes) return flogs - snakes;
else return 0;
}
//A function that manipulates an array of frogs and snakes
int execute(int snakes[], int flogs[]) {
int survivors = 0; //Total number of surviving frogs
while (true) {
//Escape the loop when you reach the end of the array
if (*snakes == NULL) break;
survivors += calc(*snakes++, *flogs++);
}
return survivors;
}
int main()
{
int snakes[] = { 5,4,3,2,1,NULL };//snake
int flogs[] = { 7,6,1,2,2 ,NULL };//Frog
printf("Number of frogs that survived%5d", execute(snakes, flogs));
getchar();
return 0;
}
Using prototype declarations, I made it possible to perform functional language reduce and map-like behavior.
sample.c
#include "stdafx.h"
typedef int(*FUNCPTR)(int a, int b);
//A function that manipulates an array of frogs and snakes
//Pass a function pointer to FUNCPTR that simulates the survival competition between frogs and snakes.
int zip_and_reduce(int snakes[], int flogs[],FUNCPTR func) {
int survivors = 0; //Total number of surviving frogs
while (true) {
//Escape the loop if NULL appears in the array
if (*snakes == NULL) break;
survivors += func(*snakes++, *flogs++);
}
return survivors;
}
//Calculate the number of surviving frogs
int calc(int snakes, int flogs) {
if (flogs >= snakes) return flogs - snakes;
else return 0;
}
//Calculate the number when frogs and snakes coexist
int calc_kyouzon(int snakes, int flogs) {
return flogs + snakes;
}
int main()
{
int snakes[] = { 5,4,3,2,1,NULL };//snake
int flogs[] = { 7,6,1,2,2 ,NULL };//Frog
printf("Number of frogs that survived%5d", zip_and_reduce(snakes, flogs,&calc));
printf("Number when snakes and frogs coexist%5d", zip_and_reduce(snakes, flogs, &calc_kyouzon));
getchar();
return 0;
}
I will also post the Ver implemented in Java.
sample.java
package test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class MyTest {
public static void main(String args[]){
List<Integer>snakes = new ArrayList<Integer>();
Collections.addAll(snakes, 1,2,3,20);
List<Integer>flogs = new ArrayList<Integer>();
Collections.addAll(flogs, 10,2,3,4,5);
System.out.println(execute(snakes,flogs));
}
//Functions exposed to the outside
//Pass the snake and frog arguments as arguments
public static int execute(List<Integer>snaeks,List<Integer>flogs){
//The first total value is 0
return execute(snaeks.iterator(),flogs.iterator() ,0);
}
//Functions used internally
//Iterator<Integer>snakes :Enums of snakes
//Iterator<Integer> :flogs enum
//sum :Total value of flogs
private static int execute(Iterator<Integer>snakes,Iterator<Integer>flogs ,int sum){
//When there are no snakes or frogs, the process is complete
if(!snakes.hasNext() && !flogs.hasNext())return sum;
//Continue processing if either snake or frog is present
else return execute(snakes,flogs,sum + calc(ifExists(snakes),ifExists(flogs) ) );
}
//Find the number of frogs
//Returns the number of frogs minus the number of snakes when there are more frogs than snakes
//int snakes: Number of snakes
//int flogs: Number of frogs
private static int calc(int snakes,int flogs){
if(snakes<= flogs) return flogs - snakes;
else return 0;
}
//If the enumerator has an element, it returns that element, otherwise it returns 0.
private static int ifExists(Iterator<Integer>ite){
if(ite.hasNext())return ite.next();
else return 0;
}
}
Looking at the improved imperative language source and functional language source, I think that each person thinks differently. I'm not very familiar with functional languages (Haskell),
--Easy to handle arrays compared to C language --Compared to Java, it is easier to handle function pointers (like) in C, and there is flexibility in defining types.
I feel that there is a merit
On the contrary, how about the explanation that it is convenient because you can use reduce and map? I think
Recommended Posts