 |
 |
|
 |
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> Yeah, I'm sure that happens. In fact, it's the kind of thing you see on
> the Daily WTF all the time. But, as everybody always points out, the
> *real* WTF is that MANAGEMENT FAILED TO ALLOCATE SUFFICIENT RESOURCES.
Management would say that the resources would be better used elsewhere (and
they are sometimes correct).
> Hey, maybe that's why we have this long, complex design process specified
> in the first place?" But, obviously, this did not happen.]
I guess that's another risk, if you have a hugely complex and long design
process with nobody checking it is being followed, then of course people are
going to avoid it.
> "Hmm, that'll be $25k + £81k + 137k EUR = 243, sir!"
HAHAHAHHA - best laugh so far today!
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> Yeah, I'm sure that happens. In fact, it's the kind of thing you see
>> on the Daily WTF all the time. But, as everybody always points out,
>> the *real* WTF is that MANAGEMENT FAILED TO ALLOCATE SUFFICIENT
>> RESOURCES.
>
> Management would say that the resources would be better used elsewhere
> (and they are sometimes correct).
Well, what should happen is that a project is either properly resourced,
or put off until such time as it can be properly resourced. The problem,
as you rightly point out, is when people demand impossible things and
get them rather than being told to take a walk.
[Indeed, I've seen a definite recurring theme of "promise the customer
absolutely anything to make them hand over their money, and worry about
whether it defies the known laws of physics later". Ultimately it is
again management's responsibility to make sure their salesmen don't do
this...]
>> Hey, maybe that's why we have this long, complex design process
>> specified in the first place?" But, obviously, this did not happen.]
>
> I guess that's another risk, if you have a hugely complex and long
> design process with nobody checking it is being followed, then of course
> people are going to avoid it.
This is the staggering thing.
This made a basic beginner's error. If anybody at my uni *ever* dared to
pull a stunt like this, they'd get their work *severely* down-marked.
[Usually anybody stupid enough to try this also sucks at programming, so
basically they get their work failed and have to start again.]
It blows my mind that we actually *got away* with this crap. There are
external auditors who should have spotted this one and had somebody
fired - and probably half the company shut down. Not doing what your
procedure documents say you're doing to do is a BIG DEAL to these
auditor types - even if in principle it doesn't "matter" as such. The
fact that you didn't do what the documents say *is* the problem.
>> "Hmm, that'll be $25k + £81k + 137k EUR = 243, sir!"
>
> HAHAHAHHA - best laugh so far today!
It is pretty hysterical, eh?
Now try ACTUALLY USING THIS SOFTWARE FOR A LIVING! >_<
For you, it's just some words on a page. For me, it's a daily reality.
This, surely, is enough to make a grown man cry... :'{
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> Management would say that the resources would be better used elsewhere
>> (and they are sometimes correct).
>
> Well, what should happen is that a project is either properly resourced,
> or put off until such time as it can be properly resourced.
What if postponing the project means a big loss in income/profit?
> [Indeed, I've seen a definite recurring theme of "promise the customer
> absolutely anything to make them hand over their money, and worry about
> whether it defies the known laws of physics later". Ultimately it is again
> management's responsibility to make sure their salesmen don't do this...]
And then you won't win any projects at all, because your competitors
salesman are doing this (even if just a little bit).
> For you, it's just some words on a page. For me, it's a daily reality.
Don't worry, I have more than my fair share of similar situations here.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>>> Management would say that the resources would be better used
>>> elsewhere (and they are sometimes correct).
>>
>> Well, what should happen is that a project is either properly
>> resourced, or put off until such time as it can be properly resourced.
>
> What if postponing the project means a big loss in income/profit?
Then it should be properly resourced. ;-)
Cost/benefit analysis. If this project is really that important, you
should be assigning resouces to it. If you can't do that, you can't have
the results. You don't get something for nothing...
>> [Indeed, I've seen a definite recurring theme of "promise the customer
>> absolutely anything to make them hand over their money, and worry
>> about whether it defies the known laws of physics later". Ultimately
>> it is again management's responsibility to make sure their salesmen
>> don't do this...]
>
> And then you won't win any projects at all, because your competitors
> salesman are doing this (even if just a little bit).
Well, then the other companies get a reputation for failing to deliver a
quality product, and you become known as the people who take slightly
longer but deliver something worth the money. :-D
Obvious counter-example: Micro$oft. But then, they have a monopoly in
almost all areas they trade in. Few others are so lucky.
>> For you, it's just some words on a page. For me, it's a daily reality.
>
> Don't worry, I have more than my fair share of similar situations here.
Heh. Seriously, adding up currency without performing a conversion
first? This stuff isn't exactly complicated. It's about the most basic
stuff there is!
Tell me, have you ever seen projects where they think "yeah, we'll
design and build the software, get it working, and then add security to
it later"? Every time I see this, unless it's a really trivial
application, I can practically *guarantee* that it won't work. Security
needs to be designed in from day #1. It's usually extremely hard to add
it later. I'd almost put *money* on that trick failing...
Obligatory QC reference:
http://www.questionablecontent.net/view.php?comic=926
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> Cost/benefit analysis. If this project is really that important, you
> should be assigning resouces to it. If you can't do that, you can't have
> the results. You don't get something for nothing...
Yeh you can, you just get the results but end up with buggy code that cannot
be reused very easily in future :-) From a managers point of view there is
no point in getting extra resource for no visible benefit.
> Well, then the other companies get a reputation for failing to deliver a
> quality product, and you become known as the people who take slightly
> longer but deliver something worth the money. :-D
That's fine for frequent short projects, but for infrequent or longer
projects (eg 5 years or so) unfortunately that never really happens. You
get new people, new supplier selection methods etc. Nokia worked like this,
in their supplier selection tables they had a column for "supplier
confidence" where exactly what you said was take account of. But they make
loads of phones the whole time, someone making cars or office blocks does so
far less frequently.
> Heh. Seriously, adding up currency without performing a conversion first?
> This stuff isn't exactly complicated. It's about the most basic stuff
> there is!
Try things like offering the customer some extra feature for $X, which they
accept, then a year later they change their mind and you say "oh, that costs
$X/2, we can take that much off the price". Just because the person
involved forgot what they said 1 year ago. Customer is not happy and then
requests detailed cost analysis of your whole product...
> Tell me, have you ever seen projects where they think "yeah, we'll design
> and build the software, get it working, and then add security to it
> later"?
Try, yeh we'll inform some dimensions off-the-cuff to the customer, then
think about design later. Or yeh we'll make the design and then think about
EMC and thermal performance later.
> Every time I see this, unless it's a really trivial application, I can
> practically *guarantee* that it won't work.
Ditto.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> Tell me, have you ever seen projects where they think "yeah, we'll
>> design and build the software, get it working, and then add security
>> to it later"?
>
> Try, yeh we'll inform some dimensions off-the-cuff to the customer, then
> think about design later. Or yeh we'll make the design and then think
> about EMC and thermal performance later.
>
>> Every time I see this, unless it's a really trivial application, I can
>> practically *guarantee* that it won't work.
>
> Ditto.
What, you mean you have to actually, like, design something to not
overheat in the first place? You can't just add some extra fans afterwards?
OK, I'm sorry. That's probably not even funny from where you're sitting...
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> What, you mean you have to actually, like, design something to not
> overheat in the first place? You can't just add some extra fans
> afterwards?
"It's always worked before"
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
scott escribió:
> I have to learn, that you always need to
GAH
That's what I was talking about. It looks so ugly in English.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> I have to learn, that you always need to
>
> GAH
>
> That's what I was talking about.
I know :-)
> It looks so ugly in English.
Agreed.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible wrote:
> Well, people claim that Lisp is an [impure] functional language too, and
> AFAIK Erlang is about as pure as Lisp is.
It's functional in the sense that you only assign once to a variable.
It's not functional in the sense that calling "read" on the same file
twice (in any language) can give you different results. Erlang just has
lots more of that latter kind of non-functionalism.
But yeah, you have to pass the seed to the random number generator, and
it gives you back your random number and a new seed to remember for
later. :-)
How does Haskell handle things like the function for "the time right now"?
--
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Bill Pragnell wrote:
> Commas are tricky... most native speakers aren't too sure where to put
> them. I know when they look wrong or right, and when there should be one
> when there isn't, but I'm not sure I could describe the rules.
There are strict rules, tho.
Put one before a conjunction joining independent clauses, but not one
joining a dependent clause to an independent clause. I.e., if you could
replace it with a period and take out the word after, it needs to be a
comma.
John went to the store, but Mary went swimming. << Right.
John went to the store but Mary went swimming. << Wrong.
John went to the store but didn't buy anything. << Right.
John went to the store, but didn't buy anything. << Wrong.
(When the sentence gets really long but has a comma, I at least tend to
get confused, as I'm instinctively looking for the second subject.)
Put one after an introductory prepositional phrase with multiple
prepositions in it:
In an emergency run away. << Right.
In case of emergency, run away. << Right.
(I think a comma in the first one is optional but not required.)
If you have a phrase that limits the preceding phrase, use "that"
without a comma. If you have a phrase that clarifies, use a comma and
"which".
My grandfather Fred is old. (Note I have two grandfathers.)
My father, Steve, is young.
The monsters that you can't kill should be avoided.
(Avoid only the monsters you can't kill,
kill the monsters you can kill.)
The greebles, which you kill with the pistol, are weak.
(The greebles are weak whether you kill them with the
pistol or not.)
Introductory adverbial clauses always get a comma, even if they're only
one word long. (These two instant sentences are rule one, btw. :-)
However, I liked the movie.
Not very helpfully, it was too long.
Put commas between elements of a list, obviously, especially if they are
more than one word.
I like peanut butter and jelly, cucumber and bacon, and mustard sandwiches.
There are two or three more that aren't coming to mind at the moment.
This is American English as taught by a British-native English teacher
who actually had to learn the information as rules, which was
tremendously helful for my nerd-brain..
> Just don't get me started on apostrophes :)
Angry Bob's Apostrophe Rules!
--
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"scott" <sco### [at] laptop com> wrote in message
news:47fc9ba8$1@news.povray.org...
> The problem is, that then software dude doesn't go back and make
> everything nice and test it (he has other stuff to do), the software just
> gets left in this "bad" state. Repeat the situation above a few times and
> you end up with a big mess.
Same with websites IMO. ;)
~Steve~
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Warp" <war### [at] tag povray org> wrote in message
news:47fbd6d4@news.povray.org...
> I write too many commas, though.
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
~Steve~ ;)
> --
> - Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Darren New wrote:
> Put one before a conjunction joining independent clauses, but not one
> joining a dependent clause to an independent clause.
Good job. Get the comma wrong in the sentence giving the rule for where
to put the comma in the sentence.
--
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> The problem is, that then software dude doesn't go back and make
>> everything nice and test it (he has other stuff to do), the software just
>> gets left in this "bad" state. Repeat the situation above a few times and
>> you end up with a big mess.
>
> Same with websites IMO. ;)
Nah - nobody "designs" those in the first place! ;-)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> Well, people claim that Lisp is an [impure] functional language too,
>> and AFAIK Erlang is about as pure as Lisp is.
>
> It's functional in the sense that you only assign once to a variable.
> It's not functional in the sense that calling "read" on the same file
> twice (in any language) can give you different results. Erlang just has
> lots more of that latter kind of non-functionalism.
>
> But yeah, you have to pass the seed to the random number generator, and
> it gives you back your random number and a new seed to remember for
> later. :-)
Well, "functional" tends to mean two things: referencial transparency,
and first-class functions. Lisp certainly has the latter, and seems to
suggest [although not enforce] the former. As for Erlang... *shrug*
In fact, all of the actually "popular" so-called functional languages
are impure. But then, the most popular OOP language is C++, which is
hardly a "pure" OOP language either...
> How does Haskell handle things like the function for "the time right now"?
Sure. To the nearest picosecond, anyway. You can also measure CPU time
instead of wall time of you want. You'll need a monad, obviously. ;-)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
St. wrote:
>
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
>
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
>
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Comma comma comma comma comma comelia...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Orchid XP v8" <voi### [at] dev null> wrote in message
news:47fcfa13$1@news.povray.org...
>>> The problem is, that then software dude doesn't go back and make
>>> everything nice and test it (he has other stuff to do), the software
>>> just gets left in this "bad" state. Repeat the situation above a few
>>> times and you end up with a big mess.
>>
>> Same with websites IMO. ;)
>
> Nah - nobody "designs" those in the first place! ;-)
Heh, well they try to design them and think that they're doing it good,
but *something* always crops up.
That's me, that is... ;)
I'll get there one day... One day... One day... ;)
~Steve~
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Orchid XP v8" <voi### [at] dev null> wrote in message
news:47fcface$1@news.povray.org...
> St. wrote:
>
>>
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
>>
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
>>
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
>
> Comma comma comma comma comma comelia...
LOL! That was funny Andrew! :)
(Now I can't get rid of the song from my head!) Grrr... ;)
~Steve~
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
St. wrote:
> I'll get there one day... One day... One day... ;)
OK, I was expecting this sentence to contain the word "gadget". Damn it,
the 80s have ruined my brain! >_<
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> Comma comma comma comma comma comelia...
>
> LOL! That was funny Andrew! :)
*takes a bow*
> (Now I can't get rid of the song from my head!) Grrr... ;)
Muhuhuhuhuh! >:-D
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Gilles Tran wrote:
> "Invisible" <voi### [at] dev null> a écrit dans le message de news:
> 47fb4807$1@news.povray.org...
>> Heh. A guy at school claimed to be able to fly - but only when nobody is
>> looking.
>
> A new batch.
>
> G.
>
>
Episode 8 reminds me of an old R.K Milholland comic.
Google can't find the image anywhere, seems the only place it's still
viewable is his store. Oh well that will have to do.
http://www.positivethinkers.net/postcard-rww-hentai.shtml
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On Wed, 09 Apr 2008 19:17:35 +0100, Orchid XP v8 wrote:
>>> Comma comma comma comma comma comelia...
>>
>> LOL! That was funny Andrew! :)
>
> *takes a bow*
Now make a comic out of it. ;-)
Jim
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Orchid XP v8 wrote:
> Well, "functional" tends to mean two things: referencial transparency,
> and first-class functions.
Erlang has first-class functions as well as closures. Indeed, there are
warnings in the docs saying things like "take care if you store a
closure in a database that when you fetch it back out to run it, you're
running the same version of the interpreter." :-)
>> How does Haskell handle things like the function for "the time right
>> now"?
>
> Sure. To the nearest picosecond, anyway. You can also measure CPU time
> instead of wall time of you want. You'll need a monad, obviously. ;-)
I think I'll have to find a good explanation of monads again. :-)
--
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> Erlang has first-class functions as well as closures. Indeed, there are
> warnings in the docs saying things like "take care if you store a
> closure in a database that when you fetch it back out to run it, you're
> running the same version of the interpreter." :-)
Ooo. So much for "you can upgrade stuff in-place without shutting down". :-P
[Mind you, persistent *closures*? That's got to be a fairly rarely used
feature...]
> I think I'll have to find a good explanation of monads again. :-)
The I/O monad is unusual as monads go, but essentially the I/O functions
return I/O command objects instead of actually *performing* I/O, and you
use the monad operators to join all those actions together until the
"main" function essentially returns a *gaint* I/O command object that
represents the operation of the entire program. [Obviously, containing
lots of closures!]
This is only the conceptual model; in practice the compiler actually
generates much the same code as a C compiler would. But it *does* mean
that an "I/O action" is first-class, just like a function is...
There are famously "two ways" to look at monads. You can look as a monad
as a kind of "container", or you can look at a monad as representing an
"action" that can have special effects. In the former case, it's
probably best to start by learning about the I/O monad. In the latter
case, the Maybe and list monads are probably an easier starting point...
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>>>> Comma comma comma comma comma comelia...
>>> LOL! That was funny Andrew! :)
>> *takes a bow*
>
> Now make a comic out of it. ;-)
Question: is "comelia" a word?
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Orchid XP v8" <voi### [at] dev null> wrote in message
news:47fd081a$1@news.povray.org...
> St. wrote:
>
>> I'll get there one day... One day... One day... ;)
>
> OK, I was expecting this sentence to contain the word "gadget". Damn it,
> the 80s have ruined my brain! >_<
"Dear Mr. Invisible,
One day, I will use the gadget that you refer to, but for now, I'm
truly sorry that the gadget that you refer to isn't available.
You do know that everything on the web is trial and error, do you
not?
Just *plink* the keys for now, and you should be good to go.
Yours,
Mr. G"
;)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On Wed, 09 Apr 2008 21:39:53 +0100, Orchid XP v8 wrote:
>>>>> Comma comma comma comma comma comelia...
>>>> LOL! That was funny Andrew! :)
>>> *takes a bow*
>>
>> Now make a comic out of it. ;-)
>
> Question: is "comelia" a word?
Does it matter? ;-)
Jim
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Orchid XP v8" <voi### [at] dev null> wrote in message
news:47fd2992$1@news.povray.org...
>>>>> Comma comma comma comma comma comelia...
>>>> LOL! That was funny Andrew! :)
>>> *takes a bow*
Deservedly. :)
>>
>> Now make a comic out of it. ;-)
>
> Question: is "comelia" a word?
Not as far as I know, but contextually, that word works. I think it
should be 'Karmelia' - if that is such a word too.
But thanks for lightening my evening up, I don't care what you said, it
made me laugh. :)
~Steve~
>
> --
> http://blog.orphi.me.uk/
> http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On Wed, 09 Apr 2008 22:39:53 +0200, Orchid XP v8 <voi### [at] dev null> wrote:
> Question: is "comelia" a word?
"Comelia" is a name.
--
FE
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Fredrik Eriksson" <fe79}--at--{yahoo}--dot--{com> wrote in message
news:op.### [at] e6600 bredbandsbolaget se...
> On Wed, 09 Apr 2008 22:39:53 +0200, Orchid XP v8 <voi### [at] dev null> wrote:
>> Question: is "comelia" a word?
>
> "Comelia" is a name.
Ah, ok, so perhaps the lyrics went: "Karma, karma, karma Comelia"?
Very possible.
~Steve~
>
>
> --
> FE
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
St. wrote:
> Ah, ok, so perhaps the lyrics went: "Karma, karma, karma Comelia"?
>
> Very possible.
>
> ~Steve~
Or "Karma Chameleon".
Wait, why am I admitting to remembering this song?
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Orchid XP v8 wrote:
>> Erlang has first-class functions as well as closures. Indeed, there
>> are warnings in the docs saying things like "take care if you store a
>> closure in a database that when you fetch it back out to run it,
>> you're running the same version of the interpreter." :-)
>
> Ooo. So much for "you can upgrade stuff in-place without shutting down".
> :-P
Heh. Well, you know, I don't think you can actually upgrade the
interpreter itself without shutting down the node you're running on. On
the other hand, you could in theory start up a new interpreter, ship the
running stuff over to it, then shut down the old one.
Upgrading without shutting anything down is easier when it's only Erlang
code you're upgrading, and not the VM itself, but you *can* do it with
enough forethought.
> [Mind you, persistent *closures*? That's got to be a fairly rarely used
> feature...]
Yah. That they even mention it boggles my mind.
> The I/O monad is unusual as monads go, but essentially the I/O functions
> return I/O command objects instead of actually *performing* I/O,
Yeah, that I figured out. I'm just trying to wrap my head around how
that would work with (say) the clock, or the status of whether your ISP
is currently screwy, or something like that, just in terms of
"referential transparency".
I'm trying to figure out conceptually how you represent "the clock" for
example in a way that it's "referentially transparent". Or can you not
actually do that, and that's the point of a monad?
--
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"Sabrina Kilian" <"ykgp at vtSPAM.edu"> wrote in message
news:47fd76c4$1@news.povray.org...
> St. wrote:
> > Ah, ok, so perhaps the lyrics went: "Karma, karma, karma Comelia"?
>>
>> Very possible.
>>
>> ~Steve~
>
> Or "Karma Chameleon".
LOL! That's it!
> Wait, why am I admitting to remembering this song?
I know, I can't stand it either...
~Steve~
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> [Mind you, persistent *closures*? That's got to be a fairly rarely
>> used feature...]
>
> Yah. That they even mention it boggles my mind.
5th rule of software design: If it's technically possible to use your
product in a certain way, somebody will try to actually use it that way.
You *know* this to be true! ;-)
>> The I/O monad is unusual as monads go, but essentially the I/O
>> functions return I/O command objects instead of actually *performing*
>> I/O,
>
> Yeah, that I figured out. I'm just trying to wrap my head around how
> that would work with (say) the clock, or the status of whether your ISP
> is currently screwy, or something like that, just in terms of
> "referential transparency".
>
> I'm trying to figure out conceptually how you represent "the clock" for
> example in a way that it's "referentially transparent". Or can you not
> actually do that, and that's the point of a monad?
I'm going to go with "you can't - hence the monad".
The "get time" function just returns an I/O command object. You can
replace that function call with the command object it returns and the
meaning of the program is left completely unchanged. Thus it is
referentially transparent.
The Haskell runtime actually *gets* the clock time, and it does this
theoretically "after" the Haskell code has already been run and
generated its giant command object, so...
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Sabrina Kilian wrote:
> Or "Karma Chameleon".
> Wait, why am I admitting to remembering this song?
>:-D Hahahaha!
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Darren New wrote:
> There are strict rules, tho.
Looking down this list, it seems I'm aware of these on an instinctive
level. I certainly use commas according to these rules, although I've
never learnt these rules explicitly. Good to know!
>> Just don't get me started on apostrophes :)
>
> Angry Bob's Apostrophe Rules!
I'd say the 90% of apostrophe abuse would be avoided if people could
remember that apostrophes are never, ever, used for pluralising anything.
:)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible wrote:
> The "get time" function just returns an I/O command object. You can
> replace that function call with the command object it returns and the
> meaning of the program is left completely unchanged. Thus it is
> referentially transparent.
So if I assign the result of "get time" to a variable and use that
variable in multiple places, do I get the same time each place I use it,
or different times? I think that's what's confusing me.
S = get_time()
print(S)
do_long_task()
print(S)
I would think you *want* that to do something different from
print(get_time())
do_long_task()
print(get_time())
How would I write each of those in Haskell?
--
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Darren New wrote:
> Invisible wrote:
>> The "get time" function just returns an I/O command object. You can
>> replace that function call with the command object it returns and the
>> meaning of the program is left completely unchanged. Thus it is
>> referentially transparent.
>
> So if I assign the result of "get time" to a variable and use that
> variable in multiple places, do I get the same time each place I use it,
> or different times? I think that's what's confusing me.
The key is "using".
Recall that the *only* way to *execute* an I/O action is to return it
from the "main" function. And, since you can only return a single
action, it's how you splice each mini-action into the giant-action
returned by "main" that counts. ;-)
If you splice in two copies of the self same action, that action gets
executed twice. It's that simple.
> S = get_time()
> print(S)
> do_long_task()
> print(S)
>
> I would think you *want* that to do something different from
> print(get_time())
> do_long_task()
> print(get_time())
>
> How would I write each of those in Haskell?
In Haskell, if you use the monadic "do" notation, then the syntax for
executing an action and putting its result into a variable is
do
...
x <- do_stuff
...
This is technically equivilent to
... do_stuff >>= \x -> ...
but less messy on paper. In your case, what you're trying to do is simply
do
t1 <- get_time
print t1
do_long_task
t2 <- get_time
print t2
as opposed to something like
do
s <- get_time
print s
do_long_task
print s
which just serves no useful purpose at all. Notice that it's the "<-"
that says "execute this *now*". In the second example, you only execute
the thing once, so it only happens once. It's really quite clear on paper.
In case you care, the desugared equivilents are:
get_time >>= \t1 -> (print t1 >> do_long_task >> get_time >>= \t2 ->
print t2))
and
get_time >>= \s -> (print s >> do_long_task >> print s)
You can see why people prefer the "do" notation...
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Orchid XP v8 wrote:
> You can see why people prefer the "do" notation...
Yah. :-) I'll have to ponder this s'more.
--
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Darren New wrote:
> Yah. :-) I'll have to ponder this s'more.
Understanding *all* of the underlying theory takes a bit of getting used
to. (Wasn't it some physacist who said "you never truly understand new
theories, you just get used to them"?) However, *using* it is pretty simple.
do
foo
bar
baz
It does those things in the order given. If you assign a result to a
variable, that result stays the same thereafter. And you can do
do
foo
let x = print "hello"
bar
x
which will print "hello" immediately after performing "bar". Nothing
hard here. ;-)
Now, the *list* monad... that's another matter! ;-) Not to mention the
Continuation monad. Even the documentation states that "incautious use
of this monad will result in completely unmaintainable code". But then,
that monad is basically for implementing new flow control constructs -
need I say more?
<long theoretic lecture on monads>
Consider the Maybe monad. It's useful for functions that might fail. For
example,
solve :: Double -> Double -> Maybe Double
solve a b = if a == 0 then Nothing else Just ((0 - b)/a)
Now, what if you wanted to perform *several* operations in sequence,
each of which might fail? This is what the monadic structure of Maybe
implements:
foo j k = do
x <- solve j k
z <- lookup x table
...etc...
This is equivilent to
foo j k =
solve j k >>= \x -> lookup x table >>= ...
So you see that ">>=" takes a Maybe and a function that returns a Maybe,
and... well, let me just write the code, it's faster:
(Just x) >>= f = f x
(Nothing) >>= f = Nothing
So when you do "solve j k >>= f", if solve returns Nothing, just skip f
completely and return Nothing directly. Otherwise, take whatever data
came from solve, fish it out of the Maybe value, and feed it to f.
In other words, we can now have a chain of actions where a single
failure triggers an escape from the whole sequence - but doesn't clutter
up the logic of the program on paper.
Now we can do exactly the same thing with lists. If you think about it,
a Maybe stores either 0 or 1 results. Well, a list can store 0 or 1 or 2
or 3 or...
xs >>= f = concat (map f xs)
As should be clear, if xs is the empty list, f is never run at all, and
you just get an empty list as the result. This is like the Maybe case.
Assuming xs is a nonempty list, run f for every element in xs and merge
the results.
It gets slightly confusing when you start using do-notation, but it's
quite powerful:
factors k = do
x <- [1..10]
y <- [1..10]
if x * y == k then [(x,y)] else []
This is a very stupid algorithm for finding all factors of k, but it
illustrates how you can use the monadic structure of lists. Saying "x <-
xs" basically means "x takes on all values in xs". Having two such lines
causes the second one to cycle faster than the first one, yielding a
Cartesian product.
Now notice that
do
x <- xs
y <- ys
f x y
is rather like the list comprehension syntax
[ f x y | x <- xs, y <- ys ]
In fact, not "rather like", but "mathematically equivilent". Apparently
in older versions of Haskell, comprehensions were permitted for
*arbitrary monads*! But it was eventually decided that this is just "too
insane" and so they removed it. Heh!
Notice that if you write
factors k = do
x <- [1..]
y <- [1..]
if x * y == k then [(x,y)] else []
you get an infinite loop. It tries all possibilities for y before moving
on to the next possibility for x. To overcome this, you need a custom
monad. My book at home shows you how to implement a "diagonal list"
monad. It looks just like a list, but the [very complicated] monadic
bind tackles combinations in diagonal order. [(1,1), (2,1), (1,2),
(3,1), (2,2), (1,3), (4,1), (3,2), (2,3), etc.] The bind function given
is possibly the most terrifying snippet of Haskell I have ever seen in
my life...
</long theoretic lecture on monads>
PS. If you've got a moment, there's a Tcl implementation of my logic
solver over in the povray.off-topic.haskell. I'd be interested to know
if you can make it any less... butt-ugly, for want of a better word!
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible wrote:
> It does those things in the order given. If you assign a result to a
> variable, that result stays the same thereafter.
OK. Same as Erlang. :-)
> And you can do
>
> do
> foo
> let x = print "hello"
> bar
> x
>
> which will print "hello" immediately after performing "bar". Nothing
> hard here. ;-)
Same as Erlang, except you'd have to make it explicitly a fun (aka lambda).
> Consider the Maybe monad. It's useful for functions that might fail. For
> example,
>
> solve :: Double -> Double -> Maybe Double
> solve a b = if a == 0 then Nothing else Just ((0 - b)/a)
solve(A,B) when A == 0 -> nothing;
solve(A,B) -> ((0-B)/A).
(Note that "nothing" here is just an "atom", i.e., an interned string, a
LISP "symbol", a Smalltalk "symbol", etc. It's not a special value or
type. Just something you can match on later.)
> So you see that ">>=" takes a Maybe and a function that returns a Maybe,
> and... well, let me just write the code, it's faster:
>
> (Just x) >>= f = f x
> (Nothing) >>= f = Nothing
>
> So when you do "solve j k >>= f", if solve returns Nothing, just skip f
> completely and return Nothing directly. Otherwise, take whatever data
> came from solve, fish it out of the Maybe value, and feed it to f.
do_maybe(Fun, X) when X == nothing -> nothing;
do_maybe(Fun, X) -> Fun(X).
Probably not equivalent in a deeper sense.
But you're giving me some ideas for some higher-order functions I
probably need. I still miss "while" loops, but I've been trying to
figure out how to make while() into a function that takes two lambdas. :-)
> In other words, we can now have a chain of actions where a single
> failure triggers an escape from the whole sequence - but doesn't clutter
> up the logic of the program on paper.
Yep.
> Now we can do exactly the same thing with lists. If you think about it,
> a Maybe stores either 0 or 1 results. Well, a list can store 0 or 1 or 2
> or 3 or...
>
> xs >>= f = concat (map f xs)
>
> As should be clear, if xs is the empty list, f is never run at all, and
> you just get an empty list as the result. This is like the Maybe case.
> Assuming xs is a nonempty list, run f for every element in xs and merge
> the results.
>
> It gets slightly confusing when you start using do-notation, but it's
> quite powerful:
>
> factors k = do
> x <- [1..10]
> y <- [1..10]
> if x * y == k then [(x,y)] else []
In Erlang:
factors(K) ->
Seq = lists:seq(1,K),
[ X*Y || X <- Seq, Y <- Seq, X * Y == K ].
Thanks for the explanation. I'm still not 100% sure what the "value" in
the monad returned by getclock looks like, tho. I know it's supposed to
be opaque, but what in theory is in there, could you say?
> PS. If you've got a moment, there's a Tcl implementation of my logic
> solver over in the povray.off-topic.haskell. I'd be interested to know
> if you can make it any less... butt-ugly, for want of a better word!
Wow. You have your own newsgroup. :-)
I'll take a look.
--
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> Consider the Maybe monad. It's useful for functions that might fail.
>> For example,
>>
>> solve :: Double -> Double -> Maybe Double
>> solve a b = if a == 0 then Nothing else Just ((0 - b)/a)
>
>
> solve(A,B) when A == 0 -> nothing;
> solve(A,B) -> ((0-B)/A).
>
> (Note that "nothing" here is just an "atom", i.e., an interned string, a
> LISP "symbol", a Smalltalk "symbol", etc. It's not a special value or
> type. Just something you can match on later.)
Heh. I remember using symbols in Smalltalk. Just for the love of God,
don't try to mutate them...!
>> (Just x) >>= f = f x
>> (Nothing) >>= f = Nothing
>
> do_maybe(Fun, X) when X == nothing -> nothing;
> do_maybe(Fun, X) -> Fun(X).
>
> Probably not equivalent in a deeper sense.
No, that's more or less exactly it. Oh, except that "f" is type
constrained to *also* return a Maybe value. (But not necessarily
containing the same type of data.)
> But you're giving me some ideas for some higher-order functions I
> probably need. I still miss "while" loops, but I've been trying to
> figure out how to make while() into a function that takes two lambdas. :-)
Well now, doesn't that rather depend on what this loop is supposed to
*do*? ;-) In Haskell, we have several different while loops, all for
different jobs.
There's takeWhile, dropWhile and span which chop up segments of lists.
There's "unfoldr" which builds lists. There's "until", which repeats a
computation until a condition holds, and returns the final result. And
so on...
>> factors k = do
>> x <- [1..10]
>> y <- [1..10]
>> if x * y == k then [(x,y)] else []
>
> In Erlang:
> factors(K) ->
> Seq = lists:seq(1,K),
> [ X*Y || X <- Seq, Y <- Seq, X * Y == K ].
Like I said, Haskell also possesses list comprehensions, and they are
intimately related to monadic expressions. In Haskell, one could write
[ x*y | x <- seq, y <- seq, x * y == k ]
Interestingly, Haskell possesses a "guard" function:
guard (x*y == k)
return (x,y)
If the condition fails, guard aborts the rest. Otherwise it continues.
Similarly "when" runs or doesn't run just one part of a computation.
I should perhaps also mention "return" and "fail" somewhere. All monads
have a "return" method that inserts a single element into the monad:
return 5 >>= print
is the same as just "print 5". The "fail" method takes a text message
and aborts the computation. For Maybe or lists, the message is ignored,
but for the IO monad it throws an exception. There are monads that allow
you to actually *use* the description for something useful. It's
basically so that pattern match failures inside a monad trigger the
monad's error-handling abilities rather than throw an exception...
> Thanks for the explanation. I'm still not 100% sure what the "value" in
> the monad returned by getclock looks like, tho. I know it's supposed to
> be opaque, but what in theory is in there, could you say?
Theoretically, you might have something like
data IO x =
CMD_GET_CHAR Handle |
CMD_PUT_CHAR Handle |
CMD_TEST_EOF Handle |
...
CMD_GET_CLOCK_TIME |
...
But in reality, I believe GHC actually implements it as a structure
holding a raw pointer to a C function that actually does the work. Note
that it's 100% compiler-specific how IO is actually implemented though.
It's completely outside the language spec... ;-)
So, when you hold an "IO Int", you're probably just holding a pointer to
a C function which, when executed, is going to return an integer.
> Wow. You have your own newsgroup. :-)
Where *have* you been dear boy? ;-)
> I'll take a look.
TY.
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Orchid XP v8 wrote:
>> figure out how to make while() into a function that takes two lambdas.
>
> There's takeWhile, dropWhile and span which chop up segments of lists.
> There's "unfoldr" which builds lists. There's "until", which repeats a
> computation until a condition holds, and returns the final result. And
> so on...
Erlang has all that stuff. They aren't "while" loops, tho, they're "for"
loops. No way to stop foldr() early, no way to have it get its stuff by
(say) reading lines from a file instead of a list, etc.
No way to say "while you haven't gotten to a directory entry that starts
with the letter 'T' in /tmp, ...."
> Interestingly, Haskell possesses a "guard" function:
>
> guard (x*y == k)
> return (x,y)
>
> If the condition fails, guard aborts the rest. Otherwise it continues.
That's what the "when" stuff above is - guards.
And a case statement and an if statement both use guards, as does the
message receiving. The languages do seem very close to each other in
capability, from my naive view.
> I should perhaps also mention "return" and "fail" somewhere. All monads
> have a "return" method that inserts a single element into the monad:
>
> return 5 >>= print
Odd name. Not sure what that means. :-)
> is the same as just "print 5". The "fail" method takes a text message
> and aborts the computation. For Maybe or lists, the message is ignored,
> but for the IO monad it throws an exception.
And Erlang crashes the process out, which sends "I crashed" messages to
anyone "linked" to that process, which in turn either crashes them out
or just queues a message saying they crashed.
> Theoretically, you might have something like
>
> data IO x =
> CMD_GET_CHAR Handle |
> CMD_PUT_CHAR Handle |
> CMD_TEST_EOF Handle |
> ...
> CMD_GET_CLOCK_TIME |
> ...
Hrm. OK.
>> Wow. You have your own newsgroup. :-)
> Where *have* you been dear boy? ;-)
Well, I remember it being created as a joke, but I never subscribed. :-)
--
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Darren New wrote:
> Orchid XP v8 wrote:
>>> figure out how to make while() into a function that takes two lambdas.
>>
>> There's takeWhile, dropWhile and span which chop up segments of lists.
>> There's "unfoldr" which builds lists. There's "until", which repeats a
>> computation until a condition holds, and returns the final result. And
>> so on...
>
> Erlang has all that stuff. They aren't "while" loops, tho, they're "for"
> loops. No way to stop foldr() early, no way to have it get its stuff by
> (say) reading lines from a file instead of a list, etc.
foldr is a for-loop, but unfoldr *is* a while-loop, as are the others I
quoted.
> No way to say "while you haven't gotten to a directory entry that starts
> with the letter 'T' in /tmp, ...."
do
fs0 <- getDirectoryContents "/tmp"
let fs1 = sort fs0
let fs2 = takeWhile (\f -> head f /= 'T') fs1
mapM (stuff) fs2
>> return 5 >>= print
>
> Odd name. Not sure what that means. :-)
Definitely an odd choice of name! "insert" or something would at least
make more sense. (That's what it does after all - insert a pure value
into a monadic wrapper...)
>> The "fail" method takes a text message
>> and aborts the computation. For Maybe or lists, the message is
>> ignored, but for the IO monad it throws an exception.
>
> And Erlang crashes the process out, which sends "I crashed" messages to
> anyone "linked" to that process, which in turn either crashes them out
> or just queues a message saying they crashed.
Haskell has a function called "error" which takes a message and then
throws an exception containing that message. Unless exceptions are
caught somewhere [which can only happen in the IO monad], the default
behaviour is for the program to exit and write a message to stdout.
"fail" is different to "error" in that it is specific to a particular
monad. So for the IO monad, fail = error. But for Maybe, fail just
returns Nothing. And for some other user-defined monad, it could do
something else instead.
factors k = do
x <- [1..10]
y <- [1..10]
if x*y == k then return (x,y) else fail "not a factor"
That does the same as the other example, while being [debatably] clearer.
>>> Wow. You have your own newsgroup. :-)
>> Where *have* you been dear boy? ;-)
>
> Well, I remember it being created as a joke, but I never subscribed. :-)
Better yet: As far as anybody knows, messages never expire! >:-)
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Orchid XP v8 wrote:
> foldr is a for-loop, but unfoldr *is* a while-loop, as are the others I
> quoted.
I see the confusion. Erlang isn't lazy.
> Better yet: As far as anybody knows, messages never expire! >:-)
Immortally famous!
--
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Orchid XP v8 wrote:
> There's takeWhile, dropWhile and span which chop up segments of lists.
> There's "unfoldr" which builds lists. There's "until", which repeats a
> computation until a condition holds, and returns the final result. And
> so on...
I think the "until" is what I was after, but the Erlang syntax for
curried functions is just klunky enough to still make it annoying.
Still, better than a global name for every while loop. :-)
--
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Darren New wrote:
> I think the "until" is what I was after, but the Erlang syntax for
> curried functions is just klunky enough to still make it annoying.
Ah. Examining unfoldr, I see I was making it too complicated. I was
trying to figure out how to make "while" (or "until") take two lambdas,
one for the condition, one for the "body" of the loop. Much easier to
just have the one function return whether to keep iterating.
Now I can easily say things like "keep prompting and reading a line
until the user actually types an integer."
--
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> foldr is a for-loop, but unfoldr *is* a while-loop, as are the others
>> I quoted.
>
> I see the confusion. Erlang isn't lazy.
Laziness for the win! (Or for the user-defined control structures,
anyway...) :-D
>> Better yet: As far as anybody knows, messages never expire! >:-)
>
> Immortally famous!
Hell yeah!
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> I think the "until" is what I was after, but the Erlang syntax for
>> curried functions is just klunky enough to still make it annoying.
>
> Ah. Examining unfoldr, I see I was making it too complicated. I was
> trying to figure out how to make "while" (or "until") take two lambdas,
> one for the condition, one for the "body" of the loop. Much easier to
> just have the one function return whether to keep iterating.
>
> Now I can easily say things like "keep prompting and reading a line
> until the user actually types an integer."
Yes indeed. You have found enlightenment...
--
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|
 |