POV-Ray : Newsgroups : povray.off-topic : Try Haskell Server Time
4 Sep 2024 19:24:22 EDT (-0400)
  Try Haskell (Message 23 to 32 of 62)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>
From: Darren New
Subject: Re: Try AJAX
Date: 3 Mar 2010 12:50:23
Message: <4b8ea15f$1@news.povray.org>
Invisible wrote:
> No, I'd just like to see if I can do a small proof-of-concept thing and 
> make it work. ;-) Let's face it, DOM is way too hard in the first place...

Then take static files and request them via xmlhttprequest. That's how I do it.

Make up files text1.txt text2.txt text3.txt and so on, then write a loop in 
javascript to sleep a few seconds, xmlhttprequest the next file in the list, 
and when it shows up take the data and populate a DOM element with it. It works.

-- 
Darren New, San Diego CA, USA (PST)
   The question in today's corporate environment is not
   so much "what color is your parachute?" as it is
   "what color is your nose?"


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: Try Haskell
Date: 3 Mar 2010 17:04:22
Message: <4b8edce6$1@news.povray.org>
Invisible wrote:
> But yes, this (alpha) web thingy lacks several important features:
> 
> - You can't define things and refer to them later. Each expression is
> processed independently.
> 
> - You can't write multi-line definitions.
> 
> - You can't do I/O. (And the error message if you try is cryptic to say
> the least!)
> 
> - You can't use all of the standard Haskell libraries, just the handful
> the interpretter offers.

They seriously should steal features from http://tryruby.org/

- You can define variables and refer to them later. Example, type a=1, press 
Enter, then type a+a.

- You can write multi-line definitions. Try this one:

5.times {
    print "Hello"
}

When it parses the first line, it will notice the statement is incomplete 
and let you continue it.

- You can do I/O (fake filesystem). The whole chapter 4 of the tutorial is 
about I/O and file handling.

- You can do HTML and see the results via a custom library made for the 
tutorial. Try:

require "popup"
Popup.make {
   h1 "Hello world"
   p "foo"
}


Post a reply to this message

From: Orchid XP v8
Subject: Re: Try Haskell
Date: 3 Mar 2010 17:10:45
Message: <4b8ede65$1@news.povray.org>
Nicolas Alvarez wrote:

> They seriously should steal features from http://tryruby.org/

Well, the page even *mentions* Try Ruby.

I guess the guy just hasn't written the code yet... A few days ago, ":t" 
didn't work. And now it does. (Annoyingly, GHCi uses ":t" as an 
abbreviation for ":type", but the website doesn't accept ":type", only 
":t".)

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


Post a reply to this message

From: scott
Subject: Re: Try Haskell
Date: 4 Mar 2010 02:36:52
Message: <4b8f6314@news.povray.org>
> The hard thing about writing a tutorial is that by the time you're 
> experienced enough to be an authority on the language, half the stuff that 
> trips newbies up is so utterly "obvious" to you that you forget to even 
> mention it.

Exactly.

> In truth, if you're using tuples bigger than about three or four elements, 
> you really ought to define a custom type for this stuff instead of relying 
> on tuples.

OK.  I take it a custom type is a bit like a struct in C-type languages, in 
that it can hold any number of different types?

> I can talk some more if you want?

Once you know a few basic things I think it's best to move on to simple 
examples (small multi-line samples, not those artificial ones needed for the 
web).

> > let factorial n = product [1..n]
> > let choose n k = (factorial n) / (factorial k * factorial (n - k))
> > choose 3 5

Exactly.  Even I can work out from that one how functions are defined now 
:-)

BTW what would happen if I typed "choose 3 (-5)" instead?

I'm just trying to think of a subject for a good example ... how about a 
card game?  Firstly how would you represent the cards (tuple or custom type 
for the suit/value?).  Then I assume you would just create a list of "Cards" 
to represent a group of cards that someone was holding (say 5 cards).  How 
would you then check to see if any two cards in that list were the same 
value, or all the same suit, etc?

> Are you actually interested enough to want to play with it more?

I was interested enough in J to learn how to use it to write a mandelbrot in 
1-line :-)  Haskell should be a doddle - at least you stand to pick up bits 
and pieces based on English, rather than just almost random single 
characters for everything!


Post a reply to this message

From: Invisible
Subject: Re: Try Haskell
Date: 4 Mar 2010 04:43:26
Message: <4b8f80be$1@news.povray.org>
>> The hard thing about writing a tutorial is that by the time you're 
>> experienced enough to be an authority on the language, half the stuff 
>> that trips newbies up is so utterly "obvious" to you that you forget 
>> to even mention it.
> 
> Exactly.

This is one of the hardest things about technical writing - and one of 
the things I most often see done wrong. Search around the Internet a 
bit, and you'll find Haskellers writing things like "a monad is just a 
monoid in the category of endofunctors - what's the problem?" like 
normal human beings have any clue WTF that means. (I have *some* clue, 
but the category theory definition of a monad doesn't even begin to 
explain why it's useful in computer programming.)

>> In truth, if you're using tuples bigger than about three or four 
>> elements, you really ought to define a custom type for this stuff 
>> instead of relying on tuples.
> 
> OK.  I take it a custom type is a bit like a struct in C-type languages, 
> in that it can hold any number of different types?

It can be. The neat thing about Haskell is that it has "algebraic data 
types". These can be like a struct or a record or whatever you want to 
call it. Or they can be like an enumeration. OR THEY CAN BE BOTH!

(I guess this is what C would call a "union". But it's type-safe. You 
cannot accidentally access a field that does not exist. Or use the wrong 
field type.)

>> I can talk some more if you want?
> 
> Once you know a few basic things I think it's best to move on to simple 
> examples (small multi-line samples, not those artificial ones needed for 
> the web).

Some things are easiest to explain by example. Like, some concepts are 
so extremely abstract that without an example, it's difficult to 
comprehend what's going on. Other things are quite tricky to demonstrate 
with examples; you end up needing to use examples which are either 
extremely complex, or very contrived. In depends what you're trying to 
demonstrate.

I think for general familiarity with a programming language, lots of 
small examples is probably the way forward.

>> > let factorial n = product [1..n]
>> > let choose n k = (factorial n) / (factorial k * factorial (n - k))
>> > choose 3 5
> 
> Exactly.  Even I can work out from that one how functions are defined 
> now :-)

Well, yeah, there is that too. ;-)

> BTW what would happen if I typed "choose 3 (-5)" instead?

Well, it would execute

   (factorial 3) / (factorial (-5) * factorial (3 + 5))

Given the above definition of factorial,

   factorial (-5) = product [1..-5] = product [] = 1

Which I'm guessing means that choose gives the wrong answer.

(I also just realised that that should probably be integer division, 
since choose is only supposed to work with integer inputs and yield 
integer outputs...)

> I'm just trying to think of a subject for a good example ... how about a 
> card game?  Firstly how would you represent the cards (tuple or custom 
> type for the suit/value?).

At the most basic level, you can always use tuples and code numbers. But 
why do that, when the language has extensive support for a better way?

The idiomatic way would probably be to do something like

   data Suit = Diamonds | Hearts | Clubs | Spades

   data Number =
     Ace | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten |
     Jack | Queen | King

   data Card = Card Suit Number

So Suit and Number are enumerations, and Card is a record with two 
fields. The record syntax is probably the most perplexing part. I'm 
using positional fields - which is common when there are very few fields 
- but you can also use named fields:

   data Card = Card {suit :: Suit, numer :: Numer}

I should probably have thrown it into the tutorial, but "thing :: type" 
is how you write explicit type signatures in Haskell. And you can do

 > 5 :: Int
 > 5 :: Double
 > 5 :: Rational
 > 5 :: Word64
 > 5 :: Complex Float

Unlike Java, "5" can represent any possible numeric type. Usually 
Haskell deduces which type you want automatically (or makes it 
polymorphic). The web interpretter seems to default to 
arbitrary-precision integers - which is reasonable.

(Similarly, "5.3" is any fractional type - Float, Double, Rational, etc.)

> Then I assume you would just create a list 
> of "Cards" to represent a group of cards that someone was holding (say 5 
> cards).

Sure, that'll work. Other representations are possible.

> How would you then check to see if any two cards in that list 
> were the same value, or all the same suit, etc?

By default, you can't compare values. That's because it's possible to 
define how to do comparison. (E.g., your data structure might have 
several equivilent representations for the same thing, and you want 
these different representations to be considered "the same".) However, 
in the common case that you just want to do a vanilla structural 
comparison, you just add "deriving Eq" to the end of the type definition.

Once you do that, you can write things like Hearts == Clubs (which is 
obviously going to give you "false"). (By a similar arrangement, you can 
auto-define comparison as well. The compiler uses the order you listed 
the values in. Might be useful for deciding which card is "higher".)

Now, if you've used named fields, then "suit" and "number" are not only 
field names, but also implicitly-defined functions that take a Card and 
return the appropriate field. So "suit card1" tells you the suit of 
whatever is in card1.

Are all the cards the same suit?
   length (group (map suit cards)) == 1
(This could be inefficient if "cards" is huge, but for a hand of 5 or 7 
cards, it should be fine.)

First, you extract a list of suits. Then you group this list into a list 
of sublists, such that each sublist contains only identical suits. If 
*all* the suits are the same, clearly you will have exactly 1 sublist.

(Equally clearly, if you have 1000 cards, alternating between Clubs and 
Spades, you will get a list with 1000 1-element sublists, which length 
will have to completely traverse before giving you an answer.)

You can use pattern matching to solve the inefficiency, but due to the 
limitations of the web interpretter, it's bloody awkward to demonstrate 
pattern matching. So I haven't shown that to you yet.

>> Are you actually interested enough to want to play with it more?
> 
> I was interested enough in J to learn how to use it to write a 
> mandelbrot in 1-line :-)  Haskell should be a doddle - at least you 
> stand to pick up bits and pieces based on English, rather than just 
> almost random single characters for everything!

LOL! OK, well if you put it that way...

Although even Haskell has a few "interesting" symbol choices. ">>=" 
leaps to mind, but you might also mention "$", "&&&", ":" and so on.


Post a reply to this message

From: scott
Subject: Re: Try Haskell
Date: 4 Mar 2010 05:47:32
Message: <4b8f8fc4@news.povray.org>
>> BTW what would happen if I typed "choose 3 (-5)" instead?
>
> Well, it would execute
>
>   (factorial 3) / (factorial (-5) * factorial (3 + 5))
>
> Given the above definition of factorial,
>
>   factorial (-5) = product [1..-5] = product [] = 1
>
> Which I'm guessing means that choose gives the wrong answer.

So what's the preferred way to cope with runtime "errors" like that? (I 
don't know if there is a technical term for such kind of errors that don't 
actually make an error, if you know what I mean).  I suspect in a lot of 
case some very low nested function detects an error, and needs to signify 
this to a much higher level calling function (eg a "ParseFile" or 
"ParseLine" function or something).

> So Suit and Number are enumerations, and Card is a record with two fields. 
> The record syntax is probably the most perplexing part. I'm using 
> positional fields - which is common when there are very few fields - but 
> you can also use named fields:
>
>   data Card = Card {suit :: Suit, numer :: Numer}

OK, so I could also do something like:

data myRecord = myRecord {age :: Int, height :: Double, weight :: Double}

> Are all the cards the same suit?
>   length (group (map suit cards)) == 1
> (This could be inefficient if "cards" is huge, but for a hand of 5 or 7 
> cards, it should be fine.)
>
> First, you extract a list of suits.

So in my example, if I had a list of myRecords, then "age MyList" would 
return a list of ages?

> Then you group this list into a list of sublists, such that each sublist 
> contains only identical suits.

What does the "map" do?  Clearly I need to download the proper 
interpretter/compiler to answer these questions myself with a bit of playing 
around :-)

OK so after Googling Haskell, implementations, GHC, go to the GHC page, 
latest release, "STOP!" they recommend I get the Haskell Platorm instead, oh 
goody a .exe installer link :-)  I'll let you know in 54 MB time how I get 
on...

> LOL! OK, well if you put it that way...

Thing is it's very rare that I find myself wanting to write something that 
*I* think would be easier/faster with a language like Haskell.  But as I 
don't really know much about the language, I'm not a very good judge.

You're also quite good a writing tutorials, you should definitely write a 
book.  Haskell for Imperative Programmers.  :-)


Post a reply to this message

From: Invisible
Subject: Re: Try Haskell
Date: 4 Mar 2010 06:16:57
Message: <4b8f96a9$1@news.povray.org>
>>> BTW what would happen if I typed "choose 3 (-5)" instead?
>>
>> Well, it would execute
>>
>>   (factorial 3) / (factorial (-5) * factorial (3 + 5))
>>
>> Given the above definition of factorial,
>>
>>   factorial (-5) = product [1..-5] = product [] = 1
>>
>> Which I'm guessing means that choose gives the wrong answer.
> 
> So what's the preferred way to cope with runtime "errors" like that? (I 
> don't know if there is a technical term for such kind of errors that 
> don't actually make an error, if you know what I mean).

The correct thing to do here would be

   choose n k
     | n < 0     = error "choose: negative n"
     | k < 0     = error "choose: negative k"
     | k > n     = 0 -- According to Wikipedia.
     | otherwise = (factorial n) `div` (factorial k * factorial (n - k))

(You would also define it to accept only unsigned integers as arguments, 
which neatly does away with most of the error checking.)

> I suspect in a 
> lot of case some very low nested function detects an error, and needs to 
> signify this to a much higher level calling function (eg a "ParseFile" 
> or "ParseLine" function or something).

The standard idiom in Haskell is this:

- If it's a program bug, use the "error" function. In particular, if a 
function is called with invalid arguments, this is probably a bug in the 
caller.

- If it's a routine, expected occurrance, return a data structure which 
indicates success or failure. For example, a parse failure is totally to 
be expected, so we need to explicitly handle it. The error is returned 
"as data". (This is where the "error monad" comes in...)

The "error" function, technically speaking, throws an exception. Other 
actions (generally only I/O operations) may also throw exceptions, and 
Haskell has the usual exception-catching machinery. (Although things 
like "catch" are library functions, not language constructs.)

> OK, so I could also do something like:
> 
> data myRecord = myRecord {age :: Int, height :: Double, weight :: Double}

Yes, that'll work.

(Actually, I'm lying. The type name MUST begin with a capital letter. 
This IS enforced by the compiler.)

The catch: Each field name is also a function name. Therefore, no two 
types can have fields with the same name. (At least, not in the same 
scope. Obviously types defined in different files can.) This restriction 
becomes quite tedious at times.

>> Are all the cards the same suit?
>>   length (group (map suit cards)) == 1
>> (This could be inefficient if "cards" is huge, but for a hand of 5 or 
>> 7 cards, it should be fine.)
>>
>> First, you extract a list of suits.
> 
> So in my example, if I had a list of myRecords, then "age MyList" would 
> return a list of ages?

No. "map age mylist" would though. You need "map" to apply "age" to 
every element of the list.

(And variable names MUST begin with a lowercase letter. The compiler 
will complain if they don't.)

> What does the "map" do?

See above. ;-)

> OK so after Googling Haskell, implementations, GHC, go to the GHC page, 
> latest release, "STOP!" they recommend I get the Haskell Platorm 
> instead, oh goody a .exe installer link :-)  I'll let you know in 54 MB 
> time how I get on...

Yes, it's... a tad large. It *does* contain a complete copy of GCC, gas, 
ld, perl.exe (?!) and a big suite of precompiled libraries, with HTML 
documentation, a profiler, a debugger...

Background: Installing GHC used to give you a complete environment. But 
the GHC guys don't want to maintain a complete environment, they want to 
maintain GHC. So now the Haskell Platform exists, and the HP guys work 
on HP, so the GHC guys can focus on just GHC. The idea is that HP will 
grow to provide more stuff. Currently there's not actually much 
difference. Follow all that?

Oh, and yes, GHC has *always* been big. You just want to play with 
Haskell, but what you're downloading has all sorts of bells and whistles 
that you won't use. There's a powerful parser library, cutting-edge 
parallel processing technology, a complete OpenGL binding, POSIX 
bindings, cross-platform filename processing... need I continue?

> Thing is it's very rare that I find myself wanting to write something 
> that *I* think would be easier/faster with a language like Haskell.

Well, yes, it completely depends on the kind of code you want to write. 
If you want to write, say, a computer game, Haskell probably isn't the 
best choice. In C or C++, you can probably just download a game engine 
and start coding. In Haskell... there's an OpenGL binding? I guess that 
helps? But it's going to take a loooong time to get to a full-featured 
game from there!

Personally, I tend to write crazy algorithm stuff. Haskell is great for 
that, even if performance is a little unpredictable.

> But 
> as I don't really know much about the language, I'm not a very good judge.

Well, yeah. That's kind of what's exciting about the web interpretter, 
unfinished as it is. Now anybody can play with Haskell and do basic 
stuff without... waiting for a 60+ MB download. ;-)

> You're also quite good a writing tutorials, you should definitely write 
> a book.  Haskell for Imperative Programmers.  :-)

Heh. I've attempted to write *several* Haskell introductions. Roughly 
once every 2 months I start writing a new one. They never get finished.

Trouble is, lots of Haskell's features depend on Haskell's other 
features, so... where do you start? Which thing do you explain first? I 
write an example, and then I go "oh crap, that uses X, I haven't even 
mentioned that yet. Bugger!"

It's not complicated, it's just difficult to decide where to begin.

But thanks for your encouragement. Go take a look at the other thing I 
just posted. ;-)


Post a reply to this message

From: Invisible
Subject: Re: Try Haskell
Date: 4 Mar 2010 06:48:54
Message: <4b8f9e26@news.povray.org>
Invisible wrote:

> Of course, it's still alpha quality.

Strike a light... It seems the bit "alpha" sticker has gone. And the 
command history seems to work properly now. Neat...


Post a reply to this message

From: Invisible
Subject: Re: Try Haskell
Date: 4 Mar 2010 07:18:31
Message: <4b8fa517@news.povray.org>
Invisible wrote:

> Yes, it's... a tad large. It *does* contain a complete copy of GCC, gas, 
> ld, perl.exe (?!) and a big suite of precompiled libraries, with HTML 
> documentation, a profiler, a debugger...

I guess it's a bit like downloading and installing VisualStudio just so 
you can write a Hello World program in C++... It'll do it, but it's kind 
of overkill. ;-)


Post a reply to this message

From: scott
Subject: Re: Try Haskell
Date: 4 Mar 2010 10:28:52
Message: <4b8fd1b4$1@news.povray.org>
>   data Suit = Diamonds | Hearts | Clubs | Spades
> 
>   data Number =
>     Ace | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten |
>     Jack | Queen | King
> 
>   data Card = Card Suit Number

I get "parse error on input 'data'" for all those.

Guess I'm missing some #include or whatever it's called.


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.