 |
 |
|
 |
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Compare these two psuedocode snippets:
To compute SUM(LIST):
1. Let TOTAL = 0.
2. Let POSITION = first node of LIST.
3. Let TOTAL = TOTAL + value at POSITION.
4. Let POSITION = next node after POSITION.
5. If POSITION is not the end of the list, go to step 3.
And now, the Other Way:
1. If LIST is the empty list then SUM(LIST) is defined as 0.
2. Otherwise, SUM(LIST) is defined as the first element of LIST +
SUM(rest of LIST).
Personally, several things strike me here.
1. The first version seems a very long and wordy way of explaining
something that (to a human) is actually quite simple.
2. The second version is very much shorter. (And simpler?)
3. The second version looks like some kind of a riddle. Not a hard
riddle, but a somewhat baffling definition all the same.
I think it neatly demonstrates the fundamental difference in the mental
model between imperative and functional programming though. Even a
layman who knows nothing about programming would (I suspect) appriciate
that these two methods are pretty different. (And without having to go
into a long lecture about how computers work, how to program in any
specific language, etc.)
Anybody else have anything to add?
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
How about another algorithm?
------------------------------------------------------
A NODE contains a VALUE entry, which holds a number, and the entries
CHILD0 and CHILD1, which either point to a NODE or point to nothing.
ADD(X, ROOT):
1. If ROOT points to nothing then
1. Let OUT = a new NODE.
2. Let OUT.VALUE = X.
3. Return OUT.
2. If ROOT.VALUE < X then
1. Let Y = ROOT.VALUE
2. Let T = ROOT.CHILD0.
2. Let ROOT.VALUE = X.
3. Let ROOT.CHILD0 = ADD(Y, ROOT.CHILD1).
4. Let ROOT.CHILD1 = T.
5. Return ROOT.
else
1. Let T = ROOT.CHILD0.
2. Let ROOT.CHILD0 = ADD(X, ROOT.CHILD1).
3. Let ROOT.CHILD1 = T.
4. Return ROOT.
------------------------------------------------------
Data of type HASH is either 'NODE' with a NUMBER value called VALUE and
a HASH value named CHILD0 and a HASH value named CHILD1, or 'NULL'.
ADD(X, NULL) = HASH (VALUE = X, CHILD0 = NULL, CHILD1 = NULL)
ADD(X, NODE A B) = HASH (VALUE = if X < Y then Y else X, CHILD0 = ADD(if
X < Y then X else Y, B), CHILD1 = A)
------------------------------------------------------
Notice: First program is long and thin. Second program is short and fat.
(My, my... line wrapping!)
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Orchid XP v7 <voi### [at] dev null> wrote:
> 1. If LIST is the empty list then SUM(LIST) is defined as 0.
> 2. Otherwise, SUM(LIST) is defined as the first element of LIST +
> SUM(rest of LIST).
OTOH, you don't define what "rest of LIST" means.
> Anybody else have anything to add?
I still like the definition of "connected" in the New Zealand go rules:
"Two stones of the same colour are connected if they are on adjacent
intersections or if they are both connected to a third stone."
Even most functional programmers have hard time understanding that
correctly the first time they see it.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> Compare these two psuedocode snippets:
>
> To compute SUM(LIST):
> 1. Let TOTAL = 0.
> 2. Let POSITION = first node of LIST.
> 3. Let TOTAL = TOTAL + value at POSITION.
> 4. Let POSITION = next node after POSITION.
> 5. If POSITION is not the end of the list, go to step 3.
>
> And now, the Other Way:
>
> 1. If LIST is the empty list then SUM(LIST) is defined as 0.
> 2. Otherwise, SUM(LIST) is defined as the first element of LIST +
> SUM(rest of LIST).
>
> Personally, several things strike me here.
>
> 1. The first version seems a very long and wordy way of explaining
> something that (to a human) is actually quite simple.
>
> 2. The second version is very much shorter. (And simpler?)
>
> 3. The second version looks like some kind of a riddle. Not a hard riddle,
> but a somewhat baffling definition all the same.
>
> I think it neatly demonstrates the fundamental difference in the mental
> model between imperative and functional programming though. Even a layman
> who knows nothing about programming would (I suspect) appriciate that
> these two methods are pretty different. (And without having to go into a
> long lecture about how computers work, how to program in any specific
> language, etc.)
>
> Anybody else have anything to add?
Neither of these ways is how you would do it if you weren't using a
computer.
By hand you would add up the digits in the first column making carry marks,
and get the rightmost digit of the answer and work your way left, column by
column. If there were several pages worth, you'd probably make sub-totals,
then add those up later. Those psuedocode examples are just describing
real code someone had already thought up, so it's not surprising that you
can
tell which way they were thinking. Are you describing a process or an
algorithm?
1. divide the list into manageable sub-lists (pages)
2. add up the sub-lists and get sub-totals
3. add up the sub-totals and get the sum of the list
vrs
1. 0 for an empty list
2. number for a list with 1 number
3. number+number for a list with 2 numbers
4. sum of the first half of list + sum of the second half of list,
for a list with at least 3 numbers.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Tim Attwood <tim### [at] comcast net> wrote:
> 1. divide the list into manageable sub-lists (pages)
> 2. add up the sub-lists and get sub-totals
> 3. add up the sub-totals and get the sum of the list
> vrs
> 1. 0 for an empty list
> 2. number for a list with 1 number
> 3. number+number for a list with 2 numbers
> 4. sum of the first half of list + sum of the second half of list,
> for a list with at least 3 numbers.
I think those require random access, which is not available for linked
lists.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> To compute SUM(LIST):
> 1. Let TOTAL = 0.
> 2. Let POSITION = first node of LIST.
> 3. Let TOTAL = TOTAL + value at POSITION.
> 4. Let POSITION = next node after POSITION.
> 5. If POSITION is not the end of the list, go to step 3.
>
> And now, the Other Way:
>
> 1. If LIST is the empty list then SUM(LIST) is defined as 0.
> 2. Otherwise, SUM(LIST) is defined as the first element of LIST +
> SUM(rest of LIST).
>
> Personally, several things strike me here.
>
> 1. The first version seems a very long and wordy way of explaining
> something that (to a human) is actually quite simple.
>
> 2. The second version is very much shorter. (And simpler?)
You made it simpler, I can make the first one simpler too :-)
1. If LIST is not the empty list, then SUM(LIST) is defined as the result of
adding up the value at each node of LIST
> 3. The second version looks like some kind of a riddle. Not a hard riddle,
> but a somewhat baffling definition all the same.
And seems unnecessarily complex. Why bother going through splitting lists
and passing them to recursive functions, when all you really need to do is
loop through all entries and add up the numbers?
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott <sco### [at] laptop com> wrote:
> You made it simpler, I can make the first one simpler too :-)
> 1. If LIST is not the empty list, then SUM(LIST) is defined as the result of
> adding up the value at each node of LIST
I can make it even simpler:
1. SUM(LIST) = the sum of the values of all nodes in LIST
In some imperative languages that can be written as something along the
lines of:
sum = 0;
foreach(element in list) sum += element;
(In some languages even the first line can be omitted if its default
behavior is that undeclared integral variables are automatically created
and initialized to 0.)
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> 1. If LIST is not the empty list, then SUM(LIST) is defined as the result
>> of
>> adding up the value at each node of LIST
>
> I can make it even simpler:
>
> 1. SUM(LIST) = the sum of the values of all nodes in LIST
What would be the point of defining sum if you already had a sum function to
use?
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott wrote:
>> 2. The second version is very much shorter. (And simpler?)
>
> You made it simpler, I can make the first one simpler too :-)
I was thinking in terms of how you would literally write the source code
in imperative and functional languages.
var total = 0;
var position = list.start();
while (position != null)
{
total = total + position.get_value();
position = position.get_next();
}
Pretty much a verbatim match there.
>> 3. The second version looks like some kind of a riddle. Not a hard
>> riddle, but a somewhat baffling definition all the same.
>
> And seems unnecessarily complex. Why bother going through splitting
> lists and passing them to recursive functions, when all you really need
> to do is loop through all entries and add up the numbers?
And of course, accessing parts of a list requires splitting them, and
recusion isn't looping. ;-)
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp wrote:
> OTOH, you don't define what "rest of LIST" means.
I also don't define what "end of LIST" means either. But then, I don't
define what a "list" is at all, so...
>> Anybody else have anything to add?
>
> I still like the definition of "connected" in the New Zealand go rules:
>
> "Two stones of the same colour are connected if they are on adjacent
> intersections or if they are both connected to a third stone."
>
> Even most functional programmers have hard time understanding that
> correctly the first time they see it.
Makes perfect sense to me - but then, I'm a maths nerd... ;-)
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> 1. divide the list into manageable sub-lists (pages)
> 2. add up the sub-lists and get sub-totals
> 3. add up the sub-totals and get the sum of the list
> vrs
> 1. 0 for an empty list
> 2. number for a list with 1 number
> 3. number + number for a list with 2 numbers
> 4. sum of the first half of list + sum of the second half of list,
> for a list with at least 3 numbers.
> I think those require random access, which is not available for linked
> lists.
I'm not sure that "list" always means linked list in a
functional language, they're optimized into arrays
behind the curtain, and you're not free to change
the link pointers because they're treated as static
(at least in Haskell).
The first one is very loosely defined, it doesn't
say what is manageable, it doesn't say how to
add those chunks together, or in what order. It's
easy to imagine processing it in parallel, or reading
numbers from a file in chunks, then adding them up
sequentially as you go along, or if manageable means
two at a time, it could identical to Andrew's.
The second describes an algorithm, not the data
structures needed to implement it. It's probably
too specific in parts, and very unspecific about
how to determine where to split the list in half,
or differences in performance between using it
for boxed or unboxed number types.
There's nothing overwhelmingly "functional biased"
about a recursive algorithm, but providing a
description of the desired results and then letting the
rest sort itself out probably is. That's not always a
good thing, machine code is imperative so every
bit of code is describing actions, the separation of
function from actions is artificial.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
I added a couple of lines:
function sum(list)
> var total = 0;
> var position = list.start();
> while (position != null)
> {
> total = total + position.get_value();
> position = position.get_next();
> }
return total
end
> Pretty much a verbatim match there.
OK, so for your "Other Method" we have:
function sum(list)
if( list.start() == NULL )
return 0
else
return list.get_value() + sum(list.get_next())
endif
end
> And of course, accessing parts of a list requires splitting them, and
> recusion isn't looping. ;-)
I suspect the recursion method is slower, because calling a function has
some overheads (storing and recalling registers and return address on stack
etc).
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott wrote:
> I added a couple of lines:
OK, fair enough.
> OK, so for your "Other Method" we have:
>
> function sum(list)
> if( list.start() == NULL )
> return 0
> else
> return list.get_value() + sum(list.get_next())
> endif
> end
Or, alternatively,
sum [] = 0
sum (x:xs) = x + sum xs
as we say in Haskell. The English translation was attempting to preserve
the structure without actually using Haskell language syntax. But either
way, you get the idea.
The important thing is you don't say "if the list is empty then *return*
0", you say "if the list is empty then total is *defined as* 0". That's
the main difference. (And yes, it's a conceptual difference rather than
an implementation difference. And that's kind of what I wanted to
hilight - without going into a long technical debate.)
>> And of course, accessing parts of a list requires splitting them, and
>> recusion isn't looping. ;-)
>
> I suspect the recursion method is slower, because calling a function has
> some overheads (storing and recalling registers and return address on
> stack etc).
Not when the compiler can detect tail recursion and transform it into a
normal loop structure automatically.
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> Not when the compiler can detect tail recursion and transform it into a
> normal loop structure automatically.
So actually, you had the same thought to start with (I want to sum all the
elements) and the end result is the same assembly code. So the only real
point is if you find writing out and thinking about the first solution
easier than the second or not. In your own words:
"3. The second version looks like some kind of a riddle. Not a hard
riddle, but a somewhat baffling definition all the same."
So why on Earth bother with the riddle in the first place?
Here's a couple of changes you can try to make to the Haskell version:
1) Modify the code so that it stores the sum up to each element in that
element.
2) Modify the code so that it sums up nodes in a tree structure, starting
from any child.
In the 1st version, it's very easy to implement. For 1) you just add:
position.sumToHere = total
in the loop.
For 2), you change the position = line to:
position = position.GetParent()
All very intuitive, requiring little modification to the sum function.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott wrote:
> So actually, you had the same thought to start with (I want to sum all
> the elements) and the end result is the same assembly code. So the only
> real point is if you find writing out and thinking about the first
> solution easier than the second or not. In your own words:
>
> "3. The second version looks like some kind of a riddle. Not a hard
> riddle, but a somewhat baffling definition all the same."
>
> So why on Earth bother with the riddle in the first place?
If all you're trying to do is sum all the elements in a list, neither
approach has a really compelling advantage or disadvantage. I used it as
an example of a simple task that anybody can easily understand, and used
it to illustrate the difference in mentallity between the two approaches.
> Here's a couple of changes you can try to make to the Haskell version:
>
> 1) Modify the code so that it stores the sum up to each element in that
> element.
Uh, OK.
sums xs = sums' 0 xs
where
sums' t [] = [t]
sums' t (x:xs) = t : sums' (t+x) xs
Takes a list of numbers, returns a list of intermediate sums. The first
element is always 0, the last element is always the total sum of the
entire list.
> 2) Modify the code so that it sums up nodes in a tree structure,
> starting from any child.
Erm... I don't really understand what you mean.
> All very intuitive, requiring little modification to the sum function.
Similarly, in Haskell I can define a single function that iterates over
a list, and then write 1-linears that will find the sum / product /
minimum / maximum of the list, or the logical AND / OR of a list of
booleans, or concatenate a list of lists, or... All very intuitive and
easy to write once you have the iteration function.
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> If all you're trying to do is sum all the elements in a list, neither
> approach has a really compelling advantage or disadvantage. I used it as
> an example of a simple task that anybody can easily understand, and used
> it to illustrate the difference in mentallity between the two approaches.
I guess the difference would be in more complex examples then, when both the
human C++ coder and the Haskell compiler have to work harder to get
efficient code.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible <voi### [at] dev null> wrote:
> > I still like the definition of "connected" in the New Zealand go rules:
> >
> > "Two stones of the same colour are connected if they are on adjacent
> > intersections or if they are both connected to a third stone."
> >
> > Even most functional programmers have hard time understanding that
> > correctly the first time they see it.
> Makes perfect sense to me - but then, I'm a maths nerd... ;-)
Does it? Can you give me several varied examples of connected stones,
as well as examples where two stones are *not* connected according
to this definition?-)
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott wrote:
>> If all you're trying to do is sum all the elements in a list, neither
>> approach has a really compelling advantage or disadvantage. I used it
>> as an example of a simple task that anybody can easily understand, and
>> used it to illustrate the difference in mentallity between the two
>> approaches.
>
> I guess the difference would be in more complex examples then, when both
> the human C++ coder and the Haskell compiler have to work harder to get
> efficient code.
If all you're after is the ultimate machine efficiency, C can probably
still do that better than almost any other language, given enough skill.
But what about factors such as code size, readability, maintainability,
code reuse, polymorphism, etc etc etc?
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible <voi### [at] dev null> wrote:
> sum [] = 0
> sum (x:xs) = x + sum xs
Don't you love it how complicated something like this looks in C++:
template<typename Iterator>
typename std::iterator_traits<Iterator>::value_type
sum(Iterator begin, Iterator end)
{
typedef typename std::iterator_traits<Iterator>::value_type t;
t result = t();
while(begin != end) result += *begin++;
return result;
}
Its advantage, though, is that it works with *any* container type
as long as it has sequential iterators, and *any* value type, as long
as it supports the + operator. So you can do for example like this:
int table[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
int result = sum(table, table+8);
or like this:
std::string table[] = { "a", "b", "cde", "f" };
std::string result = sum(table, table+8);
or like this:
std::vector<double> table(100);
// init the vector
double result = sum(table.begin(), table.end());
or like this:
std::list<std::complex<double> > l;
// init the list
std::complex<double> result = sum(l.begin(), l.end());
or like this:
std::set<std::string> s;
// init the set
std::string result = sum(s.begin(), s.end());
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible wrote:
> If all you're after is the ultimate machine efficiency, C can probably
> still do that better than almost any other language, given enough skill.
... on a machine whose architecture is well-matched to C. And given
enough skill.
A COBOL interpreter in C isn't going to be nearly as fast as a COBOL
interpreter in microcode. (Yes, btdt. :-) It's going to be hard to beat
one clock cycle per byte for an "edit byte string" (similar to "print
using" in BASIC) using a C function.
A FORTH chip is going to run FORTH way faster than it'll run the same
algorithm written in a way that looks like reasonable C, I expect.
Put 128 cores on a chip connected in a hypernet, and you're going to
have a heck of a time writing an efficient sort algorithm in C for that.
Put a big pile of SIMD processors together, and you're not going to be
able to program it in C at all. APL maybe, but not C.
C makes a whole pile of assumptions about processor architecture that
most people don't notice because most processors they use have evolved
to account for what C does. But the assumptions are there.
--
Darren New / San Diego, CA, USA (PST)
"That's pretty. Where's that?"
"It's the Age of Channelwood."
"We should go there on vacation some time."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> If all you're after is the ultimate machine efficiency, C can probably
> still do that better than almost any other language, given enough skill.
>
> But what about factors such as code size, readability, maintainability,
> code reuse, polymorphism, etc etc etc?
Yeh you're right, maybe MS wrote Vista in Haskell ;-)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp wrote:
> Invisible <voi### [at] dev null> wrote:
>> sum [] = 0
>> sum (x:xs) = x + sum xs
>
> Don't you love it how complicated something like this looks in C++:
>
> template<typename Iterator>
> typename std::iterator_traits<Iterator>::value_type
> sum(Iterator begin, Iterator end)
> {
> typedef typename std::iterator_traits<Iterator>::value_type t;
> t result = t();
> while(begin != end) result += *begin++;
> return result;
> }
>
> Its advantage, though, is that it works with *any* container type
> as long as it has sequential iterators, and *any* value type, as long
> as it supports the + operator.
Mine works for *any* type that supports the + operator too. ;-)
As for other collection types... Well you could construct something in
Haskell, but curiosly nobody bothers. The general method seems to be to
write functions for transforming your collection into or out of a list,
and then using the existing list processing functions.
That used to seem like a pretty strange idea to me. Now I realise that
with function inlining + constructor specialisation + unboxing + stream
fusion + assorted other stuff, the resulting machine code is more or
less the same as if the list functions operated directly on the
collection anyway.
In a sense, a list really *is* a loop in Haskell. When you turn
something into a list, you're not so much creating a list object as
performing a loop over the data.
The big problem of course is that all list functions are inherantly
single-threaded (since linked lists are sequential access only). I hear
they're working on a new library of parallel array manipulation
functions. [Apparently some guy is even targetting it to nVidia's CUDA
architecture for his PhD thesis!] But none of that stuff actually works
yet...
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott wrote:
>> If all you're after is the ultimate machine efficiency, C can probably
>> still do that better than almost any other language, given enough skill.
>>
>> But what about factors such as code size, readability,
>> maintainability, code reuse, polymorphism, etc etc etc?
>
> Yeh you're right, maybe MS wrote Vista in Haskell ;-)
Maybe if they *had* written it in Haskell it would have come to market
much faster, cheaper, and it would have actually *worked* properly. :-P
OK, joking aside, I present the following seriously weird fact:
Half the developers working on Haskell are Micro$oft employees.
I can't begin to imagine in what universe that even makes sense - M$ is
pushing F#, not Haskell. So why...? WTF...? Besides, M$ is renowned to
promoting low-quality badly-written software. Why would they care about
a high-quality language like Haskell? It all makes no sense...
I present a second fact, which only seems weird considering the first one:
The majority of non-trivial Haskell code doesn't work properly on
Windoze. Only Linux. Or maybe Mac OS. But not Windoze.
So M$ are paying people to develop stuff that doesn't even propperly
support M$'s own flagship product...? OK, I'm completely lost now!
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> Half the developers working on Haskell are Micro$oft employees.
Who's the other one working for then? ;-)
> I can't begin to imagine in what universe that even makes sense - M$ is
> pushing F#, not Haskell. So why...? WTF...?
MS is a big company, they don't just write OSs.
http://research.microsoft.com/research/default.aspx
> The majority of non-trivial Haskell code doesn't work properly on
> Windoze. Only Linux. Or maybe Mac OS. But not Windoze.
Why is that? Is it a problem with the Windows compiler?
> So M$ are paying people to develop stuff that doesn't even propperly
> support M$'s own flagship product...? OK, I'm completely lost now!
Who knows, maybe parts of the next MS OS will be written using a functional
language? I'm sure they are investigating such possibilities, they can't
afford not to.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible <voi### [at] dev null> wrote:
> Mine works for *any* type that supports the + operator too. ;-)
Does it work for things like balanced binary trees, double-ended queues,
arrays and strings (ie. sum the ascii values of the characters in a string)?
In other words, does it work for all possible containers which items you
can iterate over?
No, I'm not saying that with the proper language it wouldn't be possible
to make such a function as a short one-liner. I'm just curious to know if
Haskell is such a language.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp wrote:
> Invisible <voi### [at] dev null> wrote:
>> Mine works for *any* type that supports the + operator too. ;-)
>
> Does it work for things like balanced binary trees, double-ended queues,
> arrays and strings (ie. sum the ascii values of the characters in a string)?
> In other words, does it work for all possible containers which items you
> can iterate over?
The implementation I posted works only for lists. (And this - or
something equivilent to it - is what the standard library actually
contains.)
> No, I'm not saying that with the proper language it wouldn't be possible
> to make such a function as a short one-liner. I'm just curious to know if
> Haskell is such a language.
It would be perfectly possible to define a class that allows the
iteration of arbitrary collections. But such a thing is not currently
present in the standard libraries.
As I say, it seems the currently "accepted way" is to define a
transformation from any iteratable structure into a list, and then apply
list-specific operations there. The compiler seems to be rather good at
removing the apparent overhead with this method.
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott wrote:
>> Half the developers working on Haskell are Micro$oft employees.
>
> Who's the other one working for then? ;-)
>:-[
(This isn't my happy face.)
Actually, they work for various universities.
>> I can't begin to imagine in what universe that even makes sense - M$
>> is pushing F#, not Haskell. So why...? WTF...?
>
> MS is a big company, they don't just write OSs.
No, they write flawed software of many kinds. (Or just buy it from other
people.) Still not sure why they'd be interested in software that makes
it easier to write *quality* software - where's the profit in that?
>> The majority of non-trivial Haskell code doesn't work properly on
>> Windoze. Only Linux. Or maybe Mac OS. But not Windoze.
>
> Why is that? Is it a problem with the Windows compiler?
The only "working" Haskell compiler runs off GNU build tools such as
gcc, gas and ld. It also uses automake and Perl. (WTF-overload.)
Most of the things that don't work on Windoze are Haskell bindings to C
libraries. Anything that's 100% Haskell works flawlessly on all
platforms, but linking to C is fiddly. I'm told you need to install a
Unix emulator such as Cygwin to make it work - which obviously I have no
intension of doing.
>> So M$ are paying people to develop stuff that doesn't even propperly
>> support M$'s own flagship product...? OK, I'm completely lost now!
>
> Who knows, maybe parts of the next MS OS will be written using a
> functional language? I'm sure they are investigating such
> possibilities, they can't afford not to.
Heh. I doubt it.
(Not that you care, but there *is* in fact a Haskell OS. But it's a
research project rather than something end-users would be interested in.
I didn't think it was even in active development any more, but
apparently there are people still working on it...)
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible escribió:
> scott wrote:
>>> Half the developers working on Haskell are Micro$oft employees.
>>
>> Who's the other one working for then? ;-)
>
> >:-[
>
> (This isn't my happy face.)
http://icanhascheezburger.com/2008/03/06/funny-pictures-mah-happi-face/
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible wrote:
>
> Maybe if they *had* written it in Haskell it would have come to market
> much faster, cheaper, and it would have actually *worked* properly. :-P
>
And delivered years later ;). If they had written it in Haskell, they'd
actually had to rewrite it from the scratch (I'm pretty sure they've
reused lots of code from earlier versions). Bye-bye for old bugs, yes.
Welcome for new bugs, also yes.
--
Eero "Aero" Ahonen
http://www.zbxt.net
aer### [at] removethis zbxt net invalid
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> Maybe if they *had* written it in Haskell it would have come to market
>> much faster, cheaper, and it would have actually *worked* properly. :-P
>
> And delivered years later ;). If they had written it in Haskell, they'd
> actually had to rewrite it from the scratch (I'm pretty sure they've
> reused lots of code from earlier versions). Bye-bye for old bugs, yes.
> Welcome for new bugs, also yes.
Well, I'm told they rewrote a lot of it already, but yeah, you're
probably right...
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible wrote:
>>
>> And delivered years later ;). If they had written it in Haskell,
>> they'd actually had to rewrite it from the scratch (I'm pretty sure
>> they've reused lots of code from earlier versions). Bye-bye for old
>> bugs, yes. Welcome for new bugs, also yes.
>
> Well, I'm told they rewrote a lot of it already, but yeah, you're
> probably right...
>
Surely yes, lots and lots of new code (hence lots and lots of new
bugs;). But as far as I understand economic world of programming, it can
easily be cheaper to loan (working) code from earlier version than
rewrite from scratch (eg. some tiny applications that don't actually
change - that would mean rewriting the *same* code again, which is
simply stupid).
--
Eero "Aero" Ahonen
http://www.zbxt.net
aer### [at] removethis zbxt net invalid
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Eero Ahonen escribió:
> Invisible wrote:
>>>
>>> And delivered years later ;). If they had written it in Haskell,
>>> they'd actually had to rewrite it from the scratch (I'm pretty sure
>>> they've reused lots of code from earlier versions). Bye-bye for old
>>> bugs, yes. Welcome for new bugs, also yes.
>>
>> Well, I'm told they rewrote a lot of it already, but yeah, you're
>> probably right...
>>
>
> Surely yes, lots and lots of new code (hence lots and lots of new
> bugs;).
They re-wrote the network stack, and on initial betas, apparently they
had re-introduced bugs that had been fixed in Win95. (like a ping packet
forged to look like it came *from* 127.0.0.1 caused a kernel-mode
infinite loop, locking up the system badly)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Nicolas Alvarez wrote:
>
> They re-wrote the network stack, and on initial betas, apparently they
> had re-introduced bugs that had been fixed in Win95. (like a ping packet
> forged to look like it came *from* 127.0.0.1 caused a kernel-mode
> infinite loop, locking up the system badly)
History repeats itself :).
--
Eero "Aero" Ahonen
http://www.zbxt.net
aer### [at] removethis zbxt net invalid
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Eero Ahonen wrote:
> Nicolas Alvarez wrote:
>>
>> They re-wrote the network stack, and on initial betas, apparently they
>> had re-introduced bugs that had been fixed in Win95. (like a ping
>> packet forged to look like it came *from* 127.0.0.1 caused a
>> kernel-mode infinite loop, locking up the system badly)
>
> History repeats itself :).
Or "Micro$oft still hasn't learned how to write a network stack properly
even after 10 years", whichever you prefer...
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott wrote:
>> Half the developers working on Haskell are Micro$oft employees.
>
> Who's the other one working for then? ;-)
Some obscure medical lab in the UK, I heard...
--
Darren New / San Diego, CA, USA (PST)
"That's pretty. Where's that?"
"It's the Age of Channelwood."
"We should go there on vacation some time."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |