Name: Anonymous 2013-11-19 12:18
Ask /prog/ anything.
Although don't expect an answer or even a good one.
Also, keep it /prog/ related.
Although don't expect an answer or even a good one.
Also, keep it /prog/ related.
I'm familiar with object-oriented programming, but what is functional programming?Object-oriented programming is when things are centered around objects and their composition (inheritance, for example), and functions/procedures/methods are defined in terms of/around objects. Functional programming is when emphasis is put on functions instead and their composition, and objects/structures are just things that functions operate on. Purely functional programming is the extremest form of this, where all code is part of functions (in the mathematical sense) and so there is no mutation ("assignment"). Turns out that all of the above are equal in computational power (i.e. there are no computations that one of them can do but the other ones can't), so this is really just about clarity and efficiency and all those other things.
Are they compatible? Are they reconcilable?Yes; an excellent example is Common Lisp and the CLOS.
Do individual programmers generally favor one over the other, or do they utilise each when appropriate?The average programmer has the IQ of a highly-trained rhesus monkey. That being said, a Haskell programmer will almost always use functional programming (even when clarity/performance are hurt) while a Java programmer will almost use object-oriented programming (because they don't know any better).
Are the any other styles or philosophies of note or of relevance?Read up about defmacro. Also read SICP (or if you find it too hard, something like Land of Lisp).
even when clarity/performance are hurtIs this due to the flexibility and ease of debugging that was mentioned in the article, or am I missing something?
#include <stdio.h>
#include <string.h>
typedef struct _record {
char *firstname;
char *lastname;
char *mobilenum;
struct _record *Next;
} Record;
void newentry(Record *Rec);
int insert(Record *Rec, char * lname, char * fname, char * mobile);
void viewall(Record *Rec);
int main()
{
char c;
Record *Phonebook = NULL;
while(1) {
printf("%s\n", "Phonebook: ");
printf("%s\n", "\t[1] Insert");
printf("%s\n", "\t[2] Display");
printf("%s\n", "\t[3] Exit");
do {
scanf("%c", &c);
} while (!((c == '1') || (c == '2') || (c == '3')));
switch (c) {
case '1':
newentry(Phonebook);
break;
case '2':
viewall(Phonebook);
break;
case '3':
return 0;
}
}
}
void newentry(Record *Rec)
{
char lname[30], fname[30], mobile[15];
int error;
clrscr();
printf("%s", "Last Name: ");
scanf("%s", &lname);
printf("%s", "First Name: ");
scanf("%s", &fname);
printf("%s", "Mobile No.: ");
scanf("%s", &mobile);
error = insert(Rec, lname, fname, mobile);
if (error > 0) {
printf("%s\n", "Not enough memory.");
getch();
}
}
int insert(Record *Rec, char * lname, char * fname, char * mobile)
{
/*
RETURN 0 IF SUCCESSFUL.
*/
Record *New, *Temp;
int i;
New = (Record *) malloc(sizeof (Record));
/* If malloc returns an invalid pointer */
if (!New) {
return 1;
}
/* Allocate memory for strings and
copy the arguments into them.
*/
New->lastname = (char *) malloc(strlen(lname) + 1);
strcpy(New->lastname, lname);
printf("%s", New->lastname);
New->firstname = (char *) malloc(strlen(fname) + 1);
strcpy(New->firstname, fname);
New->mobilenum = (char *) malloc(strlen(mobile) + 1);
strcpy(New->lastname, mobile);
New->Next = NULL;
/* If malloc returns an invalid pointer on the strings.*/
i = !(New->lastname) || !(New->firstname) || !(New->mobilenum);
if (i) {
return 1;
}
if (Rec == NULL) {
Rec = New;
} else {
Temp = Rec;
while (Temp->Next != NULL) {
Temp = Temp->Next;
}
Temp->Next = New;
}
return 0;
}
void viewall(Record *Rec)
{
Record *Temp;
clrscr();
printf("%s\t\t", "Last Name");
printf("%s\t\t", "First Name");
printf("%s\n", "Mobile Number");
Temp = Rec;
while (Temp->Next != NULL) {
printf("%s\t\t", Temp->lastname);
printf("%s\t\t", Temp->firstname);
printf("%s\n", Temp->mobilenum);
Temp = Temp->Next;
}
}
**
-pointers as per >>23's advice but I just gave in.Fonbuk.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _record {
char *firstname;
char *lastname;
char *mobilenum;
struct _record *Next;
} Record;
void newentry(Record **Rec);
int insert(Record **Rec, char * lname, char * fname, char * mobile);
void viewall(Record **Rec);
int main()
{
char c;
Record *Phonebook = NULL;
while(1) {
system("cls");
printf("%s\n", "Phonebook: ");
printf("%s\n", "\t[1] Insert");
printf("%s\n", "\t[2] Display");
printf("%s\n", "\t[3] Exit");
do {
scanf("%c", &c);
} while (!((c == '1') || (c == '2') || (c == '3')));
switch (c) {
char lname[30], fname[30], mobile[15];
int error;
case '1':
newentry(&Phonebook);
break;
case '2':
viewall(&Phonebook);
break;
case '3':
clrscr();
}
if (c == '3')
break;
}
return 0;
}
void newentry(Record **Rec)
{
/* I am now a two-star programmer. (NOT a good thing) */
char lname[30], fname[30], mobile[15];
int error;
clrscr();
printf("%s", "Last Name: ");
scanf("%s", &lname);
printf("%s", "First Name: ");
scanf("%s", &fname);
printf("%s", "Mobile No.: ");
scanf("%s", &mobile);
error = insert(Rec, lname, fname, mobile);
if (error > 0) {
printf("%s\n", "Not enough memory.");
getch();
}
}
int insert(Record **Rec, char * lname, char * fname, char * mobile)
{
/*
RETURN 0 IF SUCCESSFUL.
*/
Record *New, *Temp;
int i;
New = (Record *) malloc(sizeof (Record));
/* If malloc returns an invalid pointer... */
if (!New) {
return 1;
}
/* Allocate memory for strings and
copy the arguments into them.
*/
New->lastname = (char *) malloc(strlen(lname) + 1);
strcpy(New->lastname, lname);
New->firstname = (char *) malloc(strlen(fname) + 1);
strcpy(New->firstname, fname);
New->mobilenum = (char *) malloc(strlen(mobile) + 1);
strcpy(New->mobilenum, mobile);
New->Next = NULL;
/* If malloc returns an invalid pointer on the strings... */
i = !(New->lastname) || !(New->firstname) || !(New->mobilenum);
if (i) {
return 1;
}
if (*Rec == NULL) {
*Rec = New;
} else {
Temp = *Rec;
while (Temp->Next != NULL) {
Temp = Temp->Next;
}
Temp->Next = New;
}
return 0;
}
void viewall(Record **Rec)
{
Record *Temp;
system("cls");
printf("%s\t\t", "Last Name");
printf("%s\t\t", "First Name");
printf("%s\n", "Mobile Number");
Temp = *Rec;
while (Temp != NULL) {
printf("%s\t\t", Temp->lastname);
printf("%s\t\t", Temp->firstname);
printf("%s\n", Temp->mobilenum);
Temp = Temp->Next;
}
}
(Un)fortunately I am as Java-ignorant as anyone can be so any nuance or implication of the given examples went over my head. I feel like I'm right on the brink of getting it, but that last puzzle piece of understanding still looks like a corner when I've already completed in the border.If you are truly new to programming, try reading SICP[1] or, if it's too rough, Land of Lisp[2], like I said before. And, of course, do at least some of the exercises as you go along.
Is this due to the flexibility and ease of debugging that was mentioned in the article, or am I missing something?Programming is all about tradeoffs. Come to think of it, anything in the world is all about tradeoffs. When you code in C, you are trading off readability, security and terseness for that extra vroom vroom. When you code in Java, you trade off, uh, everything for (the illusion of) portability. When you code in Haskell, you trade off a lot of readability for (type) safety, theoretical purity, and terseness. Overusing functional programming can certainly lead to unreadable and/or unsafe and/or slow code, as would taking any one programming approach to be your hammer and pretending everything else is a nail (or in the case of C++, a thumb).
When you code in CAnd that's why C is the most used language for security programming
trading off security
Come to think of it, anything in the world is all about tradeoffswow so wize
public static D[] map<S,D>(S[] xs, Func<S,D> f) {
D[] ys = new D[xs.Length];
int i = 0;
foreach (var x in xs) ys[i++] = f(x);
return ys;
}
And that's why C is the most used language for security programmingAnd that conclusively proves that people are retards.
Why is dynamic typing bad?
actually_a_str += 5
where actually_a_str
was expected to be an int
.char lname[30], fname[30], mobile[15];
from main.if (c == '3') break;
could be optimized with a goto
under case '3':
that exits the while loop.Record
structure to save a pointer to the last node in the list, you could eliminate the linear search for the end in the insert
function. It may be good form to separate the Record
constructor from the list insertion procedure, as in the future you may wish to make a Record but not necessarily insert it into a list, but that's not a big deal.viewall
can just take a Record*
since it doesn't need to modify the pointer to the list.So in short, dynamic typing is good for shitty and short php scripts that no one cares about, and is bad for everything else.So in short, static typing is good for shitty and short C programs that no one cares about, and is bad for everything else.
UTF-8 encodes each of the 1,112,064 code points in the Unicode character set using one to four 8-bit bytes (a group of 8 bits is known as an "octet" in the Unicode Standard). Code points with lower numerical values (i.e. earlier code positions in the Unicode character set, which tend to occur more frequently) are encoded using fewer bytes. The first 128 characters of Unicode, which correspond one-to-one with ASCII, are encoded using a single octet with the same binary value as ASCII, making valid ASCII text valid UTF-8-encoded Unicode as well.
For it to really work it needs to be interactive. Or the analyzer would need to list all inferred types so the programmer could look through it and find the ones that doesn't match what they thought, and fix the problem there.This is actually what I was thinking about, thank you for articulating it so nicely. Sometimes this can be difficult, for example if the code is actually part of macroexpanded code, but it should still be feasible. Most of the time the static analyzer will be complaining about the lack of annotations rather than pointing out mismatches.
I think the easiest way to get this would be to have the analyzer output the code in a sub language with explicit types, and then feed this into a secondary compiler.Or just let the compiler accept type hints (like CLs have been doing since forever) and use them whenever it can.
The server space and domain are paid off for forever
The more global variables you have, the more you have to worry about exactly what each function may do in terms of unexpected side effects. If you have no global variables, you can look at just what a function returns and what it calls. If you have many global variables modified in a function, you have to track each one down across every other part of your program to figure out what a function actually does.So when I avoid global variables, I do so for reasons of clarity.