C as first language?

M

Malcolm McLean

On 21/05/14 15:37, Stefan Ram wrote:

It often makes sense to think in terms of programming paradigms rather
than programming languages. The way you design an algorithm in C and in
Haskell is likely to be significantly different, but the algorithm in C
and Pascal is likely to be very similar (both are imperative languages)
while the algorithm in Haskell and OCaml will be similar (both are
functional programming languages). In each case, however, the
beginnings of the design are the same - you start with pencil and paper,
or a whiteboard, with a combination of maths, natural language and lines
and arrows rather than any programming language.
Depending on the task. I'd divide programming tasks into four general categories.

1) trivial bit shuffling functions. Functions like strlen(), or even like sprint(), which
any programmer ought to be able to write if he puts in enough effort.

2) Non-trivial bit shuffling functions. E.g. an attack on the travelling salesman problem,
which you could approach in several ways, and it's not obvious which will be best.

3) low-level IO functions. These are often difficult to write, but it's a different type of
difficulty. The challenge is in understanding how the hardware is reacting and
synchronising with it in the right way.

4) Glue code. This is often called "business logic". The rules are complex and have to
be right, but there's no fundamental algorithmic complexity in them. it's case of
having an appropriate library of the other functions, and calling them at the right time.


The type of design you need varies depending on the task.
 
B

BartC

Malcolm McLean said:
The Open GL programmers' guide famously glossed C as "God's own
programming language".
It's almost perfect as an abstraction of a general assembler.

It's some way off being perfect. (I'm working on a compiler which is now
targeting native code rather then C source; there is considerable extra
freedom in doing things that either C can't express, or doesn't allow, or
would generally moan about for no good reason.)
All procedural languages perform arithmetical or logical operations, copy
memory from
one location to another, and allow conditional jumps,
plus some mechanism for jumping to
a passed address.

What does that correspond to in C; function pointers?
The core C language provides what you need, and no more. So if you're
thinking of an
algorithm you'll think of it in C terms - usually, in terms of a graph
connected by pointers,
and operations on that graph.

I think of C as being used to implement something better! Or rather, higher
level.

If you look at any general algorithm, then in any dynamic language, you can
almost implement directly as expressed. Not so in C, not if it lacks support
for certain features (strings and lists for example, or containers of mixed
types).
 
B

Ben Bacarisse

Malcolm McLean said:
The Open GL programmers' guide famously glossed C as "God's own
programming language". It's almost perfect as an abstraction of a
general assembler.

All procedural languages perform arithmetical or logical operations,
copy memory from one location to another, and allow conditional jumps,
plus some mechanism for jumping to a passed address. You need a
slight layer over those to have a usable, non-assembly language, such
as an infix expression syntax, named variables with scoping, and a
subroutine call mechanism. But that's all you really need. The core
C language provides what you need, and no more.

Both B and BCPL have those things, and yet C was designed precisely
because of what B lacked, so to make your statement true, you need to
include some more stuff.
So if you're thinking
of an algorithm you'll think of it in C terms - usually, in terms of a
graph connected by pointers, and operations on that graph.

In what terms do people who don't know C think in when they think of an
algorithm? Was Euclid thinking "in C terms" when he devised his famous
GCD algorithm?
 
M

Malcolm McLean

Both B and BCPL have those things, and yet C was designed precisely
because of what B lacked, so to make your statement true, you need to
include some more stuff.
Maybe. I tried to be exhaustive, but I might have missed something important.
Obviously not essential, B was presumably usable, but not as nice as C.
In what terms do people who don't know C think in when they think of an
algorithm? Was Euclid thinking "in C terms" when he devised his famous
GCD algorithm?
Obviously Euclid didn't have a C compiler.

The algorithm is

Start with a pair of positive integers, a and b.
while the two integers are unequal
set a to the minimum of a and b
set b to the absolute difference between a and b
repeat
The answer is the value.

That maps pretty well to C thinking, you've got a while loop in there, and comparison operators.
Also a and b are variables you keep track of, not parameters. I can't read Greek so I
can't read Euclid's original text, and in my summary the fact that a is corrupted by the
first step is glossed over - Euclid may or may not have done that, it's a normal thing to
do when describing an algorithm in natural rather than formal language.

So yes, we're thinking of it in C terms - while loops, comparisons, a sub-function which takes
the minimum. Not in pure assembler terms, where you might only have x, y and a registers
and not be able to devote one to a and one to b. Not in object-oriented terms where a
and b are anything that supports the < and - operators. Not in Lisp terms whereby each
step is a recursive call to the previous one. C terms are the natural ones that most people
use when thinking about algorithms.

Obviously since I've been a C programmer for so long I no longer have an objective view of
the matter. But I programmed for about ten years before learning C, and I felt that very
shortly after learning the language.
 
B

BartC

Malcolm McLean said:
Obviously Euclid didn't have a C compiler.

The algorithm is

Start with a pair of positive integers, a and b.
while the two integers are unequal
set a to the minimum of a and b
set b to the absolute difference between a and b
repeat
The answer is the value.

Which one, a or b? (I tried it and it didn't seem to work, ending up with
both zero).
That maps pretty well to C thinking, you've got a while loop in there, and
comparison operators.
So yes, we're thinking of it in C terms - while loops, comparisons, a
sub-function which takes
the minimum.

I don't know why you think these basic arithmetical ops are the exclusive
domain of C; most languages will have them too!

So, for example, I can write code in one of my languages to calculate the
GCD (using a different algorithm from yours) of 31415926534676736647 and
438478473847834834784748 (answer 7). Trying it in C however didn't work
(overflow in constant).
C terms are the natural ones that most people
use when thinking about algorithms.

More likely they think in terms of pseudo-code. Such code doesn't have
annoying details such as data types and limits to worry about or to specify
(and it tends to have less punctuation).

A lot of pseudo code will *not* translate to functioning C without a lot of
work. With some languages, however, it can almost be directly transcribed.

Of course nothing stops you using C *syntax* to write pseudo-code in, but
actually running the result is another matter unless it's known to be within
the language's capabilities.
 
M

Malcolm McLean

So, for example, I can write code in one of my languages to calculate the
GCD (using a different algorithm from yours) of 31415926534676736647 and
438478473847834834784748 (answer 7). Trying it in C however didn't work
(overflow in constant).
C's got an issue with machine precision. An int means "an integer, as long
as you are sensible", not "the largest integer that can be represented
on your 100TB hard drive".
It's seldom much of a problem.
 
G

glen herrmannsfeldt

(snip, someone wrote)
The OP linked learning a language to getting involved in OS
development. Were you thinking he could use Java to develop an
OS or just as a first step before learning C or another language?

I like the analogy that someone else posted, about manual or automatic
transmissions. For a new driver to also have to learn how to shift at
the same time, isn't easy. Now, presumably 100 years ago that is what
they did, but cars have improved since then.

Java intentionally (more than C++) has many features from C.
It also requires bounds checking on arrays, and for casts on
objects that aren't appropriate. Java requires casts on narrowing
conversions, which helps avoid some strange mistakes that can
easily trap C programmers.

The "objects late" teaching style uses static methods for much
of the teaching and practice, and so is more C like.

If one was interested, there is a JOS project, to work on an OS
in Java. As well as I know, it is going pretty slow, though.

-- glen
 
I

Ian Collins

What do you guys think is the benifit of learning C first?

For what you want to do, it's a fair choice. Python will also be useful.

Otherwise I'd say learn C++ first and get C for free!
 
J

Jorgen Grahn

.
I like the analogy that someone else posted, about manual or automatic
transmissions. For a new driver to also have to learn how to shift at
the same time, isn't easy. Now, presumably 100 years ago that is what
they did, but cars have improved since then.

Java intentionally (more than C++) has many features from C.

C++ is /intentionally/ a superset of C. Java has curly brackets, but
what else? [0]
It also requires bounds checking on arrays, and for casts on
objects that aren't appropriate. Java requires casts on narrowing
conversions, which helps avoid some strange mistakes that can
easily trap C programmers.

To me that sounds as an argument /against/ using Java to learn C. You
/will/ need to learn to handle those aspects of C, and postponing that
learning seems risky.

Hell, I wouldn't even recommend using C++ to learn C -- and I really
prefer C++ to C.

/Jorgen

[0] Here I must admit here I haven't used Java for 16 years or so.
They might have added pointers, manual heap management and
call-by-value while I wasn't looking.
 
G

glen herrmannsfeldt

(snip, I wrote)
C++ is /intentionally/ a superset of C. Java has curly brackets, but
what else? [0]

I think for me, it was the C++ overload of << and >> that discouraged
me. Yes that is a small thing, but it was enough. Java makes fewer
changes to the operators and the way they are used. (I disagree
with the Java overload of +, but I can get used to it.)

If you haven't looked lately, you might look at a relatively
new addition, System.out.format(). Very interesting for C
programmers!
To me that sounds as an argument /against/ using Java to learn C.
You /will/ need to learn to handle those aspects of C, and
postponing that learning seems risky.

And those driving manual transmissions will need to learn to shift
gears, but if you have never touched a car before, and especially
never tried steering, consider the first time you are partway
around a curve and the instructor asks you to shift gears.
Hell, I wouldn't even recommend using C++ to learn C -- and I really
prefer C++ to C.
[0] Here I must admit here I haven't used Java for 16 years or so.
They might have added pointers, manual heap management and
call-by-value while I wasn't looking.

It has changed a lot in 16 years. Java is always call by value,
pretty much in the same way that C is. Primitive types are
always passed by value, and objects are always processed through
reference variables, which are passed by value.

-- glen
 
M

Malcolm McLean

It has changed a lot in 16 years. Java is always call by value,
pretty much in the same way that C is. Primitive types are
always passed by value, and objects are always processed through
reference variables, which are passed by value.
If you know C or C++, you get that instantly. All objects go on the
heap and are accessed via a pointer to them.
However it can be confusing to people new to programming.
 
J

Jorgen Grahn

[0] Here I must admit here I haven't used Java for 16 years or so.
They might have added pointers, manual heap management and
call-by-value while I wasn't looking.

It has changed a lot in 16 years. Java is always call by value,
pretty much in the same way that C is. Primitive types are
always passed by value, and objects are always processed through
reference variables, which are passed by value.

It sounds as the same system that Python uses ... I'm familiar with
/that/ one, and it's IMHO very different from C's. If that's pretty
much like C, then I cannot think of a language which isn't!

/Jorgen
 
J

James Kuyper

[0] Here I must admit here I haven't used Java for 16 years or so.
They might have added pointers, manual heap management and
call-by-value while I wasn't looking.

It has changed a lot in 16 years. Java is always call by value,
pretty much in the same way that C is. Primitive types are
always passed by value, and objects are always processed through
reference variables, which are passed by value.

It sounds as the same system that Python uses ... I'm familiar with
/that/ one, and it's IMHO very different from C's. If that's pretty
much like C, then I cannot think of a language which isn't!

Of the languages I'm familiar with, all of the following are, IMO,
substantially more different from C than Java is,

APL
COBOL
RPG II
SQL
Haskell
 
J

Jorgen Grahn

For what you want to do, it's a fair choice. Python will also be useful.

"Learn a bunch of reasonable and useful languages" is good advice.
And Python is a fine language. Popular, too.
Otherwise I'd say learn C++ first and get C for free!

There are lots of C things you don't want to learn if you're learning
C++, though. I wouldn't recommend a "two for the price of one"
strategy, especially since there are too many people writing C in C++
already.

I /would/ recommend skipping C and going straight to C++, while still
being able to use the same set of C libraries and tools ... but that
would be rude considering this is comp.lang.c.

(Also I tend to get paid for writing C code, but not C++.)

/Jorgen
 
I

Ian Collins

Jorgen said:
"Learn a bunch of reasonable and useful languages" is good advice.
And Python is a fine language. Popular, too.

I don't know how things are done elsewhere, but all of my clients who
produce "embedded" (some are Linux based) C products use Python for
their acceptance and production test systems. I'm guessing this is a
pretty popular combination. On the OS front, I'm not sure about Linux,
but Solaris derived systems use a lot of Python.
There are lots of C things you don't want to learn if you're learning
C++, though. I wouldn't recommend a "two for the price of one"
strategy, especially since there are too many people writing C in C++
already.

I /would/ recommend skipping C and going straight to C++, while still
being able to use the same set of C libraries and tools ... but that
would be rude considering this is comp.lang.c.

(Also I tend to get paid for writing C code, but not C++.)

Write your unit tests in C++!
 
B

Ben Bacarisse

Malcolm McLean said:
Maybe. I tried to be exhaustive, but I might have missed something
important.

Types. B is typeless, C has types. They not included in your list of
"all you really need" so it's for you to say if you really need them
i.e. that you missed something important, or, alternatively, that C has
*more* than you need.
Obviously not essential, B was presumably usable, but not as nice as
C.

Obviously Euclid didn't have a C compiler.

The algorithm is

Start with a pair of positive integers, a and b.
while the two integers are unequal
set a to the minimum of a and b
set b to the absolute difference between a and b
repeat
The answer is the value.

In Euclid, the procedure is presented twice to determine two separate
things. What you've written is the abstraction of the common part into
a single procedure. Euclid never did that (it was presumably not
important to him; he surely knew that there was something important in
common between the two). Furthermore, you have taken his wording of
"measures" (remainders) and lengths and turned it into a notation of
variables and loops. That all comes from you.

Someone familiar with, say, Haskell would have written this algorithm in
a different pseudo-code.
That maps pretty well to C thinking,

I think you agree with me. I said:

"the trick is to think in terms of programs that map into C"

That's exactly what you are doing. You've abstracted the algorithm from
one form (the rather ill-specified wording in the original) but you've
been careful to do that in a way that maps to into C. People with other
perspectives will see it differently.
you've got a while loop in there,
and comparison operators. Also a and b are variables you keep track
of, not parameters. I can't read Greek so I can't read Euclid's
original text, and in my summary the fact that a is corrupted by the
first step is glossed over - Euclid may or may not have done that,
it's a normal thing to do when describing an algorithm in natural
rather than formal language.

Are you looking at proposition I or II? Proposition II (the GCD one)
starts (and I too must rely on translation):

Let AB and CD be the two given numbers not relatively prime.

I don't see that in your algorithm. Could it be that you (or th editor
of your edition) abstracted
something out that was not there in the original?
So yes, we're thinking of it in C terms - while loops, comparisons, a
sub-function which takes the minimum.

Who's "we"? You and Euclid? I don't see how you can say that. If you
are trying to be inclusive, let me quote Samuel Goldwyn: include me out.
Not in pure assembler terms,
where you might only have x, y and a registers and not be able to
devote one to a and one to b. Not in object-oriented terms where a and
b are anything that supports the < and - operators. Not in Lisp terms
whereby each step is a recursive call to the previous one. C terms are
the natural ones that most people use when thinking about algorithms.

But you are avoiding the main question: if what you say is true, how do
people who don't know C, or, if you are backing down form that, a C-like
language, think about algorithms? How did Church think about his
effective procedures? Not in terms of C or anything like it, that's for
sure.
 
S

Stefan Ram

glen herrmannsfeldt said:
It also requires ....
for casts on
objects

In Java, the type of an object can be retrieved by
.getClass(). This object type cannot be modified by any
means, not even by a cast operator. It is immutable.

What you might have in mind are reference expressions.
The type of those can be set by a cast indeed.
Java requires casts on narrowing conversions, which helps
avoid some strange mistakes that can easily trap C
programmers.

This is similar to C++11, where IIRC

constexpr int i{ 1.1 };

gives an error: narrowing!
The "objects late" teaching style uses static methods for much
of the teaching and practice, and so is more C like.

The main-method of Java is static. So, unless one finds a
way to circumvent this main method in teaching, one is
forced to start with a static method declaration for the
hello-world program. Common utility methods, like »abs« or
»max« are static too.
If one was interested, there is a JOS project, to work on an OS
in Java. As well as I know, it is going pretty slow, though.

Yes. But to the common programmer who is not using the NDK,
Android appears to be a kind of Java OS, because Java is its
default programming language.
 
S

Stefan Ram

Jorgen Grahn said:
They might have added pointers, manual heap management and
call-by-value while I wasn't looking.

Java had pointers from the start. (That is, »pointers« in
the sense of the JLS - not in the sense of N1570, of course.)

The JLS 1 from 1996-08 already said:

»The reference values (often just references)
are pointers to these objects«

All of these words have /different/ meanings in Java and in C:
»object«, »variable«, »pointer«. What Java defines as a
»variable« is what C calls an »object«, for example.

The JLS 1 starts with this quotation:

»"When I use a word," Humpty Dumpty said,
in rather a scornful tone, "it means just what I
choose it to mean - neither more nor less."
"The question is," said Alice, "whether you
can make words mean so many different things."
"The question is," said Humpty Dumpty,
"which is to be master - that's all."

- Lewis Carroll, Through the Looking Glass«.
 
S

Stefan Ram

Ben Bacarisse said:
But you are avoiding the main question: if what you say is true, how do
people who don't know C, or, if you are backing down form that, a C-like
language, think about algorithms?

An algorithm expresses the solution to a problem with the
elements of a given language, whatever language this is.
 
J

James Kuyper

An algorithm expresses the solution to a problem with the
elements of a given language, whatever language this is.

According to Malcolm, that language is always "C". Ben is just pointing
out that this is a problematic assertion if it's intended to apply to
people who never learned "C". It's almost as problematic to apply it to
people who don't particular like "C".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top