Tom Hawkins | 4 Mar 2008 04:38
Picon

coreFunc has extra argument

I noticed a coreFunc has an extra argument and I'm not sure where it's
coming from.  For example if I compile:

  main :: IO ()
  main = return ()

and print out the coreFuncs and coreDatas I get:

  Main;main = Prelude;YHC.Internal.IO;Prelude.Monad;return Prelude;()
  Prelude;1807_ioReturn v25601 v25602 = YHC.Primitive;_E v25601
  Prelude;YHC.Internal.IO;Prelude.Monad;return v25600 =
      Prelude;1807_ioReturn v25600
  main = Main;main

  data YHC.Primitive;_E b =
        YHC.Primitive;_E b
  data Prelude;() =
        Prelude;()

Why does Prelude;1807_ioReturn include an extra argument (v25602) that
is not used?  If I informally type check this by hand, I get a
contradiction:

  main :: IO ()
  Main;main :: IO ()
  Prelude;YHC.Internal.IO;Prelude.Monad;return :: a -> IO a
  Prelude;YHC.Internal.IO;Prelude.Monad;return = Prelude;1807_ioReturn

Therefore if follows:

(Continue reading)

Dimitry Golubovsky | 4 Mar 2008 06:17
Picon
Gravatar

Yhc Web Service quietly opened for public testing

Hi,

I finally got the Yhc Web Service (web-based front end to the
compiler) running in public testing mode. There hasn't been any
documentation written, and Haddock stuff not brought in order, but if
anyone wants to just get a taste of it, please open this hpaste entry:

http://hpaste.org/6094

and follow the instructions.

In 10 steps, you'll get Haskell to work in your web browser* ;) No
need to install anything.

Feel free to edit the source code, and even deliberately make errors
to see how error log looks. At the moment, I do not run automatic
cleanup of failed compilations.

This is one of my old tests, not showing any GUI interaction. However,
both documents browser and new entry form were written in Haskell
which gives some idea about what can be done. Sources of these forms
are in the Yhc repo.

Thanks.

-----------
* Likely, your results will be better with Firefox than with MSIE. But
MSIE should work as well.

--

-- 
(Continue reading)

Jeremy Shaw | 4 Mar 2008 08:41
Gravatar

Re: coreFunc has extra argument

At Mon, 3 Mar 2008 21:38:51 -0600,
Tom Hawkins wrote:

> What am I missing here?  Am I to interpret this as meaning:
> 
>   b -> YHC.Primitive;_E a  ==  IO a  ?

Yes.  From src/packages/yhc-base-1.0/YHC/Internal.hs:

data World = World
newtype IO a = IO (World -> _E a)

Remember that the 'newtype' is coverted to a type alias after type
checking.

So:

main :: IO ()

is really,

main :: World -> _E ()

and when the 'compiler' calls main it actually passes in a World
value. (Or at least, in my yca2swf compiler I believe I do). I believe
'tackling the awkward squad' explains the World parameter.

http://research.microsoft.com/~simonpj/papers/marktoberdorf/

hth,
(Continue reading)

Thomas Shackell | 4 Mar 2008 13:09
Picon

Re: coreFunc has extra argument

> I believe
> 'tackling the awkward squad' explains the World parameter.
> 
> http://research.microsoft.com/~simonpj/papers/marktoberdorf/

Indeed this is the 'World' parameter. It's quite easy to see why it's 
needed. Image the getChar function ...

getChar :: IO Char

if we imagine that the World parameter wasn't present, this would make 
the type of getChar.

getChar :: _E Char

Since _E is just a box this is basically the same as.

getChar :: Char

Since this doesn't take any arguments it's a CAF, i.e. a constant value. 
Since it's constant, every call to getChar would always return the same 
character!

When we add the World parameter we turn getChar into.

getChar :: World -> Char

Now getChar takes an argument, so its value is no longer constant (its 
value can vary depending on the argument). Haskell neither knows, nor 
cares, that getChar doesn't even look at the World argument. As far as 
(Continue reading)

Tom Hawkins | 4 Mar 2008 16:06
Picon

Re: coreFunc has extra argument

Thanks Tom and Jeremy, this helps a lot.  Actually, Tom I see you
spelled this out for me a couple weeks ago in an earlier post.  Sorry,
I'm a bit slow.

So am I correct in saying that World is never reference in the
program, it's only used to emulate imperative actions?

-Tom

On 3/4/08, Thomas Shackell <shackell <at> cs.york.ac.uk> wrote:
> > I believe
> > 'tackling the awkward squad' explains the World parameter.
> >
> > http://research.microsoft.com/~simonpj/papers/marktoberdorf/
>
> Indeed this is the 'World' parameter. It's quite easy to see why it's
> needed. Image the getChar function ...
>
> getChar :: IO Char
>
> if we imagine that the World parameter wasn't present, this would make
> the type of getChar.
>
> getChar :: _E Char
>
> Since _E is just a box this is basically the same as.
>
> getChar :: Char
>
> Since this doesn't take any arguments it's a CAF, i.e. a constant value.
(Continue reading)

Tom Shackell | 4 Mar 2008 17:01
Picon

Re: coreFunc has extra argument

Tom Hawkins wrote:
> Thanks Tom and Jeremy, this helps a lot.  Actually, Tom I see you
> spelled this out for me a couple weeks ago in an earlier post.  Sorry,
> I'm a bit slow.

Not at all, it's actually quite complex. It took me a couple of attempts 
to get the IO type right. It has many funny features, and the reasons 
that some of them are there is quite subtle :)

> So am I correct in saying that World is never reference in the
> program, it's only used to emulate imperative actions?

The value of World comes up in only two places that I know of. The first 
is in the startup code. When the interpreter starts it calls the 
YHC._Driver._driver function, passing it a value of type World and the 
'main' function to evaluate.

_driver :: World -> IO () -> a

In fact _driver doesn't even use the World value it is passed, its 
existence in that function is entirely historical and it could be 
removed if anyone could be bothered :)

The second, and more useful, example is unsafePerformIO. Defined in 
YHC.Internal.

unsafePerformIO :: IO a -> a
unsafePerformIO (IO f) = case f World of
                             _E x -> x

(Continue reading)

Tom Shackell | 4 Mar 2008 17:11
Picon

Re: coreFunc has extra argument

Tom Shackell wrote:
 > The value of World comes up in only two places that I know of.

Ah I lie, the final use of World is in the Show instance of the IO Monad.

instance (Show a) => Show (IO a) where
   ...

   showsType (IO fta) = showString "(IO " . showsType ta . showChar ')'
         where (_E  ta) = fta World

Interestingly this applies World to the IO action, however, since the 
only thing that is done with the result is 'showsType' the computation 
is never actually evaluated (since you don't need to evaluate it to know 
its type).

Though why this doesn't just use unsafePerformIO I don't know ...

  showsType io = showString "(IO " . showsType a . showChar ')'
       where
       a = unsafePerformIO io

This would work just as well. *shrugs* Yhc has quite a lot of historical 
carry-overs from nhc98 :)

Cheers

Tom
Neil Mitchell | 4 Mar 2008 17:17
Picon
Gravatar

Re: coreFunc has extra argument

Hi

>   showsType io = showString "(IO " . showsType a . showChar ')'
>        where
>        a = unsafePerformIO io

You don't even need unsafePerformIO! All you need is a proxy a which
has the right type, this can be done by doing:

showsType io = showString "(IO " . showsType a . showChar ')'
     where
     a = undefined
     b = asTypeOf (return a) io

i.e. instead of unwrapping the io, you wrap up the a, and demand it
has the same type as io. Same result, but now entirely "safe".

[Note: entirely untested, but the idea should be sound]

Thanks

Neil
Tom Shackell | 4 Mar 2008 17:22
Picon

Re: coreFunc has extra argument

Neil Mitchell wrote:
> You don't even need unsafePerformIO! All you need is a proxy a which
> has the right type, this can be done by doing:
> 
> showsType io = showString "(IO " . showsType a . showChar ')'
>      where
>      a = undefined
>      b = asTypeOf (return a) io
> 

That works too, though it still relies on showsType not evaluating it's 
argument - since otherwise it'll eval undefined :S

Tom
Neil Mitchell | 4 Mar 2008 17:24
Picon
Gravatar

Re: Yhc Web Service quietly opened for public testing

Dimitry,

Wow, that is seriously impressive! I particularly love that the entire
MainGUI interface is written in Haskell with Yhc/Javascript goodness.

Thanks

Neil

On Tue, Mar 4, 2008 at 5:17 AM, Dimitry Golubovsky <golubovsky <at> gmail.com> wrote:
> Hi,
>
>  I finally got the Yhc Web Service (web-based front end to the
>  compiler) running in public testing mode. There hasn't been any
>  documentation written, and Haddock stuff not brought in order, but if
>  anyone wants to just get a taste of it, please open this hpaste entry:
>
>  http://hpaste.org/6094
>
>  and follow the instructions.
>
>  In 10 steps, you'll get Haskell to work in your web browser* ;) No
>  need to install anything.
>
>  Feel free to edit the source code, and even deliberately make errors
>  to see how error log looks. At the moment, I do not run automatic
>  cleanup of failed compilations.
>
>  This is one of my old tests, not showing any GUI interaction. However,
>  both documents browser and new entry form were written in Haskell
(Continue reading)


Gmane