Searching \ for '[EE] Self documenting code vs. Comments' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/index.htm?key=self+documenting
Search entire site for: 'Self documenting code vs. Comments'.

Exact match. Not showing close matches.
PICList Thread
'[EE] Self documenting code vs. Comments'
2008\10\06@002201 by Vitaliy

flavicon
face
Olin Lathrop wrote:
> Self documenting code where the author thinks its a replacement for
> comments
> is usually worse than terse names with profuse comments.  The right answer
> is of course to do both.  Names you think at the time tell you everything
> you need to know will leave things out.

Let me say right off the bat, that I am not suggesting not using comments at
all.

The problem I see is that well-meaning programmers use comments to try to
make up for the shortcomings of their code. I think they should practice
writing self-documenting code, because it has several important advantages
over comments:

- Function and variable names rarely get out of date
- Good names eliminate the need for line-by-line comments
- You cannot "forget" or "put off until later" naming a function or a
variable
- It helps the programmer maintain code cohesion, by focusing their
attention on the purpose of the function

This last point is very significant, IMHO. Comments are passive -- you use
them to describe what a function does, often after you've already written
it. A well chosen name actively shapes the implementation of a function. If
a piece of code you're trying to put into the function does not agree with
the name, you know you should either change the name, or (which happens more
often) put the code into another function.


> Good comments will complement well chosen names.  If you really believe
> the
> name is clear and tells you what it's about, use the comment to describe
> the
> next level up purpose.

I believe that the real purpose of comments is to provide the context, to
explain *why* something is being done (never *what* is being done). If you
follow the principles of tight cohesion, and keep the functions short (20
lines or less, is my rule of thumb) you can name the function in a way that
describes exactly what it does.


> Even if the subroutine name tells me you are getting
> the forward voltage, tell me why you are getting it here and now, for
> example. In fact, the real purpose of good naming is to allow the comments
> to provide this next level up information while leaving less confusion
> about
> the details.

This goes agains the principle of loose coupling. The function should only
be responsible for itself. It has no business knowing anything about the
function(s) that are calling it, or what they're doing with the return
value.


> A well chosen name doesn't mean rediculously verbose either.  Horizontal
> space is precious, in part because it eats into how much you get to
> explain
> in the end of line comment.  If you want to reference a symbol in a
> comment
> additionally, a long name eats into characters that might be better spent
> telling something else about the symbol or why it is being used here.

That's actually an excellent argument for not commenting every line. Use the
space you would otherwise waste on comments, to create a descriptive
function name. Make it as long as necessary. If the name is too long, it
will tell you that the function is doing too many things, and needs to be
broken down into smaller, more cohesive functions.


> While it's good to have symbol names give some idea what they're about,
> you
> should think of characters spent as being precious and use them wisely.

Why?! Characters in symbol names are *free*. Your suggestion goes against
the recommendations of leading programmers, and common sense.


[snip]
> This is a good example of a useless verb and a missing comment.  This
> function takes no arguments and returns a value.  In the code:
>
>>  forwardVoltage = GetForwardVoltage();
>
> It would be pretty obvious this function is getting something.

Make the function name more vague -- to save three letters?

Functions are verbs, which act on nouns (variables). Therefore, a function
name must have a verb in it, to help improve understanding.

Moreover, a lot of times you have no other option but to use a "Get" and a
"Set". For example:

void SetOvenTemperature(int temperature);
int GetOvenTemperature();


> The bad part
> about these two lines is that the comment was omitted.  That is a wasted
> opportunity to explain the next level up what the function is about or
> what
> the forward voltage is or why you'd want to get it right there.

So, change the function name to say exactly what it does. Put the comment
inside the function name, and you won't have to remember to copy/paste the
comment everywhere you use it.


{Quote hidden}

Unfortunately, neither comment makes sense in the context of the
application:

http://www.jasonhsu.com/swrwatt-c.txt

If they did, then I would suggest something like:

   if ( FinallyReachedMinimumLevel() )
       LightMinimumLevelLed()

or

   if ( IsAboveSafeOperatingLimit(ForwardVoltage) )
       SoundCriticalAlarm();


> Note how the comment makes a huge difference in describing the purpose of
> the statement.

Another great reason why you shouldn't use them: you don't know whether the
comment truthfully describes what actually happens. Put the comment in the
name instead.


> As a separate nit pick, I wouldn't want to see "100" hard coded like that.
> That should be a symbolic value defined at the top or in a master include
> file.

Agreed. "Magic numbers" should be avoided.


> So the two statements really should be:
>
>  if (ForwardVoltage() > MinValid) { //finally reached minimum level ?
>
>  if (ForwardVoltage() > MaxSafe) {  //above safe operating limit ?

Again, the usefulness of these examples is limited because they don't
reflect what actually happens in Jason's code. It's not "Minimum Level" or
"Safe Operating Limit", it's just a value that Jason is using to determine
whether to light a particular LED in the LED bar.


IMHO, comments have three uses:

   - Provide context
   - Explain why something is being done in an unexpected way
   - Seve as crutches when I'm too lazy to come up with a good name

Only the first two uses are legitimate. I still use the third one
occasionally, but I always try to go back and refactor the code to make the
comments unnecessary. To me, comments are red flags that mark spots in my
code that need more work.

Best regards,

Vitaliy

2008\10\06@082052 by olin piclist

face picon face
Vitaliy wrote:
> - Good names eliminate the need for line-by-line comments

I think this is our major disagreement.  A good subroutine name, for
example, can at best explain what the subroutine does.  Only a comment can
explain why that function is being used right here right now.

> Comments are passive --
> you use them to describe what a function does, often after you've
> already written it.

No!  Header comments describing a subroutine must be written first, then the
subroutine written.  You can't implement something until you've designed it.
The comments put down in writing the design of the interface to the
subroutine.  The header comments are sometimes useful to refer back to
during coding since they are the spec.

Of course you can change your mind as you get into the implementation and
update the comments accordingly.  Sometimes you encounter issues in
implementation that you didn't consider when you designed the subroutine
interface.  You have to be flexible enough to allow the subroutine to be
redefined as makes sense within the overall system.

> This goes agains the principle of loose coupling. The function should
> only be responsible for itself. It has no business knowing anything
> about the function(s) that are calling it, or what they're doing with
> the return value.

I was referring to comments by the call, not the subroutine definition.
Even if the subroutine name explains exactly what it does, it can't explain
why you are doing that particular thing right here now.

> That's actually an excellent argument for not commenting every line.
> Use the space you would otherwise waste on comments, to create a
> descriptive function name. Make it as long as necessary. If the name
> is too long, it will tell you that the function is doing too many
> things, and needs to be broken down into smaller, more cohesive
> functions.

But then where do you describe the why as apposed to the what of the
subroutine call.

> Why?! Characters in symbol names are *free*. Your suggestion goes
> against the recommendations of leading programmers, and common sense.

Horizontal space on a line is limited.  Everybody's window has some max
width, and long lines get cumbersome to handle.  Therefore characters used
in one part of the line take away from possible use in other places.
Comments perform a important function that can't be replaced by any amount
of clever naming, and therefore have their purpose on most lines.  You need
to ballance explaining the what with the why.  Clever names can only tell
you the what at best.

> Make the function name more vague -- to save three letters?

My point was that actually no information is lost.

>> The bad part
>> about these two lines is that the comment was omitted.  That is a
>> wasted opportunity to explain the next level up what the function is
>> about or what
>> the forward voltage is or why you'd want to get it right there.
>
> So, change the function name to say exactly what it does. Put the
> comment inside the function name, and you won't have to remember to
> copy/paste the comment everywhere you use it.

Again, the function can only explain what it does, not how and why it is
being used in a particular instance.

>>  if (ForwardVoltage() > 100) {  //finally reached minimum level ?
>>
>> or
>>
>>  if (ForwardVoltage() > 100) {  //above safe operating limit ?
>
> Unfortunately, neither comment makes sense in the context of the
> application:

It was just a example I made up.  I wasn't suggesting this code for any
particular application.

>     if ( FinallyReachedMinimumLevel() )
>         LightMinimumLevelLed()
>
> or
>
>     if ( IsAboveSafeOperatingLimit(ForwardVoltage) )
>         SoundCriticalAlarm();

But shouldn't that be:

 LightMinimumLevelLedWhenFinallyReachedMinimumLevel ();

 SoundCriticalAlarmIfAboveSaveOperatingLimit ();

Where does this end?  At some point you have to write some real code.

Nested levels of abstraction is a fundamental concept of software, but it
can be carried too far just like any good idea.  In my opinion, you're off
the deep end with this.

Vitaliy, I know you're a smart guy, but I think you've read too many books
and papers by ivory tower computer science types that have forgotten (or
maybe never knew) what it was like to get real projects done.  All these
high-fallooten concepts have their applications in various places, but
should all be taken with some salt and they aren't the cure-all they each
claim to be.  Just because someone came up with a better way of doing
something in the narrow niche they tested and wrote a book about it, doesn't
mean it should be blindly adopted in all other cases.  Read the book, gather
the ideas, but then let some reality set in to decide when and if to use
them.

2008\10\06@091806 by Jeff Findley

flavicon
face

"Vitaliy" <spam_OUTspamTakeThisOuTspammaksimov.org> wrote in message
news:04d001c9276b$0099e780$6f02a8c0@ws11...
> - Function and variable names rarely get out of date
> - Good names eliminate the need for line-by-line comments
> - You cannot "forget" or "put off until later" naming a function or a
> variable
> - It helps the programmer maintain code cohesion, by focusing their
> attention on the purpose of the function
>
> This last point is very significant, IMHO. Comments are passive -- you use
> them to describe what a function does, often after you've already written
> it. A well chosen name actively shapes the implementation of a function.
> If
> a piece of code you're trying to put into the function does not agree with
> the name, you know you should either change the name, or (which happens
> more
> often) put the code into another function.

I've got to disagree here, at least when dealing with complex systems.
Where I work, we typically use function comments to document pre and post
conditions as well as argumets (in/out/out that needs free'd, etc.).  If you
don't do this sort of documentation, then you have to read through the whole
function just to call it.  That's absolutely silly when you're working on
big projects with many developers spread across the globe.

Jeff
--
A clever person solves a problem.
A wise person avoids it. -- Einstein




2008\10\06@095123 by Tamas Rudnai

face picon face
> I've got to disagree here, at least when dealing with complex systems.
> Where I work, we typically use function comments to document pre and post
> conditions as well as argumets (in/out/out that needs free'd, etc.).  If you
> don't do this sort of documentation, then you have to read through the whole
> function just to call it.  That's absolutely silly when you're working on
> big projects with many developers spread across the globe.

Thanks, just as I was saying that! Also should keep in commented what
global variables (or registers in assembly) is destroyed, or if there
is a heap handling if there is any resource on heap created by the
function and supposed to release somewhere else. Personally I do not
like functions without function headers, also I expect to have a file
header at the beginning of each source that contains information of
the module instead of the licensing unlike the typical GPL'ed
projects...

BTW: Visual Studio handles function headers very well so that it can
bring up all the comments right before a function (in reflecting to
what someone mentioned here recently that a VS can be used as an IDE
for PIC projects). Also someone can use doxygen to document code which
makes sense if more than one departments / partners / coders are
working on a bigger project.

Tamas


On Mon, Oct 6, 2008 at 2:17 PM, Jeff Findley <.....jeff.findleyKILLspamspam@spam@ugs.com> wrote:
{Quote hidden}

> -

2008\10\06@100445 by John Chung

picon face



--- On Mon, 10/6/08, Olin Lathrop <.....olin_piclistKILLspamspam.....embedinc.com> wrote:

{Quote hidden}

 Books can state a world on comments but it has to end somewhere.
If I was to comment my entire code it would not be effective. It is
a blend of code and comments when the intention is not clear. I than
to write better comments when I keep the projects for a long time. Still
does it make sense to heavily comment on a project you will throw or delete
after a week working on it?

John




     

2008\10\06@115618 by olin piclist

face picon face
John Chung wrote:

> ...

You just quoted all 175 lines of the original post without quoting, then
added 6 lines without responding specifically to anything you quoted.
Please learn to use the editor in your mail program.

> I than
> to write better comments when I keep the projects for a long time.
> Still does it make sense to heavily comment on a project you will
> throw or delete after a week working on it?

Yes, it does.

First, when comments are used properly, they help you write the code in the
first place.  Think of them as explaining the code to this hypothetical
person looking over your shoulder.  You will catch a few oopses when trying
to explain things to him.

Second, code has a way of living on even if the original intent is a
temporary throw away program.

Comments should be thought of as integral to the code itself.  They are not
something you grudginly add later, but something that helps you (and saves)
time right from the start as your coding.  In other words, the payback time
for comments is immediate, so of course you use them in all code, whether
intended to be short lived or not.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\06@120604 by olin piclist

face picon face
> You just quoted all 175 lines of the original post without quoting,

Doh.  I meant to say "without trimming".

********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\06@124232 by Brian B. Riley

picon face
   ... amen ... this should be chiseled in stone (or punched in  
Hollerith!) somewhere prominent to be repeated ad nauseam until each  
new programmer can say  by rote!

On Oct 6, 2008, at 11:55 AM, Olin Lathrop wrote:

{Quote hidden}

--
cheers ... 73 de brian  riley,  n1bq , underhill center, vermont
  <http://web.mac.com/brianbr/>  Tech Blog
  <http://www.wulfden.org/TheShoppe/>
   Home of the
      K107 Serial LCD Controller Kit    FT817 Power Conditioner Kit
      Tab Robot Laser Tag Kit             MSP430 Chips and Connectors
      Propeller Robot Controller          SX48 "Tech Board" Kit
      PICAXE chips and accessories   Freeduino systems




2008\10\06@161251 by Vitaliy

flavicon
face
Hi Olin,

I just came home from a 12-hour coding marathon, so I hope you'll forgive me
for not addressing all of the points. %-)

{Quote hidden}

Of course not. The "if" statements are much more readable.

{Quote hidden}

Here is a list of the books that I'd say had the most profound effect on how
I think about programming:

"Code Complete"
by Steve McConnell

"Refactoring: Improving the Design of Existing Code"
by Martin Fowler, Kent Beck, John Brant, and William Opdyke

"Design Patterns Explained"
by Alan Shalloway, James Trott

"Lean Software Development: An Agile Toolkit"
by Mary Poppendieck, Tom Poppendieck

The authors are not "ivory tower computer science types", they are industry
professionals with many decades of experience. Check out Steve McConnell's
credentials, for example (a very short article):

http://en.wikipedia.org/wiki/Steve_McConnell

I am not a great programmer, and I don't claim to have vast programming
experience. However, I've spent enough late nights and early mornings
following blind alleys, banging my head against the wall, and pulling my
hair out in frustration to be able to say that I know what it's like in the
"real world". I am happy to say that during the last couple of years, I have
gradually discovered a systematic approach that allows me to tackle complex
projects with confidence. I know now that software development is about
managing complexity, and continuious, incremental refinement. I no longer
get stuck like I used to, because I have a clear strategy for untangling a
poorly written piece of code, and isolating bugs. It's a great feeling!

For the past four months, I've been working on a fairly complicated project
(it was recently split into two products, one of which we'll be launching
later this month). I am applying the things I've read about, and I can tell
you that I've never felt so much in control, or written code that was so
easy to understand, expand, and maintain.

The next hurdle is making the techniques work on a team level. :)

Vitaliy

2008\10\06@215153 by John La Rooy

flavicon
face
In Python we frequently use doctests http://en.wikipedia.org/wiki/Doctest

Here is an example form the wikipedia page. The comment contains actual code as
one might type into the interpreter. The output of the function has to
match what is
written in the comment or the doctest will fail.

Suppose a programmer changes the behaviour of the function but does
not update the
comment - the doctest will likely fail and so give a strong reminder
that this comment also
needs to be updated.


def list_to_0_index(lst):
   """A solution to the problem given in:
   http://rgrig.blogspot.com/2005/11/writing-readable-code.html

   'Given a list, lst, say for each element the 0-index where it appears for
   the first time. So the list x = [0, 1, 4, 2, 4, 1, 0, 2] is
   transformed into y = [0, 1, 2, 3, 2, 1, 0, 3]. Notice that for all
   i we have xyi = xi. Use any programming language and any data
   representation you want.'

   >>> x = [0, 1, 4, 2, 4, 1, 0, 2]
   >>> list_to_0_index(x)
   [0, 1, 2, 3, 2, 1, 0, 3]
   >>>
   """

   return [lst.index(i) for i in lst]

2008\10\06@222633 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

> Vitaliy wrote:
>> - Good names eliminate the need for line-by-line comments
>
> I think this is our major disagreement.  A good subroutine name, for
> example, can at best explain what the subroutine does.  Only a comment
> can explain why that function is being used right here right now.

It seems to me that you guys are saying the same thing, mostly :)

Vitaliy wrote (in a part you snipped): "I believe that the real purpose of
comments is to provide the context, to explain *why* something is being
done (never *what* is being done)."

Sounds to me pretty much the same. When you talk about "header comments",
that's different from what Vitaliy is talking about in the quote with
"line-by-line comments". The line-by-line comments usually are not about
why, they mostly are about what. In general (note that I wrote here "in
general"! :) good written code doesn't need many line-by-line comments. It
does need occasional short paragraphs that explain the "why" -- and the
minimum of such paragraphs is the function header comment. I don't think
that you're in any disagreement with Vitaliy here.

> But then where do you describe the why as apposed to the what of the
> subroutine call.

In the header comment, which is a line or a short paragraph, but not an
end-of-line comment (or a series of those).

> Comments perform a important function that can't be replaced by any amount
> of clever naming, and therefore have their purpose on most lines.  

I disagree. I have yet to see good code where end-of-line comments are
necessary to understand it. Generally a short paragraph that outlines the
"why" of the next 10 or 20 lines or so, then well-structured code with
meaningful names that make sense in the light of the "why" paragraph does
it pretty nicely.

> You need to ballance explaining the what with the why.  Clever names can
> only tell you the what at best.

Exactly, and that's their purpose. Done right, there shouldn't be much need
for explaining the "what" in comments.

> Where does this end?  At some point you have to write some real code.

The thing is that I've seen code (and not just a little of it) where the
coder tried hard to do with short names, just to add a whole romance in
comments about what was being done. This is not normally good code. In
general, I find it more useful to write meaningful names and really sparse
comments about the "what". I often even create basically unnecessary
intermediate variables with names that explain what this intermediate value
is, rather than explaining that in a comment. The variable creation (in the
cases where it is really unnecessary) is optimized out by the compiler, so
it doesn't incur any runtime overhead. It just "explains" in code rather
than in comment what is being done.

> Vitaliy, I know you're a smart guy, but I think you've read too many
> books and papers by ivory tower computer science types that have
> forgotten (or maybe never knew) what it was like to get real projects
> done.  

There are different types of projects, and they require different forms of
practices. But I don't think that what Vitaliy was describing is off for
any size project -- it doesn't cost time (it most likely saves time), and
stuff like this helps me getting my projects done. (But then, I don't do
projects in assembly :)

Gerhard

2008\10\07@043153 by Alan B. Pearce

face picon face
>Comments should be thought of as integral to the code itself.  They
>are not something you grudginly add later, but something that helps
>you (and saves) time right from the start as your coding.  In other
>words, the payback time for comments is immediate, so of course you
>use them in all code, whether intended to be short lived or not.

Being the sort of guy who is bad at planning, I find a good technique for
programming is to write the program as pseudo code comments, then go back
and put real code between the comment lines.

2008\10\07@044325 by Vitaliy

flavicon
face
Alan B. Pearce wrote:
> >Comments should be thought of as integral to the code itself.  They
>>are not something you grudginly add later, but something that helps
>>you (and saves) time right from the start as your coding.  In other
>>words, the payback time for comments is immediate, so of course you
>>use them in all code, whether intended to be short lived or not.
>
> Being the sort of guy who is bad at planning, I find a good technique for
> programming is to write the program as pseudo code comments, then go back
> and put real code between the comment lines.

I use this technique too. Sometimes I also do design with paper and pencil
at a Jack in the Box (or another place that doesn't have a computer). My
most recent favorite is the whiteboard -- we installed two large ones in the
conference room last year. It's especially good for coming up with designs
collaboratively. :)

Best regards,

Vitaliy

2008\10\07@051056 by Vitaliy

flavicon
face
Gerhard Fiedler wrote:
> It seems to me that you guys are saying the same thing, mostly :)

You know, I got that feeling too. :)

{Quote hidden}

I use the same exact trick with the variables. :) And I prefer not to use
shorthand notation, I like:

   myVar = myVar + 5;

instead of:

   myVar += 5;

> There are different types of projects, and they require different forms of
> practices. But I don't think that what Vitaliy was describing is off for
> any size project -- it doesn't cost time (it most likely saves time), and
> stuff like this helps me getting my projects done. (But then, I don't do
> projects in assembly :)

Many of the techniques that initially seem like a waste of time, end up
producing better quality code in less time. I mean, take Agile for example.
Tradition and common sense say that you must gather requirements, create a
detailed design spec, and then simply implement the paper design in code.
Common sense tells you that you should focus your energy on writing the
perfect code the first time, because every time you are forced to rewrite
your code (refactoring), you are wasting your time.

FWIW, I don't code in assembly.

Vitaliy

2008\10\07@052911 by Tamas Rudnai

face picon face
For me, the long version is not mirroring what I would like to do. For
example, in my brain
  myVar = myVar + 5;

interpreted as
   movf   myVar,W
   addlw .5
   movwf  myVar

and this:
  myVar += 5;

as
   movlw   .5
   addwf    myVar,f

No matter if the compiler was nicely optimising the first expression
into the second, in my brain those are just not equivalent in terms of
optimizasion.

Anyway, if a code does not contain what it intended to do, then it may
wrong as well in my opinion. Maybe you can read the code and can
understand, but you have to write it down what you wanted to do so -
because your code may be wrong, and the code reviewer can spot
instantly that here and there you wanted to do this and that, but
instead of your intention there was something else coded by mistake -
therefore the code is wrong... I hope it clarifies why I think a
comment is very important and not only function headers but also
inline comments as well.

Tamas


On Tue, Oct 7, 2008 at 10:09 AM, Vitaliy <@spam@spamKILLspamspammaksimov.org> wrote:
{Quote hidden}

> -

2008\10\07@060740 by Alan B. Pearce

face picon face
>I use the same exact trick with the variables. :) And I prefer
>not to use shorthand notation, I like:
>
>    myVar = myVar + 5;
>
>instead of:
>
>    myVar += 5;

However, it does make it difficult to find an error like

   myVar = myVer + 5;

where an error in typing causes problems. It should be caught by the
compiler, but what if you managed to have a variable myVer in your code ...

2008\10\07@100810 by Jeff Findley

flavicon
face

"Vitaliy" <KILLspamspamKILLspamspammaksimov.org> wrote in message
news:006f01c927ef$d8f03e20$6f02a8c0@ws11...
> Here is a list of the books that I'd say had the most profound effect on
> how
> I think about programming:
>
> "Code Complete"
> by Steve McConnell
>
> "Refactoring: Improving the Design of Existing Code"
> by Martin Fowler, Kent Beck, John Brant, and William Opdyke
>
> "Design Patterns Explained"
> by Alan Shalloway, James Trott
>
> "Lean Software Development: An Agile Toolkit"
> by Mary Poppendieck, Tom Poppendieck
>
> The authors are not "ivory tower computer science types", they are
> industry
> professionals with many decades of experience.

The first two are great books.  The other two, I've not read.

The book on design patterns I like is "Design Patterns" by Gamma, Helm,
Johnson, and Vlissides.  It's a great reference.  If you liked the design
patterns book, there is also an Analysis Patterns book by Martin Fowler.
It's good too, but you should definitely read one or two design patterns
books first.

I still feel that comments are useful.  You just don't add comments like
this:

// loop over all points
for ( int i = 0; i < nPoints; ++i )
{
  ...
}

It's obvious from the contents of the for loop what it's looping over, so
the comment is just plain dumb.  Here is a better comment which is part of
the comments in a function header:

// Output
//    controlPoints - If not NULL, the caller must free this memory.

Even though controlPoints may be a descriptive variable name, it's essential
that the caller understand that they are responsible for freeing the memory
returned.  If they don't, it will cause a memory leak!

Jeff
--
A clever person solves a problem.
A wise person avoids it. -- Einstein



2008\10\07@101715 by Jeff Findley

flavicon
face

"Vitaliy" <RemoveMEspamTakeThisOuTspammaksimov.org> wrote in message
news:018101c9285c$8d54d8a0$6f02a8c0@ws11...
> I use the same exact trick with the variables. :) And I prefer not to use
> shorthand notation, I like:
>
>    myVar = myVar + 5;
>
> instead of:
>
>    myVar += 5;

This is a religious argument.  I prefer the latter since it's standard C/C++
and saves on typing.

However, I'll usually stick with one C "shortcut" per line of code.  When
you start combining too many of these shortcuts on one line of code, it can
be bewildering for someone new to understand what's going on.

Jeff
--
A clever person solves a problem.
A wise person avoids it. -- Einstein



2008\10\07@102030 by Jeff Findley

flavicon
face

"Alan B. Pearce" <spamBeGoneAlan.B.PearcespamBeGonespamstfc.ac.uk> wrote in message
news:TakeThisOuT430C7CE862944D3A9A5C20F2DF89E2D9EraseMEspamspam_OUTspace.rl.ac.uk...> > >Comments should be thought of as integral to the code itself.  They
>>are not something you grudginly add later, but something that helps
>>you (and saves) time right from the start as your coding.  In other
>>words, the payback time for comments is immediate, so of course you
>>use them in all code, whether intended to be short lived or not.
>
> Being the sort of guy who is bad at planning, I find a good technique for
> programming is to write the program as pseudo code comments, then go back
> and put real code between the comment lines.

Where I work, we do mostly object oriented programming (mostly in C++,
sometimes in Java) so we use design tools like Together or Visio to do
class, object, and sequence diagrams.  The sequence diagrams are the most
useful as they help you spot problems which would normally show up during
the implementation.

Some design tools will output the pseudo-code (headers and source with
comments from the design), but we typically don't do that.  The best design
tools can import actual code into the system, but we've found that our code
is too complex (way too many objects and too much legacy procedural code)
for this sort of thing.

Jeff
--
A clever person solves a problem.
A wise person avoids it. -- Einstein



2008\10\07@102710 by Tamas Rudnai

face picon face
> I still feel that comments are useful.  You just don't add comments like this:
>
> // loop over all points
> for ( int i = 0; i < nPoints; ++i )
> {
>   ...
> }

Certainly not, but you can have something like:

// search for the longest line
for ( int i = 0; i < nPoints; ++i )
{
 ...
}

...and then the code reviewer can spot that this should loop through
the "nLines" instead...

Tamas


On Tue, Oct 7, 2008 at 3:07 PM, Jeff Findley <RemoveMEjeff.findleyspamTakeThisOuTugs.com> wrote:
{Quote hidden}

> -

2008\10\07@111916 by olin piclist

face picon face
Jeff Findley wrote:
> // loop over all points
> for ( int i = 0; i < nPoints; ++i )
> {
>    ...
> }
>
> It's obvious from the contents of the for loop what it's looping
> over, so the comment is just plain dumb.

This is exactly why "self documenting" code is so dangerous.  By itself it
is a good idea, but it leads people to believe they don't have to write any
separate documentation.  This makes the end result worse in the wrong hands,
which unfortunately seems to be most of them.

I would make it a end of line comment so it doesn't visually detract from
the code, and it might be better to explain why you are looping over all
points, but to think the comment is dumb is what's dumb.  It might be
obvious to you that nPoints is the number of "points", but that word can be
taken differently in different contexts.  If you're doing a graphics system,
for example, there are many things that could be called "points".  Is it the
total points in the database, the points of a particular polygon, a
linearization of 2D points in a mesh, etc, etc?

I would like to see something like:

 for (int i = 0; i < nPoints; ++i) { //once for each polygon vertex

Even if the context of "points" is clearly understood in the program, the
short end of line comment saves time looking at the code to make sure you
are really starting at the beginning, that you're really looping over all of
them, etc.  And in case you screw up and make a off by one error, for
example, the comment shows the intent so someone maintaining the program
later can feel a lot better about fixing it.

Comments are not just to explain code, but also to help you make sure your
code does what you intend it to do.  If you did screw up and were off by one
or made some other small mistake, there is some chance you'll catch it when
explaining it to that mythical person looking over your shoulder by writing
the comment.  In other words, comments save time getting to the first
working version of code, not just later when it needs to be maintained.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\07@122307 by Mongol Herdsman

picon face
Vitaliy wrote:
>> Even if the subroutine name tells me you are getting
>> the forward voltage, tell me why you are getting it here and now, for
>> example. In fact, the real purpose of good naming is to allow the comments
>> to provide this next level up information while leaving less confusion
>> about the details.
>
> This goes agains the principle of loose coupling. The function should only
> be responsible for itself. It has no business knowing anything about the
> function(s) that are calling it, or what they're doing with the return
> value.

Principle of loosly coupling is just one of many rules with no global
scope. Apply rules wisely.

Look, you used "cohesive" word:
> Make it as long as necessary. If the name is too long, it
> will tell you that the function is doing too many things, and needs to be
> broken down into smaller, more cohesive functions.

So, what "loosly coupled" or "cohesive"? Choose one, Bolivar cannot
carry double.
Each and every sub can't be broken down into smaller reusable subs.
Most of lowest level subs will be unique. There is no sence making
them loosly coupled, that is reusable. Olin is right, explaining the
context of such unique subs would be a good idea.
The very idea of breaking complex subs into smaller "unique" subs is
good as for me, even if the subs are not reusable. And I beleive this
is what Olin and others are doing in their everyday coding.

2008\10\07@122725 by John Chung

picon face

>
>   for (int i = 0; i < nPoints; ++i) { //once for each
> polygon vertex
>
> Even if the context of "points" is clearly
> understood in the program, the
> short end of line comment saves time looking at the code to
> make sure you
> are really starting at the beginning, that you're
> really looping over all of
> them, etc.  And in case you screw up and make a off by one
> error, for
> example, the comment shows the intent so someone
> maintaining the program
> later can feel a lot better about fixing it.
>
 This is the type of comments I look for. More meaningful compared
to nPoint of ???? Self documenting can only go that far...

{Quote hidden}

 This part only works with the comments being updated. I have seen too
many comments not being updated. Comments does help us check our intentions. I do quite agree with Olin's point with comments. I just don comment that frequent like every 5 line. Only when I need to get the message across which is an art at times....


John


     

2008\10\07@123535 by John Chung

picon face



--- On Tue, 10/7/08, Jeff Findley <EraseMEjeff.findleyspamugs.com> wrote:

{Quote hidden}

 I tend to write expressive C code at times. Still it depends who is
going to inherit the code in the future. If it is for maintenance keep rich expression low...

John


     

2008\10\07@125903 by Neil Cherry

flavicon
face

This is not aimed at anyone. It's more my personal experience (which
tends to agree with Olin). An easy way to find out how good your methods
of commenting are is to look at code from a decade ago. While I am not
a programmer, I can program. I've found that the mix of self commenting
code mixed in with judicious comments at the correct levels (main code,
libraries, functions, complex math, etc.) is the best route. I've come
across code that dates back to 1984 and while I commented I did not
do it very well. Later code from the late 80's is much better (uucp
locking libraries I wrote and still use). Code from as late as 10
years ago is quite readable and maintainable. Which was a good thing
since I hadn't needed to look at the code since I first wrote it.
I was every so glad I had the 'right' mix on that one as it was too
complex to read just from the code itself and I didn't feel like
rereading the RFCs jsut to catch up and make a single change.

--
Linux Home Automation         Neil Cherry       EraseMEncherryspamspamspamBeGonelinuxha.com
http://www.linuxha.com/                         Main site
http://linuxha.blogspot.com/                    My HA Blog
Author of:            Linux Smart Homes For Dummies

2008\10\08@085724 by Vitaliy

flavicon
face
Tamas Rudnai wrote:
> Certainly not, but you can have something like:
>
> // search for the longest line
> for ( int i = 0; i < nPoints; ++i )
> {
>  ...
> }
>
> ...and then the code reviewer can spot that this should loop through
> the "nLines" instead...

FindLongestLine()

;)

2008\10\08@090428 by Vitaliy

flavicon
face
Mongol Herdsman wrote:
> Principle of loosly coupling is just one of many rules with no global
> scope. Apply rules wisely.

> Look, you used "cohesive" word:
>> Make it as long as necessary. If the name is too long, it
>> will tell you that the function is doing too many things, and needs to be
>> broken down into smaller, more cohesive functions.
>
> So, what "loosly coupled" or "cohesive"? Choose one, Bolivar cannot
> carry double.

I'm afraid you don't understand the terms. They are not mutually exclusive.


http://en.wikipedia.org/wiki/Cohesion_(computer_science)

http://en.wikipedia.org/wiki/Coupling_(computer_science)


2008\10\09@223810 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

> This is exactly why "self documenting" code is so dangerous.  By itself it
> is a good idea, but it leads people to believe they don't have to write any
> separate documentation.  

IME it only leads people to that conclusion who wouldn't write good
comments anyway -- because they don't understand what should go in a
comment.

> I would like to see something like:
>
>   for (int i = 0; i < nPoints; ++i) { //once for each polygon vertex

Rather than this comment, I'd suggest

for( int iVertex=0; iVertex<iPolygonVertexes; ++iVertex ) {
 // ...
}

... plus a comment that explains /why/ you are doing this (not what you are
doing; this should be obvious from the code itself).

One additional advantage is that inside the loop, the iVertex is more
expressive than the i. (On a side note: single letter variable names can be
a real pain to hover over, which is what you can do with some debuggers to
see the value. If you like "i", maybe try "ii" -- a bit easier to hit with
the mouse :)

> Comments are not just to explain code, but also to help you make sure your
> code does what you intend it to do.  

Exactly. So just repeating what the code is doing doesn't really do it --
it needs to come from a different angle (that's the "why" aspect that was
already mentioned).

Gerhard

2008\10\10@234525 by Vitaliy

flavicon
face
Gerhard Fiedler wrote:
>> I would like to see something like:
>>
>>   for (int i = 0; i < nPoints; ++i) { //once for each polygon vertex
>
> Rather than this comment, I'd suggest
>
> for( int iVertex=0; iVertex<iPolygonVertexes; ++iVertex ) {
>  // ...
> }

Very good, but unless you just have a couple of lines of code inside this
for loop, putting it in its own function makes the code more readable (since
you're dealing with larger logical "chunks" as a result).

Also, Steve McConnell suggests using "count" as a suffix for variables like
iPolygonVertexes, as in "PolygonVerticesCount".

> ... plus a comment that explains /why/ you are doing this (not what you
> are
> doing; this should be obvious from the code itself).

Yup.

> One additional advantage is that inside the loop, the iVertex is more
> expressive than the i. (On a side note: single letter variable names can
> be
> a real pain to hover over, which is what you can do with some debuggers to
> see the value. If you like "i", maybe try "ii" -- a bit easier to hit with
> the mouse :)

That's a good point. This is actually a very difficult habit to break, I
still use and occasionally intermix i's and j's. Got me in trouble more than
a few times. :-)

>> Comments are not just to explain code, but also to help you make sure
>> your
>> code does what you intend it to do.
>
> Exactly. So just repeating what the code is doing doesn't really do it --
> it needs to come from a different angle (that's the "why" aspect that was
> already mentioned).

This just gave me another reason why "built-in" comments (meaningful
variable and function names) are better: if you see a "real" comment, you
know it's explaining the "why", not the "how". Like notes in a datasheet.

Vitaliy

2008\10\11@000227 by Vitaliy

flavicon
face
Tamas Rudnai wrote:
> For me, the long version is not mirroring what I would like to do. For
> example, in my brain
>   myVar = myVar + 5;
>
> interpreted as
>    movf   myVar,W
>    addlw .5
>    movwf  myVar
>
> and this:
>   myVar += 5;
>
> as
>    movlw   .5
>    addwf    myVar,f
>
> No matter if the compiler was nicely optimising the first expression
> into the second, in my brain those are just not equivalent in terms of
> optimizasion.

Thanks for bringing this up, Tamas. This is an excellent illustration of the
"bottom up" vs the "top down" approach to programming. In "Code Complete",
Steve refers to it as "programming in a language" vs "programming into a
language".

You and Olin like to program in assembler, so your brain likes to "see"
programming in terms of assembler instructions. My views on programming have
been strongly influenced by OOP languages like Delphi, Java, and C++. So I
like to see programming in terms of objects and higher-level abstractions. I
think the benefit of the latter is that I am working with larger pieces --  
"assemblies" instead of individual nuts and bolts (to paraphrase Brooks).

> Anyway, if a code does not contain what it intended to do, then it may
> wrong as well in my opinion. Maybe you can read the code and can
> understand, but you have to write it down what you wanted to do so -
> because your code may be wrong, and the code reviewer can spot
> instantly that here and there you wanted to do this and that, but
> instead of your intention there was something else coded by mistake -
> therefore the code is wrong... I hope it clarifies why I think a
> comment is very important and not only function headers but also
> inline comments as well.

I'm not arguing against comments per se, I'm arguing that some comments can
be made unnecessary if you use good descriptive names for variables and
functions.

Your example of comments helping a reviewer spot problems with code, is a
made up one. Reviewer must be familiar with the "project story", and review
the code in the presence of the original programmer, who can explain what
the code is intended to do. No amount of comments can replace that.

Vitaliy

2008\10\11@000542 by Vitaliy

flavicon
face
Alan B. Pearce wrote:
> >I use the same exact trick with the variables. :) And I prefer
>>not to use shorthand notation, I like:
>>
>>    myVar = myVar + 5;
>>
>>instead of:
>>
>>    myVar += 5;
>
> However, it does make it difficult to find an error like
>
>    myVar = myVer + 5;
>
> where an error in typing causes problems. It should be caught by the
> compiler, but what if you managed to have a variable myVer in your code
> ...

I have never seen a situation where this had been a problem. And I would
probably name the variables in your example myVariable and myVersion,
respectively.

That is not to say that I ever use such generic names in my "real" projects.
;-)

Vitaliy

2008\10\11@002323 by Vitaliy

flavicon
face
"Jeff Findley" wrote:
>> I use the same exact trick with the variables. :) And I prefer not to use
>> shorthand notation, I like:
>>
>>    myVar = myVar + 5;
>>
>> instead of:
>>
>>    myVar += 5;
>
> This is a religious argument.  I prefer the latter since it's standard
> C/C++ and saves on typing.

I don't consider it a religious argument (I can't even say that I feel very
strongly about it).

Yes, it's standard C/C++ notation, but it's not "natural" and perhaps that
is the reason why most other languages don't let you do it. To me, the
benefits of improved readability outweigh the cost of typing a few extra
characters. It probably helps that my typing skills, while quite average
(~70 wpm) by normal standards, seem to be above what's considered typical
for programmers (~45 wpm). :)

> However, I'll usually stick with one C "shortcut" per line of code.  When
> you start combining too many of these shortcuts on one line of code, it
> can be bewildering for someone new to understand what's going on.

It doesn't have to be someone new. Sometimes it takes me a while to untangle
the code that I myself had written just a week prior. :)  I try to make it a
habit to refactor such code to make sure I don't have to spend as much time
untangling it the next time.

Vitaliy

2008\10\11@010222 by William \Chops\ Westfield

face picon face

On Oct 10, 2008, at 9:21 PM, Vitaliy wrote:

>>>   myVar += 5;
>
> Yes, it's standard C/C++ notation, but it's not "natural"

I'm not convinced.  I remember reading somewhere that assignment  
statements are one of the most difficult things for programming  
students to learn.  After all, if you have:
       x = x + 1
It's obvious to anyone with a 6th grade algebra background that that's  
just WRONG, IMPOSSIBLE, and probably UNNATURAL.  Thus the (largely  
unsuccessful) attempts to use a different symbol for assignment in  
some languages.
Using "x += 1" instead results in less cognitive dissonance; it's a  
format that doesn't already have some other meaning...

(I suspect no one on this list is qualified to speak on what sort of  
notation is "natural", though.  Our minds have all been corrupted.)

BillW

2008\10\11@032416 by Wouter van Ooijen

face picon face
William "Chops" Westfield wrote:
> On Oct 10, 2008, at 9:21 PM, Vitaliy wrote:
>
>>>>   myVar += 5;
>> Yes, it's standard C/C++ notation, but it's not "natural"
>
> I'm not convinced.

Neither am I. This is a C 'invention' that is easy to teach, and is
easily picked up by freshman students. It reads naturally to me, and it
can avoid writing a complex expression (or long variable name) twice.

Note that there are plenty of C constructs that are not easy to teach.

for( ;*(s++)!='\0'; n++ );

Does anyone know
1. what this does
2. why on earth one would use this () construct (I did, once)?

a = ( --a, a++, a+7 );

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\11@083013 by Bob Ammerman

picon face
>> I like:
>>>
>>>    myVar = myVar + 5;
>>>
>>> instead of:
>>>
>>>    myVar += 5;
>>

>
> Yes, it's standard C/C++ notation, but it's not "natural" and perhaps that
> is the reason why most other languages don't let you do it.

I find the C/C++ concept/notation very natural.

If I ask you to add 3 to a total, do you think in terms of:

Total = Total + 3

or

Total += 3

I submit that most people think (in English at least) more like the second
than the first.

Also, in favor of the C/C++ way, what about something like:


board_array[ nKingsColumn, iPawnRank ] = board_array[ nKingsColumn,
iPawnRank ] + 3;

vs.

board_array[ nKingsColumn, iPawnRank ] += 3;

when the subscripts get messy the C/C++ way makes it very clear what you are
trying to do.

and if the subscript involves side affects (function call, n++ or whatever)
you really have to do it the C/C++ way:

   myArray[determine_subscript()] += computed_value();

but

-- Bob Ammerman
RAm Systems


2008\10\11@104547 by olin piclist

face picon face
William Chops" Westfield" wrote:
> x = x + 1
> It's obvious to anyone with a 6th grade algebra background that that's
> just WRONG, IMPOSSIBLE, and probably UNNATURAL.

I think this goes back to the very unfortunate choice by the Fortran
designers to use "=" as the assignment operator instead of the more natural
statement of equality.  Then they had to go and invent ".EQ." for the
statement of equality.

I always thought the assignment operator should be a arrow pointing from the
expression to what it was being stored in.  ASCII doesn't have left or right
arrows, but I think "<<" or maybe "<-" would have made a decent assignment
operator.  At least Pascal tried with ":=" and does use "=" for the
statement of equality.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\11@123657 by William \Chops\ Westfield

face picon face

On Oct 11, 2008, at 7:45 AM, Olin Lathrop wrote:

> I think this goes back to the very unfortunate choice by the Fortran  
> designers to use "=" as the assignment operator
>    :
> ASCII doesn't have left or right arrows

I think that in the timeframe we're talking about, the character code  
that is now underline was a left-pointing arrow in ascii.  Shift-O on  
an ASR33.  I vaguely remember at least one language that tried to use  
it looking very strange when displayed/printed on a more modern device  
that used underline.

I don't think EBCDIC had an arrow, though. (IBM added it to the  
character set for APL.  An interesting experiment, APL...)

BillW

2008\10\11@143848 by Peter Onion

flavicon
face

On Sat, 2008-10-11 at 10:45 -0400, Olin Lathrop wrote:
>  At least Pascal tried with ":=" and does use "=" for the
> statement of equality.

You need to go further back than Pascal to find the original use of
":= " ( which is read as "becomes" ).

I think it first appeared in Algol 58.  (Yup, Wikipedia agrees).

PeterO



2008\10\11@160022 by Carl Denk

flavicon
face
Was also in MAD - Michigan (Univ of) Algorithm Decoder - 1960 vintage.

Peter Onion wrote:
> On Sat, 2008-10-11 at 10:45 -0400, Olin Lathrop wrote:
>  
>>  At least Pascal tried with ":=" and does use "=" for the
>> statement of equality.
>>    
>
> You need to go further back than Pascal to find the original use of
> ":= " ( which is read as "becomes" ).
>
> I think it first appeared in Algol 58.  (Yup, Wikipedia agrees).
>
> PeterO
>
>
>
>  

2008\10\11@162422 by Wouter van Ooijen

face picon face
Carl Denk wrote:
> Was also in MAD - Michigan (Univ of) Algorithm Decoder - 1960 vintage.

which was a derivate of IAL (== Algol 58).

As freshman student I had to program in Algol60. A fine language, except
for the IO (IO? Who needs IO?) and the implementation decision to
identify keywords by quoting them. Something like

'if' a > b 'then' m = a 'else' m = b 'fi'

Now if you forget just one quote all keywords become plain text and vice
versa. Remove the first quote and the above line alone would generate a
full page of error messages.

Next year they switched to pascal (but still in batch mode on an IBM
360). By the time I became a practicum assistant they had switched to
TurboPascal, much to the relief of all first-year students.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\11@192424 by olin piclist

face picon face
Wouter van Ooijen wrote:
> As freshman student I had to program in Algol60. A fine language,

We had to learn a little Algol in a class on computer languages too.  Some
of the concepts in Algol were good, but it was a annoying language due to
all the silly choices for keywords.  They were deliberately chosen from
several different european languages.  Big surprise it never took off,
considering 99% of the computing world spoke english.  Duh.

Pascal seemed to pick up where Algol left off, without the attitude.  I
think this is how ":=" got into Pascal.  They just copied it without giving
it much fresh thought.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\12@000525 by Vitaliy

flavicon
face
Bob Ammerman wrote:
>> Yes, it's standard C/C++ notation, but it's not "natural" and perhaps
>> that
>> is the reason why most other languages don't let you do it.
>
> I find the C/C++ concept/notation very natural.
>
> If I ask you to add 3 to a total, do you think in terms of:
>
> Total = Total + 3
>
> or
>
> Total += 3
>
> I submit that most people think (in English at least) more like the second
> than the first.

The second one reads as "total plus equals three", which is nonsense. So far
I like Olin's suggestion to use an arrow the best:

   Total + 3 -> Total

..which would read as "total plus three, store result in total". TI-89's
BASIC does it this way (they actually use an arrow character).

Although when I first got into programming (which was some time *after*
dinosaurs became extinct ;-P ), a statement in Commodore BASIC:

   X = X + 1

..made total sense to me. I was 14 years old, spoke very little English, had
zero prior experience with programming and nobody around able to help.

I don't want to leave the impression that I find +=, &=, and the like
difficult, but when I first stumbled across them, they did seem rather odd.
One more time for the record: I don't feel strongly about this issue (not
nearly as strong as I feel about self documenting code vs line-by-line
comments).

{Quote hidden}

I'm not sure exactly what you're doing with this array, but I think in this
case I would use another variable to store the intermediate result. And I
probably wouldn't use a "magic number". It begs the question, "Why 3?". And
then of course you _have to_ have a comment to explain what the statement
does -- a self-fulfilling profecy.

> and if the subscript involves side affects (function call, n++ or
> whatever)
> you really have to do it the C/C++ way:
>
>    myArray[determine_subscript()] += computed_value();

Ouch! :(  This is the kind of code I would expect from a programmer who
codes for "job security".

Vitaliy

2008\10\12@004150 by Vitaliy

flavicon
face
Jeff Findley wrote:
> Where I work, we typically use function comments to document pre and post
> conditions as well as argumets (in/out/out that needs free'd, etc.).  If
> you don't do this sort of documentation, then you have to read through the
> whole function just to call it.  That's absolutely silly when you're
> working on big projects with many developers spread across the globe.

How long is your "typical function"?

My typical function is probably 10 lines of code, or less (not counting the
whitespace). As a result, it doesn't take much time at all to read it in its
entirety, and understand how it works. And unlike comments, code never lies.

Sometimes, I write a "normal", long function, just to get the rapid
gratification of seeing the code compile and run. I then refactor the code
into several small, cohesive functions.

Regarding "pre-" and "post-" conditions. It looks like in recent years,
Microchip realized how bad the quality of their code is, and is now
requiring their programmers to use verbose, rigid comment templates. It gets
to the point of ridiculous:


<MICROCHIP CODE>

/*********************************************************************
Function:        void RtccInitClock(void)

PreCondition:    None

Input:           None

Output:          None

Side Effects:    None

Overview:        The function initializes the RTCC device. It starts the
RTCC clock,
                 sets the RTCC Off and disables RTCC write. Disables the
OE.

Note:            None
********************************************************************/
void RtccInitClock(void)
{
  // enable the Secondary Oscillator
  __builtin_write_OSCCONL(2);

  RCFGCAL = 0x0;
  if(mRtccIsOn())
  {
     if(!mRtccIsWrEn())
     {
         RtccWrOn();
     }
      mRtccOff();
  }

  mRtccWrOff();
}

</MICROCHIP CODE>


If you have to describe preconditions and side effects, it's likely that the
function is violating basic principles of good programming. A function
should validate its parameters, and it shouldn't leave a mess when you
return from it.

On a side note, some of the programmers at Microchip are an embarrassment to
their company. I couldn't believe Microchip allowed such people to teach
classes at the conference. Instead of trying to force mediocre programmers
to write good code by imposing silly coding styles on everyone (a futile
effort), Microchip should fire the mediocre programmers, and replace them
with a few brilliant ones (there were those at the conference, as well).

Best regards,

Vitaliy

2008\10\12@034558 by Neil Cherry

flavicon
face
Vitaliy wrote:
{Quote hidden}

Hmm I suspect that it was actually something like this:

10 let x = x + 1

Basically the 'let' became redundant so it was dropped. I also think
assembly language may have had a hand in the left to right style of
languages and maybe a little bit of stack manipulation. Of course this
is a guess.

--
Linux Home Automation         Neil Cherry       RemoveMEncherryKILLspamspamlinuxha.com
http://www.linuxha.com/                         Main site
http://linuxha.blogspot.com/                    My HA Blog
Author of:            Linux Smart Homes For Dummies

2008\10\12@053047 by Vitaliy

flavicon
face
Jeff Findley wrote:
> Where I work, we do mostly object oriented programming (mostly in C++,
> sometimes in Java) so we use design tools like Together or Visio to do
> class, object, and sequence diagrams.  The sequence diagrams are the most
> useful as they help you spot problems which would normally show up during
> the implementation.
>
> Some design tools will output the pseudo-code (headers and source with
> comments from the design), but we typically don't do that.  The best
> design tools can import actual code into the system, but we've found that
> our code is too complex (way too many objects and too much legacy
> procedural code) for this sort of thing.

I'm curious, do you use any formal project management methodologies? Do you
know about Agile?

Vitaliy

2008\10\12@053749 by Vitaliy

flavicon
face
Neil Cherry wrote:
> While I am not
> a programmer, I can program.

I am the same way, since I probably spend less than a fifth of my time on
the job, programming. I guess I just like to flatter myself by telling
people that I am a programmer. ;)

> I've found that the mix of self commenting
> code mixed in with judicious comments at the correct levels (main code,
> libraries, functions, complex math, etc.) is the best route.

I agree with the statement.

Vitaliy

2008\10\12@092459 by Tamas Rudnai

face picon face
> If you have to describe preconditions and side effects, it's likely that the
> function is violating basic principles of good programming. A function
> should validate its parameters, and it shouldn't leave a mess when you
> return from it.

It was discussed so many times here and elswere in microcontrollers
forums that an MCU is not a PC. You just cannot afford nice principles
as you have not ot enough CPU power and other resources available to
do that so.

> On a side note, some of the programmers at Microchip are an embarrassment to
> their company. I couldn't believe Microchip allowed such people to teach
> classes at the conference. Instead of trying to force mediocre programmers
> to write good code by imposing silly coding styles on everyone (a futile
> effort), Microchip should fire the mediocre programmers, and replace them
> with a few brilliant ones (there were those at the conference, as well).

In my opinion I would not let to any programmer graduates to get their
papers before they know assembly programming very well with
disassembling different codes to analysing compilers and their
run-time strains. Also without deeply studying interpreted language
engines including virtual machines I would not pass anybody on exams.
At least a programmer has to know what is going on behind the scenes
and then there would be no discussions about why C does not have
dynamic structures or runtime checking, and about why is it so much
different to write a program on an MCU than on a PC where not only the
architecture is different but all the resources are very very limited.
I was so surprised that when there is a sentence here about "typical
length of function" noone replies that "hey, you have a very limited
stack + the overhead of the function call is what everyone wants to
avoid + in an ISR probably not so good idea to call functions" etc.

Tamas


On Sun, Oct 12, 2008 at 5:40 AM, Vitaliy <spamSTOPspamspamspam_OUTmaksimov.org> wrote:
{Quote hidden}

> -

2008\10\12@095625 by olin piclist

face picon face
Tamas Rudnai wrote:
> I was so surprised that when there is a sentence here about "typical
> length of function" noone replies that "hey, you have a very limited
> stack + the overhead of the function call is what everyone wants to
> avoid + in an ISR probably not so good idea to call functions" etc.

I had considered doing that, but it seemed to me nobody was interested in
listening any more, only about explaining how their way was so wonderful.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\12@095844 by sergio masci

flavicon
face


On Sun, 12 Oct 2008, Tamas Rudnai wrote:

> At least a programmer has to know what is going on behind the scenes
> and then there would be no discussions about why C does not have
> dynamic structures or runtime checking, and about why is it so much
> different to write a program on an MCU than on a PC where not only the
> architecture is different but all the resources are very very limited.

Hi Tamas,

Please tell me this reference to discussions about "dynamic structures" is
something other than what's being discussed in the "Is there a IN
statement" thread at the moment. If it is, you've sure got the wrong end
of the stick!

> I was so surprised that when there is a sentence here about "typical
> length of function" noone replies that "hey, you have a very limited
> stack + the overhead of the function call is what everyone wants to
> avoid + in an ISR probably not so good idea to call functions" etc.

But here you're assuming that others do not have a solution to these
problems. You're assuming that you MUST use the hardware stack to call a
function, that all functions must incure overheads for a call.

And yes there are people out there that know a hell of a lot about
compilers, interpreters, assemblers, simulators and MCUs. They know how to
get around problems and they don't just jump up and down assuming that
no one else knows how to get around them.

Regards
Sergio Masci

2008\10\12@110133 by Timothy J. Weber

face picon face
Olin Lathrop wrote:
> Tamas Rudnai wrote:
>> I was so surprised that when there is a sentence here about "typical
>> length of function" noone replies that "hey, you have a very limited
>> stack + the overhead of the function call is what everyone wants to
>> avoid + in an ISR probably not so good idea to call functions" etc.
>
> I had considered doing that, but it seemed to me nobody was interested in
> listening any more, only about explaining how their way was so wonderful.

The C compiler I use (BoostC) supports "inline" functions, so there is
no additional overhead if a function is called only once.

So, the function can be used as a purely syntactic element to point out
a unit of functionality (function-ality?).
--
Timothy J. Weber
http://timothyweber.org

2008\10\12@110228 by olin piclist

face picon face
sergio masci wrote:
> You're assuming that you MUST use the hardware stack to
> call a function,

On a PIC that is the case if you use the native instructions for that
purpose.  You can simulate a call in software, but it will take a
significant number of additional instructions and the return address still
has to be saved somewhere.  Also the subroutine has to be written to support
this since the mechanisms for returning would be different.

> that all functions must incure overheads for a call.

Unless you in-line expand them at assembly/compile time, they are going to
incurr some runtime overhead.  If you do expand them, they will take
additional program memory.  There is no free lunch.

The model of many short subroutines with no globals can be useful on "large"
systems, but on small systems like PICs the costs can get in the way.  For
low volume projects you can maybe use a bigger PIC, but that's not always a
option.  There is a reason Microchip make little PICs too.

As with any guidelines, you have to know when to apply them and when it's
not appropriate.  Global variables can be very useful, and they are
appropriate in some cases.  The same holds true for subroutines that are
more than 10 lines long.  Even on large systems, I don't really care about
the size of a subroutine in lines of code.

It's much more important, on all size systems, that the overall project be
broken into functional units in the right places.  You first have to break
the project into subsystems, then think about the tasks each of those
subsystems have to perform in a general way outside the context of the
particular project.  If you can separate the subsystem from the particular
implementation and think of its true low level tasks, you can probably
design a good subroutine interface for it.  Then of course there are always
compromises about how general is needed versus how complicated.  The right
subroutine interface gives you a better tradeoff between these, but the
tradeoff is always there.  Artificially breaking subroutine just because
they exceeded some arbitrary code limit can make the module less
understandable and more of a pain to maintain.

There is a right ballance to everything.  About the only hard and fast rule
is that hard and fast rules are generally bad.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\12@114527 by Timothy J. Weber

face picon face
Olin Lathrop wrote:
> sergio masci wrote:
>> You're assuming
...
>> that all functions must incure overheads for a call.
>
> Unless you in-line expand them at assembly/compile time, they are going to
> incurr some runtime overhead.  If you do expand them, they will take
> additional program memory.  There is no free lunch.

I thought you were arguing against pulling out fine-grained functions
from larger straight-line code.  In that case, the comparison is with an
inline function that's only expanded once, so there's no additional
program memory used.

> There is a right ballance to everything.  About the only hard and fast rule
> is that hard and fast rules are generally bad.

Hear, hear.
--
Timothy J. Weber
http://timothyweber.org

2008\10\12@122412 by Gerhard Fiedler

picon face
Timothy J. Weber wrote:

> Olin Lathrop wrote:
>> Tamas Rudnai wrote:
>>> I was so surprised that when there is a sentence here about "typical
>>> length of function" noone replies that "hey, you have a very limited
>>> stack + the overhead of the function call is what everyone wants to
>>> avoid + in an ISR probably not so good idea to call functions" etc.
>>
>> I had considered doing that, but it seemed to me nobody was interested in
>> listening any more, only about explaining how their way was so wonderful.
>
> The C compiler I use (BoostC) supports "inline" functions, so there is
> no additional overhead if a function is called only once.

It's not the only one. Some are even smart enough to recognize that a
function is only used once (or maybe it's short and only used a few times)
and inline it during their normal optimization automatically, even if it's
not declared inline.

But then, you can't really expect that people who like to do that manually,
and in assembly, consider such details :)

Gerhard

2008\10\12@134844 by Mark Rages

face picon face
On Sun, Oct 12, 2008 at 11:23 AM, Gerhard Fiedler
<spamBeGonelistsSTOPspamspamEraseMEconnectionbrazil.com> wrote:
> Timothy J. Weber wrote:
>
>>
>> The C compiler I use (BoostC) supports "inline" functions, so there is
>> no additional overhead if a function is called only once.
>
> It's not the only one. Some are even smart enough to recognize that a
> function is only used once (or maybe it's short and only used a few times)
> and inline it during their normal optimization automatically, even if it's
> not declared inline.
>

You can help the C compiler by declaring functions "inline" and making
one big file that includes all of your source files.  Then compile
everything statically at once:
$ cc -o program.hex includes_everything.c

Now the compiler knows it won't have to link the functions elsewhere
and can optimize the calls accordingly.  This can save stack space
too.

Notice that this technique messes with the namespace.  But if you were
using same-named variables in file scope, you deserve what you get...
Also, make sure each header file is protected against double inclusion
(the standard #ifndf macro).  On little microprocessor programs,
compilation time is actually faster than having a separate link step.

Regards,
Mark
mark
--
Mark Rages, Engineer
Midwest Telecine LLC
KILLspammarkragesspamBeGonespammidwesttelecine.com

2008\10\12@150749 by Peter Onion

flavicon
face

On Sat, 2008-10-11 at 19:24 -0400, Olin Lathrop wrote:
>  They were deliberately chosen from
> several different european languages.  Big surprise it never took off,
> considering 99% of the computing world spoke english.  Duh.

Your "USA == the world" blinkers are stopping you seeing the facts.

Algol 60 was a very successful language in it's day.

PeterO


2008\10\12@151615 by Tamas Rudnai

face picon face
> The C compiler I use (BoostC) supports "inline" functions, so there is
> no additional overhead if a function is called only once.

But you do know (don't you?) that an 'inline' only tells the compiler, that
you *prefer* that function to be inlined... Also when you have variables
inside that inline function, then those variables has to be "doubled" - aka
the stack for those local variables has to be crated + the values has to be
copied - otherwise the funcion behaves different than what the programmer
may wants.

Now get into some pratcise:

I have chosen "gcc version 4.2.3 (Ubuntu 4.2.3-2ubuntu7)" for this testing,
and just created a silly test source as follows:

------------------------------------------------------------------
#include <stdio.h>

inline void inl(int i)
{
   int h, j;

   h = i;
   i+=h;
   j = i;
   h += j;
   i++;

   printf("%u",i);
}


int main(void)
{
   int i;

   for(i = 10; i--; )
   {
       inl(i);
       printf("%X\n",i);
   }

   return 0;
}
------------------------------------------------------------------

I know, there is no comments but I hope everyone see what it does: nothing
:-)
Now the first attempt to compile this code:

$ gcc -Winline -o testInline testInline.c

For those who not familiar with gcc, -Winline tells the compiler to warn if
there was a function marked as inline but was not inlined. We got not
warnings, so I think it is good, but let's check the generated code:

$ objdump -d testInline

...
080483ab <main>:
80483ab:       8d 4c 24 04             lea    0x4(%esp),%ecx
80483af:       83 e4 f0                and    $0xfffffff0,%esp
80483b2:       ff 71 fc                pushl  -0x4(%ecx)
80483b5:       55                      push   %ebp
80483b6:       89 e5                   mov    %esp,%ebp
80483b8:       51                      push   %ecx
80483b9:       83 ec 24                sub    $0x24,%esp
80483bc:       c7 45 f8 0a 00 00 00    movl   $0xa,-0x8(%ebp)
80483c3:       eb 1e                   jmp    80483e3 <main+0x38>
80483c5:       8b 45 f8                mov    -0x8(%ebp),%eax
80483c8:       89 04 24                mov    %eax,(%esp)
80483cb:       e8 a4 ff ff ff          call   8048374 <inl>  <=== THAT IS
INTERESING!
80483d0:       8b 45 f8                mov    -0x8(%ebp),%eax
80483d3:       89 44 24 04             mov    %eax,0x4(%esp)
80483d7:       c7 04 24 c3 84 04 08    movl   $0x80484c3,(%esp)
80483de:       e8 f5 fe ff ff          call   80482d8 <printf@plt>
80483e3:       83 6d f8 01             subl   $0x1,-0x8(%ebp)
80483e7:       83 7d f8 ff             cmpl   $0xffffffff,-0x8(%ebp)
80483eb:       75 d8                   jne    80483c5 <main+0x1a>
80483ed:       b8 00 00 00 00          mov    $0x0,%eax
80483f2:       83 c4 24                add    $0x24,%esp
80483f5:       59                      pop    %ecx
80483f6:       5d                      pop    %ebp
80483f7:       8d 61 fc                lea    -0x4(%ecx),%esp
80483fa:       c3                      ret

Now as we realised something is wrong try somwthing else:

$ gcc -Winline -Os -o testInline testInline.c
testInline.c: In function 'main':
testInline.c:5: warning: inlining failed in call to 'inl': --param
max-inline-insns-single limit reached
testInline.c:24: warning: called from here

Ok, so when we ask the compiler to do optimization for size it warns us that
the inline was uncussessful. Right, try to increase the size of the function
that can be inlined:

$ gcc -Winline -finline-limit=1200 -Os -o testInline testInline.c

No warning, so far so good again, but as it happened previously just check
if inline occured:

$ objdump -d testInline

...
08048391 <main>:
8048391:       8d 4c 24 04             lea    0x4(%esp),%ecx
8048395:       83 e4 f0                and    $0xfffffff0,%esp
8048398:       ff 71 fc                pushl  -0x4(%ecx)
804839b:       55                      push   %ebp
804839c:       89 e5                   mov    %esp,%ebp
804839e:       56                      push   %esi
804839f:       be 13 00 00 00          mov    $0x13,%esi
80483a4:       53                      push   %ebx
80483a5:       bb 0a 00 00 00          mov    $0xa,%ebx
80483aa:       51                      push   %ecx
80483ab:       83 ec 0c                sub    $0xc,%esp
80483ae:       eb 20                   jmp    80483d0 <main+0x3f>
80483b0:       51                      push   %ecx
80483b1:       51                      push   %ecx
80483b2:       56                      push   %esi
80483b3:       83 ee 02                sub    $0x2,%esi
80483b6:       68 b0 84 04 08          push   $0x80484b0
80483bb:       e8 18 ff ff ff          call   80482d8 <printf@plt>
80483c0:       58                      pop    %eax
80483c1:       5a                      pop    %edx
80483c2:       53                      push   %ebx
80483c3:       68 b3 84 04 08          push   $0x80484b3
80483c8:       e8 0b ff ff ff          call   80482d8 <printf@plt>
80483cd:       83 c4 10                add    $0x10,%esp
80483d0:       4b                      dec    %ebx
80483d1:       83 fb ff                cmp    $0xffffffff,%ebx
80483d4:       75 da                   jne    80483b0 <main+0x1f>
80483d6:       8d 65 f4                lea    -0xc(%ebp),%esp
80483d9:       31 c0                   xor    %eax,%eax
80483db:       59                      pop    %ecx
80483dc:       5b                      pop    %ebx
80483dd:       5e                      pop    %esi
80483de:       5d                      pop    %ebp
80483df:       8d 61 fc                lea    -0x4(%ecx),%esp
80483e2:       c3                      ret

Right, now the function inlined, but do you notice the size of the code?
Loads of stack operation for nothing - this is only a snipplet, it does not
contain the startup ccode and the C library of course.
Now examine this binary a bit further. Just before the main function, I
notice this:

08048374 <inl>:
8048374:       55                      push   %ebp
8048375:       89 e5                   mov    %esp,%ebp
8048377:       83 ec 10                sub    $0x10,%esp
804837a:       8b 45 08                mov    0x8(%ebp),%eax
804837d:       8d 44 00 01             lea    0x1(%eax,%eax,1),%eax
8048381:       50                      push   %eax
8048382:       68 b0 84 04 08          push   $0x80484b0
8048387:       e8 4c ff ff ff          call   80482d8 <printf@plt>
804838c:       83 c4 10                add    $0x10,%esp
804838f:       c9                      leave
8048390:       c3                      ret

Erm, if this function was inlined, why the earth it was stored separately?

I know, gcc is only one compiler out of the millions, I just wanted to point
out, that sometimes a theory about these compiler techniques just does not
work or works erratically, and that's why assembly programmers like better
to control everything instead of relying on compiler features.

Tamas





On Sun, Oct 12, 2008 at 4:00 PM, Timothy J. Weber <EraseMEtwspamEraseMEtimothyweber.org>
wrote:
{Quote hidden}

> -

2008\10\12@165155 by Timothy J. Weber

face picon face
Tamas Rudnai wrote:
>> The C compiler I use (BoostC) supports "inline" functions, so there is
>> no additional overhead if a function is called only once.
>
> But you do know (don't you?) that an 'inline' only tells the compiler, that
> you *prefer* that function to be inlined...

I do know that that is the only guarantee made by ANSI C++ - but I also
know that BoostC always takes the advice.

(Was 'inline' back-ported to ANSI C from C++ at some point?  I thought
it was a non-portable extension added by BoostC.)

> Also when you have variables
> inside that inline function, then those variables has to be "doubled" - aka
> the stack for those local variables has to be crated + the values has to be
> copied - otherwise the funcion behaves different than what the programmer
> may wants.

Right.  But, again, we were talking about breaking functions out of a
big main line, in which case this makes no difference.

Further, BoostC provides reference arguments (another borrowing from
C++), so you can define something as

  void DoSomeGranularSubtask(char& foo, char& bar)

and no local stack or local variables are created for 'foo' or 'bar' -
it operates on the passed variables in-place.

> I know, gcc is only one compiler out of the millions, I just wanted to point
> out, that sometimes a theory about these compiler techniques just does not
> work or works erratically, and that's why assembly programmers like better
> to control everything instead of relying on compiler features.

Absolutely.  You have to invest time to learn how a compiler behaves in
order to use it efficiently (or when to avoid it).
--
Timothy J. Weber
http://timothyweber.org

2008\10\12@170316 by olin piclist

face picon face
Mark Rages wrote:
> But if you were using same-named variables in file scope,
> you deserve what you get...

So you're saying that making use of the feature that each module gets its
own local namespace is irresponsible, and that you should track all
variables, data types, local subroutines, and other symbols private to every
module you write and guarantee there are no collisions?  That's totally
rediculous.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\12@174414 by olin piclist

face picon face
Peter Onion wrote:
> Your "USA == the world" blinkers are stopping you seeing the facts.

That fact is that in the 1960s USA and England was 99% of the world of
computing.

> Algol 60 was a very successful language in it's day.

It caught on in a few niches and was popular in europe for a while (probably
exactly because it wasn't completely based on english), but I would hardly
call it successful as a language.  Some of its concepts do live on, but the
language doesn't.  Also notice that silly keywords chosen only to not be
english hasn't been tried with any seriousness since.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\12@181316 by David Meiklejohn

face
flavicon
face
Olin Lathrop wrote:
>
> sergio masci wrote:
>> You're assuming that you MUST use the hardware stack to
>> call a function,
>
> On a PIC that is the case if you use the native instructions for that
> purpose.  You can simulate a call in software, but it will take a
> significant number of additional instructions and the return address still
> has to be saved somewhere.  Also the subroutine has to be written to
> support
> this since the mechanisms for returning would be different.

That's the approach taken by the C compilers for the baseline PICs (which
have only a 2-level hardware stack).  It's messy, and uses up data memory
(to save return address), but works.  Ok for very small programs (which
may as well have been written in assembler anyway, but that's another
discussion...).


David Meiklejohn
http://www.gooligum.com.au

2008\10\12@190431 by William \Chops\ Westfield

face picon face

On Oct 12, 2008, at 2:43 PM, Olin Lathrop wrote:

>> Algol 60 was a very successful language in it's day.
>
> It caught on in a few niches and was popular in europe for a while  
> (probably
> exactly because it wasn't completely based on english), but I would  
> hardly
> call it successful as a language.

Like many languages since, Algol was one of those languages praised by  
"computer scientists" of the day for its elegance and capabilities,  
but never gaining much traction in "the real world."  (although one  
might have an interesting discussion on just what constituted "the  
real world" in computers in the 60s.)  Pascal is similar.  Lots of  
languages since have borrowed ideas from algol; wasn't it the first  
language to introduce the block structure for code (wikipedia agrees  
with this recollection.)

I'm not sure that one can trust the opinions of "computer scientists"  
on some issues.  Perhaps not enough of them are "good  
*programmers*".)  It seems to me that two of the most successful  
languages (C and Basic) NEVER had much acceptance from academics.  It  
seems to be a favorite error (?) on their part to exclaim "this  
structure is evil and a source of bugs; we must not permit our ideal  
language to allow it at all!" without bothering to understand why that  
structure is so common, or to provide a replacement.


{Quote hidden}

Microchip is not a software company.  They probably employ fewer  
"real" programmers than the average high tech company their size,  
because they spent their engineering dollars on EEs.  Besides, if  
you're a "brilliant programmer", chances are your interests lie  
outside of deeply embedded code on obscure and ugly architectures.

This is a universal problem.  Even at software companies, the high-
glory projects attract the best programmers, and the critical but  
"less interesting" jobs fall to lesser qualified people.  "No one  
joins cisco because the want to work on low-level operating system  
code."  (And when was the last time you saw someone with a PhD who  
specialized in software testing?)  So management, and the industry in  
general, tries to correct for these lesser programmers with  
"methodologies" and rules..  As was said, this doesn't seem to work  
very well.  Maybe it helps.  Maybe some day they'll come up with the  
right formula.  Meanwhile, the rules are tightest where the code is  
worst, FURTHER discouraging the better people from participating in  
those areas.

(I suspect that the problem is that the industry is ADAPTED to running  
at the speed of the "super-coder", and has even shown acceptance of a  
certain level of bugs to achieve that speed of development.  The  
effort therefore ends up being an attempt to speed up development time  
(of code that "works", with a certain ("acceptable") level of bugs) by  
adding additional process.  And we're surprised that it doesn't work?  
("You cannot have a baby in 1 month by getting nine women pregnant!"))

Hmmph.
BillW

2008\10\12@193631 by Gerhard Fiedler

picon face
Tamas Rudnai wrote:

> I know, gcc is only one compiler out of the millions, I just wanted to
> point out, that sometimes a theory about these compiler techniques just
> does not work or works erratically, ...

The same goes for assembler... right? :)

Inlining is an optimization feature. The language itself doesn't guarantee
any specific performance, and optimizations are optional --
implementation-dependent. That means you have to read your compiler manual,
not the language spec.

> ... and that's why assembly programmers like better to control everything
> instead of relying on compiler features.

I guess it doesn't matter that much whether you rely on assembler features
or compiler features -- you have to know your specific compiler or
assembler. Try using Olin's environment with any PIC assembler other than
MPASM and you'll see what I mean :)

Gerhard

2008\10\12@194340 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

> Peter Onion wrote:
>> Your "USA == the world" blinkers are stopping you seeing the facts.
>
> That fact is that in the 1960s USA and England was 99% of the world of
> computing.

I wasn't aware enough at the time to be able to tell whether you say that
because it's obvious, or because you may not be familiar what was going on
at the time outside of USA and England.

Is there any objective quality to this statement?

Gerhard

2008\10\12@195420 by Chris McSweeny

picon face
I had no awareness at all at the time, but am sufficiently educated in
computing history to suggest it's obvious (no facts to back that up - I
suspect Olin may have though).
Chris

On Mon, Oct 13, 2008 at 12:43 AM, Gerhard Fiedler <
@spam@lists@spam@spamspam_OUTconnectionbrazil.com> wrote:

{Quote hidden}

> -

2008\10\12@214335 by Dave Tweed

face
flavicon
face
Olin Lathrop wrote:
> Peter Onion wrote:
> > Your "USA == the world" blinkers are stopping you seeing the facts.
>
> That fact is that in the 1960s USA and England was 99% of the world of
> computing.
>
> > Algol 60 was a very successful language in it's day.
>
> It caught on in a few niches and was popular in europe for a while (probably
> exactly because it wasn't completely based on english), but I would hardly
> call it successful as a language.  Some of its concepts do live on, but the
> language doesn't.  Also notice that silly keywords chosen only to not be
> english hasn't been tried with any seriousness since.

Granted, Algol-60 was more of an academic language, much like the orignal
Pascal.

However, Burroughs Corporation created a version (based on Algol 68) for
programming its stack-based mainframe computers that was quite useable --
similar to what Apollo did with Pascal. Burroughs Algol was used for both
systems and application programming. It was, in fact, my first* high-level
language, because it was used for the CS courses at the University of
Delaware.

I have no idea what you're referring to with respect to non-English
keywords.

-- Dave Tweed

* Actually, that's not quite true -- I had a little bit of exposure to the
 original Dartmouth BASIC running under DTSS on the GE 635 computer at the
 Naval Academy, while attending a one-week camp there during high school.

2008\10\13@014647 by Wouter van Ooijen

face picon face
>> Algol 60 was a very successful language in it's day.
>
> It caught on in a few niches and was popular in europe for a while (probably
> exactly because it wasn't completely based on english), but I would hardly
> call it successful as a language.  Some of its concepts do live on, but the
> language doesn't. Also notice that silly keywords chosen only to not be
> english hasn't been tried with any seriousness since.

Are you mixing up Algol60 and Algol68? The 58/60 version used normal
english keywords. AFAIK the language itself was not as widely used as
FORTRAN and COBOL, but most concepts it introduced survive in nearly
every computer language today.

The 68 version was a mathematical marvel, but 'a little' too difficult
to explain (and probably use and to compile). I recall that any student
who could derive a small Algol68 program using its 2-level syntax got a
top mark for a certain course on programming languages. The professor
was vd Poel, one of the 'oldies'.

The direction Algol68 was taking was what pushed Wirth (in disgust of
the complexity of Algol68) to develop his branch of algol60-like
languages (pascal, modula).

List of Algol60 keywords from
http://www.csci.csusb.edu/dick/samples/algol60.syntax.html:

   1. array::lexeme, indicates a type of data -- an n-dimensional array.
   2. begin::lexeme, indicates the start of a block of code
   3. Boolean::lexeme, name of the Boolean data type.
   4. comment::lexeme, indicates that start of a comment.
   5. do::lexeme, indicates the end of a for clause.
   6. else::lexeme, separates the else from the then in a conditional
statement
   7. end::lexeme, indicates the end of a block of code.
   8. false::lexeme, one of the Boolean data types.
   9. for::lexeme, indicates the start of a loop.
  10. goto::lexeme, indicates an unconditional transfer of control to a
label.
  11. if::lexeme, starts a selection statement of conditional expression.
  12. integer::lexeme, name of a fixed point data type.
  13. label::lexeme, indicate a label parameter.
  14. own::lexeme, indicates a variable with static life time but local
scope.
  15. procedure::lexeme, indicates a sub-program or function.
  16. real::lexeme, name of a floating point type.
  17. step::lexeme, used in a for clause to indicate an increment
  18. string::lexeme, a type of character string data type.
  19. switch::lexeme, declares a variables that is something like an
array of labels.
  20. then::lexeme, Separates a condition from the true part of a
selection.
  21. true::lexeme, a Boolean value
  22. until::lexeme, indicates the final value in for clause.
  23. value::lexeme, indicate pass by value in a parameter.
  24. while::lexeme, indicates a conditional loop part of a for clause.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\13@015357 by Wouter van Ooijen

face picon face
> I'm not sure that one can trust the opinions of "computer scientists"  
> on some issues.  Perhaps not enough of them are "good  
> *programmers*".)  It seems to me that two of the most successful  
> languages (C and Basic) NEVER had much acceptance from academics.  It  
> seems to be a favorite error (?) on their part to exclaim "this  
> structure is evil and a source of bugs; we must not permit our ideal  
> language to allow it at all!" without bothering to understand why that  
> structure is so common, or to provide a replacement.

Bullocks. Like all specialisms, you can not trust just anyone who calls
himself a "computer scientist" to tell you the final truth. But the
general direction of computer languages was definitely influenced most
by Algol60 (block-structure) and SIMULA (OO). Although it often took a
major overhaul from the industry to make the fresh ideas into something
workable. Look at a few contributions from the opposite side: FORTRAN,
PL/1, ADA. Pity everyone who still uses FORTRAN. PL/1, anyone? ADA
deserved a better faith, but also a much shorter definition.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\13@082204 by Peter

picon face
Wouter van Ooijen <wouter <at> voti.nl> writes:
> PL/1, ADA. Pity everyone who still uses FORTRAN. PL/1, anyone? ADA
> deserved a better faith, but also a much shorter definition.

Ada was deisgned not by one commitee, but by several. Ditto VHDL ...

Peter



2008\10\13@085703 by Wouter van Ooijen

face picon face
Peter wrote:
> Wouter van Ooijen <wouter <at> voti.nl> writes:
>> PL/1, ADA. Pity everyone who still uses FORTRAN. PL/1, anyone? ADA
>> deserved a better faith, but also a much shorter definition.
>
> Ada was deisgned not by one commitee, but by several. Ditto VHDL ...

Nope. Its requirements might have been huge, but the design team at CII
Honeywell Bull was quite small.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\13@092007 by olin piclist

face picon face
Gerhard Fiedler wrote:
>> I know, gcc is only one compiler out of the millions, I just wanted
>> to point out, that sometimes a theory about these compiler
>> techniques just does not work or works erratically, ...
>
> The same goes for assembler... right? :)

No, since in assembler you specify everything, so there is no intermediate
layer where it's not clear what it might be doing.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\13@092502 by olin piclist

face picon face
Gerhard Fiedler wrote:
>> That fact is that in the 1960s USA and England was 99% of the world
>> of computing.
>
> I wasn't aware enough at the time to be able to tell whether you say
> that because it's obvious, or because you may not be familiar what
> was going on at the time outside of USA and England.

That was a little too early for me too, but I think it's still roughly true.
Make two lists.  One with all the important advances in computing and
industry-shaping products produced in the 1960s in the US and the UK, and
the other for the same things elsewhere.  I think you'll find that list
rather one sided.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\13@093404 by olin piclist

face picon face
Dave Tweed wrote:
> I have no idea what you're referring to with respect to non-English
> keywords.

Maybe my recollection is a bit garbled, or maybe Burroughs' implementation
differed from the original (just like Apollo's Pascal).  The last time I
touched Algol was freshman year in college in a computing languages course,
almost 35 years ago.  There were definitely some keywords that didn't make
any sense in english and were things you just had to learn.  I'm pretty sure
they were explained as having meaning in other languages because Algol was
developed by europeans.  I definitely remember I wasn't the only one that
thought the strange keywords annoying.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\13@111557 by Mark Rages

face picon face
On Mon, Oct 13, 2008 at 7:56 AM, Wouter van Ooijen <spamBeGonewouterspamKILLspamvoti.nl> wrote:
> Peter wrote:
>> Wouter van Ooijen <wouter <at> voti.nl> writes:
>>> PL/1, ADA. Pity everyone who still uses FORTRAN. PL/1, anyone? ADA
>>> deserved a better faith, but also a much shorter definition.
>>
>> Ada was deisgned not by one commitee, but by several. Ditto VHDL ...
>
> Nope. Its requirements might have been huge, but the design team at CII
> Honeywell Bull was quite small.
>

http://bit.csc.lsu.edu/~gb/csc4101/Reading/gigo-1997-04.html

--
Mark Rages, Engineer
Midwest Telecine LLC
.....markragesspam_OUTspammidwesttelecine.com

2008\10\13@153923 by sergio masci

flavicon
face


On Sun, 12 Oct 2008, Olin Lathrop wrote:

> sergio masci wrote:
> > You're assuming that you MUST use the hardware stack to
> > call a function,
>
> On a PIC that is the case if you use the native instructions for that
> purpose.  You can simulate a call in software, but it will take a
> significant number of additional instructions and the return address still
> has to be saved somewhere.  Also the subroutine has to be written to support
> this since the mechanisms for returning would be different.

What do you class as significant? Surely "a significant number" would mean
a number that would correspond to a significant overhead in either
execution time or program space, not just "hey it takes 4 extra
instructions to do this simulated call - that's significantly more than
1".

>
> > that all functions must incure overheads for a call.
>
> Unless you in-line expand them at assembly/compile time, they are going to
> incurr some runtime overhead.  If you do expand them, they will take
> additional program memory.  There is no free lunch.

Correct. But if it's the cost of overcomming a problem then so be it. It's
like saying I need to do floating point calculations on a PIC so I need a
floating point library. Yes it consumes promgram space but if you need it
you need it.

>
> The model of many short subroutines with no globals can be useful on "large"
> systems, but on small systems like PICs the costs can get in the way.  For
> low volume projects you can maybe use a bigger PIC, but that's not always a
> option.  There is a reason Microchip make little PICs too.

Yes I agree. And sometimes it becomes necessary to convert a few common
instructions into a subroutine and call it in several places even though
the net result is only a saving of a few instructions, just so that the
program will fit in the limited space available. Yes you incure the
overhead of the call and return but at least your program fits.

>
> As with any guidelines, you have to know when to apply them and when it's
> not appropriate.  Global variables can be very useful, and they are
> appropriate in some cases.  The same holds true for subroutines that are
> more than 10 lines long.  Even on large systems, I don't really care about
> the size of a subroutine in lines of code.

Agreed.

{Quote hidden}

But that's what a good HLL and compiler will do for you. It will have a
selection of protocols available to it from which it can select the
optimum way of calling functions and passing parameters and results
between them.

> Artificially breaking subroutine just because
> they exceeded some arbitrary code limit can make the module less
> understandable and more of a pain to maintain.

Yes but sometimes you've no choice.

I'm not sure I follow. On the one hand you seem to be argueing against
breaking down software so that it will fit into a small PIC and on the
other you seem to be argueing that your software should not be compromised
by being forced into a small PIC?

>
> There is a right ballance to everything.  About the only hard and fast rule
> is that hard and fast rules are generally bad.

Agreed.

Regards
Sergio Masci

2008\10\13@220858 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

> Gerhard Fiedler wrote:
>>> I know, gcc is only one compiler out of the millions, I just wanted
>>> to point out, that sometimes a theory about these compiler
>>> techniques just does not work or works erratically, ...
>>
>> The same goes for assembler... right? :)
>
> No, since in assembler you specify everything, so there is no intermediate
> layer where it's not clear what it might be doing.

Have you tried to use your environment with a (PIC) assembler other than
MPASM? (You know, there are other PIC assemblers, and they all do several
things differently, even though the basic assembly language is the same, In
a way not much different from different C compilers...)

And whether it's clear or not depends on the compiler's and assembler's
documentation and your degree of familiarity with it.

Gerhard

2008\10\14@045111 by Tamas Rudnai

face picon face
Gerhard,

> Have you tried to use your environment with a (PIC) assembler other than
> MPASM? (You know, there are other PIC assemblers, and they all do several
> things differently, even though the basic assembly language is the same, In
> a way not much different from different C compilers...)

Yes, there are some differences. There could be difference on syntax -
for example on x86 based Linux you can use nasm for Intel syntax or
gas for AT&T syntax. There can be differences on macro supporting -
for example gputils use the gnu cpp while MPASM has a built in C
preprocessor, and both of them supports the original MPASM macro as
well. There can be difference on output as well, like gputil does not
support COD format as far as I know while MPASM does. There could be
difference on linkers as well etc etc etc.

But the *principle* is the same: No any assembly compiler would
reorganise my code or trying to optimise my code saying that they are
more clever than me and they know better what I wanted to do. Whatever
I write down will be exactly compiled. If I am good enough on
optimization then the binary will be a well optimised code, but if I
am crap on it then the code will be terrible. All depends on me as the
developer, not on a compiler where I assume that it do something which
might be true might be not.

The original thoughts where this discussion started from was that it
is a good idea to split up large piece of code into smaller chunks.
Noone replied with the idea of the macros even though you can do the
splitting with that without penalty. I know, macro would break so many
great programming theories again :-)

Anyway


On Tue, Oct 14, 2008 at 3:08 AM, Gerhard Fiedler
<TakeThisOuTlists.....spamTakeThisOuTconnectionbrazil.com> wrote:
{Quote hidden}

> -

2008\10\14@070704 by olin piclist

face picon face
Gerhard Fiedler wrote:
> Have you tried to use your environment with a (PIC) assembler other
> than MPASM?

No, that would be silly.  My added stuff assumes the standard toolchain.

********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\14@091442 by sergio masci

flavicon
face


On Tue, 14 Oct 2008, Tamas Rudnai wrote:

{Quote hidden}

By "assembly compiler" I take it you mean the assembler software itself.

Actually, if your assembly code is well written you will most likely
be taking advantage of conditional, loop and macro constructs - not to
mention libraries produced by others that also contain these constructs.
If so, chances are high that at some point the assembler will have
generated code that you did not expect and it took you some debugging in
order to discover this.

And yes, as an assembly programmer gains more experience on an
architecture he/she will incorporate little optimisations in his/her
macros. At first it might be little things like replacing an
initialisation with a faster shorter instruction sequence:

e.g.
       movlw        arg2
       movwf        arg1

with
       if arg2 == 0

               clrf        arg1
       else

               movlw        arg2
               movwf        arg1
       endif

but soon this will grow to include other macro invokations. Before long
the assembly programmer is looking at the generated listing just to make
sure that what he thinks he has produced is what has actually been
produced.

So when you get to this level of debugging how is it any different from
looking at what the HLL compiler has produced?

You think you have more control because you built the source from the
ground up, macro by macro, conditional construct by conditional construct.
But even if that is the case, the fact that you are re-using old macros
that you wrote for a previous project means that there WILL be some side
effect that you forgot about and need to go back and investigate. This
becomes much more of a problem if it is somebody else's code or it's your
code and you haven't touched it in a long time.

Regards
Sergio Masci

2008\10\14@134628 by Gerhard Fiedler

picon face
Tamas Rudnai wrote:

> But the *principle* is the same: No any assembly compiler would
> reorganise my code or trying to optimise my code ...

Yes, they do. There are these macros (and AFAIK some built-in functionality
in some assemblers) that try to make bank and page selection automatic. Why
would they do this if the programmer knows it better?

> ... saying that they are more clever than me and they know better what I
> wanted to do.

It's not about being more clever; it's (at least for me) about dealing with
the stuff that I don't want to have to deal with. I suspect that even a
die-hard assembly programmer like Olin feels this way, or else he wouldn't
have implemented such an elaborate development environment -- which goes a
long way to automate many things a normal assembly programmer has to do
manually, and which seems to require just as much study to be able to use
it efficiently as any old C compiler.

> Whatever I write down will be exactly compiled.

Only for the simplest of programs. Trying to efficiently use the
environment of any long-time assembly programmer to create a reasonably
complex program will take you just as long as trying to use a new compiler
for it.

> All depends on me as the developer, not on a compiler where I assume that
> it do something which might be true might be not.

See, this is probably where the trouble starts. Most of the time, people
like to assume stuff that they shouldn't. Either you know (from reading the
docs, for example) or you don't... :)

> The original thoughts where this discussion started from was that it is a
> good idea to split up large piece of code into smaller chunks. Noone
> replied with the idea of the macros even though you can do the splitting
> with that without penalty. I know, macro would break so many great
> programming theories again :-)

Of course you can do it with macros, and I use them occasionally for this,
even in C. But in order to use macros, there have to be a few things
resolved: how to allocate variables local to the macro and how to
automatically handle paging and banking when instantiating the macro, just
to name two. An environment more complex than a simple assembler without
any libraries to speak of definitely helps here -- at the expense of having
to learn how to use it (without too many assumptions :)

Gerhard

2008\10\14@135211 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

> Gerhard Fiedler wrote:
>> Have you tried to use your environment with a (PIC) assembler other
>> than MPASM?
>
> No, that would be silly.  My added stuff assumes the standard toolchain.

I know. That was simply to confirm my point: any efficient development
environment is sufficiently complex to either require specific
implementations for different assemblers/compilers/... or works on only
one. This is no different between assemblers and compilers, and in both
cases you better read up in the assembler/compiler manuals regularly rather
than assuming stuff.

Gerhard

2008\10\14@143629 by olin piclist

face picon face
Gerhard Fiedler wrote:
> I know. That was simply to confirm my point: any efficient development
> environment is sufficiently complex to either require specific
> implementations for different assemblers/compilers/... or works on
> only one. This is no different between assemblers and compilers, and
> in both cases you better read up in the assembler/compiler manuals
> regularly rather than assuming stuff.

Um, OK, I don't think anyone was arguing the contrary.

********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\15@024337 by Vitaliy

flavicon
face
Olin Lathrop wrote:
>> I was so surprised that when there is a sentence here about "typical
>> length of function" noone replies that "hey, you have a very limited
>> stack + the overhead of the function call is what everyone wants to
>> avoid + in an ISR probably not so good idea to call functions" etc.
>
> I had considered doing that, but it seemed to me nobody was interested in
> listening any more, only about explaining how their way was so wonderful.

That's a fair comment. Recently I've been working on fast PICs with lots of
RAM and Flash, and programming them is quite different than programming the
8-bits. I like the change, I feel like I can focuse more on the design, and
less on the implementation details.

This goes back to what I said earlier regarding selecting the right chip for
your application. Unless you're planning to build millions of cheap copies
of your device, it doesn't make sense to be saving $0.50 (or even $1) per
part, because chips with less resources are harder to write programs for. Of
course, it makes perfect sense if you have large quantities of code written
for the lower-end parts and the skillset to go with it.

Use the best tool for the job, "best" meaning what makes you most
productive.

Vitaliy

2008\10\15@025332 by Vitaliy

flavicon
face
Tamas Rudnai wrote:
> In my opinion I would not let to any programmer graduates to get their
> papers before they know assembly programming very well with
> disassembling different codes to analysing compilers and their
> run-time strains. Also without deeply studying interpreted language
> engines including virtual machines I would not pass anybody on exams.

Perhaps there is a reason you are not in a position to make such decisions?


> At least a programmer has to know what is going on behind the scenes
> and then there would be no discussions about why C does not have
> dynamic structures or runtime checking, and about why is it so much
> different to write a program on an MCU than on a PC where not only the
> architecture is different but all the resources are very very limited.
> I was so surprised that when there is a sentence here about "typical
> length of function" noone replies that "hey, you have a very limited
> stack + the overhead of the function call is what everyone wants to
> avoid

I don't use assembly, and I'm doing quite well. Microchip's own best and
brightest suggest that you learn to trust the compiler (it's an echo of what
we've been told for a while now, in the PC world -- I remember reading the
same thing almost verbatim in "Delphi Unleashed").

That is not to say that there's no place for assembly programmers, but as
far as I can tell, it is a rapidly shrinking niche.


> + in an ISR probably not so good idea to call functions" etc.

I never advocated calling functions from an ISR.

Best regards,

Vitaliy

2008\10\15@030227 by Vitaliy

flavicon
face
Olin Lathrop wrote:
>> I know. That was simply to confirm my point: any efficient development
>> environment is sufficiently complex to either require specific
>> implementations for different assemblers/compilers/... or works on
>> only one. This is no different between assemblers and compilers, and
>> in both cases you better read up in the assembler/compiler manuals
>> regularly rather than assuming stuff.
>
> Um, OK, I don't think anyone was arguing the contrary.

I'm pretty sure that was Gerhad's response to an earlier post by Tamas:

> But the *principle* is the same: No any assembly compiler would
> reorganise my code or trying to optimise my code saying that they are
> more clever than me and they know better what I wanted to do. Whatever
> I write down will be exactly compiled. If I am good enough on
> optimization then the binary will be a well optimised code, but if I
> am crap on it then the code will be terrible. All depends on me as the
> developer, not on a compiler where I assume that it do something which
> might be true might be not.

Vitaliy

2008\10\15@034056 by Vitaliy

flavicon
face
Olin Lathrop wrote:
> As with any guidelines, you have to know when to apply them and when it's
> not appropriate.

I agree with the general statement.


> Global variables can be very useful, and they are
> appropriate in some cases.

Yes.


> The same holds true for subroutines that are
> more than 10 lines long.  Even on large systems, I don't really care about
> the size of a subroutine in lines of code.

This is clearly a reference to what I said. Let me clarify: I never said
that a subroutine cannot be longer than 10 lines. IIRC, I said that the
average size of my functions is 10 lines. Some are shorter, some are
longer -- but personally, I like to keep them under 20 lines. I think that
Calvert's recommendation is in the same ballpark.

The longer a function is, the longer it takes to read the code inside it,
and understand what it does. It becomes more difficult to find an
appropriate name for the function, because it does too many things (low
cohesion). When you replace 30 lines of code with three function calls, you
start dealing with much larger units of meaning, which the brain finds much
easier to manipulate. Each of the new functions is more cohesive, which is
conducive to their reuse -- within the project, and in other projects.


> It's much more important, on all size systems, that the overall project be
> broken into functional units in the right places.

Absolutely, this is what I have in mind when I say "tight cohesion". But
note that one doesn't hurt the other: you can cave cohesion within a module,
AND within its functions.


> You first have to break
> the project into subsystems, then think about the tasks each of those
> subsystems have to perform in a general way outside the context of the
> particular project.

Yup, that's a good way to decouple the various pieces of the project.


> If you can separate the subsystem from the particular
> implementation and think of its true low level tasks, you can probably
> design a good subroutine interface for it.  Then of course there are
> always
> compromises about how general is needed versus how complicated.  The right
> subroutine interface gives you a better tradeoff between these, but the
> tradeoff is always there.  Artificially breaking subroutine just because
> they exceeded some arbitrary code limit can make the module less
> understandable and more of a pain to maintain.

I'd like to state again that I'm not advocating breaking down subroutines
based on arbitrary code limits. I'm advocating against writing excessively
long and difficult to follow  subroutines.


> There is a right ballance to everything.  About the only hard and fast
> rule
> is that hard and fast rules are generally bad.

Sure, but rules can also be good, if you understand them and use your
judgement. "Thou shalt not ask Stupid questions, for thou shall endure the
wrath of Olin" ;-)


Vitaliy

2008\10\15@055634 by Tamas Rudnai

face picon face
> Perhaps there is a reason you are not in a position to make such
decisions?

Perhaps there is a reason why we have more and more powerful computers while
programs are not going to be faster and not even more stable :-)

BTW: Just something came into my mind I almost forgotten. I was something
like 13-14 in 1982-1983 and my parents owned an Apple II (which was a big
thing in Hungary due to the embargo to the communist countries). My father
made a contract with some programmers to write an application for expense
calculations for his job and those programmers did not see microcomputer
before. Apple II had only an 8 bit proc (Motorola 6502) with 64k RAM, but
you could use only 48k. They've written the application in the Apple Basic
which was the only choice on Apple II that time as a high level language
(No, there was a Forth as well but that was not included in the ROM).
Anyway, the program was never been able to run correctly as they did not
know what "limited resources" means, how to write a code efficiently. After
a year or so that program was still not working so my father decided to
learn programming and he successfully written his application by his own.

Why I am telling this? Because nowadays it is pretty much the same, not so
many people cares about resources - Not enough memory? Buy a bigger one -
they say. I am not saying everyone have to program in assembly. All I say is
that programmers have to know how things work. I just got enough from
programmers who do not even know assembly or how a compiler works but saying
that a C++ with templates generates much efficient code that I can in
assembly. This inline thing was the same, that's ok to use, that's ok to use
a non-inline function as well but has to know by nature what it costs like.
Regarding to this conversation I just wanted to point out that to break up a
code just for the sake of programming theories is not always a good thing in
terms of code efficiency. I am not trying to convience you to stop duing
that, that is your choice - but when you do that you should know that your
code is getting bigger and slower.

Tamas



On Wed, Oct 15, 2008 at 7:52 AM, Vitaliy <TakeThisOuTspamKILLspamspamspammaksimov.org> wrote:

{Quote hidden}

> -

2008\10\15@092036 by sergio masci

flavicon
face


On Wed, 15 Oct 2008, Tamas Rudnai wrote:

{Quote hidden}

Hi Tamas,

I understand your frustration. I also programmed a lowly Apple II back in
the early 80's and like you I find it difficult to accept how we now need
such high powered machines to do a similar job.

I belive the fundamental problem is that so many people are now
concentrating on "method" and "process" that they have lost sight of the
underlying truth which is that many programmers are just not cut out to be
programmers.

The idea that you can take a recipe, follow it and hey presto you have a
program is just plain rubish. It takes hard work to become a good
programmer. A task that many people seem unprepared to undertake, and many
employer seem to discourage. They want product quickly, at low cost and
don't want to pay for good quality programmers when they can get less
competant people to do the job for less. After all, all they need to do is
follow the recipe and you don't need to pay someone a lot to do that.

I'm sorry but there is no quick fix. All you can really say is "hey,
this is what helped me progress from writing small crap programs
that I'm now embarised about to big beautiful programs that I am now proud
of". At the end of the day it always comes down to constantly trying
to improve yourself and your code. In other words hard work.

Yes you can lay down rules that help a team cooperate but dig deep enough
and in that team you will always find a core of people that are
making the project work dispite the others (unless the project is a
complete disaster in which case there may not be such a core at all).

One of the things I really like about the MIT PICLIST is that there are
lots of people on it that WORK HARD to achive good things despite the
restrictions. Some of these people are not even professional PIC
programmers. They are not trying because they are being paid to, they are
trying because they want to. These are the sort of people that make good
programmers, the ones that push themselves, not the clock watching recipe
following form fillers who have little interest in the code that they
write.

Regards
Sergio Masci

2008\10\15@162541 by Vitaliy

flavicon
face
Tamas Rudnai wrote:
>> Perhaps there is a reason you are not in a position to make such
> decisions?
>
> Perhaps there is a reason why we have more and more powerful computers
> while
> programs are not going to be faster and not even more stable :-)

Good job Tamas, you responded to my prick in a constructive way. :-)  I'm
sure you would make a great teacher, but I do believe that your requirements
are too harsh. Many programmers do very well without the intimate knowledge
of assembly.


[snipped Apple II story]
> Why I am telling this? Because nowadays it is pretty much the same, not so
> many people cares about resources - Not enough memory? Buy a bigger one -
> they say. I am not saying everyone have to program in assembly. All I say
> is
> that programmers have to know how things work. I just got enough from
> programmers who do not even know assembly or how a compiler works but
> saying
> that a C++ with templates generates much efficient code that I can in
> assembly.

Did I ever say that? I do recall referencing a whitepaper that claimed that
modern compilers are as good (or better) than assembly programmers at
producing efficient code.


{Quote hidden}

I fully realize that there is often a tradeoff between readability and
efficient use of resources. It is a conscious choice on my part to err on
the side of readability, and I believe it makes sense considering that the
cost of hardware is dropping rapidly, and the cost of programmer-hour is
increasing.

I think when you said "just for the sake of programming theories", you meant
it to be derogatory. There are many smart people who for decades have
developed software, and tried to figure out how to make software development
better. Fred Brooks said there's no silver bullet, and improvement will be
incremental, and he said that the best way to improve productivity, is to
use the largest chunks of code (software components, libraries, even entire
applications like MS Excel) available, instead of constantly reinventing the
wheel.

I think that instead of dismissing their work as "just theories", you should
at least consider what they have to say.

Vitaliy

2008\10\15@165142 by Vitaliy

flavicon
face
sergio masci wrote:
> I belive the fundamental problem is that so many people are now
> concentrating on "method" and "process" that they have lost sight of the
> underlying truth which is that many programmers are just not cut out to be
> programmers.

Many experts on the matter say that there is an order of magnitude
difference among some programmers, in terms of productivity. So it makes
sense to pay more to get the best programmers.

But methods and processes are still necessary: even those who claim they
don't use either, have to somehow ensure that the project doesn't fall
apart. And if you have a good process that works for you, you are much
better off than the programmer whose process impedes his work.


> The idea that you can take a recipe, follow it and hey presto you have a
> program is just plain rubish. It takes hard work to become a good
> programmer. A task that many people seem unprepared to undertake, and many
> employer seem to discourage. They want product quickly, at low cost and
> don't want to pay for good quality programmers when they can get less
> competant people to do the job for less. After all, all they need to do is
> follow the recipe and you don't need to pay someone a lot to do that.

It is the way it is, because of the economic reality: hardware is much
cheaper than software. From an economic standpoint, it's better to tape
together a bunch of software components, even if the contraption will
require a 3GHz machine to run, than to write it from scratch to run on a
286.


> I'm sorry but there is no quick fix. All you can really say is "hey,
> this is what helped me progress from writing small crap programs
> that I'm now embarised about to big beautiful programs that I am now proud
> of". At the end of the day it always comes down to constantly trying
> to improve yourself and your code. In other words hard work.

I would be more specific, it's "smart hard work".

Working hard using old tools and ideas, won't bring much improvement. True,
you can get better at digging trenches with a shovel if you practice, but
you're likely to see a more significant increase in productivity, if you use
an excavator.


> Yes you can lay down rules that help a team cooperate but dig deep enough
> and in that team you will always find a core of people that are
> making the project work dispite the others (unless the project is a
> complete disaster in which case there may not be such a core at all).

"Despite the others", it's a classic. :)  Conclusion: keep the core, fire
the others.


> One of the things I really like about the MIT PICLIST is that there are
> lots of people on it that WORK HARD to achive good things despite the
> restrictions. Some of these people are not even professional PIC
> programmers. They are not trying because they are being paid to, they are
> trying because they want to. These are the sort of people that make good
> programmers, the ones that push themselves, not the clock watching recipe
> following form fillers who have little interest in the code that they
> write.

While I agree with what you said, I must comment that well-meaning
programmers are known to write the most horrible code. Even people who are
"cut out" to be programmers, need to learn how to program properly.

Today I visited a local student project fair, and looked at the code listing
for one of the projects. They had a function that, among other things, went
something like this:

   sensor1 = PORTA & 0x01
   sensor2 = PORTA & 0x02
   // and so on, for a total of about 12 sensors

This was followed by a bunch of "if" statements:

   if (sensor2 & 0x02)
   {
       // do stuff
   }

The students have invested a lot of time in developing the project, and were
really proud of it, but the code was like a roll of toilet paper, with some
functions spanning multiple pages. If they followed the simple rule that
functions longer than 10 lines are suspect, and should be considered for
refactoring, the code would have been much easier (and fun-ner) to develop,
debug, and maintain.

Best regards,

Vitaliy

2008\10\16@074737 by olin piclist

face picon face
Vitaliy wrote:
> The students have invested a lot of time in developing the project,
> and were really proud of it, but the code was like a roll of toilet
> paper, with some functions spanning multiple pages. If they followed
> the simple rule that functions longer than 10 lines are suspect, and
> should be considered for refactoring, the code would have been much
> easier (and fun-ner) to develop, debug, and maintain.

I disagree.  They are students just getting into programming.  At this point
it is more important that they get something done in a way that makes sense
to them.  If you impose a bunch of rules, especially ones off the deep end
like 10 line subroutines, it will just make the task seem overwhelming to
them.

Now that they are done with the project it is a good time to go over the
code with them and suggest improvements.  Start by finding sections of code
that are repeated and put them into subroutines.  The logical structure is
far more important than the length of the subroutines.  And of course get
them used to the idea of documenting the code, but go easy knowing they will
think it's silly and rebell.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\16@111425 by William \Chops\ Westfield

face picon face

> 10 line subroutines


Throughout this discussion I've seen "code can't lie like comments  
can", and it seems to me like this isn't really true.  By the time you  
get to the depth of function calls implied by 10-line subroutines, I  
think the obvious string of self-documenting function names can  
actually lie quite a bit.  You're assuming when you look at such code  
that the lower level of functions is debugged and working, which may  
or may not be true (just like the comments may or may not match the  
actual code.)  Not to mention less obvious errors like:
       int myBrightness = random(0, 100000);

You can only REALLY count on the most primitive levels of the language  
you're using (and even then there can be compiler issues, if you're  
unlucky.)  This applies to assembler a well; once you start using  
macros and defines and so on, you COULD be hiding problems that would  
be obvious otherwise.

I'm sure I've done this many times.  Spent hours staring at a function  
to try to figure out what was wrong with it, only to eventually  
realize that the actual problem was in a lower-level function that I  
was "trusting" to work in the obvious way.

(This used to bug me a lot on an assembler-based mainframe I used to  
program.  System calls were done by putting arguments in registers 1  
through 4 (of 16.)  It HAD to be 1 through 4, and specific arguments  
went in specific registers.  Yet the convention was to use symbols for  
those registers.  Sometimes A..D, sometimes T1..T4, but it was NOT  
GOOD to just use numeric registers, even though the symbols HAD to  
have the right values or things would break.  I'm still not sure I  
agree...)
(similarly, I have occasional doubts about the "avoid numeric  
constants" rule in most C environments.  If there is code like:
>  for (i=0; i<NUM_INTERFACES; i++)
>    enqueue(interface_info_queue, malloc(INTERFACE_DATA_SIZE));
whether this is "reasonable" or not to me as a code reviewer depends  
substantially on the actual values of NUM_INTERFACES and  
INTERFACE_DATA_SIZE, and sometimes figuring out what those are  
involves diving down through multiple layers of stuff (#define  
NUM_INTERFACES (NUM_ETHERNET+NUM_SERIAL+NUM_ASYNC), #define NUM_ASYNC  
(NUM_ASYNC_PAS+N_AUX_LINES+N_VIRTUAL_ASYNC), #define N_VIRTUAL_ASYNC  
PLATFORM_MAXVTYS, ...)  If the loop is allocating 1000000 10-byte  
blocks, or 10000 10000-byte blocks, those are both not-so-good, for  
different reasons, but I CAN'T TELL!   Grr.)

Of course, this doesn't mean that we should write all our code in  
straight-line statements of the simplest form possible.  BALANCE!  Ten-
line functions may be for academic exercises of less than 1000 total  
lines, but that doesn't mean my million line behemoth should get to  
use functions thousands of lines long, either...

BillW

2008\10\16@114516 by olin piclist

face picon face
William Chops" Westfield" wrote:
> Of course, this doesn't mean that we should write all our code in
> straight-line statements of the simplest form possible.  BALANCE!
> Ten- line functions may be for academic exercises of less than 1000
> total lines, but that doesn't mean my million line behemoth should
> get to use functions thousands of lines long, either...

I agree.  The important part is how the system is partitioned into
subroutines.  This has very little to do with the size of those subroutines.
Lines of code is the wrong metric to decide whether a subroutine should be
broken up or not.  In fact, it's probably damaging to do so since this comes
at the expense of more relevant criteria.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\16@121034 by Neil Cherry

flavicon
face
Olin Lathrop wrote:
> William Chops" Westfield" wrote:
>> Of course, this doesn't mean that we should write all our code in
>> straight-line statements of the simplest form possible.  BALANCE!
>> Ten- line functions may be for academic exercises of less than 1000
>> total lines, but that doesn't mean my million line behemoth should
>> get to use functions thousands of lines long, either...
>
> I agree.  The important part is how the system is partitioned into
> subroutines.  This has very little to do with the size of those subroutines.
> Lines of code is the wrong metric to decide whether a subroutine should be
> broken up or not.  In fact, it's probably damaging to do so since this comes
> at the expense of more relevant criteria.

When I was studying computer science I never heard of the 10 line
rule. It kind of sounds like a good rule to teach new students
but I'd bet that many would keep it as a golden rule. The one
thing schools fail to teach is thinking. My rules on subroutines/
functions are to group like code together. That way debugging it
is made easier. My understanding is that this is top down programming.
My 'main' routine contains almost all functions calls with very little
manipulation in it. The other rule for breaking something out is when
the same code is used in more than one place it goes into a sub/func
and/or eventually a library (if it's used often enough). My libraries
follow the Unix tradition of doing only one thing and nothing more.

My 'main' routine contains lot of functions with descriptive names
and very few extra comments (I do use them if the function name is
too complex). The subs/funcs get lots of comments and some descriptive
names. Any library needs a descriptive name and a man page :-). Even
my assembly language routines look this way (glad we're not limited to
6 characters anymore). My OO programs are a little different as it's
no longer subs and funcs but rather methods which is their simpliest
form are exactly the same thing (set/get) but in their most useful
complex form are entirely something else.

--
Linux Home Automation         Neil Cherry       .....ncherryspamRemoveMElinuxha.com
http://www.linuxha.com/                         Main site
http://linuxha.blogspot.com/                    My HA Blog
Author of:            Linux Smart Homes For Dummies

2008\10\16@124025 by Dr Skip

picon face
Partitioning and structuring code is like beauty. One general rule doesn't
usually work, there are a thousand different approaches or opinions that may be
'better' or 'worse' in the eye of the viewer, and sometimes a combination you
might have thought wouldn't work well turns out to be great... ;)

-Skip


Neil Cherry wrote:
{Quote hidden}

2008\10\16@165932 by Vitaliy

flavicon
face
Olin Lathrop wrote:
>> The students have invested a lot of time in developing the project,
>> and were really proud of it, but the code was like a roll of toilet
>> paper, with some functions spanning multiple pages. If they followed
>> the simple rule that functions longer than 10 lines are suspect, and
>> should be considered for refactoring, the code would have been much
>> easier (and fun-ner) to develop, debug, and maintain.
>
> I disagree.  They are students just getting into programming.

Yes, sadly. After three and a half years of Computer Engineering, and just
one semester away from graduating with their BS degrees.


> At this point
> it is more important that they get something done in a way that makes
> sense
> to them.

Since when are you an advocate of newbie rights? :)

What you said above doesn't make sense -- why not show the students that
there is a better way? Not "impose" anything on them, but show them the
available options, and explain the pros and cons of different programming
styles.

I'm actually thinking about getting in touch with the Dean to pitch the idea
of offering seminars for students who are interested. Our selfish
self-interest in this, is finding and snatching the best and the brightest,
before Microchip and Freescale have a chance to get them. :)


> If you impose a bunch of rules, especially ones off the deep end
> like 10 line subroutines, it will just make the task seem overwhelming to
> them.

I think you have a very narrow and distorted vision of what I'm talking
about. I think if you just try to understand what I'm talking about, you'll
see that I have never argued for arbitrarily splitting up functions based on
the line count (that would be ridiculous). Let me ask you several very
relevant questions:

1. Do you currently develop software in C? The feeling I get from your posts
(and other people's comments) is that you prefer assembly (which is a very
different beast).

2. What is the average size of your functions? What is the size of the
shortest one? Longest one?

Please don't ignore these questions, lest we continue down the path of vague
abstractions, baseless accusations, and strawmen.


> Now that they are done with the project it is a good time to go over the
> code with them and suggest improvements.

Too late, they're done. An iterative approach would have worked best, but if
that's not an option, a short presentation on available tools and
methodologes would be far better than trying to pick up the pieces after the
fact (when all the motivation is removed).


> Start by finding sections of code
> that are repeated and put them into subroutines.  The logical structure is
> far more important than the length of the subroutines.  And of course get
> them used to the idea of documenting the code, but go easy knowing they
> will
> think it's silly and rebell.

"Small" and "cohesive" go hand in hand. A lot of times, you don't realize
that "code is repeated" until you put it in its own subroutine, and find
yourself calling it from other subroutines.


Vitaliy

2008\10\16@171654 by Vitaliy

flavicon
face
William "Chops" Westfield wrote:
> Throughout this discussion I've seen "code can't lie like comments
> can", and it seems to me like this isn't really true.  By the time you
> get to the depth of function calls implied by 10-line subroutines,

You'd may be surprised to know that it's not as deep as you think. Splitting
up large bloated functions usually doesn't mean that you end up with a chain
of functions, each calling the one down (which is how you are imagining
this):

   funct1-> funct2-> funct3-> funct4-> funct5

Instead, you end up with just two levels, regardless of the number of
functions being called:

   HigherLevelFunction()
   {
       funct1();
       funct2();
       funct3();
       funct4();
       funct5();
   }

Sure, there's more overhead because now you have five extra function calls.
That's the price I'm willing to pay to make my code more readable.


> I think the obvious string of self-documenting function names can
> actually lie quite a bit.  You're assuming when you look at such code
> that the lower level of functions is debugged and working, which may
> or may not be true (just like the comments may or may not match the
> actual code.)

The difference is, the programmer is more likely to change the function name
to reflect what it really does, than to update the comments.

When that happens, the programmer is then FORCED by the compiler to update
other parts of the code, that call this function. You don't have this luxury
with comments.


> You can only REALLY count on the most primitive levels of the language
> you're using (and even then there can be compiler issues, if you're
> unlucky.)  This applies to assembler a well; once you start using
> macros and defines and so on, you COULD be hiding problems that would
> be obvious otherwise.

I make an effort to practice what I preach, and I haven't found this to be a
problem. In fact, the tight cohesion makes it easy to isolate the problem.
I'm never looking for a problem with the A/D in a UART module.


> I'm sure I've done this many times.  Spent hours staring at a function
> to try to figure out what was wrong with it, only to eventually
> realize that the actual problem was in a lower-level function that I
> was "trusting" to work in the obvious way.

I'm trying to break this habit of "staring" at functions. Instead, I step
through the code, watch the variables and registers, and write tests so I
don't have to "trust" a function. There are times when the best thing to do
is to just scrap the function, and rewrite it from scratch, testing it along
the way.


> Of course, this doesn't mean that we should write all our code in
> straight-line statements of the simplest form possible.  BALANCE!  Ten-
> line functions may be for academic exercises of less than 1000 total
> lines, but that doesn't mean my million line behemoth should get to
> use functions thousands of lines long, either...

I don't understand what your guys' beef is, with small functions?  I'm not
writing academic exercises, I'm writing real production code.


Vitaliy

2008\10\16@174515 by olin piclist

face picon face
Vitaliy wrote:
> Yes, sadly. After three and a half years of Computer Engineering, and
> just one semester away from graduating with their BS degrees.

I somehow got the impression these were highschool students.

> I think if you just try to understand what I'm talking
> about, you'll see that I have never argued for arbitrarily splitting
> up functions based on the line count (that would be ridiculous).

OK, I got the impression you did, and I think others also got that
impression.

> 1. Do you currently develop software in C?

Only when I can't avoid it since C is such a awful language.

> The feeling I get from
> your posts (and other people's comments) is that you prefer assembly
> (which is a very different beast).

To say I prefer assembly in general is wrong.  We do enough cram jobs with
PICs that we have to be proficient at assembly on PICs.  MPASM is not a
great assembler.  I think the best I've used was Microsoft MASM for the x86
CPU.  MPASM isn't even near the top of the best list.  Since assembler is a
necessity for us and MPASM is what there is, we have spent significant
effort on tools that make it much more usable, decrease the chance of common
errors, make things more symbolic, etc.  The result is a environment I am
very comfortable with and can get things done in quickly and realiably.
That, the fact that there is now a large base of reusable code on the disk,
and that I feel like needing a shower after touching C code means I prefer
assembly on PICs and am quite effective with it.  If a better high level
language than C was common on these little systems I'd probably use it more
on less crammed jobs, but C is just too awful.  The issue is with C and some
particularly stupid implementations of it, not with high level languages in
general.

On PCs I write most of my code in Pascal.  This Pascal is supported thru my
own source to source translator that in the case of PCs running Windows
emits Microsoft visual C code because that's the most solid, well used, and
supported compiler for that platform.  This really is much better than C.
Before people try to defend the common use of C, they should at least spend
a few months experiencing something better.  I doubt they'd go back.  My
Pascal is free to anyone, by the way, including source code for the
translator.

> 2. What is the average size of your functions? What is the size of the
> shortest one? Longest one?

First, I think you are asking about subroutines in general, not just
functions.  Note that calling all subroutines "functions" is a C-ism.  Since
we are talking computer science in general, you shouldn't say "function"
unless you specifically mean a subroutine that returns a value.

To answer your question, I don't know since I don't have a way to scan for
this except by manually looking at code.  I know I have subroutines that are
only a few lines long, significantly less than 10.  I'm sure I've also got
subroutines that are in the 100s of lines somewhere.  The line length of a
subroutine is not relevant, so I never paid much attention to it.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\16@175637 by Vitaliy

flavicon
face
Neil Cherry wrote:
> When I was studying computer science I never heard of the 10 line
> rule. It kind of sounds like a good rule to teach new students
> but I'd bet that many would keep it as a golden rule. The one
> thing schools fail to teach is thinking.

I can't say great thing about the programming classes that I took in
college. They were all either unstructured (do whatever to get the result),
or too rigid, it was almost like "fill in the blanks".

However, I've been self-educating (can you say this? :) sort of like
"self-medicating"), and there are recurring ideas in many good books on
programming. Here's one I found in "Delphi 4 Unleashed", Chapter 1
("Programming Design Basics"):

"== Short Methods ==

In the interest of keeping things simple, I like to create short methods.
Not all methods need be short, but most of them should be short. In
particular, I think about four out of five methods that I write should be
short, where I define short as being 25 lines or fewer."

Yeah, I know -- he said "25 lines or fewer". Personally, I prefer even
shorter functions, most of the time -- but this is an example of using a
limit expressed as a number of lines of code, from someone far more
experienced and knowledgeable than me.


> My rules on subroutines/
> functions are to group like code together.

Same book, next paragraph: "Just as it is important to see that the Form1
object of a program can contain multiple objects, so is it important to see
that a single method can contain multiple methods that need to be broken
out. I try to discover the methods buried in my code, just as I seek to find
the objects buried in my code."

I do the same thing. The "10-line limit" rule sort of evolved over time.
Small function size can almost be thought of as a byproduct of tight
cohesion.


> That way debugging it
> is made easier. My understanding is that this is top down programming.
> My 'main' routine contains almost all functions calls with very little
> manipulation in it. The other rule for breaking something out is when
> the same code is used in more than one place it goes into a sub/func
> and/or eventually a library (if it's used often enough). My libraries
> follow the Unix tradition of doing only one thing and nothing more.

Can't argue with anything you said, except that I prefer to keep main() as
short as possible, and put the main loop in a function called RunMainLoop(),
which is called after InitializeAll().


> My 'main' routine contains lot of functions with descriptive names
> and very few extra comments (I do use them if the function name is
> too complex).

I think that a function name that is too complex (some agilists use the word
"smelly") is a good indicator of a function that needs to be refactored.
Chances are, it's trying to do the work of two or more functions.


> The subs/funcs get lots of comments and some descriptive
> names. Any library needs a descriptive name and a man page :-). Even
> my assembly language routines look this way (glad we're not limited to
> 6 characters anymore).

This is called by some "programming into a language", as opposed to
"programming in a language". You take useful concepts from higher level
languages, and "back port" them into a lower level language.

I use objects and methods when I program in C, and Timothy J Weber and I
have recently been discussing how to make Test Driven Design work on PICs.
:)


Vitaliy

2008\10\16@180902 by olin piclist

face picon face
> To answer your question, I don't know since I don't have a way to
> scan for this except by manually looking at code.  I know I have
> subroutines that are only a few lines long, significantly less than
> 10.  I'm sure I've also got subroutines that are in the 100s of lines
> somewhere.  The line length of a subroutine is not relevant, so I
> never paid much attention to it.

I should have added that if you really want to know, you can look for
yourself.  Go to http://www.embedinc.com/pic/dload.htm and install the "Host
source code and everything" release.  I've written a lot more code that what
I give out publicly, but there is plenty there to take see the style.

I just ran the release script and measured the Pascal code.  There are over
175,000 lines in a bit over 1000 files.  Some of those date back to the late
1980s and others are recent.  In that volume of code I'm sure you can find a
few stupidities if you look hard enough, but overall I stand by this being
well written code.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\16@194648 by Mongol Herdsman

picon face
Olin Lathrop wrote:
> Lines of code is the wrong metric to decide whether a subroutine should be
> broken up or not.  In fact, it's probably damaging to do so since this comes
> at the expense of more relevant criteria.

In a case a sub is perfoming a lot of simple straightforward
operations that won't be reused, I'm commenting the blocks of code
inside the sub, no need to flood the sub's namespaces with hundreds
names you won't refer to anymore. Such "composite" subs easily reached
more than hundred of lines in my experience.

2008\10\16@195114 by Vitaliy

flavicon
face
Olin Lathrop wrote:
> I agree.  The important part is how the system is partitioned into
> subroutines.  This has very little to do with the size of those
> subroutines.
> Lines of code is the wrong metric to decide whether a subroutine should be
> broken up or not.  In fact, it's probably damaging to do so since this
> comes
> at the expense of more relevant criteria.

This is probably something we will have to agree to disagree on.

Vitaliy

2008\10\16@204830 by Vitaliy

flavicon
face
Olin Lathrop wrote:
>> Yes, sadly. After three and a half years of Computer Engineering, and
>> just one semester away from graduating with their BS degrees.
>
> I somehow got the impression these were highschool students.

No, they're DeVry University students (the same school I graduated from).
Having said that, majority of our engineering and technical staff were hired
from there -- so it can't be that bad. I guess you just have to know how to
separate the wheat from the chuff, and provide proper incentives and
training.

One of our engineers commented to me that he also noticed that over the
years, the quality of projects really went south. The project that our
company sponsored was by far the best one (it took all the awards), but IMHO
considering the size of the team, it was not challenging enough:

http://www.youtube.com/watch?v=hr41qPnyigE

I don't know for sure, but I get the feeling that the guy in the video did
90% of the work (he's the project leader of a 5-person team).


>> I think if you just try to understand what I'm talking
>> about, you'll see that I have never argued for arbitrarily splitting
>> up functions based on the line count (that would be ridiculous).
>
> OK, I got the impression you did, and I think others also got that
> impression.

I don't know what to do about it. I try to explain what I mean in the
simplest and plainest language possible, but it seems that people who read
my posts misinterpret them all the time.

Here's my original statement from October 5 that started all this:

"I believe that the real purpose of comments is to provide the context, to
explain *why* something is being done (never *what* is being done). If you
follow the principles of tight cohesion, and keep the functions short (20
lines or less, is my rule of thumb) you can name the function in a way that
describes exactly what it does."

Can you explain to me why Olin et al took the above to mean that I advocate
breaking up subroutines once they grow beyond 10 lines?


>> 1. Do you currently develop software in C?
>
> Only when I can't avoid it since C is such a awful language.

I think it's fine. :)

But then again, I'm still using CorelDraw 9 (state-of-the-art in the late
90's), because I can't get used to the quirks of Adobe CS3 that everyone
else here is using. I'm just far more efficient using CorelDraw, than CS3 --  
because I've used it so much.


> On PCs I write most of my code in Pascal.  This Pascal is supported thru
> my
> own source to source translator that in the case of PCs running Windows
> emits Microsoft visual C code because that's the most solid, well used,
> and
> supported compiler for that platform.  This really is much better than C.
> Before people try to defend the common use of C, they should at least
> spend
> a few months experiencing something better.  I doubt they'd go back.

I have about as much experience with Object Pascal as I do with C, and I
think they're both decent tools for getting the job done. I would definitely
prefer to program in some sort of OOP language, but for now I have to work
with what I got and I try to make C look as much as C# or Object Pascal, as
I can.


>> 2. What is the average size of your functions? What is the size of the
>> shortest one? Longest one?
>
> First, I think you are asking about subroutines in general, not just
> functions.  Note that calling all subroutines "functions" is a C-ism.
> Since
> we are talking computer science in general, you shouldn't say "function"
> unless you specifically mean a subroutine that returns a value.

Yes, sir!


> To answer your question, I don't know since I don't have a way to scan for
> this except by manually looking at code.  I know I have subroutines that
> are
> only a few lines long, significantly less than 10.  I'm sure I've also got
> subroutines that are in the 100s of lines somewhere.  The line length of a
> subroutine is not relevant, so I never paid much attention to it.

I think "100s of lines" is excessive. I know that there is no way my brain
can treat such subroutine as a single, cohesive entity.

So what would be the reason for not breaking it up -- performance?


Vitaliy

2008\10\16@205251 by Vitaliy

flavicon
face
Dr Skip wrote:
> Partitioning and structuring code is like beauty. One general rule doesn't
> usually work, there are a thousand different approaches or opinions that
> may be
> 'better' or 'worse' in the eye of the viewer, and sometimes a combination
> you
> might have thought wouldn't work well turns out to be great... ;)

Beauty has plenty of rules.

http://en.wikipedia.org/wiki/Vitruvian_Man

"Form is liberating."

Vitaliy

2008\10\16@210547 by Mongol Herdsman

picon face
Olin Lathrop wrote:
> I agree.  The important part is how the system is partitioned into
> subroutines.

Vitaly seems to know how the system should be partitioned into
subroutines. Subs should be losely coupled and tightly cohesive,
that's it, If I understand him correctly.

You seem to state (at least how I'm getting it) that the above
criteria are derivative not primary. There are a lot of other
"primary" criteria to be satisfied first. In real life trying to focus
on getting max derivative may not neccesarily lead to the max primary
criteria score in the end.

2008\10\16@211319 by Dr Skip

picon face
Art has rules, beauty does not.

Vitaliy wrote:
> Dr Skip wrote:
>> Partitioning and structuring code is like beauty. One general rule doesn't
>> usually work, there are a thousand different approaches or opinions that
>> may be
>> 'better' or 'worse' in the eye of the viewer, and sometimes a combination
>> you
>> might have thought wouldn't work well turns out to be great... ;)
>
> Beauty has plenty of rules.
>
> http://en.wikipedia.org/wiki/Vitruvian_Man
>
> "Form is liberating."
>
> Vitaliy
>

2008\10\16@212841 by Jinx

face picon face
> Art has rules, beauty does not.

I think Tracey Emin might have an argument with you about that

2008\10\16@215454 by Vitaliy

flavicon
face
> Art has rules, beauty does not.

Define "beauty". If you can't, then how's your analogy useful?

2008\10\17@014043 by Dr Skip

picon face
Vitaliy wrote:
>
> Define "beauty". If you can't, then how's your analogy useful?

Not so, and at the risk of being chastised for being off-topic, I know it when
I see it. Both have multiple dimensions in which it can be evaluated. One
person's 'ugly' can be another's beautiful, and both are valid. That's the
point. One finds more than 10 or 20 lines of code in a sub to be an 'ugly' sub,
another may use a complex, difficult to articulate metric that combines many
attributes of the sub in question before passing judgement. Opinions may, and
often, change as the 'beholder' becomes more intimate with the object being
assessed.

The little grey haired old woman may never make the fashion mag cover, but as
wife or mother, is the most beautiful person someone else knows. Others might
use more simplistic metrics - the tan blonde in high heels and mini skirt might
be beautiful, but the same person in rags and covered in mud isn't (or may be
more so ;) ).

Both areas are alike in that there are not hard and fast rules for judgement,
only broad guidelines, the metrics can change with context and with person
(judge), they can even change as more is known about the subject, people will
endlessly disagree about the details and merits of both, and in the end, there
is no 'universal' right or wrong, only opinion, even if there is consensus at
certain times and certain situations. Another commonality seems to be that
proponents of some particular viewpoint will assume it is 'the' metric by which
the subject is or should be judged.



-Skip

2008\10\17@035746 by Alan B. Pearce

face picon face
>I'm never looking for a problem with the A/D in a UART module.

<VBG> Unless you are using a low range PIC, and looking for where to put the
missing bank and page instructions ... ;)))

2008\10\17@040203 by Alan B. Pearce

face picon face
>PCs running Windows emits Microsoft visual C code
>because that's the most solid, well used, and
>supported compiler for that platform.

I have heard of people moving from Visual C to Intel C compilers for
Windows, and having both speed improvements and less strange problems in the
code. The newest Microsoft compilers may be better, but there was a stage
where they did have strange problems apparently - I did only hear about them
third hand.

2008\10\17@041600 by Alan B. Pearce

face picon face
>the tan blonde in high heels and mini skirt might be
>beautiful, but the same person in rags and covered
>in mud isn't (or may be more so ;) ).

Me Tarzan - her? she Jane ...

2008\10\17@074032 by olin piclist

face picon face
Vitaliy wrote:
> I think "100s of lines" is excessive. I know that there is no way my
> brain can treat such subroutine as a single, cohesive entity.
>
> So what would be the reason for not breaking it up -- performance?

The point of good subroutine partitioning is in what the subroutine does,
not how it's implemented.  At each level in the hierarchy of the project, a
subroutine should do a single comprehensible thing.  Once you've written and
debugged it, how many lines of code are inside is irrelevant.

It is quite possible for a subroutine to present a task that is simple and
indivisible to the rest of the system, but still takes several sequential
steps inside.  There is nothing wrong with this.  You might implement some
of these sequential steps as internal subroutines (oh yeah, another thing C
doesn't have) if you think they are individually complex enough or require
enough private state that the other steps don't.

On the other hand, if the sequential steps are more related and deal with
the same local state, it may be better to just write them in sequence in the
subroutine.  This can make the subroutine easier to understand since you
don't have to jump all over the place to find the actual code.  It's the
logical partitioning that matters.  Nowhere does lines of code enter into
it.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\17@091232 by Tamas Rudnai

face picon face
> You might implement some
> of these sequential steps as internal subroutines (oh yeah, another thing
C
> doesn't have) if you think they are individually complex enough or require
> enough private state that the other steps don't.

Oh yes, you can always move to C++ and use private member functions and
variables to encapsulate those things :-)

BTW you could actually put "private functions" to a different C source and
mark them as static but then you loose the usage of local variables that
might be a good idea in some cases. Like how would someone write this in C?

procedure MyProc;
var Var1, Var2 : integer;

   procedure insideProc;
   begin
       Var1 := 3;
       Var2 := 4;
   end;


begin
   Var1 := 1;
   Var2 := 2;

   insideProc;
end;

Var1 and Var2 are local variables to MyProc, thus created on stack when the
function is getting called. Then insideProc can use those locals just as was
theirs. I could not remember any solution for this in C except references,
pointer and other magic.

Tamas



On Fri, Oct 17, 2008 at 12:40 PM, Olin Lathrop <RemoveMEolin_piclistspamspamBeGoneembedinc.com>wrote:

{Quote hidden}

> -

2008\10\17@100353 by olin piclist

face picon face
Tamas Rudnai wrote:
> Like how would someone write this in C?
>
> procedure MyProc;
> var Var1, Var2 : integer;
>
>     procedure insideProc;
>     begin
>         Var1 := 3;
>         Var2 := 4;
>     end;
>
>
> begin
>     Var1 := 1;
>     Var2 := 2;
>
>     insideProc;
> end;

You can't.  C has no notion of "internal" subroutines.  All subroutines are
separately compiled.

I deal with this in my translator by adding additional call arguments to the
internal routines to explicitly pass all local state that the implicitly
reference in Pascal.

This is a case where Pascal is actually more efficient since the compiler
knows where the parent routine's local variables are on the stack relative
to the internal routine's stack pointer.  The C workaround causes addresses
to be explicitly passed to the "internal" routine.

So there's one example of Pascal being inherently more efficient.  I'm still
waiting for Peter to show a example of how C is inherently more efficient
(Although I suspect he was really just spouting off without concrete
evidence).


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\17@170211 by Gerhard Fiedler

picon face
Alan B. Pearce wrote:

>>I'm never looking for a problem with the A/D in a UART module.
>
> <VBG> Unless you are using a low range PIC, and looking for where to put the
> missing bank and page instructions ... ;)))

See... this is one of the reasons why I like compilers: they do this really
lowly housekeeping for me. Plus other such things (like assigning
non-overlapping addresses to local variables etc.)

Gerhard

2008\10\17@171841 by Gerhard Fiedler

picon face
William "Chops" Westfield wrote:

>> 10 line subroutines
>
> Throughout this discussion I've seen "code can't lie like comments can",
> ...

I don't think anybody has written this in this thread.

> ... and it seems to me like this isn't really true.  

It isn't; you're right.

What is true (IMO, of course) is that it is less likely that a function
name gets out of sync with what the function does than the header comment
of the function getting out of sync with what it does. That's all there is
to it, but IMO it's powerful. Especially when you try to get into the habit
of giving your symbols meaningful (consistently meaningful) and specific
names.

> By the time you get to the depth of function calls implied by 10-line
> subroutines, I think the obvious string of self-documenting function
> names can actually lie quite a bit.  

But you can work on this chunk by chunk. If you look at such a 10-line
function, it's usually relatively obvious whether the function name lies or
not. If it doesn't seem to be clear, find a better description. If there
isn't a good descriptive name, there's a good chance that your design is
somewhat off.

> You're assuming when you look at such code that the lower level of
> functions is debugged and working, which may or may not be true ...

Right, of course. The devil may be everywhere. It's not about bug-free
code, it's about reducing the likelihood of bugs and about reducing the
time to find them. I think 10-liners are a bit on the extreme side, but IMO
functions that don't span much more than a single screen height make
debugging a whole lot easier. (And this is completely independent of the
overall complexity of the system... works for me as well in one-day
programs as it works in programs that contain dozens of man-years.)

For the last few months I've worked over some (C++) code that I inherited.
It was almost impossible to understand, and the comments didn't help much.
It's now a reasonable construct of reasonably short and clear functions --
and guess what, it works better and is /much/ easier to expand.

> ... (just like the comments may or may not match the actual code.)  

"Just like" in the sense of possibility, but not in the sense of
probability. Again, it's not about getting all the black out and creating
something purely white, it's about getting the grey as clear as reasonably
possible.

> I'm sure I've done this many times.  Spent hours staring at a function to
> try to figure out what was wrong with it, only to eventually realize
> that the actual problem was in a lower-level function that I was
> "trusting" to work in the obvious way.

Well, you shouldn't trust, in such a case. (You probably know this :) This
of course can happen with long functions and with short functions. The
question is not whether or not, the question is what helps you reducing the
likelihood of it happening and what helps you reducing the time to find and
fix it.

{Quote hidden}

You may need a better editor. It may be a pain to collect all those pieces,
and it may or may not be badly designed (I don't think anybody ever claimed
that short functions is a reasonable replacement for good design :), but it
shouldn't be farther away than a few right clicks or hover-overs or
whatever your editor needs to get you to the definition.

If it is actually so complex, a numeric constant wouldn't really cut it
either, because you'd have to change it whenever you change any of its
dependencies -- now that would be a mess, it seems :)

Gerhard

2008\10\17@172541 by Gerhard Fiedler

picon face
Dr Skip wrote:

> One finds more than 10 or 20 lines of code in a sub to be an 'ugly' sub,
> another may use a complex, difficult to articulate metric that combines
> many attributes of the sub in question before passing judgement.
> Opinions may, and often, change as the 'beholder' becomes more intimate
> with the object being assessed.

Problems with this point of view arise when you start working together.
Then it's more about what works best for all than what you personally "just
like". So far, my style of breaking down functionality into relatively
easily understandable pieces and combining them in ways that make sense for
the structure of the programming language, its community and the target
domain has been appreciated by coworkers. The spaghetti style of writing
long-winded functions spanning hundreds of lines generally isn't that much
appreciated -- even by the ones who write such code, the difference being
that they often only realize what a pain it can be when they have to start
working on someone else's code that's written like this :)

Which is of course not to say that there is a single, "right" way. But
there /are/ some things that are reasonably proven to work, almost like
Ohm's "law".

Gerhard

2008\10\17@173806 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

> Vitaliy wrote:
>> I think if you just try to understand what I'm talking about, you'll see
>> that I have never argued for arbitrarily splitting up functions based
>> on the line count (that would be ridiculous).
>
> OK, I got the impression you did, and I think others also got that
> impression.

Really? Hm... there must be missing something. To me it was downright
/obvious/ that this is not what he was talking about.

Gerhard

2008\10\17@174334 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

> First, I think you are asking about subroutines in general, not just
> functions.  Note that calling all subroutines "functions" is a C-ism.  Since
> we are talking computer science in general, you shouldn't say "function"
> unless you specifically mean a subroutine that returns a value.

Could it be that making this distinction between subroutines and functions
is a Pascal-ism -- and not that not making it is a C-ism? :)

FWIW, this Wikipedia article uses these terms, in a general form, as
synonymous.

http://en.wikipedia.org/wiki/Function_(computer_science)

Gerhard

2008\10\17@184908 by olin piclist

face picon face
Gerhard Fiedler wrote:
>> First, I think you are asking about subroutines in general, not just
>> functions.  Note that calling all subroutines "functions" is a
>> C-ism.  Since we are talking computer science in general, you
>> shouldn't say "function" unless you specifically mean a subroutine
>> that returns a value.
>
> Could it be that making this distinction between subroutines and
> functions
> is a Pascal-ism -- and not that not making it is a C-ism? :)

The distinction is common to many languages.  Fortran, the first compiled
language, used the name "subroutine" and "function".  Pascal uses
"procedure" and "function".  C came after both these.  In C all subroutines
sortof are functions, just that some of them return "void".  If that's how
you view C (and possibly the designers of C viewed exactly that way), then
calling subroutines in C all functions isn't wrong.  What's wrong is going
back to the general computing world outside C and calling all subroutines
functions.  Unfortunately a lot of people can't seem to separate C specifics
from general computing.  That is definitely bad.

> FWIW, this Wikipedia article uses these terms, in a general form, as
> synonymous.

That only shows how heavily C conventions have infected general computer
science, not that it's right.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\17@231018 by Vitaliy

flavicon
face
Gerhard Fiedler wrote:
>> Throughout this discussion I've seen "code can't lie like comments can",
>> ...
>
> I don't think anybody has written this in this thread.

I think it's just another example of people taking the original statement
and misinterpreting it to make it into a straw man. :-)


{Quote hidden}

Couldn't agree more.


{Quote hidden}

Yup!


>> You're assuming when you look at such code that the lower level of
>> functions is debugged and working, which may or may not be true ...
>
> Right, of course. The devil may be everywhere. It's not about bug-free
> code, it's about reducing the likelihood of bugs and about reducing the
> time to find them. I think 10-liners are a bit on the extreme side,

I'm pretty sure I qualified what "10 lines" mean. It's 10 lines of *actual
statements*, not including blank lines, comments, curly braces, etc. And I
didn't say it was a hard upper limit, but that it was the average size of my
functions.

> but IMO
> functions that don't span much more than a single screen height make
> debugging a whole lot easier.

The definition of "single screen height" can vary widely. :) I have a 30"
monitor at work, but sometimes I work on the same project remotely, from a
15" laptop.


> For the last few months I've worked over some (C++) code that I inherited.
> It was almost impossible to understand, and the comments didn't help much.
> It's now a reasonable construct of reasonably short and clear functions --
> and guess what, it works better and is /much/ easier to expand.

I can truly relate. Earlier this year, I had to go back to the code we've
written long ago. I had to completely refactor a huge (several hundred
lines) function which was basically one big complicated state machine,
before I felt confident to make any changes to the functionality. I broke it
down into a dozen smaller functions, which made it trivial to understand and
modify.

Two years ago, I would approach the same problem by re-reading and possibly
re-commenting the code to get familiar with it enough to make changes to it.
Now, I refactor.


{Quote hidden}

The complaint refers to the programming practice called "avoid magic
numbers". If I had to choose between having a named constant that tells me
something about itself, or a number, I would choose the former every time.
To take your example,

   for (i = 0; i < 100000000; i++)

What does the number represent? I have no clue.

As long as you follow another rule -- "declare/define a variables or a
constant as close as possible to the place where you are using it" -- the
problem you described becomes a non-issue. I usually put "local" #defines
right before the function that uses it. Like this:


   // start of file

   // ... a bunch of code

   #define INTERFACE_COUNT    100

   void Foo()
   {
       // use INTERFACE_COUNT here
   }


This last rule is another reason why short functions are a good -- the
variables are declared and initialized just a few lines above the statement
that is using the variable.


Vitaliy

2008\10\17@234541 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

> Gerhard Fiedler wrote:
>>> First, I think you are asking about subroutines in general, not just
>>> functions.  Note that calling all subroutines "functions" is a C-ism.
>>> Since we are talking computer science in general, you shouldn't say
>>> "function" unless you specifically mean a subroutine that returns a
>>> value.
>>
>> Could it be that making this distinction between subroutines and
>> functions is a Pascal-ism -- and not that not making it is a C-ism? :)
>
> The distinction is common to many languages.  

So what? That doesn't make it more basic than not distinguishing them --
there are also many languages that don't.

So far, you've only cited a few languages that make a similar distinction.
This is a /very/ long shot from "computer science in general".

> Fortran, the first compiled language, used the name "subroutine" and
> "function".  Pascal uses "procedure" and "function".  C came after both
> these.  In C all subroutines sortof are functions, just that some of
> them return "void".  

Assembly came before all of these, and in assembly, a function call and a
subroutine call are the same. We could shoot examples back and forth all
night long, but the fact remains that you claimed that this distinction is
somehow something fundamental in computing science, and so far you only
showed that some languages do make it. I don't know whether you know or not
(your post seems to imply you don't, but I think you're just faking that
you don't know when actually you do know, just that this knowledge doesn't
suit your point :), but there are also languages that don't, which makes
citing examples a rather moot point, as there are many on both sides of the
fence. There doesn't seem to be a general principle at play; it's a mere
matter of syntax that some languages make this distinction and others
don't.

> What's wrong is going back to the general computing world outside C and
> calling all subroutines functions.  

Now why would this be wrong (other than because you don't like it)? It
simply depends whether this distinction adds anything to the (general, that
is, non-C and non-Pascal) discussion. In the scope of our discussion, this
distinction has no meaning at all, so why put on my Pascal hat and make a
distinction, where there is no need?

> Unfortunately a lot of people can't seem to separate C specifics from
> general computing.  That is definitely bad.

And some people seem to have a need to inject their favorite's language's
features in every general discussion, be they relevant or not :)

Gerhard

2008\10\18@035807 by Wouter van Ooijen

face picon face
> So far, you've only cited a few languages that make a similar distinction.
> This is a /very/ long shot from "computer science in general".

Amost all languages that 'inherit' from Algol58/60 have this
distinction, and then some more (Fortran). That's almost all languages,
but indeed, not C.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\18@044742 by Tamas Rudnai

face picon face
> Assembly came before all of these, and in assembly, a function call and a
> subroutine call are the same.

Do not forget, that early machines did not even have stack and call/return
mechanism.

I think the discussion is more like using the words from real languages in
the programming languages. In my mind function is a mathematical term for
calculating something

X = Y^2

for example. A function without a return does not make sense in mathematical
point of view:

Y^2

...so what? :-) Therefore a function have something to return. A procedure
is only to something to do --> there is no return. The big difference
(should be) also that a procedure has side effects while a function should
not. It is because a function only takes some input and gives back the
result while a procedure is a procedure of something, like for example
sending a message over the serial line.

I thing C started to use function only as Kernighan and Ritchie might
thought that every procedure has to give back a status - and they may
thought that a status is also a function return. Alternatively they had only
a baseline PIC that did not have RETURN instruction only RETLW :-)

Tamas





On Sat, Oct 18, 2008 at 4:44 AM, Gerhard Fiedler <spamBeGonelists@spam@spamspam_OUTconnectionbrazil.com
{Quote hidden}

> -

2008\10\18@060656 by Mongol Herdsman

picon face
Gerhard Fiedler <TakeThisOuTlistsspamspamconnectionbrazil.com> wrote:
>> What's wrong is going back to the general computing world outside C and
>> calling all subroutines functions.
>
> Now why would this be wrong (other than because you don't like it)? It
> simply depends whether this distinction adds anything to the (general, that
> is, non-C and non-Pascal) discussion. In the scope of our discussion, this
> distinction has no meaning at all, so why put on my Pascal hat and make a
> distinction, where there is no need?

His distinction seems to add to the discussion. A sub that returns a
value and a sub that doesn't, are of a great difference:

When a value is returned, the parent sub basically says to the child
sub: Do this and that and I'll be waiting for your to return
something.
For example: Handle this or that hardware and reply how things are
done. I'll wait for the reply.)

When no value is returned, the parent sub says to the child: Go and do
this and that and do not bother me anymore. This is not the same as
"return void". "Return void" basically means, - When you finish, let
me know and I'll resume. "Do not bother me" means: "I'm working in
parallel".  This is the fundamental difference, especially when
talking about "Loosely coupled" things. "Asynchronous" is one of the
most popular words, if not the most popular in that achitecture
related "Loosely coupled" discussions.

When someone tries to state that this or that concept is extremely
vital, he should use precise terminology at least.


>> Unfortunately a lot of people can't seem to separate C specifics from
>> general computing.  That is definitely bad.
>
> And some people seem to have a need to inject their favorite's language's
> features in every general discussion, be they relevant or not :)

Seem to be relevant. I'm imressed.

2008\10\18@072713 by Gerhard Fiedler

picon face
Tamas Rudnai wrote:

>> Assembly came before all of these, and in assembly, a function call and a
>> subroutine call are the same.

> I think the discussion is more like using the words from real languages in
> the programming languages. In my mind function is a mathematical term for
> calculating something
>
> X = Y^2

Right.

> The big difference (should be) also that a procedure has side effects
> while a function should not.

Maybe, but in reality this distinction is rather blurred -- even in a
typical Pascal program.

> I thing C started to use function only as Kernighan and Ritchie might
> thought that every procedure has to give back a status - and they may
> thought that a status is also a function return.

One way of looking at this is how it is generally implemented. IMO you can
understand much of what C does (and why it is the way it is) when looking
at it as some kind of higher-level assembly. Both a function and a routine
are basically a call/return structure (on a stack machine, which is what C
has been designed for), the only difference being that the function call
expects something useful in a certain register on return. The register is
always there, so there is not really any structural difference between
something useful being in there (say, an int) or not (which C calls "void")
-- at this level.

Gerhard

2008\10\18@074744 by Gerhard Fiedler

picon face
Wouter van Ooijen wrote:

>> So far, you've only cited a few languages that make a similar distinction.
>> This is a /very/ long shot from "computer science in general".
>
> Amost all languages that 'inherit' from Algol58/60 have this
> distinction, and then some more (Fortran). That's almost all languages,
> but indeed, not C.

"Almost all" seems strong. Let's make a quick collection of languages?

Cobol (it had to be :) -- I don't know.
Fortran (still) -- yes.
Pascal -- yes.
Algol -- you say yes.
Lisp -- not really, doesn't actually apply.
PHP -- no.
Java -- no.
C -- no.
C++ -- no.
Assembly -- no.
Python -- not that I know of.
Logo -- don't think so.

Perl
Smalltalk
Ruby
Scheme
APL
PL/1
Prolog
Basic
Forth
Haskell


Additions, completions and corrections appreciated.

FWIW, whether or not a language makes a distinction between functions (that
return a value) and procedures (that don't -- this nomenclature isn't even
that useful outside of a specific language that does make a distinction)
doesn't seem to be a general classification criterion for languages. It
doesn't seem to be regarded as a general principle and more like an
arbitrary syntactic feature of a language.

See also
http://en.wikipedia.org/wiki/Categorical_list_of_programming_languages

Nobody seems to have thought it worthwhile to create a category "'Real'
languages (the ones that make a distinction between functions and
procedures)" :)

Gerhard

2008\10\18@080357 by Isaac Marino Bavaresco

flavicon
face
Mongol Herdsman escreveu:
> ...
> When no value is returned, the parent sub says to the child: Go and do
> this and that and do not bother me anymore. This is not the same as
> "return void". "Return void" basically means, - When you finish, let
> me know and I'll resume. "Do not bother me" means: "I'm working in
> parallel".  This is the fundamental difference, especially when
> talking about "Loosely coupled" things. "Asynchronous" is one of the
> most popular words, if not the most popular in that achitecture
> related "Loosely coupled" discussions.
> ...
>  
Just calling a sub-routine does not usually make the caller and called
procedures to run in parallel (perhaps in Occam). To do this you would
need to create a new thread, in a system that support it.

__________________________________________________
Faça ligações para outros computadores com o novo Yahoo! Messenger
http://br.beta.messenger.yahoo.com/

2008\10\18@082352 by Wouter van Ooijen

face picon face
> "Almost all" seems strong. Let's make a quick collection of languages?

> PHP -- no.
> Java -- no.
> C -- no.
> C++ -- no.

In some sense those four are just one language ;) But under that
interpretation 'almost all' other languages are in the Algol family :)

> Assembly -- no.

I would vote yes: there are only subroutines/functions, all data passing
is by side effects in registers and/or globals.

> Python -- not that I know of.

true

{Quote hidden}

The functional languages generally don't have a procedure-like construct
- not surprisingly.

> FWIW, whether or not a language makes a distinction between functions (that
> return a value) and procedures (that don't -- this nomenclature isn't even
> that useful outside of a specific language that does make a distinction)

I agree, it is a minor point. Unless the languages forces functions to
be pure it is a weak distinction at best.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\18@084137 by Lee Jones

flavicon
face
>>> So far, you've only cited a few languages that make a similar
>>> distinction.  This is a /very/ long shot from "computer science
>>> in general".

>> Amost all languages that 'inherit' from Algol58/60 have this
>> distinction, and then some more (Fortran). That's almost all
>> languages, but indeed, not C.

> "Almost all" seems strong. Let's make a quick collection of
> languages?
>
> Cobol (it had to be :) -- I don't know.

As I recall (it's been several years since I did any COBOL(*)
programming), it _only_ has subroutines.  There is no way for
a procedure to pass back a "result" that can be tested or
assigned to a variable (i.e. no funcitons).  To pass back any
result, the procedure has to use a variable.  This made COBOL
a pain in comparison to C, Pascal, Algol, etc.

Later COBOL standards may have addressed this issue.  Luckily,
I have not had to keep familiar with it.

[* Acronym --> COBOL == COmmon Business Oriented Language ]


> FWIW, whether or not a language makes a distinction between
> functions (that return a value) and procedures (that don't --
> this nomenclature isn't even that useful outside of a specific
> language that does make a distinction) doesn't seem to be a
> general classification criterion for languages.

I think the subroutine versus function distinction matters.

If your language de jour has functions, you can treat them like
subroutines.  If you are using a language with only subroutines,
you _will_ miss having functions.

                                               Lee

2008\10\18@094044 by olin piclist

face picon face
Gerhard Fiedler wrote:
> We could shoot examples back and
> forth all night long, but the fact remains that you claimed that this
> distinction is somehow something fundamental in computing science,
> and so far you only showed that some languages do make it.

So obviously the distinction exists, just some languages don't differentiate
by it.

It is likely that C is the first language that didn't distinguish between
subroutines that returned a value (functions) and those that don't.  At
least I can't think of any that predated C that didn't.

> Now why would this be wrong (other than because you don't like it)?

You seriously don't see how blurring the distinction between the general
case and a particular implementation is a bad thing!!?

> It simply depends whether this distinction adds anything to the
> (general, that is, non-C and non-Pascal) discussion.

No.  Sloppy use of terms is a Bad Thing.  You may get away with it some of
the time, even most of the time, due to implicit shared knowledge but it's
still asking for trouble.  Ask NASA about that probe.  Each side of the team
couldn't imagine that anyone would interpret the distance in anything but
meters, or was that feet.  They lost sight of what was specific to their
implementation as apposed to the larger world.  This is no different.

Continual sloppy use of terms even causes some people to eventually forget
there is a distinction and assume the whole world is like the niche they
have gotten used to talking about.  This is definitely a Bad Thing.

> so why put on my Pascal hat and make a distinction,

It has nothing to do with Pascal since that would be just another specific
case.  If you were talking specifically about Pascal syntax, then you'd say
"procedure" not "subroutine".


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\18@095215 by olin piclist

face picon face
Wouter van Ooijen wrote:
> Amost all languages that 'inherit' from Algol58/60 have this
> distinction, and then some more (Fortran). That's almost all
> languages,
> but indeed, not C.

You could even say C does have the distinction, just that it has no
subroutines, only functions.  All subroutines in C return a value, just that
some return the special case of void.  The fact the the designers of C
called these specifically "functions" further supports this view that they
were quite aware of the distinction and chose not to include general
subroutines that don't return a value.

In fact, I can't think of a language that called a subroutine that returns a
value anything but a "function".  The names for subroutines that don't
return a value vary such as "subroutine" (Fortran) and "procedure" (Algol),
but can anyone think of a language where "function" is used for a subroutine
that does not return a value?


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\18@100804 by Mongol Herdsman

picon face
Olin Lathrop wrote:
> In fact, I can't think of a language that called a subroutine that returns a
> value anything but a "function".  The names for subroutines that don't
> return a value vary such as "subroutine" (Fortran) and "procedure" (Algol),
> but can anyone think of a language where "function" is used for a subroutine
> that does not return a value?

Javascript, if I am not mistaken. Everything is "function" and it may
or may not return some value.

>From "JavaScript: The Definitive Guide", 5th Edition By David Flanagan

Chapter 8. Functions
A function is a block of JavaScript code that is defined once but may
be invoked, or executed, any number of times. Functions may have
parameters, or argumentslocal variables whose value is specified when
the function is invoked. Functions often use these arguments to
compute a return value that becomes the value of the
function-invocation expression. When a function is invoked on an
object, the function is called a method, and the object on which it is
invoked is passed as an implicit argument of the function. You may
already be familiar with the concept of a function under a name such
as subroutine or procedure.

2008\10\18@101650 by olin piclist

face picon face
> Java -- no.
> C -- no.
> C++ -- no.

First, these are of one syntax root, which is C.  However I think the answer
should be YES for these languages.  The designers made a concious choice
that all subroutines would return a value, and therefore deliberately used
the term "function" for them.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\18@102417 by Mongol Herdsman

picon face
Isaac Marino Bavaresco escreveu:
>> When no value is returned, the parent sub says to the child: Go and do
>> this and that and do not bother me anymore. This is not the same as
>> "return void". "Return void" basically means, - When you finish, let
>> me know and I'll resume. "Do not bother me" means: "I'm working in
>> parallel".  This is the fundamental difference, especially when
>> talking about "Loosely coupled" things. "Asynchronous" is one of the
>> most popular words, if not the most popular in that achitecture
>> related "Loosely coupled" discussions.
>> ...
>>
> Just calling a sub-routine does not usually make the caller and called
> procedures to run in parallel (perhaps in Occam). To do this you would
> need to create a new thread, in a system that support it.

MS is doing something in the area:

http://en.wikipedia.org/wiki/Parallel_FX_Library

TPL
Task Parallel Library (TPL) is the task parallelism component of
PFX.[1] It exposes parallel constructs like parallel for and while
loops, using regular method calls and delegates. As such, the
constructs can be used from any language supporting the .NET
Framework. The job of spawning and terminating threads, as well as
scaling the number of threads according to the number of available
processors, is done by the library itself.[2]

TPL also includes other constructs such as Task and Future. A Task is
an action that can be executed independent of the rest of the program.
In that sense, it is equivalent to a thread, except that the
programmer is relieved of the job of synchronizing the execution of
the thread. A Future is a specialized task that returns a result. The
result is computed in a background thread encapsulated by the Future
object, and the result is buffered until it is retrieved.[2]

2008\10\18@122638 by Tamas Rudnai

face picon face
> In fact, I can't think of a language that called a subroutine that returns
a
> value anything but a "function".  The names for subroutines that don't
> return a value vary such as "subroutine" (Fortran) and "procedure"
(Algol),

Actually Perl uses a 'sub' directive to define a subroutine and you still
can use 'return' directive to pass back value. But as in some definition
both procedure and function are belonging to subroutines, so we may can say
that is ok. I think with C the directive 'function' would have been better
as 'subroutine' as well.

I agree with you Olin here that C was definitely not the best ever designed
language, see the directive 'static' used for functions... that does not
make any sense. Also there is no bit rotation which is quite interesting in
a low level language like this. Also that there is no way to handle
structure elements in banch way like with the 'with' in Pascal - I know,
Pascal again...

Tamas



On Sat, Oct 18, 2008 at 2:51 PM, Olin Lathrop <olin_piclistEraseMEspamembedinc.com>wrote:

{Quote hidden}

> -

2008\10\18@122828 by Bob Ammerman

picon face
If I recall correctly, the concept of 'void' functions (ie: 'subroutines')
did not exist in the original K&R "C". You could declare and define a
function without any return type, but in that case 'int' was assumed. Now,
of course, whatever the "C" books call them, 'functions' that return 'void'
are in fact 'subroutines'. It is just a "C"ism to call them 'functions'. Any
kind of computer science analysis would have to treat them as subroutines.

-- Bob Ammerman

2008\10\18@144335 by Carl Denk

flavicon
face
Kerrighan & Richie "The C Programming Language" copyright 1978 (I think
this is first edition) only discusses "Functions". "Subroutine" does not
appear in the index. In a quick review, I couldn't find "NULL" or "VOID"
mentioned in this section, but it did say" The calling function is free
to ignore the returned value if it wishes. ... "there need be no
expression after the return, in that case no value is returned to the
caller".

Bob Ammerman wrote:
> If I recall correctly, the concept of 'void' functions (ie: 'subroutines')
> did not exist in the original K&R "C". You could declare and define a
> function without any return type, but in that case 'int' was assumed. Now,
> of course, whatever the "C" books call them, 'functions' that return 'void'
> are in fact 'subroutines'. It is just a "C"ism to call them 'functions'. Any
> kind of computer science analysis would have to treat them as subroutines.
>
> -- Bob Ammerman
>
>  

2008\10\18@151320 by Gerhard Fiedler

picon face
Wouter van Ooijen wrote:

>> PHP -- no.
>> Java -- no.
>> C -- no.
>> C++ -- no.
>
> In some sense those four are just one language ;)

I just knew someone would say that :)

> But under that interpretation 'almost all' other languages are in the
> Algol family :)

Some say that C is in that family, too...

>> Assembly -- no.
>
> I would vote yes: there are only subroutines/functions, all data passing
> is by side effects in registers and/or globals.

I'm not sure I understand you here; the question (answered with "yes" or
"no") was "does the language make a distinction between functions and
procedures?" Your response seems to say you agree with me: assembly doesn't
make any distinction between the two, all is a call/return construct, so
the answer is "no".

> Unless the languages forces functions to be pure [...]

What do you mean by "pure function"? And which languages enforce such a
thing?

Gerhard

2008\10\18@152103 by William \Chops\ Westfield

face picon face

On Oct 18, 2008, at 7:16 AM, Olin Lathrop wrote:

> The designers [of C] made a concious choice that all subroutines  
> would return a value, and therefore deliberately used the term  
> "function" for them.

Um, perhaps.  It's sort of interesting (now that we're deep into  
"meanings") that in fact C *doesn't* use the "term" "function."  There  
is no "function" keyword; it's merely a term used in describing the  
behavior (in comparison with most of those algol-derived languages  
that DO use explicit keywords for subroutine definition.)

Probably things started to fall apart, "purity of language wise", when  
software started being so much less mathematical than in the olden  
days.  A "function" that returns a mathematical value is nicely  
parallel to the mathematical definition of "function."  A "function"  
that returns an error code, or a string, or that has multiple results,  
not so much.  And so the blurring of definitions begun...

BillW

2008\10\18@152504 by Gerhard Fiedler

picon face
Mongol Herdsman wrote:

>>> What's wrong is going back to the general computing world outside C and
>>> calling all subroutines functions.
>>
>> Now why would this be wrong (other than because you don't like it)? It
>> simply depends whether this distinction adds anything to the (general,
>> that is, non-C and non-Pascal) discussion. In the scope of our
>> discussion, this distinction has no meaning at all, so why put on my
>> Pascal hat and make a distinction, where there is no need?
>
> His distinction seems to add to the discussion. A sub that returns a
> value and a sub that doesn't, are of a great difference:
> [...]
> When no value is returned, the parent sub says to the child: Go and do
> this and that and do not bother me anymore. This is not the same as
> "return void". "Return void" basically means, - When you finish, let
> me know and I'll resume. "Do not bother me" means: "I'm working in
> parallel".  

I think here you are way out of scope. Working in parallel is not what a
procedure call is about, and definitely not what creates a distinction to a
function call. If you're talking about spawning a worker thread, this can
be spawned by both a function and a procedure. No difference here. If
you're talking about other constructs, you're not talking about either
functions or procedures anymore.

> When someone tries to state that this or that concept is extremely
> vital, he should use precise terminology at least.

Correct. Neither a Pascal-type procedure call nor function call has
anything to do with parallel execution; both are purely sequential. As are
C-style functions.

> "Return void" basically means, - When you finish, let me know and I'll
> resume.

You don't seem to have understood the concept. C-style "return void" is (on
a typical stack-based machine) the exact same thing that happens when
Pascal calls a procedure: a call/return construct, with no relevant data
returned. Neither implies that working in parallel is even possible; to the
contrary: in both languages it is assumed that the caller will wait.

If you want to go to other languages, you'll find that it is just as
possible to do the parallel execution thingy with a C-style "return void"
function as it is with a Pascal-style procedure. Again an artificial
distinction based on syntax of certain languages, but not a general
concept. (If you don't know it, the compiler does know that "return void"
means "there's nothing to wait for that would be returned" -- just as the
Pascal compiler knows that a procedure doesn't return anything.)

Gerhard

2008\10\18@155151 by Gerhard Fiedler

picon face
Lee Jones wrote:

>> FWIW, whether or not a language makes a distinction between functions
>> (that return a value) and procedures (that don't -- this nomenclature
>> isn't even that useful outside of a specific language that does make a
>> distinction) doesn't seem to be a general classification criterion for
>> languages.
>
> I think the subroutine versus function distinction matters.

In some contexts, of course. But I think it's important to keep the context
in mind (see the subject line, which it seems many people fail to consider
when reading and writing messages): this is about how to structure a
program into functions (procedures, subroutines, ...) of adequate size, and
about rules of thumb for "adequate size".

Can we please get back on topic, and maybe somebody explain how this
distinction is in any way relevant to the subject? Does the "adequate size"
of a Pascal function differ from the "adequate size" of a Pascal procedure?
Why? If not, why is the distinction relevant in this context?

Thanks,
Gerhard

2008\10\18@155408 by William \Chops\ Westfield

face picon face

On Oct 18, 2008, at 12:12 PM, Gerhard Fiedler wrote:

> assembly doesn't make any distinction between the two, all is a call/
> return construct, so the answer is "no".

Older CPU architectures had some really obscure (by todays standards)  
subroutine linkages.  I don't recall ever investigating in detail, but  
it wouldn't surprise me if some were specifically aimed at subroutines  
that returned values, and some were aimed at each type...  (PDP10:  
JSR, JSP, JSA, JRA, PUSHJ)  Subroutine linkage before the wide use of  
stacks was ... weird.

BillW



2008\10\18@155944 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

>> We could shoot examples back and forth all night long, but the fact
>> remains that you claimed that this distinction is somehow something
>> fundamental in computing science, and so far you only showed that some
>> languages do make it.
>
> So obviously the distinction exists, just some languages don't
> differentiate by it.

Nobody said it didn't exist, just that it's not really that important and
especially not for the discussion here. You said it's very important,
generally, in computer science, and failed to bring up any kind of evidence
besides a few examples of really old languages that do make the
distinction.

> It is likely that C is the first language that didn't distinguish between
> subroutines that returned a value (functions) and those that don't.  At
> least I can't think of any that predated C that didn't.

In general you seem to think better. I already gave you the prime example:
assembly languages in general don't distinguish between the two, because
the machine languages in general don't.

But then, there may have not been that many predating C that didn't, but
there definitely are a /lot/ that came later that don't. See my list in the
other message... you conveniently decided to ignore it, even though it
provided a really good opportunity to make your point and cite a lot of
languages (and computer science material) that do make this distinction.

>> Now why would this be wrong (other than because you don't like it)?
>
> You seriously don't see how blurring the distinction between the general
> case and a particular implementation is a bad thing!!?

The general case is that it's not important in this (and in almost all)
contexts, as it is an implementation detail of some specific languages
only. So not making the distinction in this context is not wrong; it only
would be if it were of any importance. (It may be important in a Pascal
context, but even there the contexts where this distinction is important
are rather rare.)

>> It simply depends whether this distinction adds anything to the
>> (general, that is, non-C and non-Pascal) discussion.
>
> No.  Sloppy use of terms is a Bad Thing.  

You just don't get it. Outside of the context of a language that makes a
syntactic difference between a function and a procedure, both can be
considered to be synonymous. (For now not considering that not having
functions can really be a pain... but that is not the issue here.)
Definitely in the context here, where it is about style and commenting; it
should be obvious even to you that whatever in this context applies to a
Pascal function also applies to a Pascal procedure (and to a C function,
and and and). So why the nitpicking?

> Ask NASA about that probe.  

Now this is something different. This is all about being able to see what
is relevant and what is not. Units (for anything physical) /are/ relevant,
and "6" is not a length, but "6 m" is one, as is "6 yd". But when I talk
about length in general, I again don't have to mention whether I talk about
length in meters or length in yards -- length is length, as long as I don't
bring in numbers. (Besides, it was you who said that basically the
engineers in the USA keep two separate measurement systems alive because
it's more efficient... a while ago, on this list :)

> This is no different.

Now come on... you're smarter than that, and you (should) know that I am.
There's no relationship at all.

>> so why put on my Pascal hat and make a distinction,
>
> It has nothing to do with Pascal since that would be just another specific
> case.  

Making that distinction between functions and procedures means that you are
going into a specific case. In general, both are a call/return construct.
Some specific languages abstract certain constructs differently and make a
syntactic difference between function and procedures, others don't. So in
general, there's no difference. In some specific languages, there is a
difference, but one that is only relevant for those specific languages. As
long as we don't talk specifically about any of these languages, there's no
need to distinguish between functions and procedures.

For example, I've never read anything from you trying to bring this
distinction up in a discussion about assembly programming -- even though it
applies there as much as it does to this discussion about appropriate size
of functions (and/or procedures, subroutines, however you want to call
them, pick your selection).

Gerhard

2008\10\18@162139 by William \Chops\ Westfield

face picon face

On Oct 18, 2008, at 12:51 PM, Gerhard Fiedler wrote:

> Does the "adequate size" of a Pascal function differ from the  
> "adequate size" of a Pascal procedure?  Why? If not, why is the  
> distinction relevant in this context?

Interesting question.  I was going to point out that several of the  
Basics I've used DO have a specific implementation for functions that  
return mathematical values ("deffn"), and IIRC they were all  
restricted to functions of a single line (ie functions that LOOK like  
mathematical functions.)
  deffn polynomial(x) = x^3 - 3*x^2 + 2^x - 12

But I wasn't sure what "modern" basics did WRT subroutines/functions.

The distinction (deffn vs "gosub") in those BASIC implmentations is a  
fine example of "old style thinking" for the two, including the many  
problems introduced by the "gosub" construct.  (and, oh! the evil  
things that one did in fortran "subroutines" to get around enforced  
pass-by-value semantics.  "Named common areas."  Shudder.)

Another thing that has blurred the distinction is subroutines that  
"return" multiple values by modifying their parameters.  (And Pascal  
specifically allows this, right?)

BillW

2008\10\18@162440 by Vitaliy

flavicon
face
Gerhard Fiedler wrote:
> Can we please get back on topic, and maybe somebody explain how this
> distinction is in any way relevant to the subject?
[...]
> So why the nitpicking?

I share your sentiments. I can also see where Olin is coming from: after
all, "subroutines" is a generic term that encompasses
procedures/functions/methods and would have been more appropriate for this
discussion (since the principles discussed apply not only to C). Personally,
I don't mind being corrected, and I'm happy to use terms that people are
comfortable with. It improves the quality of communication.

I wish you guys didn't waste your time on splitting hairs. Or at least
changed the subject to:

   [EE] "Subroutines" or "Functions"?

Best regards,

Vitaliy

2008\10\18@163936 by olin piclist

face picon face
Mongol Herdsman wrote:
> Javascript, if I am not mistaken. Everything is "function" and it may
> or may not return some value.

I took a quick look, and it appears that Javascript has only one type of
subroutine syntactically.  There is no distinction between subroutines that
return values and those that don't, unlike subroutine/function of Fortran or
procedure/function of Algo.  So this is more like the C case where they are
called functions because any of them could return a value.  It also looks
like subroutine calls always have a value, like in C.  They do seem to have
dispensed with having to say a subroutine "returns" void when it doesn't
explicitly return a value.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\18@165644 by Wouter van Ooijen

face picon face
> I'm not sure I understand you here; the question (answered with "yes" or
> "no") was "does the language make a distinction between functions and
> procedures?" Your response seems to say you agree with me: assembly doesn't
> make any distinction between the two, all is a call/return construct, so
> the answer is "no".

I interpreted the question at hand slightly differently: which languages
distinguish between functions and procedures (examples: algol, pascal,
ada), and which languages have both but don't distinguish them
(examples: C, Python). There is a third group, which does not have both,
so it makes no sense to distinguish them (examples: assembler, basic in
its original form).

> What do you mean by "pure function"? And which languages enforce such a
> thing?

functional languages. Haskell IIRC is close.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\18@170153 by olin piclist

face picon face
Gerhard Fiedler wrote:
> Again an
> artificial distinction based on syntax of certain languages, but not
> a general concept.

You don't see it only because C makes no distinction.  In other languages
where everything isn't a expression, there is a fundamental difference
between subroutines and functions.  Subroutines are things that are called
by themselves in a syntactically specific way that is NOT part of any
expression.  Fortran has the explicit CALL statement, for example, whereas
function names have a data type and can be reference in a expression
anywhere that data type would be legal.

C has no true subroutines, only cases where functions don't return values
and many cases where values of function calls (and many other expressions)
are ignored.  In better languages it is illegal to have a expression that is
not used.  In Pascal (the Apollo version anyway), you can call a function
like a subroutine by wrapping it in the DISCARD intrinsic function.  That
tells the compiler "yes I know I'm calling a function which returns a value,
but in this one case I want to ignore that return value".


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\18@170634 by olin piclist

face picon face
Gerhard Fiedler wrote:
> Can we please get back on topic, and maybe somebody explain how this
> distinction is in any way relevant to the subject?

It's the same thing as when someone talks about a circuit and mentions 2.2K
this and 47u that without units.  That sort of sloppiness must never be
tolerated.  The best way to do this is to jump on it whenever it pops up.

If you don't want to derail a topic (the original topic has already been
well beat to death and I doubt anyone really has anything new to say), then
don't get sloppy with terms.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\18@170824 by olin piclist

face picon face
William Chops" Westfield" wrote:
> Older CPU architectures had some really obscure (by todays standards)
> subroutine linkages.  I don't recall ever investigating in detail, but
> it wouldn't surprise me if some were specifically aimed at subroutines
> that returned values, and some were aimed at each type...  (PDP10:
> JSR, JSP, JSA, JRA, PUSHJ)  Subroutine linkage before the wide use of
> stacks was ... weird.

You are using binoculars when you should be looking under your nose.
Midrange core PICs have both a RETURN and a RETLW instruction.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\18@171026 by Mongol Herdsman

picon face
Olin Lathrop wrote:
> I took a quick look, and it appears that Javascript has only one type of
> subroutine syntactically.  There is no distinction between subroutines that
> return values and those that don't, unlike subroutine/function of Fortran or
> procedure/function of Algo.  So this is more like the C case where they are
> called functions because any of them could return a value.  It also looks
> like subroutine calls always have a value, like in C.  They do seem to have
> dispensed with having to say a subroutine "returns" void when it doesn't
> explicitly return a value.

Yes, but Javascript is not that great like to serve as example of
anything good; just mentioned it for using the keyword "function" for
things that in my understanding are not functions at all. I use to
take "function" the way the term is handled in math. Though, perhaps
I'm missing something, - I am not that good at math.

2008\10\18@172148 by olin piclist

face picon face
Gerhard Fiedler wrote:
> failed to bring up any kind of evidence besides a few
> examples of really old languages that do make the distinction.

Only one is required for a existance proof.  I mentioned a few others for
good measure.

> For example, I've never read anything from you trying to bring this
> distinction up in a discussion about assembly programming

You keep mentioning assembly language, but that's irrelevant.  Strictly
speaking there are no subroutines in assembly, only call and return
instructions.  You may build things with these instructions you call
subroutines, but that's your abstraction, not the language's.  Where in
MPASM, for example, is the subroutine or function definition operator,
keyword, or whatever?


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\18@172601 by olin piclist

face picon face
William Chops" Westfield" wrote:
> and, oh! the evil
> things that one did in fortran "subroutines" to get around enforced
> pass-by-value semantics.

Actually all arguments were pass by reference in Fortran.

> Another thing that has blurred the distinction is subroutines that
> "return" multiple values by modifying their parameters.  (And Pascal
> specifically allows this, right?)

Yes.  In C one must do evil things to get around the enforced pass-by-value
semantics.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\18@180414 by Mongol Herdsman

picon face
Olin Lathrop wrote:
>> Can we please get back on topic, and maybe somebody explain how this
>> distinction is in any way relevant to the subject?
>
> It's the same thing as when someone talks about a circuit and mentions 2.2K
> this and 47u that without units.  That sort of sloppiness must never be
> tolerated.  The best way to do this is to jump on it whenever it pops up.

If the discission were inside C language, I'd rather call it "term
overloadiong", not sloppiness. This was not a big issue so far. But
now confusing the call to process supplied data and return the result
(function) with the call to happen something outside the parent
(subrouting) is getting an ideological bottleneck in evolving the
language.

The call to happen something should have the choice to go
asynchronous. But overloaded function style structure screams out
loud, - need the result right here and right now. This is too bad
thing taking into account that underlying computational resources are
getting dirt cheap and could work in parallel.

2008\10\18@182711 by William \Chops\ Westfield

face picon face

On Oct 18, 2008, at 2:25 PM, Olin Lathrop wrote:

> Actually all arguments were pass by reference in Fortran.

Ah.  Right.  That was how one modified constants...


> In C one must do evil things to get around the enforced pass-by-
> value semantics.


Pointers are evil?

BillW

2008\10\18@185231 by olin piclist

face picon face
William Chops" Westfield" wrote:
>> Actually all arguments were pass by reference in Fortran.
>
> Ah.  Right.  That was how one modified constants...

When I was a freshman at RPI there was a grad student, Bob, known for kludgy
programming on the Varian 620-I system in a particular lab.  The assembler
and linker pooled references to constants and re-used them as much as
possible.  However this machine didn't have memory protection, so they could
be accessed like any other memory location.  In one case Bob changed the
value of the literal 5 as a system wide flag to mean something particular to
his program.  Changing a literal was bad enough, but five!!?

>> In C one must do evil things to get around the enforced pass-by-
>> value semantics.
>
> Pointers are evil?

Pointers aren't inherently evil, but having to manually pass a pointer to
something so that the subroutine can modify it is evil.  Better languages
have pass by reference built in.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\18@194747 by Peter Todd

flavicon
face
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Sat, Oct 18, 2008 at 12:20:40PM -0700, William Chops Westfield wrote:
{Quote hidden}

Or for that matter, the very common practice of passing pointers to
pointers as an argument to a function, and having the function set the
content of the pointer:

void foo(int src,int **dest){
   *dest = src;
}

or in C++:

void foo(int src,int &dest){
   dest = src;
}

As pure as a... never mind.

- --
http://petertodd.org 'peter'[:-1]@petertodd.org
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFI+nTU3bMhDbI9xWQRAp9WAKCYI458XJgJpCiTauTsaYj5s2ErSACfft5K
B2Qi5WKUsfVNuwLBvwvbnKo=
=KHzB
-----END PGP SIGNATURE-----

2008\10\19@080120 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

> Gerhard Fiedler wrote:
>> failed to bring up any kind of evidence besides a few
>> examples of really old languages that do make the distinction.
>
> Only one is required for a existance proof.  I mentioned a few others for
> good measure.

I really think you should do some reading of what other people write,
rather than building your strawmen out of nothing. Nobody ever said that
the distinction doesn't exist. But you claimed that there is a distinction
that is relevant for the discussion at hand, and that it is of general
relevance (that is, outside the languages that make it).

For example, I haven't ever seen (in a generally relevant computer science
publication) programming languages classified by whether or not they make
that distinction. Now I don't doubt that there is some obscure paper about
this, but the mere fact that you can't bring up anything from computer
science (not just some syntax examples) that would support your claim tells
me that you claimed something that's not much more than an opinion of
yours. This may be something extremely important to you, but it isn't to
the world at large.

> You keep mentioning assembly language, but that's irrelevant. Strictly
> speaking there are no subroutines in assembly, only call and return
> instructions. You may build things with these instructions you call
> subroutines, but that's your abstraction, not the language's. Where in
> MPASM, for example, is the subroutine or function definition operator,
> keyword, or whatever?

There is none. That's my point. It doesn't make this distinction. It has
one mechanism (call/return; assembly statements are quite similar to what
keywords are in C, for example: the element of the language), which is used
to create indistinguishable functions and procedures and subroutines
(however you want to call them).

Using a label and a return statement ("keyword") is no different (albeit on
a different abstraction level) from using the Procedure keyword to create a
subroutine.

Gerhard

2008\10\19@080526 by Gerhard Fiedler

picon face
Mongol Herdsman wrote:

> ideological

That's probably the most relevant contribution to this :)

2008\10\19@083105 by Tamas Rudnai

face picon face
> There is none. That's my point. It doesn't make this distinction. It has
> one mechanism (call/return; assembly statements are quite similar to what
> keywords are in C, for example: the element of the language), which is
used
> to create indistinguishable functions and procedures and subroutines
> (however you want to call them).

That is one of the reason I thing software and firmware developers should
learn how compilers work and what code they generate. This is not the first
time here in this subject talking about how a C would compile code and
non-assembly minded developers tend to get it wrong - or just simplify it. A
function in C (and virtually all HLLs) has prologues and epilogues that
initialize the function and then when returns de-initialize it. Also many
things depending on call conventions for example whenever the epilogue
cleans the stack or that's the duty of the caller - therefore sometimes even
the calling mechanism is not just a CALL instruction in the compiled code.

Tamas



On Sun, Oct 19, 2008 at 1:00 PM, Gerhard Fiedler <RemoveMElistsEraseMEspamspam_OUTconnectionbrazil.com
{Quote hidden}

> -

2008\10\19@093849 by olin piclist

face picon face
Gerhard Fiedler wrote:
> I really think you should do some reading of what other people write,
> rather than building your strawmen out of nothing. Nobody ever said
> that the distinction doesn't exist.

But if it exists somewhere, then it also exists in the general computer
science sense, since one is a superset of the other.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\19@121354 by Bob Ammerman

picon face
>> Unless the languages forces functions to be pure [...]
>
> What do you mean by "pure function"? And which languages enforce such a
> thing?
>
A pure function is one which has no side effects, and which, for any
particular set of argument values always returns the same value (ie: is
deterministic).

Some functions in Microsoft's T-SQL language are enforced as pure.

Bob Ammerman
RAm Systems

2008\10\19@203658 by Bob Axtell

face picon face
I personally like flowcharts better than commenting, because
if the program is to be rewritten, the author has a choice of
languages to use.

What happens is that a company has a great programmer that
did a fine job. Say he did his work in MPASM. Now that guy
retires (or moves because his wife, a doctor, makes the REAL
bucks in the family) and it is almost impossible to find someone
that writes MPASM to replace him.

See what I mean? Flowcharts beat the TAR out of comments, every
day of the week.

I use WIZFLOW, a very inexpensive, bugless program. Used
Visio in the past, but it became too fluffy and expensive when
$MS took it over.

--Bob A

2008\10\20@034024 by Vitaliy

flavicon
face
Bob Axtell wrote:
>I personally like flowcharts better than commenting, because
> if the program is to be rewritten, the author has a choice of
> languages to use.
>
> What happens is that a company has a great programmer that
> did a fine job. Say he did his work in MPASM. Now that guy
> retires (or moves because his wife, a doctor, makes the REAL
> bucks in the family) and it is almost impossible to find someone
> that writes MPASM to replace him.
>
> See what I mean? Flowcharts beat the TAR out of comments, every
> day of the week.


Flowcharts are great, in theory. :-)

I believe it is Alistair Cockburn who argues in his book, that project
documentation cannot replace what's called a "project story" (a common
understating/vision of the project), because human communication is so
imperfect. A project story resides in the programmer or the team of
programmers who work on the project. One of the implications is that you
cannot take documentation, however perfect, throw it over the wall, and
expect another team to pick up where the old team left off without missing a
beat: they must first develop their own project story. Another implication
is that the value of documentation tends to be overrated.

Flowcharts share many of the same problems with comments. Probably the
biggest problem is that they both get out of sync with the code. Flowcharts
are even more vulnerable in this regard: it's easier to update a comment,
than a flowchart.

In the past, I used to create complex flowcharts. They were necessary
because I simply could not hold all the details of the huge state machines
in my head. Today, I no longer find them necessary -- instead, I write ten
small functions, in place of one very long one. The state machine then
easily fits in one screenful of code (a single function).

In my opinion, flowcharts are useful in two ways:

1. As an aid to help create the project story. The process of creating the
flowchart is the valuable part, not the end result.

2. In situations where you are forced to write ugly code due to the
limitations of the target hardware (can't afford the extra overhead of
function calls, must code in assembly, etc).

Best regards,

Vitaliy

2008\10\20@035151 by Vitaliy

flavicon
face
Tamas Rudnai wrote:
{Quote hidden}

I think your insistence on people having an intimate understanding of what a
compiler does, is akin to someone demanding that every driver must be able
to take apart an engine, and put it back together -- before they can get a
driver license.

Sure, the skill can be useful. But most drivers couldn't care less, and
they're doing just fine.

Vitaliy


2008\10\20@042544 by William \Chops\ Westfield

face picon face

>
>> I personally like flowcharts better than commenting
>
> In my opinion, flowcharts are useful in two ways:
> 1. As an aid to help create the project story.

Yah; that's about my opinion; flowcharts aren't so much a competitor  
of COMMENTS as a competitor or component of SPECIFICATIONS.

In theory, we use a hierarchy of documentation:
1) Functional specification.  What it's supposed to do; the "marketing  
view."
  2) Design specification.  How it's supposed to do it.
    3) Code comments.  How it IS doing it.  Usually divided into those
       largish "subroutine" descriptions, and the smaller inline comments
       covering the details.
      4) "self documenting code."  Having 1-3 is no excuse for single
         character variable names...

(If you think COMMENTS get out-of-sync with the actual code, you  
should see how badly the specifications become out-of-date!  The  
specifications are typically needed prerequisites for the overall  
software development process, and it is unfortunately REALLY RARE for  
anyone to update the specs after that phase of approval is over.  Sigh.)

(I hardly ever do functional or design specs for "personal" project,  
although it seems like it would be a good idea.  If I'm lucky,  
something similar might get written up AFTER the coding, as a sort of  
step toward publication...  Sigh, again.)

(So with all these new-style "development environment", do ANY of them  
aid in keeping high-level formatted documentation (HTML, RTF, WORD,  
whatever) in sync with the actual code?  I mean, I can hover a cursor  
over a preprocessor symbol and see its definition, or over a  
subroutine call and see its header-comment; right?  Shouldn't there be  
some standardized method of associating a region of code with a subset  
of a design document or functional description, so that a single  
keyclick reminds me what I'm supposed to be doing and how, and allows  
me to edit it if I've changed my mind?  URL tags in source code; how  
hard can it be?  Sometimes the failings of software design and  
implementation have more to do with those mis-matches between high-
level descriptions and source code, regardless of how well written (or  
not) the source code itself is.  Sigh, a third time.)

In other words, documenting the "project" is at least as important as  
documenting "the code."  And is much more often neglected...  (flow  
charts (remember flow charts, this is a reply to a message about flow  
charts!) are nicely intermediate...)

BillW

2008\10\20@085012 by Peter

picon face

Olin Lathrop <olin_piclist <at> embedinc.com> writes:
> I took a quick look, and it appears that Javascript has only one type of
> subroutine syntactically.  There is no distinction between subroutines that
> return values and those that don't, unlike subroutine/function of Fortran or
> procedure/function of Algo.  So this is more like the C case where they are
> called functions because any of them could return a value.  It also looks
> like subroutine calls always have a value, like in C.  They do seem to have
> dispensed with having to say a subroutine "returns" void when it doesn't
> explicitly return a value.

The obsession with strongly typed languages that try but not quite succeed to
replace a proper source code linter and proper coding practice comes up over and
over again. I wonder why.

The only reason to have strong types is when one is very tight on space and/or
time and wants total control on data size, stack depth etc. In all other cases
ths is not needed.

Most "modern" languages have late binding and dynamic typing, and their
variables (!) are first class objects. Those include Tcl, Javascript and may
others, and most are interpreted. C is not in that class, neither is Pascal.
There is no way to compare apples and prunes. I need typeless languages for
prototyping when I tear down the thing and rebuild it several times in 10
minutes and I won't use that for embedded because there is no space for such
luxury in a $0.5 device.

So what is this discussion about ? C initially had NO types whatsoever. It was
written by a programmer to port an operating system. Pascal was born with types
before it could be used at all and had support for expensive structures such as
(tiny, large enough for student exercises but not for any real work) sets which
are very useful - in academia. Where did the rest of the thread come from ?!

Peter


2008\10\20@091714 by Wouter van Ooijen

face picon face
> The only reason to have strong types is when one is very tight on space and/or
> time and wants total control on data size, stack depth etc. In all other cases
> ths is not needed.

The main reason for (strict) type checking is to catch errors as early
as possible: better caught during compilation that during testing.

Loosely typed languages do have some use. I am a big an of Python, but I
often wished it had some form of type checking, especially on parameters.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\20@095804 by olin piclist

face picon face
Peter wrote:
> The obsession with strongly typed languages that try but not quite
> succeed to replace a proper source code linter and proper coding
> practice comes up over and over again. I wonder why.

Because strong type checking is very useful.  Good programmers like that
strong type checking gives the compiler the ability to catch mistakes and
help you write clean code.  Those who prefer hacking sometimes rebell
against type checking, but once they grow up they usually appreciate it.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\20@103117 by Alden Hart

flavicon
face
I agree with BillW on Cockburn's project story concept (see Agile
Software Development). I have also fund flow charts to be a useful tool
in developing the story.

If you put it in UML terms: flow charts ~= activity diagrams. The other
main types of UML diagrams - class, use case, sequence diagrams and
sometimes component diagrams are also useful in developing the story
(and communicating it to new members of the team - something often
overlooked). The "pragmatic modeling" practice has developed around
these 5 diagrams, which teams in my company have used over the years to
good effect.

One caveat we have discovered is that you have to get past the rigid
formalisms of UML (baggage like weird cardinality notation, drawing
constraints that Visio puts on objects to ensure "model compliance",
etc.) It's just a tool for thinking through designs and collaborating -
not for generating code.

I have found this works well regardless of the SW level - we use it on
everything from assembly, to C, Java, and enterprise system integration.

We also don't document everything - just the big picture and the hard
stuff. No reason to over-document data entry forms when a list of
required and optional fields, and validators will do.

Alden



William "Chops" Westfield wrote:
{Quote hidden}

2008\10\20@110333 by Paul Hutchinson

picon face
> -----Original Message-----
> From: @spam@piclist-bouncesRemoveMEspamEraseMEmit.edu On Behalf Of William "Chops" Westfield
> Sent: Monday, October 20, 2008 4:25 AM
>
> >
<snip>
{Quote hidden}

The best code documentation software I've found is Doxygen.
http://www.doxygen.org

Paul Hutch

>
> In other words, documenting the "project" is at least as important as  
> documenting "the code."  And is much more often neglected...  (flow  
> charts (remember flow charts, this is a reply to a message about flow  
> charts!) are nicely intermediate...)
>
> BillW

2008\10\20@143724 by Mongol Herdsman

picon face
Peter wrote:
> The only reason to have strong types is when one is very tight on space and/or
> time and wants total control on data size, stack depth etc. In all other cases
> ths is not needed.

A little user functionality more to compete on the market and you
easily will be "tight on space, time, data size etc". What big popular
software products based on interpretive languages do you know?

2008\10\21@012324 by William \Chops\ Westfield

face picon face

On Oct 20, 2008, at 8:03 AM, Paul Hutchinson wrote:

>> So with all these new-style "development environment", do ANY of them
>> aid in keeping high-level formatted documentation (HTML, RTF, WORD,
>> whatever) in sync with the actual code?

> The best code documentation software I've found is Doxygen.
> http://www.doxygen.org

We use Doxygen, and at least the way we use it, it's very aimed at  
allowing documentation to be embedded in the code, and mostly  
documentation especially about the code.  (We mostly use it for  
documenting APIs at the subroutine/function level, and it seems to do  
pretty good at that.)  I'm looking for something different - how would  
you associate a particular piece of code with a flowchart drawn in  
visio, for example?  I want a tool that keeps formatted documentation  
and source code IN SYNC and with cross references to each other (and  
why not, since there are so many tools aimed at keeping multiple bits  
of source code in sync?)

(Back in the depths of time, I did use DEC Runoff to implement a "self  
documenting" project.  You could embed formatting code and whatnot  
inside comments, and runoff (an early document preparation system,  
vaguely similar to TeX, sort of) would recognize the comments, strip  
the source code, and produce a nicely formatted document describing  
the operation of the project.  It was a PITA, and the resulting source  
module was pretty ugly.  I rated it as a rather unsuccessful  
experiment.)

BillW

2008\10\21@030054 by Vitaliy

flavicon
face
William "Chops" Westfield wrote:
> (I hardly ever do functional or design specs for "personal" project,
> although it seems like it would be a good idea.  If I'm lucky,
> something similar might get written up AFTER the coding, as a sort of
> step toward publication...  Sigh, again.)

You're not alone. If you're the developer and the customer at the same time,
I think this approach makes perfect sense.

I like the Agile approach: whip something up very quickly, see how you like
it, make a change, see how you like the result, repeat. Rigid specs based on
incomplete information, are counter-productive.

Even if you have a customer, same idea works just as well: whip up a quick
prototype, get customer's feedback, make the changes, another review...

One of my professors described what happened in the days before Agile: he
worked on a project team that was in charge of developing some sort of
meter. Based on prior experience, the most frustrating part was getting the
interface "right" (as defined by marketing folks and other non-engineers).
So, one of the guys on their team put together a crude representation of the
device interface in VB, which was shown to the marketing department. "Add
five buttons, put this button in the left corner, make it red". Several
iterations quickly followed, and eventually, the comments widdled down to
"change the font color to white", and "make this text lowercase". According
to the professor, the project was a big success.

We have this sort of informal "customer reviews" for the products we
develop. Documentation is usually written based on the project artefacts,
after the main development is done.

Vitaliy


2008\10\21@103022 by William \Chops\ Westfield

face picon face

On Oct 20, 2008, at 7:30 AM, Alden Hart wrote:

> If you put it in UML terms...

Ah.  "Program Modeling" (w UML/etc) has been rearing up at work, and  
I've been viewing it with a great deal of distrust.  You say that it  
has worked pretty well for you?

BillW


2008\10\21@104933 by Timothy Weber

face picon face
William "Chops" Westfield wrote:
> On Oct 20, 2008, at 7:30 AM, Alden Hart wrote:
>
>> If you put it in UML terms...
>
> Ah.  "Program Modeling" (w UML/etc) has been rearing up at work, and  
> I've been viewing it with a great deal of distrust.  You say that it  
> has worked pretty well for you?

(butting in) I like it a lot - but I mainly view it as a shared set of
idioms for drawing on a whiteboard.  Also useful for collecting and
documenting ideas from multiple people to ensure everyone's on the same
page.  I don't attempt to keep UML diagrams in sync with all code or
anything like that.
--
Timothy J. Weber
http://timothyweber.org

2008\10\21@122543 by Peter

picon face
Mongol Herdsman <inner.mongolia.herd <at> gmail.com> writes:

> Peter wrote:
> > The only reason to have strong types is when one is very tight on space
> > and/or
> > time and wants total control on data size, stack depth etc. In all other
> > cases ths is not needed.
>
> A little user functionality more to compete on the market and you
> easily will be "tight on space, time, data size etc". What big popular
> software products based on interpretive languages do you know?

Most of the WWW (what people call "Internet" anyway) is based on an arcane
collection of interpreted or jit compiled languages. And there are several HUGE
software packages in use by companies that are based on same. Not to mention
"VB" the "language", which i don't even count here (its eval is crippled - one
can't use it for lambda expressions etc <G>).

F.ex. I am hacking away at a 5000 loc project in tcl in private and I changed a
pretty hairy function's return type four times in about 2 hours "adding some
functionality" (such as profiling and timing analysis). tcl is one of the
(slower) jit compiled (to bytecode) languages. It would have taken me a few days
to do it with a strongly typed language (assuming I would have been crazy enough
to try it). The function is a sort of interpreter/linter itself, and it has to
cope with recursion, continuation and variadic calls, plus variadic returns
(several return values are polymorphic lists). I don' even want to think about
doing that in anything but a typeless language (in tcl everything is a string,
and strings are first class objects).

Peter


2008\10\21@143807 by Peter Onion

flavicon
face

On Mon, 2008-10-20 at 23:59 -0700, Vitaliy wrote:
>
> One of my professors described what happened in the days before Agile:

Ah, in the dark ages when every large software project failed!  ;-)

PeterO




2008\10\21@143908 by Alden Hart

flavicon
face
Yes, UML has worked well for me (and our teams) over a number of years
---but you have to be very careful not to get caught in the academic
swirl that typically surrounds the conventions. If you find yourself
debating the direction of arrows or the way to number one-to-many
relationships you are wasting time you should be spending figuring out
what you really want to do.

My group does systems development for a number of large and small
companies - from the enterprise systems integration level, down to Java,
down to C, down to assembly and some HW. We have been using lightweight
UML for going on 10 years. Here's a case history of one of our clients:
Big Financial Regulator - heavyweight processes for documentation, heavy
thud factor, 3" thick reqs that don't actually say much. We introduced a
"pragmatic UML" approach for system definition at these various levels.
We typically use a combination of class diagrams, activity diagrams,
sequence diagrams, and some collaboration diagrams. We immediately threw
out the Visio stuff that locks you into some constrained model, and
didn't worry about "correctness". This client had a significant need for
maintenance (15 yr+ project lifecycles), so they paid for someone
(sometimes us) to update it once he system as "finished".

Personally, I use these techniques (in the small) when I'm thinking
through one of my own designs. I update them because when I come back 6
months later I end up wasting more time than if I didn't.


Alden




William "Chops" Westfield wrote:
{Quote hidden}

2008\10\21@150734 by Paul Hutchinson

picon face
> -----Original Message-----
> From: EraseMEpiclist-bouncesspam@spam@mit.edu On Behalf Of William "Chops" Westfield
> Sent: Tuesday, October 21, 2008 1:23 AM
>
> We use Doxygen, and at least the way we use it, it's very aimed at
> allowing documentation to be embedded in the code, and mostly
> documentation especially about the code.  (We mostly use it for
> documenting APIs at the subroutine/function level, and it seems to do
> pretty good at that.)  I'm looking for something different - how would
> you associate a particular piece of code with a flowchart drawn in
> visio, for example?  I want a tool that keeps formatted documentation
> and source code IN SYNC and with cross references to each other (and
> why not, since there are so many tools aimed at keeping multiple bits
> of source code in sync?)

Doxygen's special commands and embedded HTML command support should do what
you're looking for. Use \image to insert an image in the generated
documentation. To include whole external files in the documentation use
\htmlinclude or \verbinclude (verbatim include).

You can use different Doxygen configuration files with the same source files
to generate different documentation types. While it is primarily targeted to
standard code documentation tasks, as the Doxygen page points out "3. You
can even abuse doxygen for creating normal documentation (as I did for this
manual)".

Paul Hutch

{Quote hidden}

2008\10\21@152257 by Vitaliy

flavicon
face
Peter Onion wrote:
>> One of my professors described what happened in the days before Agile:
>
> Ah, in the dark ages when every large software project failed!  ;-)

I didn't say that, now -- did I, Peter? :)

2008\10\21@160729 by Peter Onion

flavicon
face

On Tue, 2008-10-21 at 12:22 -0700, Vitaliy wrote:
> Peter Onion wrote:
> >> One of my professors described what happened in the days before Agile:
> >
> > Ah, in the dark ages when every large software project failed!  ;-)
>
> I didn't say that, now -- did I, Peter? :)

No indeed you didn't.  But to listen to some of the "Agile Evangelists"
it's hard to see how anything ever got produced before the latest, best
ever, must have, "development bling" was used :-)

None of the projects I've ever worked on has used a single
"methodology", we pick and mix the bits we need when we need them.

PeterO


2008\10\21@161643 by Gerhard Fiedler

picon face
William "Chops" Westfield wrote:

> We use Doxygen, and at least the way we use it, it's very aimed at  
> allowing documentation to be embedded in the code, and mostly  
> documentation especially about the code.  

This is already a good way to make sure the doc about the code is
reasonably in sync with the code -- it's not some tech writer that writes
it after the fact, but the programmer. And if it's some tech writer after
the fact, the programmer still sees it when she works on the code.

You can even write the docs first, kind of laying out what you're intending
to code, already creating the framework.

> I'm looking for something different - how would  
> you associate a particular piece of code with a flowchart drawn in  
> visio, for example?  

I'm not sure how you want to associate the two. Many editors allow you to
embed clickable links; that's prettyl close to "associate". There's of
course literate programming, which is something I don't understand why it's
not taking off.

> I want a tool that keeps formatted documentation and source code IN SYNC
> and with cross references to each other (and why not, since there are so
> many tools aimed at keeping multiple bits of source code in sync?)

If this is what you mean, I think you can embed images in Doxygen.

Gerhard

2008\10\21@162533 by Gerhard Fiedler

picon face
Tamas Rudnai wrote:

>> There is none. That's my point. It doesn't make this distinction. It has
>> one mechanism (call/return; assembly statements are quite similar to
>> what keywords are in C, for example: the element of the language),
>> which is used to create indistinguishable functions and procedures and
>> subroutines (however you want to call them).
>
> That is one of the reason I thing software and firmware developers
> should learn how compilers work and what code they generate. This is not
> the first time here in this subject talking about how a C would compile
> code and non-assembly minded developers tend to get it wrong - or just
> simplify it. A function in C (and virtually all HLLs) has prologues and
> epilogues that initialize the function and then when returns
> de-initialize it.

I'm not sure you meant to say that I got it wrong, but if you did, you're
wrong. And you got it wrong, too. In C, there /may/ be some additional
code, but in general, on 8-bit micros, a function call without arguments is
a simple call statement and a return from a void function is a simple
return. (There may be some rare exception, but I think you won't find many
examples.)

Given that Pascal can be quite efficient, too, I suspect that this also is
valid for the better Pascal compilers when calling a procedure.

Besides, this is all besides the point I was making.

Gerhard

2008\10\21@163049 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

> Gerhard Fiedler wrote:
>> I really think you should do some reading of what other people write,
>> rather than building your strawmen out of nothing. Nobody ever said
>> that the distinction doesn't exist.
>
> But if it exists somewhere, then it also exists in the general computer
> science sense, since one is a superset of the other.

Now you're far below yourself... :)  Again the same strawman. (Remember how
you tend to call people who make the same mistake twice?)

Nobody ever doubted that it /exists/, but you said that it was /important/.
That's different. You just can't bring forward anything that would show
that it's important in CS in general, much less that it's important for
this discussion.

Gerhard

2008\10\21@163531 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

> Those who prefer hacking sometimes rebell against type checking, but once
> they grow up they usually appreciate it.

Do you actually have the experience to be able to say something like this?
Or are you just on a bad trip the last few days?

Did you spend any reasonable amount of time programming in a language that
purposefully uses weak (or no) typing? (I'm obviously not talking about C
here... :)

Gerhard

2008\10\21@165202 by olin piclist

face picon face
Gerhard Fiedler wrote:
> but in general, on 8-bit micros, a function call
> without arguments is a simple call statement and a return from a void
> function is a simple return.

This is definitely not true of C18, and not true of C30 with the default
settings.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\21@165651 by olin piclist

face picon face
Gerhard Fiedler wrote:
> Do you actually have the experience to be able to say something like
> this? Or are you just on a bad trip the last few days?
>
> Did you spend any reasonable amount of time programming in a language
> that purposefully uses weak (or no) typing? (I'm obviously not
> talking about C here... :)

I have used enough languages of different flavors to know that strong type
checking is a Good Thing, as long as you can disable it in specific
instances with a special syntax that isn't likely to come up accidentally.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\21@180005 by Peter Todd

flavicon
face
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Tue, Oct 21, 2008 at 04:56:34PM -0400, Olin Lathrop wrote:
{Quote hidden}

I think the question isn't how much experience with different languages
you have, but rather, different environments. Programming web apps is a
completely different environment than microcontrollers and it calls for
different tradeoffs.

- --
http://petertodd.org 'peter'[:-1]@petertodd.org
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFI/lCU3bMhDbI9xWQRAhFOAKCZn94yo7ZxBmcER23rrei09QFObgCfbk+v
/RGMdodsD2FF6zV0Ie29seY=
=vEsq
-----END PGP SIGNATURE-----

2008\10\21@200525 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

>> but in general, on 8-bit micros, a function call without arguments is a
>> simple call statement and a return from a void function is a simple
>> return.
>
> This is definitely not true of C18, and not true of C30 with the default
> settings.

I'm not using them; there may be a reason :)

Seems they fall into the "obscure exception" category. They definitely are
not representative in this for the typical, industry-standard efficient
8-bit C compiler.

Gerhard

2008\10\21@201942 by Vitaliy

flavicon
face
Peter Onion wrote:
> On Tue, 2008-10-21 at 12:22 -0700, Vitaliy wrote:
>> Peter Onion wrote:
>> >> One of my professors described what happened in the days before Agile:
>> >
>> > Ah, in the dark ages when every large software project failed!  ;-)
>>
>> I didn't say that, now -- did I, Peter? :)
>
> No indeed you didn't.  But to listen to some of the "Agile Evangelists"
> it's hard to see how anything ever got produced before the latest, best
> ever, must have, "development bling" was used :-)
>
> None of the projects I've ever worked on has used a single
> "methodology", we pick and mix the bits we need when we need them.

Agile project teams do have a higher rate of success, according to DDJ. And
I think that there really is no such thing as a true "waterfall-based
development approach". Change happens.

Vitaliy

2008\10\21@231223 by Mongol Herdsman

picon face
Peter wrote:
>> > The only reason to have strong types is when one is very tight on space
>> > and/or
>> > time and wants total control on data size, stack depth etc. In all other
>> > cases ths is not needed.
>>
>> A little user functionality more to compete on the market and you
>> easily will be "tight on space, time, data size etc". What big popular
>> software products based on interpretive languages do you know?
>
> Most of the WWW (what people call "Internet" anyway) is based on an arcane
> collection of interpreted or jit compiled languages.

Huge part, if not the biggest of WWW related software is ASP.NET
based. "C# and VB.NET code-behind" is getting compiled before the
first launch of a project. And variables in those languages are
strongly typed. "Just In Time" (JIT) or not JIT, still these languages
are compiled. Java, the base for the rest, except for PHP, is also
compiled language, I beleive.

Regarding the interpreted PHP vs compiled ASP.NET discussion, the best
I've found is:
http://codeclimber.net.nz/archive/2008/08/23/.net-vs-php-in-the-enterprise-comics-strip.aspx

Regarding the client side, Javascript running on a browser is getting
interpretered by a browser, but still it's a small part of the overall
code. And also nobody would write anything big in Javascript.


> And there are several HUGE software packages in use by companies that
> are based on same. Not to mention "VB" the "language", which i don't even
> count here (its eval is crippled - one can't use it for lambda expressions etc <G>).

VB.NET is a great compiled language. I have no idea what do you mean
"its eval is crippled".


> ... The function is a sort of interpreter/linter itself, and it has to
> cope with recursion, continuation and variadic calls, plus variadic returns
> (several return values are polymorphic lists). I don' even want to think about
> doing that in anything but a typeless language

C# and VB.NET feature great techniques (overriding, overloading etc)
to process different types the same way. You can arrange "typless
functionality" if you really need it inside the language.


> (in tcl everything is a string, and strings are first class objects).

"everything is a string" is not that good idea as for me, particularly
for loop counters.

2008\10\22@064945 by sergio masci

flavicon
face


On Mon, 20 Oct 2008, Olin Lathrop wrote:

> Peter wrote:
> > The obsession with strongly typed languages that try but not quite
> > succeed to replace a proper source code linter and proper coding
> > practice comes up over and over again. I wonder why.
>
> Because strong type checking is very useful.  Good programmers like that
> strong type checking gives the compiler the ability to catch mistakes and
> help you write clean code.  Those who prefer hacking sometimes rebell
> against type checking, but once they grow up they usually appreciate it.

Hi Olin,

I started writing a reply to your post giving reasons (and examples) why
non-hacking grown-up programmers like BOTH strong and weak type checking.
But after several pages and the prospect of several more I decided to
scrap it and just say this:

Often writing a ton of code to pursuade a compiler to produce what you
want just gives the illusion that the compiler is protecting you from
silly mistakes. It makes the code seem necessarilly complex. It hides the
possibility of simplifying the solution.

Sometimes less really is more.

Regards
Sergio Masci

2008\10\22@070558 by cdb

flavicon
face
On Mon, 20 Oct 2008 22:23:21 -0700, Chops\ wrote:
::I 'm looking for something different - how would  
:: you associate a particular piece of code with a flowchart drawn in
::  
:: visio, for example?

Isn't this what UML coding is supposed to do? Convert a flow chart
into near code, near code could then be tidied up to look like a
program description list.

Colin


--
cdb, @spam@colinspam_OUTspam.....btech-online.co.uk on 22/10/2008

Web presence: http://www.btech-online.co.uk  

Hosted by:  http://www.1and1.co.uk/?k_id=7988359






2008\10\22@072152 by olin piclist

face picon face
Gerhard Fiedler wrote:
>> This is definitely not true of C18, and not true of C30 with the
>> default settings.
>
> I'm not using them; there may be a reason :)
>
> Seems they fall into the "obscure exception" category. They
> definitely are not representative in this for the typical,
> industry-standard efficient 8-bit C compiler.

Have you looked at the instructions generated by various C compilers?  I'd
be surprised if even most of them generate just a return for a empty
subroutine, unless they have a specific optimization built in for that case.
I'm pretty sure the standard Microsoft Visual C compiler for the x86 doesn't
just create a return instruction either.  There will be some linking and
unlinking of its stack frame, and probably saving/restoring one or two
registers on the stack.

There is the off chance that this is not done for the special case of a
totally empty subroutine, but then again that hardly sounds like a case
worth bothering to optimize for.

Take a look at some machine code before jumping to conclusions.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\22@102757 by Herbert Graf

flavicon
face
On Wed, 2008-10-22 at 07:21 -0400, Olin Lathrop wrote:
> There is the off chance that this is not done for the special case of a
> totally empty subroutine, but then again that hardly sounds like a case
> worth bothering to optimize for.

I'd have to agree, and am now curious: What would be the point of trying
to optimize a call to a completely empty subroutine? Wouldn't it be
better to just get rid of the call completely?

TTYL

2008\10\22@104211 by sergio masci

flavicon
face


On Wed, 22 Oct 2008, Herbert Graf wrote:

> On Wed, 2008-10-22 at 07:21 -0400, Olin Lathrop wrote:
> > There is the off chance that this is not done for the special case of a
> > totally empty subroutine, but then again that hardly sounds like a case
> > worth bothering to optimize for.
>
> I'd have to agree, and am now curious: What would be the point of trying
> to optimize a call to a completely empty subroutine? Wouldn't it be
> better to just get rid of the call completely?

If you consider the building of an executable as several seperate
processes you may find that the process specific to generating the call
has come and gone before the subroutine was optimised out of existance
(reduced to zero length). However the piece of code containing the call is
by then cast in stone and the only way to remove the call is by replacing
it with NOPs.

Regards
Sergio Masci

2008\10\22@110148 by Chris Emerson

flavicon
face
On Wed, Oct 22, 2008 at 10:27:53AM -0400, Herbert Graf wrote:
> On Wed, 2008-10-22 at 07:21 -0400, Olin Lathrop wrote:
> > There is the off chance that this is not done for the special case of a
> > totally empty subroutine, but then again that hardly sounds like a case
> > worth bothering to optimize for.
>
> I'd have to agree, and am now curious: What would be the point of trying
> to optimize a call to a completely empty subroutine? Wouldn't it be
> better to just get rid of the call completely?

You might have a system with callbacks, and sometimes set the callback
to a no-op.

I agree that optimising an empty function probably isn't very important,
though I don't see why you wouldn't want to optimise other very small
functions.

Chris

2008\10\22@111604 by William \Chops\ Westfield

face picon face

On Oct 22, 2008, at 7:27 AM, Herbert Graf wrote:

> I'd have to agree, and am now curious: What would be the point of  
> trying
> to optimize a call to a completely empty subroutine? Wouldn't it be
> better to just get rid of the call completely?

I believe we had to add a switch to get the Intel x86 compiler to  
generate a stack frame for many short "stub" functions (functions that  
didn't call other functions), or something like that (perhaps it was  
functions with no local variables.)  Our debuggers didn't work very  
well without stack frames.

BillW


2008\10\22@174503 by olin piclist

face picon face
Herbert Graf wrote:
> I'd have to agree, and am now curious: What would be the point of
> trying to optimize a call to a completely empty subroutine? Wouldn't
> it be better to just get rid of the call completely?

If the caller and called routines are separately compiled, then this option
is not available to the compiler.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\22@192129 by Bob Ammerman

picon face
Many compilers avoid the standard 'stack frame' linkage stuff for leaf
functions (those which do not call any other functions). This can be a 'big
win' for performance on some architectures.

-- Bob Ammerman
RAm Systems

2008\10\22@222143 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

>>> This is definitely not true of C18, and not true of C30 with the
>>> default settings.
>>
>> I'm not using them; there may be a reason :)
>>
>> Seems they fall into the "obscure exception" category. They definitely
>> are not representative in this for the typical, industry-standard
>> efficient 8-bit C compiler.
>
> Have you looked at the instructions generated by various C compilers?  

Yes.

> I'd be surprised if even most of them generate just a return for a empty
> subroutine,

I wasn't ever talking about an empty subroutine. I was talking about a
subroutine without arguments (or more specifically, a C function without
arguments that returns void).

> I'm pretty sure the standard Microsoft Visual C compiler for the x86

I also was talking about compilers for 8-bit micros. I'm pretty sure the
x86 is not generally considered an 8-bit micro.

> Take a look at some machine code before jumping to conclusions.

Take a look at my messages and try to actually read them before jumping to
conclusions. The arrogance of your email persona is barely supportable when
you're right, but when you just write a load of completely unrelated stuff
to "prove" you're right when you're miles off target, it's way over the
line

Gerhard

2008\10\23@081518 by olin piclist

face picon face
> Take a look at my messages and try to actually read them before jumping to
> conclusions. The arrogance of your email persona is barely supportable
> when
> you're right, but when you just write a load of completely unrelated stuff
> to "prove" you're right when you're miles off target, it's way over the
> line

Oh grow up Gerhard.  I cited two examples from the PIC world, C18 and C30,
that I happen to know create stack frames.  For whatever reason you objected
to those so I mentioned normal C on x86 also does it, at least for the few
examples I looked at a while back.  These things are all relevant to the
general discussion, just apparently not what you want to hear.

So what specifically is your point?  I thought you wanted to know whether
compilers would optimize a empty subroutine to a single return instruction.
Or is that you are trying to explain why it should be so despite the fact
that it isn't?


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\23@084800 by Tamas Rudnai

face picon face
> Many compilers avoid the standard 'stack frame' linkage stuff for leaf
> functions (those which do not call any other functions). This can be a
'big
> win' for performance on some architectures.

Yes, they are thinking upfront of me (me as a developer), so that they
replace all the variables to 'static' variables - so that is no longer
needed to use FSR calculations and therefore stack manipulation for locals.
That leads to other issues as well, like RAM usage (needs more RAM) and
sometimes very nasty issues like what if I do something different in the
next version of my firmware? So that the compiler is no longer able to
optimise the functions in that way aming bigger code or much slower than was
it before or because all the variables becoming "normal locals" when there
was an initialisation problem in the firmware that was not determined before
it brakes the whole project just because of a small update... These things
lead to the problems of "it was working before, and I did not change that
routine, only put this or that which is irrelevant but now it does not work
any more".

Because of these things, personally I do not think if that is generally a
good idea from the compiler to make optimisation like that by itself - if
compiler lets the developer to create static locals, and if there are other
techniques that can be used to reduce performance issues and all the side
effects known by the developer, then it is ok. But I do not like when some
artificial intelligence decides how to write a fimrware.

Tamas



On Thu, Oct 23, 2008 at 12:20 AM, Bob Ammerman <spamBeGonerammermanEraseMEspamverizon.net>wrote:

> Many compilers avoid the standard 'stack frame' linkage stuff for leaf
> functions (those which do not call any other functions). This can be a 'big
> win' for performance on some architectures.
>
> -- Bob Ammerman
> RAm Systems
>
> -

2008\10\23@084954 by Wouter van Ooijen

face picon face
> I cited two examples from the PIC world, C18 and C30,
> that I happen to know create stack frames.  

They cerate stack frames for empty (no locals, no code) functions?
Stupid stupid! Now if I had the time two write a proper compiler... But
in that case I would probably choose a different language.

None of the 12/14-bit core C compilers that I know create stack frames
(or maybe they will, but only if pressed to do so). One might argue that
such compilers are not proper C compilers, because they use a
stack-stack memory allocation that does not permit recursion.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\23@091916 by Tamas Rudnai

face picon face
>> I cited two examples from the PIC world, C18 and C30,
>> that I happen to know create stack frames.
>
> They cerate stack frames for empty (no locals, no code) functions?

If there is no locals and parameters then C18 will not create a stack frame.
I did not have a look at the C30 yet.

> None of the 12/14-bit core C compilers that I know create stack frames
> (or maybe they will, but only if pressed to do so). One might argue that
> such compilers are not proper C compilers, because they use a
> stack-stack memory allocation that does not permit recursion.

It is not only the recursion, but also reentability - like a function is
execution when an interrupt occurs where the ISR calls that function as
well. Or if there is an RTOS - how would it deal with the concurrent
threads?

BTW: How would you resolve the increased RAM which should occur when only
static variables are in use? (even functions that are rarely called
statically occupies RAM). Is there any compiler technique to statically
analyse the program flow and use overlapped memory usage for these local
variables?

Tamas



On Thu, Oct 23, 2008 at 1:49 PM, Wouter van Ooijen <wouterspamBeGonespamvoti.nl> wrote:

{Quote hidden}

> -

2008\10\23@093557 by Wouter van Ooijen

face picon face
> Yes, they are thinking upfront of me (me as a developer), so that they
> replace all the variables to 'static' variables - so that is no longer
> needed to use FSR calculations and therefore stack manipulation for locals.
> That leads to other issues as well, like RAM usage (needs more RAM) and

No, it does not need more RAM. (Because they don't realy replace all
variable with 'static' veriables - they do something more intelligent.)

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\23@095203 by Wouter van Ooijen

face picon face
> BTW: How would you resolve the increased RAM which should occur when only
> static variables are in use? (even functions that are rarely called
> statically occupies RAM). Is there any compiler technique to statically
> analyse the program flow and use overlapped memory usage for these local
> variables?

Yes, it is commonly called "static (pseudo) stack allocation". Using a
real stack on 12/14-bit core PICs is excessively costly (in code space
en execution time), so it is seldom used (if ever).

Re-entrancy is not an issue on 12/14 bit core PICs because you can't
create a preemptive multitasking system anyway (that request
manipulation of the stack, which is not possible).

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\23@103529 by olin piclist

face picon face
Wouter van Ooijen wrote:
> They cerate stack frames for empty (no locals, no code) functions?

I don't know that for sure.  I do know that C18 creates stack frames for
normal functions, and that C30 does so by default for normal functions.  C30
have a command line option to disable creation of stack frames, but C18 has
no such option.

As I said before, maybe those compilers have optimizations for the special
case of empty function.  Nothing in the documentation mentions this that I
recall, and I haven't tested it myself.

On a side note, C18 uses stupid conventions for the stack in a number of
ways.  The PIC 18 has three of the four combinations of pre/post inc/dec
indirect addressing modes.  It does not have pre-decrement.  That leaves
pre-increment and post-decrement as the only complementary pair of
instructions that could be used for stack pushing and popping.

That leaves two possible stack conventions.  The first is to have the stack
grow towards higher addresses so that writing to pre-inc is a push and
reading from post-dec is a pop.  In this case the pointer is pointing to the
last pushed byte when not being used.

The second possibility is to have the stack grow towards low addresses,
which means a push is writing to post-dec and a pop is reading from pre-inc.
The stack pointer is pointing to the next empty stack location when not in
use.

Incredibly, C18 uses a model incompatible with both these possibilities.
The stack grows towards high addresses, but the stack pointer points to the
next empty byte when not being used.  A push is a write to post-inc, but a
pop would require a read from pre-dec, which the PIC doesn't have.  This not
only wastes cycles performing a pop, but also makes the operation no longer
atomic, which is a complication that must be considered if using the stack
in interrupt code.

Another stupdity is the subroutine argument passing conventions.  C18 uses a
caller-clean model.  This means subroutines can't remove the call arguments
from the stack after grabbing them and before calling other routines.  This
uses a lot more stack space than could be necessary when routines are deeply
nested, as is the case with the Microchip network routines, for example.
They need large stacks.

Yet another stupidity is that C18 uses up both FSR1 and FSR2.  FSR1 is the
stack pointer and FSR2 is the frame pointer.  Stack frames may be of some
use during debugging, but they shouldn't be the default, and they certainly
shouldn't be the only option.

My PIC development environment uses FSR2 as the stack pointer with the stack
growing towards high addresses and pre-inc and post-dec for push and pop.  I
do have a C18 compatibility option that switches to FSR1 as the stack
pointer and uses the brain dead stack management of C18.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\23@103642 by olin piclist

face picon face
Wouter van Ooijen wrote:
> One might argue that
> such compilers are not proper C compilers, because they use a
> stack-stack memory allocation that does not permit recursion.

Allocating a formal stack frame wastes memory and uses a extra pointer, but
I don't see how it inhibits recursion.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\23@105823 by Wouter van Ooijen

face picon face
 > Another stupdity is the subroutine argument passing conventions.
C18 uses a
> caller-clean model.  

This the default for C. I agree it is a stupid choice.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\23@110714 by Wouter van Ooijen

face picon face
Olin Lathrop wrote:
> Wouter van Ooijen wrote:
>> One might argue that
>> such compilers are not proper C compilers, because they use a
>> stack-stack memory allocation that does not permit recursion.
>
> Allocating a formal stack frame wastes memory and uses a extra pointer, but
> I don't see how it inhibits recursion.

I mistyped, it should be "static stack". That's a stack that is
pre-calculated at compile time, so it can use fixed adresses at run
time. But this does not permit recursion or reentrancy.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\23@114015 by olin piclist

face picon face
Wouter van Ooijen wrote:
>  > Another stupdity is the subroutine argument passing conventions.
> C18 uses a
>> caller-clean model.
>
> This the default for C. I agree it is a stupid choice.

So are you saying this is specified in the C standard?  I would expect a
standard to say things like local variables need not be persistant between
calls to the same routine, but this sounds like a detail that should be left
to the implementation.  Is there a case where the calling convention matters
to someone programming only in the language?


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\23@114955 by Peter

picon face
Mongol Herdsman <inner.mongolia.herd <at> gmail.com> writes:
> Huge part, if not the biggest of WWW related software is ASP.NET
> based. "C# and VB.NET code-behind" is getting compiled before the
> first launch of a project. And variables in those languages are
> strongly typed. "Just In Time" (JIT) or not JIT, still these languages
> are compiled. Java, the base for the rest, except for PHP, is also
> compiled language, I beleive.

I used jit as "late binding/bytecode compilation/just in time compilation". The
larger part of the net does not run on m$ servers but on unix and company and
asp is often supported by cross tools and emulation thereon. The larger part of
backends are Perl PHP4 Ruby on Rails, Python and Java based. Asp plays a certain
role on certain commercial servers.

See for yourself: news.netcraft.com/archives/web_server_survey.html

Peter


2008\10\23@115504 by Chris Emerson

flavicon
face
On Thu, Oct 23, 2008 at 11:40:24AM -0400, Olin Lathrop wrote:
> Wouter van Ooijen wrote:
> >  > Another stupdity is the subroutine argument passing conventions.
> > C18 uses a
> >> caller-clean model.
> >
> > This the default for C. I agree it is a stupid choice.
>
> So are you saying this is specified in the C standard?  I would expect a
> standard to say things like local variables need not be persistant between
> calls to the same routine, but this sounds like a detail that should be left
> to the implementation.  Is there a case where the calling convention matters
> to someone programming only in the language?

It's not specified directly, I think, but the called function doesn't
necessarily know how many parameters were passed in (eg printf).

Chris

2008\10\23@120910 by Wouter van Ooijen

face picon face
> So are you saying this is specified in the C standard?  I would expect a
> standard to say things like local variables need not be persistant between
> calls to the same routine, but this sounds like a detail that should be left
> to the implementation.  Is there a case where the calling convention matters
> to someone programming only in the language?

It was specified (dunno about the most recent definitions) that a
function can be called with any number of parameters, regardless of the
number of parameters in its definition. So it is most practical (but OK,
not the only) way to have the caller remove the parameters, because only
he knows how many there are...

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\23@124332 by olin piclist

face picon face
Chris Emerson wrote:
> It's not specified directly, I think, but the called function doesn't
> necessarily know how many parameters were passed in (eg printf).

I'm not familiar enough in C to remember how variable number of arguments
are handled in the language, but wouldn't that need to be described somehow
in the routine declaration?  If so, the comipler could use different passing
conventions for routines that accept variable number of arguments.

Even if not, I can think of other means of supporting variable number of
arguments than requiring caller cleaned stack.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\23@125302 by Dave Tweed

face
flavicon
face
Olin Lathrop wrote:
> Wouter van Ooijen wrote:
> > > Another stupdity is the subroutine argument passing conventions.
> > > C18 uses a caller-clean model.
> >
> > This the default for C. I agree it is a stupid choice.
>
> So are you saying this is specified in the C standard?  I would expect a
> standard to say things like local variables need not be persistant between
> calls to the same routine, but this sounds like a detail that should be
> left to the implementation.  Is there a case where the calling convention
> matters to someone programming only in the language?

You have to read between the lines a bit, but it is implicit in the
standard. It is implied by the fact that a function does not necessarily
know at compile time the number of arguments that it is going to be given,
and by the fact that arguments are treated the same as automatic variables.

All variables in C are either "automatic" (local, allocated on the stack),
or at fixed addresses (static or global). All arguments to functions are
passed by value, and from the called function's point of view, they are
simply a subset of its automatic variables -- a subset that happens to be
initialized by the caller. The first argument is pushed last, and the
called function does not necessarily know how many arguments are actually
there. Also, within the called function, you can modify the value of an
argument just like any other automatic variable.

This model does have some advantages, including the fact that if a function
does not require any additional local variables beyond its arguments, and
calls no other functions, then (even with separate compliation), it does
not need to generate a stack "frame" for itself. An empty function could
indeed consist of only a bare "return" instruction.

On CPUs that have real stacks, the frame pointer usually points to the
top of the stack at the moment the function is called, so arguments are
accessed with negative offsets (if the stack is growing upward in memory),
and any other automatic variables defined inside the function are accessed
with positive offsets.

>From the caller's point of view, arguments to functions that it wants to
call are simply additional anonymous automatic variables on the stack,
sitting just beyond the named ones.

Indeed, the whole concept of a stack frame is not required by the standard,
since within any given function, the frame pointer and the stack pointer
have a fixed relationship to each other. All automatic variables (including
arguments) can be accessed using fixed offsets from etiher one. If you have
the registers and the addressing modes to support it, though, a frame
pointer tends to make the code simpler and more efficient, and simplifies
bookkeeping for the compiler. It also helps with debugging.

On CPUs that have weak or nonexistent support for stacks, all of this can
be simulated with static allocation of automatic variables (in registers,
if possible), if the compiler can "see" all of the source code at once and
analyze the call tree, but you give up reentrancy in favor of tighter code.
Otherwise, you need to generate code and allocate memory to support a
software stack.

-- Dave Tweed

2008\10\23@134812 by Tamas Rudnai

face picon face
> I mistyped, it should be "static stack". That's a stack that is
> pre-calculated at compile time, so it can use fixed adresses at run
> time. But this does not permit recursion or reentrancy.

That is what I call overlayed memory usage - that is not even a stack. In my
opinion it is much better what C18 do, it does not try to figure out what I
want, but I can trigger this option by the storage specifier 'overlay':

(from C18 Compiler's Guide)

                     2.3.1    Overlay
                     The MPLAB C18 compiler introduces a storage class of
overlay. The overlay storage
                     class may be applied to local variables (but not
formal parameters, function definitions
                     or global variables). The overlay storage class will
allocate the associated symbols
                     into a function-specific, static overlay section. Such
a variable will be allocated
                     statically, but initialized upon each function entry.
For example, in:
                     void f (void)
                     {
                         overlay int x = 5;
                         x++;
                     }
                     x will be initialized to 5 upon each function entry,
although its storage will be statically
                     allocated. If no initializer is present, then its
value upon function entry is undefined.
                     The MPLINK linker will attempt to overlay local
storage specified as overlay from
                     functions that are guaranteed not to be active
simultaneously. For example, in:
                     int f (void)
                     {
                         overlay int x = 1;
                         return x;
                     }
                     int g (void)
                     {
                         overlay int y = 2;
                         return y;
                     }
                     if f and g will never be active at the same time, x
and y become candidates for sharing
                     the same memory location. However, in:
                     int f (void)
                     {
                         overlay int x = 1;
                         return x;
                     }
                     int g (void)
                     {
                         overlay int y = 2;
                         y = f ( );
                         return y;
                     }
                     since f and g may be simultaneously active, x and y
will not be overlaid. The advantage
                     of using overlay locals is that they are statically
allocated, which means that, in
                     general, fewer instructions are required to access
them (resulting in a smaller program
                     memory image). At the same time, the total data memory
allocation required for these
                     variables may be less than what would be required had
they been declared as static
                     due to the fact that some of the variables may be
overlaid.

       If the MPLINK linker detects a recursive function that contains a
local variable of
       storage class overlay, it emits an error and aborts. If the MPLINK
linker detects a call
       through a function pointer in any module and a local variable of
storage class overlay
       in any (and not necessarily the same) module, it emits an error and
aborts.
       The default storage class for local variables is auto. This can be
overridden explicitly
       with the static or overlay keywords or implicitly with either the
-scs (static local
       variables) or -sco (overlay local variables) command-line option.
For completeness,
       MPLAB C18 also supports the -sca command-line option. This option
allows the
       storage class for local variables to be explicitly specified as
auto.


Tamas



On Thu, Oct 23, 2008 at 3:59 PM, Wouter van Ooijen <RemoveMEwouter@spam@spamspamBeGonevoti.nl> wrote:

{Quote hidden}

> -

2008\10\23@141313 by Wouter van Ooijen

face picon face
Tamas Rudnai wrote:
>> I mistyped, it should be "static stack". That's a stack that is
>> pre-calculated at compile time, so it can use fixed adresses at run
>> time. But this does not permit recursion or reentrancy.
>
> That is what I call overlayed memory usage - that is not even a stack. In my
> opinion it is much better what C18 do, it does not try to figure out what I
> want, but I can trigger this option by the storage specifier 'overlay':

I don't think the world cares much how you call it - it is commonly
called "stactic stack allocation" or something similar. In the absence
of re-entry and recursion it is )for the user)m indistinguishable from a
"real" stack.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\23@141723 by Isaac Marino Bavaresco

flavicon
face
Wouter van Ooijen escreveu:
>   > Another stupdity is the subroutine argument passing conventions.
> C18 uses a
>  
>> caller-clean model.  
>>    
>
> This the default for C. I agree it is a stupid choice.
>  
With the callee cleaning the stack it would be impossible (or at least
very difficult) to have functions with variable-length argument lists
like printf.

For some architectures it adds more complexity also, because first the
return address need to be removed from the stack and saved, then the
stack pointer must be incremented (decremented for some) and the return
address finally used to return.

The caller always knows how many bytes it pushed onto the stack, the
callee don't. If the callee cleans the stack and there is some mistake
with the function prototypes (or the equivalent) you get a hard crash.
If the caller cleans, you may have a hard to find bug.

Some processors have an unlink and return instruction that does this
automatically, but others not.

Isaac

__________________________________________________
Faça ligações para outros computadores com o novo Yahoo! Messenger
http://br.beta.messenger.yahoo.com/

2008\10\23@151154 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

> Oh grow up Gerhard.  

Huh?

> For whatever reason you objected to those

Where in the world do you get this from?

> I thought you wanted to know whether compilers would optimize a empty
> subroutine to a single return instruction.

You thought wrong. I didn't want to know anything. You really don't have to
go out of your way to help me poor lonesome.

Here's where this subthread started (since you don't seem to remember any
of this):

>>> but in general, on 8-bit micros, a function call without arguments is a
>>> simple call statement and a return from a void function is a simple
>>> return.
>>
>> This is definitely not true of C18, and not true of C30 with the
>> default settings.
>
> I'm not using them; there may be a reason :)

I never objected to your examples, but you seem to have a problem with
something. The only thing is that they don't affect my statement... C30 is
not for 8-bit micros, and C18 seems to be an oddity in this respect in the
wide world of C (and Pascal) compilers for 8-bit micros.

So what's your problem?

Gerhard

2008\10\23@154009 by olin piclist

face picon face
Isaac Marino Bavaresco wrote:
> With the callee cleaning the stack it would be impossible (or at least
> very difficult) to have functions with variable-length argument lists
> like printf.
>
> For some architectures it adds more complexity also, because first the
> return address need to be removed from the stack and saved, then the
> stack pointer must be incremented (decremented for some) and the return
> address finally used to return.

On the PIC 18 there are separate data and return address stacks, so this is
not a issue.  I didn't realize that all C functions are allowed to be called
with different number of arguments.  Is this really the case?  To me this
seems like a really brain dead choice considering that fixed number of
arguments is common and knowing that at compile time allows for some obvious
optimizations.  I can see the point to variable numbers of arguments, but I
also don't see a drawback to making you say this is a possibility in the
routine declaration.  The compiler can then catch accidental wrong number of
arguments supplied in the majority of cases where you intend to always call
with the fixed list of arguments.  Is C really defined to not allow for
this?


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\23@154553 by Wouter van Ooijen

face picon face
Isaac Marino Bavaresco wrote:
> Wouter van Ooijen escreveu:
>>   > Another stupdity is the subroutine argument passing conventions.
>> C18 uses a
>>  
>>> caller-clean model.  
>>>    
>> This the default for C. I agree it is a stupid choice.
>>  
> With the callee cleaning the stack it would be impossible (or at least
> very difficult) to have functions with variable-length argument lists
> like printf.

I think variable-length arguments is a stupid idea anyway, but if really
wanted it could have been implemented using a pointer to an array of
caller-chosen size.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\23@162405 by Wouter van Ooijen

face picon face
> I didn't realize that all C functions are allowed to be called
> with different number of arguments.  

The original (K&R) C was not meant to have any cross-function checking.
What that caller put on the stack was his business, how the called
function interpreted its arguments was another business. The type of the
arguments wasn't even part of the header, it was syntactically inside
the function (from memory and internet):

double Total_SA(r, h)
   double r;
   double h;
{
   return 2*PI*r*(r+h);
}

IIRC this syntax is still accepted in standard C, but I hope most
compilers will at least issue a warning.

It is not without ground that C is often called "a nice, almost
cpu-independent assembler"! Function prototypes and the idea of
cross-function argument checking was a 'late' addition, and all
additions tried very hard to keep the old syntax valid. Like the Pentium
still being able to execute 8086 instructions (which are just souped-up
16-bit versions of the 8008 instructions...).

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\23@173820 by sergio masci

flavicon
face


On Thu, 23 Oct 2008, Olin Lathrop wrote:

{Quote hidden}

Yes and no.

Originally a function call just pushed things onto the stack and the
function itself expected the right things to be there when it was called.
The compiler did very little checking for you.

varible argument lists were accessed using a simple pointer to the memory
after the last known argument. This caused problems with register
based argument passing optimisations (e.g. SPARC).

C compilers grow up a little with the introduction of function prototypes
(the compiler actually checking the formal parameter list against the
actual parameter list) and type safe linking.

>  To me this
> seems like a really brain dead choice considering that fixed number of
> arguments is common and knowing that at compile time allows for some obvious
> optimizations.  I can see the point to variable numbers of arguments, but I
> also don't see a drawback to making you say this is a possibility in the
> routine declaration.

I think the variable number of arguments thing was originally really a
side effect rather than a goal. Yes nowadays you need to explicitly say
that unknown arguments may follow the defined ones using "..." at the end
of the formal arg list.

>  The compiler can then catch accidental wrong number of
> arguments supplied in the majority of cases where you intend to always call
> with the fixed list of arguments.  Is C really defined to not allow for
> this?

no.

Regards
Sergio Masci

2008\10\23@175837 by sergio masci

flavicon
face


On Thu, 23 Oct 2008, Tamas Rudnai wrote:

{Quote hidden}

You build multi-tasking into the language and not try to implement it as
an after thought through libraries.

>
> BTW: How would you resolve the increased RAM which should occur when only
> static variables are in use? (even functions that are rarely called
> statically occupies RAM). Is there any compiler technique to statically
> analyse the program flow and use overlapped memory usage for these local
> variables?

Yes, a compiler can analyse the way functions interact and produce a map
of which RAM locations must be preserved during which function calls. This
allows areas of RAM to be statically assigned during compile time to
multiple functions (functions which cannot be active at the same time).
The effect is like modeling the runtime stack by predicting where the
stack pointer will be when function X is called from function Y and then
hard coding the location of the automatic local variables relative to the
predicted top of stack. This type of stack is often refered to as a static
stack because it doesn't actually change at run time.

The XCSB compiler (which is not a C compiler) supports multitasking,
builds static stacks for each thread and produces task (and ISR) safe
code.

Regards
Sergio Masci

2008\10\23@180837 by sergio masci

flavicon
face


On Thu, 23 Oct 2008, Tamas Rudnai wrote:

{Quote hidden}

I disagree. A high level programming lanugage is just a way for you to
specify what you want a computer to do. A good language will make it
easier for you to do this and at the same time allow the compiler to
generate the best possible code. Kind of like you telling an assembler
programmer what you want the computer to do and then letting the
programmer get on and write the best code he can.

If you have an issue with a section of the generated code then I would
suggest that either the language was not able to convey the importance and
constraints necessary of that section or the programmer did not do a good
enough job of telling the compiler.

Regards
Sergio Masci

2008\10\23@181531 by sergio masci

flavicon
face


On Thu, 23 Oct 2008, Dave Tweed wrote:

> Indeed, the whole concept of a stack frame is not required by the standard,
> since within any given function, the frame pointer and the stack pointer
> have a fixed relationship to each other.

Is this true even if you use "alloca" to dynamically allocate space on the
stack (never used it myself)?

Regards
Sergio Masci

2008\10\23@184110 by Christopher Head

picon face
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

sergio masci wrote:
> Is this true even if you use "alloca" to dynamically allocate space on the
> stack (never used it myself)?
>
> Regards
> Sergio Masci

alloca() is not part of ISO C.

Chris

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: GnuPT 2.7.2
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkkA/YAACgkQiD2svb/jCb4gQQCaAj3E1dWeHadUIwSYGEKKtm1U
R4YAoI+CNJ0uuB2ZXUOeAAY1N7YyMHRl
=kz/D
-----END PGP SIGNATURE-----

2008\10\23@214859 by Dave Tweed

face
flavicon
face
sergio masci wrote:
> On Thu, 23 Oct 2008, Dave Tweed wrote:
> > Indeed, the whole concept of a stack frame is not required by the
> > standard, since within any given function, the frame pointer and
> > the stack pointer have a fixed relationship to each other.
>
> Is this true even if you use "alloca" to dynamically allocate space on
> the stack (never used it myself)?

Never heard of it before!

http://www.gnu.org/software/libtool/manual/libc/Variable-Size-Automatic.html

Yes, this would probably require a stack frame pointer to get right.

Obviously, this would only be used on a system that had a large,
well-supported stack to begin with. Equally obviously, it needs to be
closely tied to the compiler itself, because it's mucking about with
things that normally only the compiler can see.

-- Dave Tweed

2008\10\24@030156 by Tamas Rudnai

face picon face
> I don't think the world cares much how you call it - it is commonly
> called "stactic stack allocation" or something similar. In the absence
> of re-entry and recursion it is )for the user)m indistinguishable from a
> "real" stack.

As you can see in C18 it is not only me who calls this as an overlay :-) -
And no, it was not me who designed C18 :-) Anyway, I would not mind calling
it as static or pseudo stack but I do think that this naming is misleading.

Anyway,



On Thu, Oct 23, 2008 at 7:12 PM, Wouter van Ooijen <.....wouter@spam@spamEraseMEvoti.nl> wrote:

{Quote hidden}

> -

2008\10\24@034706 by Wouter van Ooijen

face picon face
> As you can see in C18 it is not only me who calls this as an overlay :-) -

Yeah, Microchip. I have to explain each year (in my PIC class) that what
the rest of the world calls RAM is called "general purpose file
registers" in PIC datasheets, and that is only the start...

> And no, it was not me who designed C18 :-) Anyway, I would not mind calling
> it as static or pseudo stack but I do think that this naming is misleading.

Overlays were already used in the early TurboPascal compilers (and
probably long before that, guess why compilers were often written in
separate passes?), to break the 64K code limit. IIRC the programmer had
to specify which code parts overlayed, so I think the term overlay is
more commonly associated with a mechanism that it visible to and/or
managed by the programmer.

A static stack is (except for the ban on recursion/reentrancy)
completely invisible to the user. And it takes the same amount of RAM as
a real data stack.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\24@051837 by Tamas Rudnai

face picon face
> Yeah, Microchip. I have to explain each year (in my PIC class) that what
> the rest of the world calls RAM is called "general purpose file
> registers" in PIC datasheets, and that is only the start...

Bit confusing that's for sure, but technologically 8bit PIC uses registers
only and have no RAM. For example on AVR you have to load the value of a RAM
location to a register, then you can make some calculations and then have to
store it back. In PIC it is not necessary as all RAM location is treated as
a register therefore there is no difference in between RAM or registers and
has a direct access to the whole area by every instruction.

> A static stack is (except for the ban on recursion/reentrancy)
> completely invisible to the user. And it takes the same amount of RAM as
> a real data stack.

Fair enough, I just have a bad feeling on automatic decisions which variable
is like that. With C18 you can choose if the default storage is auto, static
or overlay and also can choose that one by one in the source using these
directives - so I have a better control over it. Still the RAM (register :-)
) location of these overlayed variables are placed automatically by the
compiler - pretty much the same way as with any other compiler.

Tamas


On Fri, Oct 24, 2008 at 8:46 AM, Wouter van Ooijen <.....wouterRemoveMEspamvoti.nl> wrote:

{Quote hidden}

> -

2008\10\24@062937 by Wouter van Ooijen

face picon face
> Bit confusing that's for sure, but technologically 8bit PIC uses registers
> only and have no RAM.

It looks like a duck, it quacks like one...

I certainly don't know any other CPU architecture that has indexed
access to its registers!

> For example on AVR you have to load the value of a RAM
> location to a register, then you can make some calculations and then have to
> store it back. In PIC it is not necessary as all RAM location is treated as
> a register therefore there is no difference in between RAM or registers and
> has a direct access to the whole area by every instruction.

The PIC isntruction set technically a mix of 'single-accumulator' and
'memory-memory' architecture.

>> A static stack is (except for the ban on recursion/reentrancy)
>> completely invisible to the user. And it takes the same amount of RAM as
>> a real data stack.
>
> Fair enough, I just have a bad feeling on automatic decisions which variable
> is like that.

Why? C has clear requirements about variables, and (without recursion or
reentrancy) these can equally be met by a static stack or a real stack
(and by allocating all variables to unique locations - but takes takes
more memory).

> With C18 you can choose if the default storage is auto, static
> or overlay and also can choose that one by one in the source using these
> directives - so I have a better control over it.

Yes, but that is because recursion and reentrancy make sense on 18F
PICs. Without recursion and reentrancy you (as user/programmer) can't
tell the difference between a static stack and a real stack.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\24@084605 by olin piclist

face picon face
Wouter van Ooijen wrote:
> A static stack is (except for the ban on recursion/reentrancy)
> completely invisible to the user. And it takes the same amount of RAM
> as a real data stack.

Not quite.  A static stack has to allocate storage based on the worst case
possible subroutine nesting.  A real stack uses storage according to the
actual subroutine nesting that occurs at run time.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\24@091243 by Wouter van Ooijen

face picon face
>> A static stack is (except for the ban on recursion/reentrancy)
>> completely invisible to the user. And it takes the same amount of RAM
>> as a real data stack.
>
> Not quite.  A static stack has to allocate storage based on the worst case
> possible subroutine nesting.  A real stack uses storage according to the
> actual subroutine nesting that occurs at run time.

True, but would you allow an application to be build with less stack
reserved than according to 'the worst case subroutine nesting'? Note
that the worst case is calculated based on the call tree, so it is a
worst case, but a realistic one (one that can happen in practice).

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\24@100349 by Tamas Rudnai

face picon face
> True, but would you allow an application to be build with less stack
> reserved than according to 'the worst case subroutine nesting'? Note
> that the worst case is calculated based on the call tree, so it is a
> worst case, but a realistic one (one that can happen in practice).

I thought this technique is based on function references, so that if there
is a switch-case or an if structure where the condition cannot be calculated
or predicted at compile time, then the compiler will not be able to tell
when is the function going to be called, so it assumes that at any point the
function name was referenced?

Tamas


On Fri, Oct 24, 2008 at 2:12 PM, Wouter van Ooijen <.....wouterSTOPspamspam@spam@voti.nl> wrote:

{Quote hidden}

> -

2008\10\24@102502 by Wouter van Ooijen

face picon face
> I thought this technique is based on function references, so that if there
> is a switch-case or an if structure where the condition cannot be calculated
> or predicted at compile time, then the compiler will not be able to tell
> when is the function going to be called, so it assumes that at any point the
> function name was referenced?

Yes.

Would you (in the case you sketch) sleep well with a stack allocated
based on your assumption?

But I have to agree, there are cases where the 'worst case' won't be
reached.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\24@104355 by Tamas Rudnai

face picon face
> Would you (in the case you sketch) sleep well with a stack allocated
> based on your assumption?

Nope :-) I have to admit that in some cases the stack is worse in the way
that it is quite hard to calculate the usage by hand. In the worse case the
stack overwrites RAM area that was used for static data - for example the
stack is built from the top RAM to towards the bottom, while the static
variables or heap is from the bottom to the top, and in worse case the stack
can grow that much that it overwrites some data from the static or heap
area. Considering this it is better to use a more predictable method, like
this "static stack".

Tamas



On Fri, Oct 24, 2008 at 3:24 PM, Wouter van Ooijen <wouterEraseMEspam@spam@voti.nl> wrote:

{Quote hidden}

> -

2008\10\24@110528 by olin piclist

face picon face
Wouter van Ooijen wrote:
> True, but would you allow an application to be build with less stack
> reserved than according to 'the worst case subroutine nesting'? Note
> that the worst case is calculated based on the call tree, so it is a
> worst case, but a realistic one (one that can happen in practice).

Sometimes you know based on runtime logic (that the compiler can't know)
that some parts of the worst case call tree are impossible.  You had better
know what you're doing, but in very memory limited cases you could possibly
make use of this.

I agree this is a unusual corner case.  I was responding to your statement
more on theoretical grounds than practical ones.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\24@111158 by olin piclist

face picon face
Tamas Rudnai wrote:
> Nope :-) I have to admit that in some cases the stack is worse in the
> way that it is quite hard to calculate the usage by hand. In the
> worse case the stack overwrites RAM area that was used for static
> data - for example the stack is built from the top RAM to towards the
> bottom, while the static variables or heap is from the bottom to the
> top, and in worse case the stack can grow that much that it
> overwrites some data from the static or heap area. Considering this
> it is better to use a more predictable method, like this "static
> stack".

Both are completely predictable and use the same size if you assume the
worst case.  In no case do you need a dynamic stack that exceeds a "static
stack" in size if it was properly derived by analysing the worst case path
of the call tree.

The point was that due to program logic, the worst case call tree may never
occur, and therefore a smaller runtime stack is in theory possible.  I agree
with Wouter that I would not normally want to take the risk of missing a
runtime call tree case.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\24@115440 by William \Chops\ Westfield

face picon face

On Oct 24, 2008, at 3:29 AM, Wouter van Ooijen wrote:

> I certainly don't know any other CPU architecture that has indexed
> access to its registers!

DEC PDP-10; the registers were also addressable as the first 16
memory locations.  You could even put code in the registers and
jump to them, for a speed boost.

The "register vs ram" thing on PIC got particularly interesting
when comparing low-end PICs vs low-end AVRs, since the AVRs had
32 registers and 0 "ram", while the PIC had W and "less than 32"
"general purpose registers."

For that matter, the AVR registers also share an indexed address space  
with RAM.  The "indexed" space has "general purpose" registers from 0  
to 31, "IO registers" from 32 to 95, and "Ram" from 96 upward  
(at90s2313; exact values might differ.)

BillW

2008\10\24@141436 by Wouter van Ooijen

face picon face
> DEC PDP-10; the registers were also addressable as the first 16
> memory locations.  You could even put code in the registers and
> jump to them, for a speed boost.

OK, I did not know that one, but I think it is a bit of a borderline
case: the registers are stored in memory, so as a consequence they can
be addressed indirectly  (much like the 990/9900).

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\24@143604 by Peter

picon face
Wouter van Ooijen <wouter <at> voti.nl> writes:

>
> > The only reason to have strong types is when one is very tight on space
and/or
> > time and wants total control on data size, stack depth etc. In all other
cases
> > ths is not needed.
>
> The main reason for (strict) type checking is to catch errors as early
> as possible: better caught during compilation that during testing.
>
> Loosely typed languages do have some use. I am a big an of Python, but I
> often wished it had some form of type checking, especially on parameters.

Compiler errors are not a replacement for linting. Use a linter and a
highlighting source editor (I assume you already do that).

As anyone who wrote a program longer than 1000 lines knows, programming is
mostly about keeping the number of errors small enough to be fixable at any
given stage of the programming process. You said some time ago that you do not
like C because it is not very helpful to point out where you made a mistake in
its /compiler/ error messages. Using a highlighting editor will likely help you
put the correct number of braces and brackets in and that will help a proper
linter to point out the errors before you run the compiler.

I am not aware of any of the larger compiler ide packages having a built in
linter. Wrong ? (none of Borland C++ Builder, Eclipse, kdevelop or Sun
netbeans/mobility have one). Please correct me if I am wrong.

I have used lclint and splint (see also clint) before, with good success. It
tends to point out a lot if interesting things. That and the C profiling book
from O'Reilly (High Performance Computing) will go a long way towards a good
start at writing reasonably good portable C. There is also weblint and tidyhtml
for web pages (those asp people should be made to use it all the time ...).

I once wanted to extend lclint with embedded C extensions but it is too much of
a hassle. I just #declare'd the relevant keywords as voids in the linted source.

Peter


2008\10\24@151130 by Wouter van Ooijen

face picon face
>> Loosely typed languages do have some use. I am a big an of Python, but I
>> often wished it had some form of type checking, especially on parameters.
>
> Compiler errors are not a replacement for linting. Use a linter and a
> highlighting source editor (I assume you already do that).

I never used a linter, and I mostly use simple text editors. Do linters
exist for Python??

> You said some time ago that you do not
> like C because it is not very helpful to point out where you made a mistake in
> its /compiler/ error messages.

You do have a good memory!

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\24@153510 by Bob Ammerman

picon face
>> DEC PDP-10; the registers were also addressable as the first 16
>> memory locations.  You could even put code in the registers and
>> jump to them, for a speed boost.
>

IBM 1130: The 3 INDEX registers (but not the accumulator) were in memory and
could be addressed that way, including Indexing the Index registers.... :-)

-- Bob Ammerman


2008\10\24@160116 by Peter

picon face
Olin Lathrop <olin_piclist <at> embedinc.com> writes:
> Chris Emerson wrote:
> > It's not specified directly, I think, but the called function doesn't
> > necessarily know how many parameters were passed in (eg printf).
>
> I'm not familiar enough in C to remember how variable number of arguments
> are handled in the language, but wouldn't that need to be described somehow
> in the routine declaration?  If so, the comipler could use different passing
> conventions for routines that accept variable number of arguments.
>
> Even if not, I can think of other means of supporting variable number of
> arguments than requiring caller cleaned stack.

The C implementations always use caller cleans stack convention. Better
compilers allow one to choose at compile time, per subroutine (C call
convention or Pascal call convention). The variable arity function I gave as
an example in another posting ( foo( int arg, ... ); <- the three dots are
valid C syntax ) is the way it is implemented, e.g. there must be at least
one named argument of known type, and the caller takes it from there. Usually
this argument is the argument count proper. The callee must know the type of
each argument (at runtime). Basically C is a simple stack based machine, it
pushes arguments to a subroutine on the stack, then calls it.

function:

int foo( int bar, char *p ) {
 int b = 1;
 int x = 3,y; // useless variables

 ++p;

 return (x=b*3+2);
}

stack at function entry call time:

[(ptr_width)p] <- the next argument ...
[(int_width)bar] <- leftmost argument is ALWAYS the first one above the ret. a.
[return address] <- sp points past here

now the function saves sp and puts its local variables on the (same!) stack,
which will look like:

[p]
[bar]
[return addr]___________v function uses the stack below this line
[bx] <- subroutine saves bp, then does mov bp, sp
[b==1]
[x]
[y] <- sp points past here

;; subroutine code, x86ish conventions
foo:
 push bx ; save caller's bp
 mov bx, sp ; copy sp to access parameters on stack
 ; function arguments have positive offsets and local vars have negative ones
 movw ax,1 ; b local variable
 push ax
 movw ax, 3 ; x local var
 push ax
 push ax ; y local var, uninitialized

;; ++p
 incw [bx-offset(p)]

;; inside compiled code for return(x=y=b*3+2)
;; this is totally unoptimized code
;; b
 push offset(b)
 call fetch ; stack arithmetic evaluator, fetch b, consume address
;; 3
 pushw 3 ; stack 3
;; *
 call mulw ; multiply top 2 stack elements, leave one result on stack
;; 2
 pushw 2 ; put 2 on stack
;; +
 call addw ; add top 2 elements, consume one, leave result on top

;; now the rhs part of the argument of return() is on the stack
;; x=...
 push offset(x) ; prepare to assign x
 call assign ; consume address at top of stack and copy next element to x=
;; y=...
 push offset(y) ; prepare to assign y
 call assign ; same as above, y=

;; now we are ready to return, put the value at the top of the stack
;; in a predetermined register and then restore the old sp and return

pop ax ; this is the return value
mov sp, bx ; point stack at (just below) saved bx
pop bx
ret ; with result in ax

note that there are ways to return data wider than the accumulator by leaving
it on the stack (overwriting the local variables just after the saved bp). this
is necessary on machines that have a narrow word size (e.g. pics and not only)
that wish to implement wide pointers. Typically the widest return type equals
the widest register width available to pass the data in, but the stack can be
used to make it as wide as necessary, regardless of the register (d,q)word
width.

You can read more about it here (among other places):

http://www.nasm.us/doc/nasmdoc9.html
http://www.codeproject.com/KB/cpp/calling_conventions_demystified.aspx

For compiler flags that switch the C/Pascal style cleanup see __cdecl and
__stdcall on Google. Borland has these (I assume M$ also has them). On *nix
foobaring the call convention will result in nonfunctional code, the usual
standard is the one established by Intel with their iBCS2 which specifies just
this (the function call interface). There are other specs for kernel calls
however.

other:
http://www.linuxjournal.com/article/2809

Peter


2008\10\24@160741 by Peter

picon face
Tamas Rudnai <tamas.rudnai <at> gmail.com> writes:

> > Would you (in the case you sketch) sleep well with a stack allocated
> > based on your assumption?

"stack allocation" is really bad news for any program that heavily relies on
recursion to do its job. In this case it may be better to have a stack that
grows upwards because the size of the heap can be predicted better than the size
of the stack. I have had programs that went several tens of millions of
recusions deep on x86 32 bits. I do not know why they worked :) For most normal
heap/stack assumptions they should have failed. Apparently having virtual memory
and a stack segment that lives in its own vm space is vey helpful ...

Peter


2008\10\24@164820 by peter green

flavicon
face

> I'm not familiar enough in C to remember how variable number of arguments
> are handled in the language, but wouldn't that need to be described somehow
> in the routine declaration?  
NO! you don't have to specify anything about a routines parameter list
in the declaration. In fact you don't actually have to
declare them at all! (doing so is a bad idea because the behaviour when
a parameter list is not given can be somewhat counterintuitive)

It does of course have to be specified in the routines definition but
that may be in a different "compilation unit" and therefore not
availible to the compiler.

2008\10\24@164909 by Isaac Bavaresco

flavicon
face
--- Em qui, 23/10/08, Olin Lathrop <RemoveMEolin_piclistspamspamBeGoneembedinc.com> escreveu:

> ...
> On the PIC 18 there are separate data and return address
> stacks, so this is
> not a issue.  I didn't realize that all C functions are
> allowed to be called
> with different number of arguments.  Is this really the
> case?  To me this
> seems like a really brain dead choice considering that
> fixed number of
> ...

The problem with C is that the compiler relies only on the function prototypes to check for argument types and number. The prototypes are usually kept in header files ("*.h"), which are source (text) files. If the header file is changed one can foil the compiler and say the function takes any type and number of arguments he wants.

Hi-Tech PICC has an interesting approach: It embeds in the object files a magic number (signature) that says what type and number of arguments it takes and what type it returns. Then the linker catches such errors.

Most compilers will allow you to call a function without a protype accepting any arguments you give it, but then it issues a warning.

Pascal has a good approach with the Units, that include together the code and the prototypes for everything.

Regards,

Isaac


     Novos endereços, o Yahoo! que você conhece. Crie um email novo com a sua cara @ymail.com ou @rocketmail.com.
http://br.new.mail.yahoo.com/addresses

2008\10\24@173104 by Bob Ammerman

picon face
>> I'm not familiar enough in C to remember how variable number of arguments
>> are handled in the language, but wouldn't that need to be described
>> somehow
>> in the routine declaration?
> NO! you don't have to specify anything about a routines parameter list
> in the declaration. In fact you don't actually have to
> declare them at all! (doing so is a bad idea because the behaviour when
> a parameter list is not given can be somewhat counterintuitive)
>
> It does of course have to be specified in the routines definition but
> that may be in a different "compilation unit" and therefore not
> availible to the compiler.

The good news: Most modern "C" compilers can generate a warning if you
attempt to call a function without having a prototype in scope.
The bad news: you have to be sure that the prototype in scope matches the
one actually used when defining the function.
The good news: the compiler will complain if you define a function
differently than an in-scope prototype.

So, IMNSHO....

Always prototype all your functions in appropriate header files.
Include the header file in every module that defines or uses any of the
functions defined therein.
Enable whatever 'missing prototype' warning might be available in your
compiler.
DON'T USE VARIABLE ARGUMENT LISTS!

If you do this, then "C" will be almost as smart as Pascal in making sure
you don't screw yourself :-)

---Bob Ammerman
RAm Systems

2008\10\24@181947 by peter green

flavicon
face

>
> "stack allocation" is really bad news for any program that heavily relies on
> recursion to do its job. In this case it may be better to have a stack that
> grows upwards because the size of the heap can be predicted better than the size
> of the stack. I have had programs that went several tens of millions of
> recusions deep on x86 32 bits. I do not know why they worked :)
IIRC windows dynamically grows the stack if the application runs off the
end of it and there is a pretty big chunk of address space availible for
it to grow into.

2008\10\24@184800 by olin piclist

face picon face
William Chops" Westfield" wrote:
>> I certainly don't know any other CPU architecture that has indexed
>> access to its registers!
>
> DEC PDP-10; the registers were also addressable as the first 16
> memory locations.

Same with dsPICs.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\24@185318 by olin piclist

face picon face
Peter wrote:
> Compiler errors are not a replacement for linting.

Why not?  Since you are running lint you obviously want to catch these
errors.  How would having this capability built into the compiler not solve
the same problem and more simply.

> Use a linter

The fact that lint even exists proof of inadequate compiler.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\24@205149 by John La Rooy

flavicon
face
On Sat, Oct 25, 2008 at 6:10 AM, Wouter van Ooijen <spamBeGonewouterKILLspamspam@spam@voti.nl> wrote:

>
> I never used a linter, and I mostly use simple text editors. Do linters
> exist for Python??
>
Yes. pylint and pychecker

You can also turn on a code coverage tool when you run your unit tests.

John

2008\10\25@055222 by Gerhard Fiedler

picon face
Isaac Bavaresco wrote:

>> On the PIC 18 there are separate data and return address stacks, so this
>> is not a issue.  I didn't realize that all C functions are allowed to
>> be called with different number of arguments.  Is this really the case?
>>  To me this seems like a really brain dead choice considering that
>> fixed number of ...
>
> The problem with C is that the compiler relies only on the function
> prototypes to check for argument types and number. The prototypes are
> usually kept in header files ("*.h"), which are source (text) files. If
> the header file is changed one can foil the compiler and say the
> function takes any type and number of arguments he wants.

But only the compiler. The linker will still only link your call with a
function definition that fits the call signature.

> Hi-Tech PICC has an interesting approach: It embeds in the object files a
> magic number (signature) that says what type and number of arguments it
> takes and what type it returns. Then the linker catches such errors.

I think this is basically how all C compilers/linkers work. You can compile
your source with any old prototype you want, but when you want to link an
executable, you need to provide object files that contain the function
definitions for exactly the prototypes you used.

> Pascal has a good approach with the Units, that include together the code
> and the prototypes for everything.

A problem with this approach may be that you have to distribute source code
for every library you sell. FWIW, a number of C compilers are taking this
approach for optimizations: they read whatever is available as source and
use the knowledge from this to change how the individual source files are
compiled.

Gerhard

2008\10\25@061423 by Tamas Rudnai

face picon face
>> Pascal has a good approach with the Units, that include together the code
>> and the prototypes for everything.
>
> A problem with this approach may be that you have to distribute source
code
> for every library you sell.

No, you don't. You do not have to give away the implementation section, only
the interface one. Take a look at this example from the freePascal
documentation (it contains both sections but once you compiled your unit you
can cut off the implementation...):

{$mode objfpc}
unit testprop;

Interface

Function GetMyInt : Integer;
Procedure SetMyInt(Value : Integer);

Property
 MyProp : Integer Read GetMyInt Write SetMyInt;

Implementation

Uses sysutils;

Var
 FMyInt : Integer;

Function GetMyInt : Integer;

begin
 Result:=FMyInt;
end;

Procedure SetMyInt(Value : Integer);

begin
 If ((Value mod 2)=1) then
   Raise Exception.Create('MyProp can only contain even value');
 FMyInt:=Value;
end;

end.


Tamas



On Sat, Oct 25, 2008 at 10:51 AM, Gerhard Fiedler <
listsspam_OUTspam@spam@connectionbrazil.com> wrote:

{Quote hidden}

> -

2008\10\25@062029 by Gerhard Fiedler

picon face
Peter wrote:

> "stack allocation" is really bad news for any program that heavily relies
> on recursion to do its job. In this case it may be better to have a
> stack that grows upwards because the size of the heap can be predicted
> better than the size of the stack.

How would this be better? If you have 4 GB of address space (32 bit) and
grow the heap from the bottom up and the stack from the top down (slightly
simplified), how would it be better to make the stack grow from the bottom
up, too?

Gerhard

2008\10\25@063049 by Gerhard Fiedler

picon face
Wouter van Ooijen wrote:

>> Compiler errors are not a replacement for linting. Use a linter and a
>> highlighting source editor (I assume you already do that).
>
> I never used a linter, and I mostly use simple text editors.

I'm not sure how simple is simple for you, but IMO one can gain a lot of
productivity with a good editor. There are a few decent free ones out
there, and also a few not so expensive ones. For whoever makes his living
(or part of it) with coding, spending even a few hundred USD on an editor
that helps save an hour a week is a very good investment.

Syntax highlighting I consider a very basic minimum for a source code
editor. Some means to display and jump to the definition and/or declaration
of a symbol is also important. Knowing the symbols in my symbol universe
(depending on the scope) and suggesting appropriate ones helps reduce
typing a lot and makes using meaningful names much easier. Code folding
helps with keeping the big picture in the eye. A regex-based grep-style
search and replace that can work over files in an editor project can be
quite useful (as editor projects). Project setups that can be stored in
editor config files make it easier to just jump into a project that I've
worked on months or years ago, and be right back in the setup I used when
working on it -- even if it's in a language that I haven't used since.

Gerhard

2008\10\25@064353 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

>> Compiler errors are not a replacement for linting.
>
> Why not?  Since you are running lint you obviously want to catch these
> errors.  How would having this capability built into the compiler not
> solve the same problem and more simply.

Rather than saying "compiler errors", I think this should be "compiler
warnings". With this substitution, I agree.

>> Use a linter
>
> The fact that lint even exists proof of inadequate compiler.

I think what you're seeing here is the Unix style of single-purpose
applications and tool chains rather than single, integrated tools.

A C compiler is (at least conceptually) not an end-to-end compiler that
receives source code and produces an executable (like e.g. Turbo Pascal
was). It is a tool chain that, at the minimum, includes a compiler and a
linker and which is typically controlled by a makefile (and the make
utility). In such a setup, adding a linter to the chain isn't anything that
would increase the complexity.

Seen from this angle, the linter's function is to make sure that everything
is according to your coding style. And the C compiler's function is to make
sure that everything is according to the C spec. And the linker's function
is to make sure everything needed is there and that a proper executable can
be created. Using the Unix application paradigm, this is not inadequate; it
is just how things are done.

Of course, many (especially Windows) setups are not like this. Make and
makefiles are replaced by compiler-built-in smarts, the different stages of
compiling and linking are hidden inside a single executable, the compiler
provides a number of warnings that have nothing to do with the C spec and
are moving towards linting... So why not build full-blown lint
functionality into the compiler?

Probably an economic decision, simply. It's not something that isn't there,
it's just not up to the same level in compilers as it is in dedicated
linters. It's the 80/20 rule at work: with the 20% of linting that are
built into the better compilers, they satisfy 80% of the users. To satisfy
the remaining 20%, they'd have to spend 5 times as much and implement the
remaining 80% of linting -- economically not attractive :)

Gerhard

2008\10\25@081813 by olin piclist

face picon face
> > I'm not familiar enough in C to remember how variable number of
arguments
> > are handled in the language, but wouldn't that need to be described
somehow
> > in the routine declaration?
> NO! you don't have to specify anything about a routines parameter list
> in the declaration.

Wow, C is even worse than I realized.  I can maybe forgive a couple of
hackers creating a quick and dirty language for their own use, but using C
for more real purposes is blatantly irresponsible programming.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\25@083623 by Peter

picon face
Olin Lathrop <olin_piclist <at> embedinc.com> writes:

> Peter wrote:
> > Compiler errors are not a replacement for linting.
>
> Why not?  Since you are running lint you obviously want to catch these
> errors.  How would having this capability built into the compiler not solve
> the same problem and more simply.
>
> > Use a linter
>
> The fact that lint even exists proof of inadequate compiler.

?!

A C compiler's purpose is to compile supposedly correct C source into object
code, not to find typos and missing braces. As others have noticed, C compiler
error messages are cryptic at best. This is because the compiler is actually a
tool in a chain that comprises the C preprocessor cpp, the compiler, and the
linker.

The fact that the compiler can (but must not - more refined make scripts call
each tool in turn) invoke all three tools does not make it a linter. Finding
errors in the source is simply not the compiler's job. Often it can't figure out
the error location because it has to 'look' behind at what the preprocessor did
and it is not possible for it to do that, as cpp's purpose is to add and delete
lines and modify strings and text in the source following compilation time
flags. The normal toolchain is:

<source.c cpp | cc | ld >a.out

cc and cpp on unix invoke the other tools as a convenience for simple programs.
They refuse to work like that and require a make script for more complex cases.

Peter


2008\10\25@084016 by Peter

picon face
Gerhard Fiedler <lists <at> connectionbrazil.com> writes:

>
> Peter wrote:
>
> > "stack allocation" is really bad news for any program that heavily relies
> > on recursion to do its job. In this case it may be better to have a
> > stack that grows upwards because the size of the heap can be predicted
> > better than the size of the stack.
>
> How would this be better? If you have 4 GB of address space (32 bit) and
> grow the heap from the bottom up and the stack from the top down (slightly
> simplified), how would it be better to make the stack grow from the bottom
> up, too?

quoting myself: "because the size of the heap is more predictable than that of
the stack". Or, if you want, because the heap should be reallocated less often
than the stack.

Peter

2008\10\25@085733 by Peter

picon face
Olin Lathrop <olin_piclist <at> embedinc.com> writes:
> Wow, C is even worse than I realized.  I can maybe forgive a couple of
> hackers creating a quick and dirty language for their own use, but using C
> for more real purposes is blatantly irresponsible programming.

<G!!!!> Olin, you must do your citizen's duty and tell all these people stop
blowing tax money on these SUPERCOMPUTERS, each of which runs an os created by a
Finn and another 2-300 anarchic Libertarians and Communists. The os contains
about 3 million lines of C ...

http://news.cnet.com/2100-1001-884297.html
www.forbes.com/2005/03/15/cz_dl_0315linux.html
http://www.linuxdevices.com/news/NS6099969220.html

Quick, Olin, you must save the world.

<aside>I do not worship my screwdriver, but C and *nix have been the state of
the art operating system and systems implementation and programming language
respectively for the last 20 years and are still going strong. There are no
other languages besides C that I know, that will scale from an 8 bit $0.5 CPU
with 24 words of ram to machines installations that are large enough that one
needs a bike and an elevator to be able to get to the toilets in time.</aside>

As far as I know, no other language comes close to these features.

Peter


2008\10\25@091817 by olin piclist

face picon face
Peter wrote:
>> The fact that lint even exists proof of inadequate compiler.
>
> ?!

That should have been "exists is proof".

> A C compiler's purpose is to compile supposedly correct C source into
> object code, not to find typos and missing braces. As others have
> noticed, C compiler error messages are cryptic at best. This is
> because the compiler is actually a tool in a chain that comprises the
> C preprocessor cpp, the compiler, and the linker.

You are explaining how it is, but that has no bearing on how it could or
should be.

My point was more about the language definition than how the toolchain is
broken up.  In other words, with a properly defined language with sensible
synytax rules, there would be no point in a separate lint step because all
that would be caught as true language violations, which is something the
compiler would do by definition.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\25@091905 by Wouter van Ooijen

face picon face
>> NO! you don't have to specify anything about a routines parameter list
>> in the declaration.
>
> Wow, C is even worse than I realized.

No worse than assembly ;)

But note "you don't have to" - you *can* specify the number and type of
parameters, and all modern style guides make this mandatory.

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\25@092359 by olin piclist

face picon face
Peter wrote:
> <G!!!!> Olin, you must do your citizen's duty and tell all these
> people stop blowing tax money on these SUPERCOMPUTERS, each of which
> runs an os created by a Finn and another 2-300 anarchic Libertarians
> and Communists. The os contains about 3 million lines of C ...

Yes I know that's how things are.  I was talking about how they should be.

> There are no other languages besides C that I know,
> that will scale from an 8 bit $0.5 CPU with 24 words of ram to
> machines installations that are large enough that one needs a bike
> and an elevator to be able to get to the toilets in time.
>
> As far as I know, no other language comes close to these features.

A number of other languages could do that.  It is only the prominence of C
that has kept them from wider use.  I don't see how the syntax of most
compiled languages would prevent what you are talking about any more than C.
And besides, C does NOT scale all that nicely to small CPUs.  Once again, it
is only there because it is there, which is irrelevant when discussing how
things could be better as apposed to how they are.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\25@092939 by Tamas Rudnai

face picon face
> A C compiler is (at least conceptually) not an end-to-end compiler that
> receives source code and produces an executable (like e.g. Turbo Pascal
> was).

That was Turbo Pascal 3.0 only which was basically creating a COM fieformat
(hint: COM is not a fileformat, that is a plain binary). I was using
TurboPascal 3.0 on an Apple II Z-80 Softcard (made by Microsoft, and guess
what, used CP/M operating system).
>From Turbo Pascal 4.0 Borland introduced Units and therefore linkers and
libraries. That was a damn good development system by that time.

http://en.wikipedia.org/wiki/Turbo_Pascal

Tamas


On Sat, Oct 25, 2008 at 11:43 AM, Gerhard Fiedler <
spamBeGonelists@spam@spamconnectionbrazil.com> wrote:

{Quote hidden}

> -

2008\10\25@094111 by Tamas Rudnai

face picon face
> I do not worship my screwdriver, but C and *nix have been the state of
> the art operating system and systems implementation and programming
language
> respectively for the last 20 years and are still going strong. There are
no
> other languages besides C that I know, that will scale from an 8 bit $0.5
CPU
> with 24 words of ram to machines installations that are large enough that
one
> needs a bike and an elevator to be able to get to the toilets in time

So you are saying that there is no Pascal for PIC and there is no Delphi?
:-) Anyway, used by most people and being good are two different things.
Look at the operating systems, OS/2 was way better than Win95,
Linux/Unix/Xenix was also better - only one thing they did not have: good
marketing...

Tamas




On Sat, Oct 25, 2008 at 1:56 PM, Peter <RemoveMEplpeter2006EraseMEspamKILLspamyahoo.com> wrote:

{Quote hidden}

> -

2008\10\25@102431 by Dave Tweed

face
flavicon
face
Olin Lathrop wrote:
> > > I'm not familiar enough in C to remember how variable number of
> > > arguments are handled in the language, but wouldn't that need to
> > > be described somehow in the routine declaration?
> >
> > NO! you don't have to specify anything about a routines parameter
> > list in the declaration.
>
> Wow, C is even worse than I realized.  I can maybe forgive a couple
> of hackers creating a quick and dirty language for their own use, but
> using C for more real purposes is blatantly irresponsible programming.

Yeah, and using assembly language for any sort of commercial product,
embedded or otherwise, is downright criminal!

-- Dave Tweed

2008\10\25@130616 by Gerhard Fiedler

picon face
Tamas Rudnai wrote:

>>> Pascal has a good approach with the Units, that include together the
>>> code and the prototypes for everything.
>>
>> A problem with this approach may be that you have to distribute source
>> code for every library you sell.
>
> No, you don't. You do not have to give away the implementation section,
> only the interface one. Take a look at this example from the freePascal
> documentation (it contains both sections but once you compiled your unit
> you can cut off the implementation...):

[snipped code]

Ok, but how is this different from the C-style header and implementation
file process? Looks to me like it's pretty much the same.

Gerhard

2008\10\25@132447 by Gerhard Fiedler

picon face
Peter wrote:

>>> "stack allocation" is really bad news for any program that heavily relies
>>> on recursion to do its job. In this case it may be better to have a
>>> stack that grows upwards because the size of the heap can be predicted
>>> better than the size of the stack.
>>
>> How would this be better? If you have 4 GB of address space (32 bit) and
>> grow the heap from the bottom up and the stack from the top down (slightly
>> simplified), how would it be better to make the stack grow from the bottom
>> up, too?
>
> quoting myself: "because the size of the heap is more predictable than that of
> the stack". Or, if you want, because the heap should be reallocated less often
> than the stack.

Contrary to some others (not you :), I read what I reply to, so I have read
this. But I still don't see why this would be any different.

Again (so to speak quoting myself, with extras thrown in :): you have a
maximum of 4 GB address space. You start the stack at the top and grow
downwards. You start the heap at the bottom and grow upwards. The memory
manager allocates real memory to each of the two areas as needed and pages
out other memory to virtual memory on disk as needed. The problem comes
when the stack meets the heap -- and there's no difference whether the
stack would have grown from the bottom up; the address space is all used
up.

The only difference is that in reality either the stack or the heap would
have reached its limit earlier (when growing both in the same direction),
because you'd have to assign each one a certain size which may not coincide
with the exact runtime situation.

Or am I misunderstanding you?

Gerhard

2008\10\25@133253 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

> My point was more about the language definition than how the toolchain is
> broken up.  In other words, with a properly defined language with sensible
> synytax rules, there would be no point in a separate lint step because all
> that would be caught as true language violations, which is something the
> compiler would do by definition.

This is all correct, but lacks understanding of the history and purpose of
C and its specification. I've written this a few times before, and this
really would help you understand (not like!) C: C is not what you call a
high-level language, it's a reasonably portable machine language that was
designed to be able to implement operating systems of the time. Just
because it doesn't look like an assembler doesn't make it (conceptually)
anything else. This is why and how it was developed. The rest of its
features is due to improving some things while maintaining backwards
compatibility.

So, when you talk about error checking and linting and all that, the proper
comparison is assembly. It /is/ a step forward from assembly in this
respect.

Gerhard

2008\10\25@133806 by Gerhard Fiedler

picon face
Tamas Rudnai wrote:

> So you are saying that there is no Pascal for PIC and there is no Delphi?
> :-)

I think what he said is that so far nobody chose Delphi (or Pascal) for
both implementing a multi-user OS and a small program that fits into a 12F
PIC.

Actually, I don't know of any OS that is implemented in a Pascal dialect.
Is there one?

Gerhard

2008\10\25@135457 by Dr Skip

picon face
Only because of snobbery... otherwise BASIC would have been ported everywhere
and then you couldn't say that! ;)


Peter wrote:
> There are no
> other languages besides C that I know, that will scale from an 8 bit $0.5 CPU
> with 24 words of ram to machines installations that are large enough that one
> needs a bike and an elevator to be able to get to the toilets in time.</aside>
>
> As far as I know, no other language comes close to these features.

2008\10\25@140600 by Vitaliy

flavicon
face
Olin Lathrop wrote:
> using C for more real purposes is blatantly irresponsible programming.

:-)

2008\10\25@142927 by Mongol Herdsman

picon face
Peter wrote:
> I used jit as "late binding/bytecode compilation/just in time compilation". The
> larger part of the net does not run on m$ servers but on unix and company and
> asp is often supported by cross tools and emulation thereon. The larger part of
> backends are Perl PHP4 Ruby on Rails, Python and Java based. Asp plays a certain
> role on certain commercial servers.
>
> See for yourself: http://news.netcraft.com/archives/web_server_survey.html

According to your link Market Share for Apache is 52% and Microsoft
platform is 35%.
35% Market Share certainly is not "Asp plays a certain role on certain
commercial servers".

Read in the doc:
"Many of the new Apache sites are hosted at ThePlanet.com, which alone
saw growth of 2.6 million sites.
As has been the trend for the past few months, hundreds of thousands
of the new sites at ThePlanet.com
are link farms hosted on Polish (.pl) domain names and contain little
more than pornographic text links to
other sites within the same domain.

We were talking about "compiled vs interpreted" aspects of serious
sites, zillions pornographic and other
scam Apache-based sites usually do not require programming at the
level when "compiled vs interpreted"
aspects plays role.

And all these millions personal blogs based on some template do not
require programming at all.

And, I beleive, not all corporate servers were reached by Netcraft in
its survey, say banks and large businesses.
Also you should take into accont multi-billion intranet software
ASP.NET market based on MS Windows.

So when it comes to more or less serious business programming not just
porno or social sites, ASP.NET
will take much more than 35% Market Share.

2008\10\25@144012 by Peter

picon face
Gerhard Fiedler <lists <at> connectionbrazil.com> writes:
> The only difference is that in reality either the stack or the heap would
> have reached its limit earlier (when growing both in the same direction),
> because you'd have to assign each one a certain size which may not coincide
> with the exact runtime situation.

As far as I understand it the os caches that map from virtual to real pages need
to work much harder when there is a huge gap in the address space of the
program. I am not sure how it's really done. And it's not necessarily 4G, it can
be a 64 bit machine. The way I understand it, the stack has its own permissions
(non executable among others, to avoid certain attacks) and its own segment, so
it is/can be a whole 4G on a 32 bit machine.

Peter

2008\10\25@145045 by Mongol Herdsman

picon face
Olin Lathrop wrote:
> Peter wrote:
>> Use a linter
>
> The fact that lint even exists proof of inadequate compiler.

"Linter" is not the same as "lint". Guys, do not be sloppy with terms
when pretending to talk techy.

2008\10\25@155325 by William \Chops\ Westfield

face picon face

On Oct 25, 2008, at 6:23 AM, Olin Lathrop wrote:

>> As far as I know, no other language comes close to these features.
>
> A number of other languages could do that.  It is only the  
> prominence of C
> that has kept them from wider use.

The evolution of C has been interesting.  These "other languages" you  
mention mostly started at about the same time as C, but somehow failed  
to "catch on" to nearly the same extent.  Turbo Pascal pre-dated Turbo-
C, and the early state of C compilers for non-unix systems was  
basically awful.  And yet, here we are...

I think I blame the simplicity of C for its success.  While "standard  
pascal" was a pretty useless beast, and you needed "proprietary  
extensions" to make it useful, C was so *bare* that you could move it  
anywhere.  No standard libraries, no I/O capabilities in the language  
itself; you could just plunk C right on top of whatever operating  
systems calls your computer or CPU happened to support (and many did,  
and early multi-OS C programs are incomprehensible constructs of  
conditional compilation (and it's not clear to me that the current  
open source "./configure" business is much better!)

So C showed up and flourished on MSDOS, 68000, CPM, DecSystem20, and  
on and on, while the Pascal folk (just for example) were still arguing  
about whether Borland or Apollo was heading in the right direction...

BillW

2008\10\25@182636 by olin piclist

face picon face
Gerhard Fiedler wrote:
> Actually, I don't know of any OS that is implemented in a Pascal
> dialect.

Apollos Domain/OS definitely was, and I sortof remember a early Apple OS was
too.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\25@192847 by Tamas Rudnai

face picon face
> Apollos Domain/OS definitely was, and I sortof remember a early Apple OS
was
> too.

Yes, from Apple Lisa through the first MacOS till the 9 I think Pascal was
the main development environment - as far as I know even for the kernel &
API. Also one can wonder why old Windows APIs had the pascal call
convention?

Tamas



On Sat, Oct 25, 2008 at 11:26 PM, Olin Lathrop <spamBeGoneolin_piclistspam_OUTspamRemoveMEembedinc.com>wrote:

{Quote hidden}

> -

2008\10\26@092527 by Gerhard Fiedler

picon face
Peter wrote:

>> The only difference is that in reality either the stack or the heap
>> would have reached its limit earlier (when growing both in the same
>> direction), because you'd have to assign each one a certain size which
>> may not coincide with the exact runtime situation.
>
> As far as I understand it the os caches that map from virtual to real
> pages need to work much harder when there is a huge gap in the address
> space of the program. I am not sure how it's really done. And it's not
> necessarily 4G, it can be a 64 bit machine. The way I understand it, the
> stack has its own permissions (non executable among others, to avoid
> certain attacks) and its own segment, so it is/can be a whole 4G on a 32
> bit machine.

FWIW, I think both the C heap and stack are in the same segment, but I'm
not an expert on memory allocation techniques. I assumed a 32-bit machine
for simplicity of discussion, but the question remains the same (and
independent of the segmentation techniques used).

I don't understand why you think the memory requirements would be less or
easier to fulfill if the stack grew upwards. I mean... if you need 1GB of
heap and 4GB of stack, you need 5GB of memory, no matter in which direction
the stack grows. ??

Gerhard

2008\10\26@093539 by Gerhard Fiedler

picon face
Tamas Rudnai wrote:

>>> Actually, I don't know of any OS that is implemented in a Pascal
>>> dialect.
>>
>> Apollos Domain/OS definitely was, and I sortof remember a early Apple
>> OS was too.
>
> Yes, from Apple Lisa through the first MacOS till the 9 I think Pascal
> was the main development environment - as far as I know even for the
> kernel & API. Also one can wonder why old Windows APIs had the pascal
> call convention?

So it seems there was a start, long ago, so it's not the lack of seeds.
What happened? Why did Apple abandon Pascal?

Gerhard

2008\10\26@114904 by olin piclist

face picon face
Gerhard Fiedler wrote:
> So it seems there was a start, long ago, so it's not the lack of
> seeds. What happened? Why did Apple abandon Pascal?

I think C mostly gained the popularity it did because it tagged along with
Unix.

I also think there are way too many programmers out there are lazy or
immature and think C is easier because it doesn't impose any discipline on
them.  In the end it costs way more, but hey, they got the initial program
hacked out quickly without all that annoying type checking and such.  Think
back to the 1980s when C gained most of its popularity.  There was much less
focus on good programming methods then than now.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\26@115128 by Tamas Rudnai

face picon face
> So it seems there was a start, long ago, so it's not the lack of seeds.
> What happened? Why did Apple abandon Pascal?

I have no clue, maybe it is easier to get C programmers nowadays + the
because of the increased computing speed and cheap storage the faster and
smaller pascal calling convention is not that important anymore? 10-15 years
ago it was so 'cool' to say 'real programmer is not programming in Pascal'.
I think that was one of the reason Borland calls Object Pascal as Delphi.

Anyway, I think C has many good things as a language but overall I loved
programming in Pascal while just using C as earning my food. Same as with
Apple II - I loved that machine, that was brilliant, then I had to swap to
IBM XT and later on to AT as I needed some money to bring home...

Tamas


On Sun, Oct 26, 2008 at 1:35 PM, Gerhard Fiedler <.....listsspamRemoveMEconnectionbrazil.com
{Quote hidden}

> -

2008\10\26@175628 by Gerhard Fiedler

picon face
Tamas Rudnai wrote:

>> So it seems there was a start, long ago, so it's not the lack of seeds.
>> What happened? Why did Apple abandon Pascal?
>
> I have no clue, maybe it is easier to get C programmers nowadays + the
> because of the increased computing speed and cheap storage the faster
> and smaller pascal calling convention is not that important anymore?
> 10-15 years ago it was so 'cool' to say 'real programmer is not
> programming in Pascal'. I think that was one of the reason Borland calls
> Object Pascal as Delphi.

I don't know about this... Turbo Pascal had an /extremely/ good name in its
day, much better than any C environment at the time. IIRC, after Turbo
Pascal came out, programming in Pascal was downright "hot" (and "cool" at
the same time :)
_________________________________

Olin wrote:
> I think C mostly gained the popularity it did because it tagged along
> with Unix.

How does this explain its popularity with the 8-bit micros? That was
generally an area that wasn't heavily influenced by Unix, I think.

> I also think there are way too many programmers out there are lazy or
> immature and think C is easier because it doesn't impose any discipline
> on them.  

I haven't met any who would think like this; IME C is not more a target for
lazy programmers than anything else. FWIW, just like assembly (but to a
lesser degree), programming decently in C requires more discipline than
"higher" level languages.

Gerhard

2008\10\26@181638 by olin piclist

face picon face
Gerhard Fiedler wrote:
>> I think C mostly gained the popularity it did because it tagged along
>> with Unix.
>
> How does this explain its popularity with the 8-bit micros? That was
> generally an area that wasn't heavily influenced by Unix, I think.

The popularity came first.  C compilers were created for micros later
because C was already so popular.

>> I also think there are way too many programmers out there are lazy or
>> immature and think C is easier because it doesn't impose any
>> discipline on them.
>
> I haven't met any who would think like this

You lead a sheltered life ;-)


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\26@200151 by sergio masci

flavicon
face


On Sun, 26 Oct 2008, Olin Lathrop wrote:

{Quote hidden}

That may be true for a small percentage but there are other reasons why
there are a lot of bad programmers around. One of these reasons is lack of
experience. Take a HW eng and track his carear. I'm sure you will find
that he will start off making many mistakes and as his experience grows,
the mistakes will drop. He learns what works and what doesn't. Regardless
of what he has been taught his experience reinforces his own style.
Mistakes stear him away from what wont work and success gives him
confidence that what he is doing is right - but that doesn't necessarilly
make it right, it just isn't so wrong that it wont work.

It's the same with programming. When you get programs working this gives
you confidence that what you are doing is right. It's only after years of
struggling with debugging and maintanence that you learn that there are
different levels of "right". Being tought how to breakdown a problem into
a sequence of instructions teachs you how write a program, but years of
writing programs teachs you how to write programs well.

It doesn't mater what the programming language, or the methodology is,
programs written by a novice will usually stink. It's experience that
counts.

>  In the end it costs way more, but hey, they got the initial program
> hacked out quickly without all that annoying type checking and such.  Think
> back to the 1980s when C gained most of its popularity.  There was much less
> focus on good programming methods then than now.

But who is doing the focusing? Could it be that "the powers that be" want
to employ monkeys instead of expensive experienced programmers?

Regards
Sergio Masci

2008\10\26@232245 by William \Chops\ Westfield

face picon face

>> I also think there are way too many programmers out there are lazy  
>> or immature and think C is easier because it doesn't impose any  
>> discipline on them.

There is a short distance between "imposes discipline" and "makes it  
unreasonably difficult to do the sorts of things I want to do."  We've  
already admitted that "standard" pascal as originally documented is  
essentially useless; unfortunately, a LOT of the "stronger" languages  
seem to fall into that category.  The architects were so busy working  
on the language itself, and preventing programmer errors that they  
forget about the things that make a language generally useful: speed  
of compilation, size of objects, ability to use 3rd party libraries  
written in other languages, keeping up-to-date with library and OS  
changes, running on more than one host, running for more than one  
target, interface to debuggers, interface to 3rd party static,  
dynamic, and performance analysis tools, and so on and on.
C has remain relatively constant and multi-platform for so long that  
the tools that have grown up around it push it ahead of most  
competition even though the language is week.

I supposed we can blame Borland and Apollo; they had useful pascals  
quite early in the game, but didn't pursue standardization or multiple  
targets.  I can't think of all that many other languages that ever got  
beyond single vendors (more or less.  I mean, there was smalltalk that  
got some exposure.  Alas; a fine example of what I was talking about  
above in terms of not being very "practical.")

BillW

2008\10\26@234115 by Vitaliy

flavicon
face
Mongol Herdsman wrote:
>>> Use a linter
>>
>> The fact that lint even exists proof of inadequate compiler.
>
> "Linter" is not the same as "lint". Guys, do not be sloppy with terms
> when pretending to talk techy.

What's the difference, in this context?


2008\10\26@234428 by Vitaliy

flavicon
face
Tamas Rudnai wrote:
>> So it seems there was a start, long ago, so it's not the lack of seeds.
>> What happened? Why did Apple abandon Pascal?
>
> I have no clue, maybe it is easier to get C programmers nowadays

This begins to sound like a circular argument.

Vitaliy

2008\10\27@065250 by olin piclist

face picon face
William Chops" Westfield" wrote:
> I supposed we can blame Borland and Apollo; they had useful pascals
> quite early in the game, but didn't pursue standardization or multiple
> targets.  I can't think of all that many other languages that ever got
> beyond single vendors

Again, my modified version of Apollo Pascal is available to anyone for free.
It has run on Domain/OS, 4 different flavors of Unix, and Windows.  That's
how I routinely program on Windows today.  The source to source translator,
SST, is included in the everything release at
http://www.embedinc.com/pic/dload.htm.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2008\10\27@080237 by Gerhard Fiedler

picon face
William "Chops" Westfield wrote:

> I supposed we can blame Borland and Apollo; they had useful pascals  
> quite early in the game, but didn't pursue standardization or multiple  
> targets.  

Right... At a point, Turbo Pascal was the market leader in PC programming
environments, long before people even thought of programming anything in C
on the PC. They simply blew it.

> I can't think of all that many other languages that ever got beyond
> single vendors (more or less.  I mean, there was smalltalk that got some
> exposure.  Alas; a fine example of what I was talking about above in
> terms of not being very "practical.")

I always wonder why Forth didn't get more exposure. At least for
stack-based micros, it seemed to be a logical choice, combining the
advantages of a compiled C-style environment with an interpreted Basic-like
environment.

Gerhard

2008\10\27@081005 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

>>> I think C mostly gained the popularity it did because it tagged along
>>> with Unix.
>>
>> How does this explain its popularity with the 8-bit micros? That was
>> generally an area that wasn't heavily influenced by Unix, I think.
>
> The popularity came first.  C compilers were created for micros later
> because C was already so popular.

I'm not sure this is true. IIRC, programming in C on the PC wasn't all that
popular; the original MS-DOS came with Basic, not C. Then Turbo Pascal
came, and for a few years it was /the/ programming environment for the PC
(besides Basic, of course). Only then C started to become popular with the
PC crowd.

Of course it was known for a long time, and popular among Unix guys, but in
the 80ies Unix was something like a mainframe OS, nothing for the masses :)

>>> I also think there are way too many programmers out there are lazy or
>>> immature and think C is easier because it doesn't impose any
>>> discipline on them.
>>
>> I haven't met any who would think like this
>
> You lead a sheltered life ;-)

I don't think so. It's just that IMO C isn't a typical target for a lazy
programmer; there are other languages that don't blow up so easily, that
provide more interactive support, etc. From your stance, it seems more like
you have only experience with bad C programmers :)

Gerhard

2008\10\27@092757 by Alan B. Pearce

face picon face
>>> Could it be that making this distinction between subroutines and
>>> functions is a Pascal-ism -- and not that not making it is a C-ism? :)
>>
>> The distinction is common to many languages.
>
>So what? That doesn't make it more basic than not distinguishing them
> -- there are also many languages that don't.
...
>Assembly came before all of these, and in assembly, a function call
>and a subroutine call are the same. We could shoot examples back and
>forth all night long, but the fact remains that you claimed that this
>distinction is somehow something fundamental in computing science,

Quite frankly I always found the distinction confusing. Why have two
different names for what is essentially the same thing? OK, so one returns a
value, and the other doesn't. So what? Why call them different names?

And then there is the Visual Basic oddity where if you want to pass a value
to a subroutine, it has to be a function, because VB insists it has to
return a value ...

2008\10\27@103459 by Wouter van Ooijen

face picon face
> Quite frankly I always found the distinction confusing. Why have two
> different names for what is essentially the same thing? OK, so one returns a
> value, and the other doesn't. So what? Why call them different names?

Maybe the word function should be reserved for pure functions (only 'in'
parameters, no side effects). All other subroutines should be called,
subroutines? procedures? Now we have to convince the C, C++, and some
other standard commitees. Volunteers?

--

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu

2008\10\27@140434 by Gerhard Fiedler

picon face
Wouter van Ooijen wrote:

>> Quite frankly I always found the distinction confusing. Why have two
>> different names for what is essentially the same thing? OK, so one returns a
>> value, and the other doesn't. So what? Why call them different names?
>
> Maybe the word function should be reserved for pure functions (only 'in'
> parameters, no side effects). All other subroutines should be called,
> subroutines? procedures? Now we have to convince the C, C++, and some
> other standard commitees. Volunteers?

That's then a change for pretty much all languages... AFAIK even a Pascal
function is allowed to access (and modify) global variables or variables of
the enclosing scope.

Also, there may be functions (in your sense) that return two or more
related values, so the "only 'in' parameters" requirement may not make that
much sense.

I'm not sure where you want to go with this, but it seems to me that a "no
side effects" assurance would be where you're headed. However, this is
difficult to enforce for a compiler. What about read access to memory (or
memory mapped hardware)? While that often doesn't have any side effects,
sometimes it does.

What's the purpose of this?

Gerhard

Display limited to first 300 matches. Add keywords to narrow the result set or browse by year:
- In 2008 , 2009 only
- Today
- New search...