POV-Ray : Newsgroups : povray.off-topic : My first C++ program Server Time
30 Sep 2024 21:29:50 EDT (-0400)
  My first C++ program (Message 120 to 129 of 149)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>
From: andrel
Subject: Re: A test
Date: 22 Sep 2008 17:38:18
Message: <48D81094.5040401@hotmail.com>
On 22-Sep-08 23:16, Darren New wrote:
> andrel wrote:
>> My point was always the other way around: does Haskell allow you to 
>> introduce concepts and control structures that from that point on will 
>> become conceptually 'part of the language' for you? 
> 
> No, I don't think it does. I don't think it's possible to write "case" 
> or "let" in Haskell. That's kind of the point.  I think you're taking 
> "reserved words" to mean the same as "meaningful concepts."  I'm talking 
> from the point of view of someone building a compiler or something, not 
> from someone conceptualizing about an application.
> 
>> To the extent that for you they behave like 'reserved words'. 
> 
> I don't care what it behaves like in my brain. I care what happens when 
> it compiles.

OK, so there is where we part. I don't want to think about hardware or 
compiler issues when I am solving a problem. (except when I end up 
writing a compiler of course). I want to express my thoughts in as clear 
a way as possible. If the language does not give me the freedom to 
express myself as I think is the most clear, I'll try to extend the 
language. Just as when I am doing math and I feel that I should need to 
introduce a new syntax. Standard and new syntax will form my new 
framework. Whatever someone else at any one time though were his 
fundamental concepts is immaterial to me.

> 
>>> OK, maybe I misphrased it. How does the compiler distinguish the 
>>> variable name from the syntactic form that "case" currently 
>>> introduces in Haskell?  If "you don't", then it means your compiler's 
>>> behavior is unspecified when you use the word "case" as a variable. 
>>> People generally don't like compiler behavior to be unspecified for 
>>> valid programs.
>>
>> Normal scoping rules may apply.
> 
> Then it wouldn't be a reserved word, would it? :-)
> 
> I don't know if Haskell actually disallows the use of variables named 
> the same as "reserved words", but if it doesn't, then that's a reserved 
> word.
> 

Let me reiterate, I don't even care if Haskell allows it or not. The 
discussion was if Haskell should visually make the distinction or not. 
To which my answer is no, because what is and what isn't a reserved word 
is too arbitrary. i.e. some are legitimate reserved (most of your 
examples are from that stock), some are reserved but a case could be 
made to relieve them of that status and some are not reserved, but might 
be. So fuzziness all over, hence: do not treat them visually different.


Post a reply to this message

From: Warp
Subject: Re: A test
Date: 22 Sep 2008 18:07:18
Message: <48d81716@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> >   There just is something about the Haskell paradigm and syntax that
> > makes it confusing and hard to assimilate.

> I think most of the powerful languages have syntax that's confusing and 
> hard to assimilate. C and C++ are also very confusing in syntax. (For 
> example, I can barely follow the reference-counting pointer code you 
> posted, and that only because I am only trying to read it and not write 
> it. :-)

  OTOH, I assume his code was something relatively simple. Something you
would write when you are creating a simple and straightforward program.

  My reference counting pointer code uses rather advanced techniques
(related to, among other things, how allocators are used and how templates
behave) which are quite unusual in "normal" C++.

  One good thing in C++ is that usually you can *hide* all that overly
complicated and advanced code behind a simple and nice public interface,
so that the code which *uses* that code can be simple, straightforward
and easy to understand.

  With the Haskell examples I often get the feeling that the code which
I have hard time understanding is code which you write normally, when
implementing your main code, not some advanced techniques you hide behind
a nice module interface.

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: A test
Date: 22 Sep 2008 18:20:42
Message: <48d81a3a@news.povray.org>
Warp wrote:
>   OTOH, I assume his code was something relatively simple. Something you
> would write when you are creating a simple and straightforward program.

It was "guess a number from 1 to 100, and I'll tell you if you're too 
high or too low."  I don't imagine it would be any more straightforward 
in C or C++, really.  Sure, there were a couple of somewhat odd lines 
that you had to rely on English to understand, like
   case compare number target of
But I found that pretty easy to understand given what the rest of the 
program was doing. I might not have been able to write it or tell you if 
it was wrong/buggy, but I could read it OK.

Throw in the syntax of printf() or "cout << std::eoln" or whatever, and 
I think the syntax in something like C++ is certainly something you need 
to learn to read.

There are some languages (like Ada, for example) that do all that C++ 
does and more, but which use spelled-out words. That doesn't help too 
much when you don't know what the words mean. Telling you it's a limited 
tagged access type doesn't really tell you what it means any more than
   void xyz(void) = 0;
is comprehensible without knowing what it means.

>   My reference counting pointer code uses rather advanced techniques
> (related to, among other things, how allocators are used and how templates
> behave) which are quite unusual in "normal" C++.

OK. Question: I think I've figured out what some of your advice means...

When you say "don't use new", are you really saying "use the calls to 
new that are in the libraries, and you shouldn't have to do that 
yourself"? Or are you really saying "C++ programs rarely need to execute 
the 'new' operator"?

The former I can understand. The latter would seem really confusing to 
me, and I've been interpreting it as the latter, methinks.

>   One good thing in C++ is that usually you can *hide* all that overly
> complicated and advanced code behind a simple and nice public interface,
> so that the code which *uses* that code can be simple, straightforward
> and easy to understand.

Welll..... There's still a bunch of syntax. Template instantiation, << 
and >> for I/O, etc.  I mean, compare Haskell add-up-a-list-of-numbers 
to C++'s. Something like
   fold (+) my_list
to something like
   for (j = std::list.begin(); j != std::list.end(); j = j.next())
     i += j.value;
or some such. :-)

>   With the Haskell examples I often get the feeling that the code which
> I have hard time understanding is code which you write normally, when
> implementing your main code, not some advanced techniques you hide behind
> a nice module interface.

Agreed. I just think it's hard for you for a different reason than C++ 
is hard for Andrew. Haskell is hard to read because there's a lot of 
powerful stuff going on without enough syntax. C++ is hard to read 
because there's a lot of powerful stuff going on with too much syntax. 
If you're used to a lot of syntax, C++ might be easier to read than 
Haskell, and vice versa.

-- 
Darren New / San Diego, CA, USA (PST)


Post a reply to this message

From: Darren New
Subject: Re: A test
Date: 22 Sep 2008 18:45:55
Message: <48d82023$1@news.povray.org>
andrel wrote:
> OK, so there is where we part. I don't want to think about hardware or 
> compiler issues when I am solving a problem. 

Me neither. But someone has to. If you're using a language with reserved 
words, you're going to have to avoid them.

> Just as when I am doing math and I feel that I should need to 
> introduce a new syntax. Standard and new syntax will form my new 
> framework. Whatever someone else at any one time though were his 
> fundamental concepts is immaterial to me.

Yep. Then you should be using FORTH or LISP or Tcl or something like 
that, right? What language *do* you prefer? There aren't very many that 
let you introduce new syntax to the language.

In any case, you're still going to have to explain the new syntax, which 
means you're going to have to use a language comprehensible to your 
listeners. You can't just make up a new language from scratch and expect 
to be able to communicate with someone else, even if that other person's 
brain is flexible enough to learn it if taught it.

> Let me reiterate, I don't even care if Haskell allows it or not. The 
> discussion was if Haskell should visually make the distinction or not. 
> To which my answer is no, because what is and what isn't a reserved word 
> is too arbitrary. i.e. some are legitimate reserved (most of your 
> examples are from that stock), some are reserved but a case could be 
> made to relieve them of that status and some are not reserved, but might 
> be. So fuzziness all over, hence: do not treat them visually different.

OK. I'd say I'd want them treated differently if they actually are 
reserved. I.e., if I have a variable called "case", I'd want to see the 
statement starting
    case case of
to have two different color words, for example.

I take it you don't like syntax coloring in your editor?

-- 
Darren New / San Diego, CA, USA (PST)


Post a reply to this message

From: Warp
Subject: Re: A test
Date: 22 Sep 2008 19:50:06
Message: <48d82f2e@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> OK. Question: I think I've figured out what some of your advice means...

> When you say "don't use new", are you really saying "use the calls to 
> new that are in the libraries, and you shouldn't have to do that 
> yourself"? Or are you really saying "C++ programs rarely need to execute 
> the 'new' operator"?

> The former I can understand. The latter would seem really confusing to 
> me, and I've been interpreting it as the latter, methinks.

  It was not a generic advice for making C++ programs. It was an advice
for a *complete beginner* who is starting to learn the basics of the
language.

  It is obvious that at some point a C++ programmer will have to deal
with 'new' and memory management. However, IMO that can be left for later.
First get to know the program without the dirty details.

  Of course using managed memory is a good advice for all C++ programmers,
beginners and experts. Even experts should avoid raw pointers and 'new',
unless there's a good reason not to. When you *must* use them, then it's
good to follow certain programming practices.

> >   One good thing in C++ is that usually you can *hide* all that overly
> > complicated and advanced code behind a simple and nice public interface,
> > so that the code which *uses* that code can be simple, straightforward
> > and easy to understand.

> Welll..... There's still a bunch of syntax. Template instantiation, << 
> and >> for I/O, etc.  I mean, compare Haskell add-up-a-list-of-numbers 
> to C++'s. Something like
>    fold (+) my_list
> to something like
>    for (j = std::list.begin(); j != std::list.end(); j = j.next())
>      i += j.value;
> or some such. :-)

  At least the latter states more explicitly what you are doing.
(And by the way, you advance an iterator with the ++ operator.)

  In the haskell case, it's not at all clear what you are doing. In fact,
I don't even think that your haskell example is correct. I can't find the
function "fold", but the closest thing I can find is the (rather unclearly
named): http://www.zvon.org/other/haskell/Outputprelude/foldl1_f.html

  It seems that, as the name clearly implies, the difference between
foldl and foldl1 is that the first one applies the function to the
second parameter and the first element of the list, then applies the
function to the result and the second element of the list, and so on,
while foldl1 there's only a function and a list and the first element
of the list is now in the role of the second parameter to foldl.

  I think it would be perfectly possible to simulate the same thing in C++
with something like:

    int result = foldl1(plus, intContainer);

with proper implementations of the 'foldl1' and 'plus' templates. The
foldl function would be equally easy:

    int result = foldl(plus, 64, intContainer);

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: A test
Date: 22 Sep 2008 22:10:50
Message: <48d8502a$1@news.povray.org>
Warp wrote:
>   It was not a generic advice for making C++ programs. It was an advice
> for a *complete beginner* who is starting to learn the basics of the
> language.

Oh, I see. Well, the handling of assignment and copy constructors is the 
only bit that is particularly confusing to me, language-wise. I may not 
be an expert, but conceptually that's the only concepts I don't think I 
have down.

>>    fold (+) my_list
>> to something like
>>    for (j = std::list.begin(); j != std::list.end(); j = j.next())
>>      i += j.value;
>> or some such. :-)
> 
>   At least the latter states more explicitly what you are doing.

Ehn. The call to fold does too, if you know its definition. Just like if 
you don't know what std::list.begin() does, you're not going to 
understand the C++. Basically, the Haskell line is "put plus signs 
between the elements of my_list and evaluate the result."

>   In the haskell case, it's not at all clear what you are doing. In fact,
> I don't even think that your haskell example is correct. I can't find the
> function "fold", but the closest thing I can find is the (rather unclearly
> named): http://www.zvon.org/other/haskell/Outputprelude/foldl1_f.html

Well, "fold" is the mathematical term. If you worry about associativity 
and such, then you need foldl and foldr, and if you worry about what the 
identity for the operator is, then you use the foldl1 and such. I guess 
Haskell, unlike (say) Erlang, doesn't alias "fold" to one of those.

>   It seems that, as the name clearly implies, the difference between
> foldl and foldl1 is that the first one applies the function to the
> second parameter and the first element of the list, then applies the
> function to the result and the second element of the list, and so on,
> while foldl1 there's only a function and a list and the first element
> of the list is now in the role of the second parameter to foldl.

Yep! That's basically it. But in functional languages, things like fold 
and map and apply and such are used so often, they're as much an idiom as
   for (i = 0; i < j; i++)
is in C.

>   I think it would be perfectly possible to simulate the same thing in C++
> with something like:
> 
>     int result = foldl1(plus, intContainer);
> 
> with proper implementations of the 'foldl1' and 'plus' templates. The
> foldl function would be equally easy:
> 
>     int result = foldl(plus, 64, intContainer);

Yep. I think it could very easily be a function in C++, or even C if you 
want to specialize it every time.

-- 
Darren New / San Diego, CA, USA (PST)


Post a reply to this message

From: Orchid XP v8
Subject: Re: A test
Date: 23 Sep 2008 02:29:30
Message: <48d88cca$1@news.povray.org>
Warp wrote:

>   In the haskell case, it's not at all clear what you are doing. In fact,
> I don't even think that your haskell example is correct. I can't find the
> function "fold", but the closest thing I can find is the (rather unclearly
> named): http://www.zvon.org/other/haskell/Outputprelude/foldl1_f.html
> 
>   It seems that, as the name clearly implies, the difference between
> foldl and foldl1 is that the first one applies the function to the
> second parameter and the first element of the list, then applies the
> function to the result and the second element of the list, and so on,
> while foldl1 there's only a function and a list and the first element
> of the list is now in the role of the second parameter to foldl.

printf() is short for "print formatted".

foldl is "fold-left", while foldr is "fold-right". Similarly foldl1 and 
foldr1 only work for non-empty lists (and thus don't require a start 
value; foldr returns the start value unaltered in the case of an empty 
list). More subtle is foldl', which causes the subtotal to *actually 
compute* at each step, rather than just building a giant expression 
which is only evaluated right at the end.

The other name for a fold is "catamorphism", but we won't worry about 
that. ;-)

You can use folds for all kinds of interesting things. E.g., "foldr1 
max" finds the highest element of a list, and "foldr (++) []" takes a 
list of lists and returns a flatterned list. A huge number of standard 
list processing functions are or theoretically can be defined as folds. 
For example:

   filter p = foldr (++) [] . map (\x -> if p x then [x] else [])

That is, take a list. For every element where "p" returns true, make a 
1-element list, otherwise make an empty list. Now just the list of lists 
together...

Map itself can be similarly defined, as can reverse and lookup. In fact, 
just about any process that involves linearly traversing a list (i.e., 
almost all list processing!) can be implemented as a fold. This is quite 
possible not the most *efficient* implementation, but it demonstrates 
the power of the abstraction.

Many other Haskell datatypes also have "fold" functions too. It's a 
common idiom.

>   I think it would be perfectly possible to simulate the same thing in C++
> with something like:
> 
>     int result = foldl1(plus, intContainer);
> 
> with proper implementations of the 'foldl1' and 'plus' templates. The
> foldl function would be equally easy:
> 
>     int result = foldl(plus, 64, intContainer);

It sounds plausible to me...

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Mueen Nawaz
Subject: Re: A test
Date: 23 Sep 2008 11:22:57
Message: <48d909d1$1@news.povray.org>
Warp wrote:
>> Welll..... There's still a bunch of syntax. Template instantiation, << 
>> and >> for I/O, etc.  I mean, compare Haskell add-up-a-list-of-numbers 
>> to C++'s. Something like
>>    fold (+) my_list
>> to something like
>>    for (j = std::list.begin(); j != std::list.end(); j = j.next())
>>      i += j.value;
>> or some such. :-)
> 
>   At least the latter states more explicitly what you are doing.
> (And by the way, you advance an iterator with the ++ operator.)

	Yes, but imagine a conversation between two people. One of them says to 
the other:

1. Take a list of numbers.
2. Take the first element.
3. Add it to the variable i.
4. If you're not at the end of the list, take the next number and repeat 
step 3.

	As opposed to what Darren said:

"Take all the numbers, put a plus sign between them, and give me the 
result".

	I think the name functional programming is very apt. The latter is 
placing more emphasis on the "function" that we want (combining all the 
numbers to get a result).

	In Python, we have reduce, which is a simpler form of foldl (and 
perhaps a better name). Guido hates map, filter and reduce, but I love 
them. Sometimes I use a list comprehension or even an explicit for loop. 
But if in my mind it's "obvious" that what I want to do is a map or a 
reduce, then I write it that way.

	The reality is we don't *always* think procedurally. I'm sure even you 
in your head do occasionally think functionally. It's just that you're 
so used to converting that into a procedure that you don't notice it.

-- 
He's got a magnet!!!  Everybody BACKUP!!!!!!!!


                     /\  /\               /\  /
                    /  \/  \ u e e n     /  \/  a w a z
                        >>>>>>mue### [at] nawazorg<<<<<<
                                    anl


Post a reply to this message

From: Invisible
Subject: Re: A test
Date: 23 Sep 2008 11:25:24
Message: <48d90a64$1@news.povray.org>
Mueen Nawaz wrote:

>     In Python, we have reduce, which is a simpler form of foldl (and 
> perhaps a better name).

...except that the result of a fold can be another list. (And possible 
one that's larger than the original.)

>     The reality is we don't *always* think procedurally. I'm sure even 
> you in your head do occasionally think functionally.

Indeed.


Post a reply to this message

From: Fredrik Eriksson
Subject: Re: A test
Date: 23 Sep 2008 14:07:11
Message: <op.uhx4l9fs7bxctx@e6600>
On Tue, 23 Sep 2008 00:20:42 +0200, Darren New <dne### [at] sanrrcom> wrote:
> Welll..... There's still a bunch of syntax. Template instantiation, <<  
> and >> for I/O, etc.  I mean, compare Haskell add-up-a-list-of-numbers  
> to C++'s. Something like
>    fold (+) my_list
> to something like
>    for (j = std::list.begin(); j != std::list.end(); j = j.next())
>      i += j.value;
> or some such. :-)

'fold' (should probably be 'foldl1') is just a library function, not a  
language primitive. The corresponding C++ library function is  
'std::accumulate'.

   std::accumulate( my_list.begin(), my_list.end(), 0 );



-- 
FE


Post a reply to this message

<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.