Re: [Haskell-cafe] Using unsafePerformIO safely

2009-06-25 Thread Luke Palmer
On Wed, Jun 24, 2009 at 11:13 PM, Hector Guilarte hector...@gmail.comwrote:


 Thanks! Actually,  if I understood well what you proposed, that's how I
 first tought of doing it, but with a [Maybe String] and only append whenever
 I actually had a (Just string), but as I said before, I don't think my
 teacher is gonna like that solution since it is not going to print when the
 interpreter finds the show instruction in the GCL code, it is gonna wait
 until it finishes to interpret the whole code and then print everything.


Not true!  Haskell is lazy.  You just have to think about program evaluation
inside out.  So it's not print *when* you come across this instruction,
but rather run the program just far enough to print the first line.

That's would be ok with me, but actually in a language point of view that
 wouldn't be to usefull, since trying to debug a program printing flags
 couldn't be done (and I'm not doing a debbuger for it). I know my language
 is not gonna be used for real, but I'm sure that would be my teacher's
 argument to tell me I can't do it that way. Still, I sent him an e-mail
 asking if it can be done like that just in case.


I assume that Haskell is *your* language choice, not the teacher's.  In
which case it may be very hard to convince the teacher that this is correct,
if he is used to thinking in an imperative style.  Nonetheless, you chose a
functional language and it is only fair to solve the program in a functional
way, right?  Haskell tries to be a language with *no* side effects at all,
it just accidentally falls short here and there; if it achieves its goal,
there would be *no* correct way to solve it by your alleged teacher's
argument.



 If I didn't understand what you said, can you explain it again please?


I think you've got it, except for the understanding that lists are lazy so
running the program is equivalent to asking for elements from the list.



 If I did then, does anybody knows how to print on the screen in the moment
 the show instruction is interpreted that guarantees that my code is gonna be
 safe


That is a very hard thing to ask of a pure language, which does not really
concern itself with such questions.  The moment the show instruction is
interpreted is abstracted away from the Haskell programmer, so that the
compiler may choose to evaluate it any time it pleases (as long as it gives
you the answer you asked for).


 Also, nobody has told me why I shouldn't just use my original solution
 using unsafePerformIO, is it really bad? is it dangerous? why is it
 unsafe?


It is contrary to the spirit of Haskell, and breaks invariants that
reasoning in the language relies on.  It is not technically dangerous,
i.e. your program will still work, but you will be contested here and
there about whether it should be considered correct.  If you published a
Haskell module which used such a trick to the community, you would have a
very hard time convincing people to use it.

The invariant it breaks is called referential transparency, or maybe
purity (those terms are kind of muddled together the way I look at
things).  Either way, consider the following program:

mult2 x = 2*x
main = do
print (mult2 21)
print (mult2 21)

Now, functions are in the mathematical sense in Haskell, so the result of a
function is *entirely* determined by its arguments.  That means, without
considering anything about the definition of mult2, refactor main into:

main = do
let answer = mult2 21
print answer
print answer

And we *know* that this program will behave exactly the same.

However, if mult2 were instead:

mult2 x = unsafePerformIO $ do { print x; return (2*x) }

Then the former program would probably print 21,42,21,42,  whereas the
latter would print 21,42,42.  Thus our *correct* transformation of programs
changed behavior.

Haskell programmers rely on this sort of refactoring all the time, and
unsafePerformIO has the potential to break it.  That is why it's unsafe.

Safe uses of unsafePerformIO are those where any such transformation won't
change the overall behavior of the program.  They do exist, and are usually
employed for optimization purposes.  But yours is not such a case; your
unsafePerformIO has observable side-effects.

The list of strings solution is *the* Haskell way to solve this problem.
If your teacher does not accept the solution, then your teacher is not
actually letting you program in Haskell.

Cheers,
Luke
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Using unsafePerformIO safely

2009-06-25 Thread minh thu
2009/6/25 Hector Guilarte hector...@gmail.com:


 On Fri, Jun 26, 2009 at 12:58 AM, Brandon S. Allbery KF8NH
 allb...@ece.cmu.edu wrote:

 On Jun 26, 2009, at 00:43 , Hector Guilarte wrote:

 Thanks! Actually,  if I understood well what you proposed, that's how I
 first tought of doing it, but with a [Maybe String] and only append whenever
 I actually had a (Just string), but as I said before, I don't think my
 teacher is gonna like that solution since it is not going to print when the
 interpreter finds the show instruction in the GCL code, it is gonna wait
 until it finishes

 I think maybe you don't quite have a grasp of lazy evaluation yet.  Try
 it.

 Also, nobody has told me why I shouldn't just use my original solution
 using unsafePerformIO, is it really bad? is it dangerous? why is it
 unsafe?

 You were told earlier:

 Well, writing to the standard output is certainly a side effect. (This
 does not mean that you cannot use unsafePerformIO. The compiler,
 however, may assume that any value is free from side effects. This
 means
 that you could get, in theory, less or more output from your program
 than you want. In this sense it is not safe.)

 Because pure (i.e. non-IO) values by definition never change, the compiler
 is free to assume that it can do them exactly once and remember the result.
  This means that it is possible for the compiler to evaluate your
 unsafePerformIO once and never again... or, more likely, to notice that the
 pure result is always () (because unsafePerformIO hides the IO from the
 compiler) and optimize it away completely (the do it exactly once being at
 compile time instead of run time).

 Ok, I got it this time, thanks! I should really talk this with my teacher.
 I'll post whatever he tells me... Let's hope he lets me just acumulate all
 the strings and print them in the end.

Hi Hector,

The notion you have about print in the end or (in a previous mail)
print as soon as it is evaluated is wrong.

Haskell is lazy.

This means things are evaluted when they are needed. Here, this means
the strings are produced *because* you print them out. If you don't
print them (or use them in another needed computation), they won't be
evaluated.

Also, garbage collection will reclaim the memory used by the strings
already evaluated and printed, so the accumulation doesn't really
occur from a memory usage point of view.

Cheers,
Thu
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Using unsafePerformIO safely

2009-06-25 Thread Brandon S. Allbery KF8NH

On Jun 26, 2009, at 01:11 , Hector Guilarte wrote:
Ok, I got it this time, thanks! I should really talk this with my  
teacher. I'll post whatever he tells me... Let's hope he lets me  
just acumulate all the strings and print them in the end.



You're still missing what lazy evaluation means.  If you write the  
equivalent of


  while x := read line do
mylist = mylist ++ x
  done
  result = process mylist -- this is the accumulate all the strings  
part.. except it isn't

  for x in result do
print x
  done

what you get is actually something like

  while x := read line do
print (process [x])
  done

This is because of laziness:  each part of the program requests only  
the minimum that is needed at any given time, and execution is  
interleaved as necessary.  You can think of it as:  print x requires  
a single item x, so it steps through process until a single item  
is produced; process then steps through the while read until it  
gets enough information to produce that single item being demanded at  
the moment.  How much depends on what process actually does:  if,  
for example, it's adding 1 to each item in the list, then it only  
needs to do 1 iteration of the while read in order to get something  
to add 1 to and pass on to the print x that is demanding an item  
from it.


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon universityKF8NH




PGP.sig
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Using unsafePerformIO safely

2009-06-25 Thread Ketil Malde
Luke Palmer lrpal...@gmail.com writes:

 mult2 x = unsafePerformIO $ do { print x; return (2*x) }

 main = do
 let answer = mult2 21
 print answer
 print answer

 [this] would print 21,42,42.  Thus our *correct* transformation of programs
 changed behavior.

Just to expand a bit on this, if you now enable optimization, the
compiler might decide that mult2 is a small function and just inline
it, essentially turning the program back into the first version (which
I didn't quote).

So the output of your program also may depend on the compiler and
compiler switches you use - this too is frowned upon in the ivory
towers of functional programming. 

 Safe uses of unsafePerformIO are those where any such transformation won't
 change the overall behavior of the program.  They do exist

Debug.Trace.trace is, I guess, the most well-known example?  Which you might
even consider using here, since at least the library will try to
instruct the compiler not to inline, so it's somewhat less likely to
do unexpected things.

 The list of strings solution is *the* Haskell way to solve this problem.
 If your teacher does not accept the solution, then your teacher is not
 actually letting you program in Haskell.

...which would come as no big surprise.

I'm told that my old alma mater, the informatics department at the
University of Bergen, is now going to teach Haskell as a small part of
a small course titled programming paradigms or some such this fall.
Haskell FTW! (Or more like Haskell 1 - Java 9311, but still.)

-k
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Using unsafePerformIO safely

2009-06-25 Thread gladstein
Regarding how to make the show instructions cause printout as soon as
they are executed:

If you write your interpreter to return a list of printout lines
(strings), you get this behavior for free. Haskell's laziness enables
the printing to start right away, while in an imperative language the
list of strings wouldn't be returned until it was complete.

To see this in action, try this program:

main = mapM putStrLn myList

myList = [first, second, loop, third]

loop = loop 

Despite the infinite loop, first and second print out.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Using unsafePerformIO safely

2009-06-24 Thread Hector Guilarte
Hello,

I made a GCL compiler using Alex and Happy and now I'm making the
interpreter to that program. Here's the deal:

First of all, I'm no expert in the usage of monads. Now:

Whenever a show instruction is found in any GCL program while the
interpretation is being done it is supposed to print on the stdout the
string or the aritmetic expresion it was called with, so I guessed I need to
run an IO operation and continue the interpretation of my program. I managed
to do this using unsafePerformIO and `seq` like is shown below. My question
is: Is it safe to use it this way? So far it is working great, but I need to
be sure I'm using it in a safe way. Like I said, I'm no expert in monads
and the System.IO.Unsafe documentation says:



*unsafePerformIO* ::
IOhttp://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIOa
- a
This is the back door into the
IOhttp://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIOmonad,
allowing
IOhttp://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIOcomputation
to be performed at any time. For this to be safe, the
IOhttp://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIOcomputation
should be free of side effects and independent of its
environment.


I don't know if the IO computation I'm doing is free of side effects and
independent of its enviroment :s. (is just hPutStr stdout )

Also I've read something about my code not being executed for sure or
something like that. Can somebody check the code and tell me if I'm safe
with it?

Thanks a lot!

Here's the code:

-- Tabla is my Symbol Table of the program being interpreted
evalInstruccion:: Instruccion - Tabla - Tabla
evalInstruccion (ShowY showY) tabla = myRunIO (evalShow showY tabla)
evalInstruccion _ tabla = tabla  -- There are many other Instructions
here missing wich are not relevant to my question

{-# NOINLINE myRunIO #-}
myRunIO:: (Tabla, IO()) - Tabla
myRunIO tupla = ((unsafePerformIO (snd tupla)) `seq` (fst tupla)) -- Here's
the unsafePerformIO Am I safe?

evalShow:: ShowY - Tabla - (Tabla, IO())
evalShow (ShowS string) tabla = (tabla,(hPutStr stdout string))
evalShow (ShowE expr) tabla = (tabla,(hPutStr stdout (show (evalExpr expr
tabla -- Don't worry about evalExpr, it works and returns an Int
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Using unsafePerformIO safely

2009-06-24 Thread Jochem Berndsen
(Also taking this to the -cafe)

Hector Guilarte wrote:
  I made a GCL compiler using Alex and Happy and now I'm making the
  interpreter to that program. Here's the deal:
 
  First of all, I'm no expert in the usage of monads. Now:
 
  Whenever a show instruction is found in any GCL program while the
  interpretation is being done it is supposed to print on the stdout the
  string or the aritmetic expresion it was called with, so I guessed I
need to
  run an IO operation and continue the interpretation of my program. I
managed
  to do this using unsafePerformIO and `seq` like is shown below. My
question
  is: Is it safe to use it this way? So far it is working great, but I
need to
  be sure I'm using it in a safe way. Like I said, I'm no expert in
monads
  and the System.IO.Unsafe documentation says:
 
  
  *unsafePerformIO* ::
 
IOhttp://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIOa
  - a
  This is the back door into the
 
IOhttp://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIOmonad,
  allowing
 
IOhttp://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIOcomputation
  to be performed at any time. For this to be safe, the
 
IOhttp://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIOcomputation
  should be free of side effects and independent of its
  environment.
  
 
  I don't know if the IO computation I'm doing is free of side effects and
  independent of its enviroment :s. (is just hPutStr stdout )

Well, writing to the standard output is certainly a side effect. (This
does not mean that you cannot use unsafePerformIO. The compiler,
however, may assume that any value is free from side effects. This means
that you could get, in theory, less or more output from your program
than you want. In this sense it is not safe.)

  Also I've read something about my code not being executed for sure or
  something like that. Can somebody check the code and tell me if I'm
safe
  with it?

It's safe in the sense that it probably won't blow up your computer.
It may also work. On the other hand, I would not recommend using
unsafePerformIO in this way.

I see two possibilities for resolving this issue:
* (ugly) run your GCL (Guarded Command Language?) interpreter in the IO
monad, and using print/putStr/... whenever you encounter a 'show'
statement in the GCL program.
* (nicer/Haskellier) adapt your interpreter such that it returns a list
of Strings to output. You have then a purely functional interpreter, and
in the main function of your program you can print this list. This will
be lazily evaluated as the GCL program runs. You now have a very nice
separation of clean, pure code, and impure code in the IO monad (your
main function, which can be pretty small in your case). To avoid
boilerplate, you can use the Writer monad, for example, but others may
have better suggestions.

Kind regards,

--
Jochem Berndsen | joc...@functor.nl
GPG: 0xE6FABFAB
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Using unsafePerformIO safely

2009-06-24 Thread Hector Guilarte
Thanks for answering so fast.

Yes, GCL == Guarded Command Language... It is for an assigment I have in my
Languages and Machines Course.

About the nicer/Haskellier solution you proposed: If there is a way of
printing right in the moment the Interpreter finds the show instruction then
I don't think the teacher is gonna like this soluttion (I would bet on that)
so, can you (or somebody) explain a little bit better how would the ugly
solution be? As I said earlier, I'm no expert in monads, actually the truth
is that I know almost nothing about monads, so please, explain it to me as
if you are explaining it to a Monads newbie...

Also, can somebody explain me how would it be using the Writer Monad?
remember is for a Monads newbie...

Thanks a lot!

Hector Guilarte


On Thu, Jun 25, 2009 at 6:04 PM, Jochem Berndsen joc...@functor.nl wrote:

 Hector Guilarte wrote:
  I made a GCL compiler using Alex and Happy and now I'm making the
  interpreter to that program. Here's the deal:
 


  First of all, I'm no expert in the usage of monads. Now:
 
  Whenever a show instruction is found in any GCL program while the
  interpretation is being done it is supposed to print on the stdout the
  string or the aritmetic expresion it was called with, so I guessed I need
 to
  run an IO operation and continue the interpretation of my program. I
 managed
  to do this using unsafePerformIO and `seq` like is shown below. My
 question
  is: Is it safe to use it this way? So far it is working great, but I need
 to
  be sure I'm using it in a safe way. Like I said, I'm no expert in
 monads
  and the System.IO.Unsafe documentation says:
 
  
  *unsafePerformIO* ::
  IO
 http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIO
 a
  - a
  This is the back door into the
  IO
 http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIO
 monad,
  allowing
  IO
 http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIO
 computation
  to be performed at any time. For this to be safe, the
  IO
 http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIO
 computation
  should be free of side effects and independent of its
  environment.
  
 
  I don't know if the IO computation I'm doing is free of side effects and
  independent of its enviroment :s. (is just hPutStr stdout )

 Well, writing to the standard output is certainly a side effect. (This
 does not mean that you cannot use unsafePerformIO. The compiler,
 however, may assume that any value is free from side effects. This means
 that you could get, in theory, less or more output from your program
 than you want. In this sense it is not safe.)

  Also I've read something about my code not being executed for sure or
  something like that. Can somebody check the code and tell me if I'm
 safe
  with it?

 It's safe in the sense that it probably won't blow up your computer.
 It may also work. On the other hand, I would not recommend using
 unsafePerformIO in this way.

 I see two possibilities for resolving this issue:
 * (ugly) run your GCL (Guarded Command Language?) interpreter in the IO
 monad, and using print/putStr/... whenever you encounter a 'show'
 statement in the GCL program.
 * (nicer/Haskellier) adapt your interpreter such that it returns a list
 of Strings to output. You have then a purely functional interpreter, and
 in the main function of your program you can print this list. This will
 be lazily evaluated as the GCL program runs. You now have a very nice
 separation of clean, pure code, and impure code in the IO monad (your
 main function, which can be pretty small in your case). To avoid
 boilerplate, you can use the Writer monad, for example, but others may
 have better suggestions.

 Kind regards,

 --
 Jochem Berndsen | joc...@functor.nl
 GPG: 0xE6FABFAB

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Using unsafePerformIO safely

2009-06-24 Thread Luke Palmer
On Wed, Jun 24, 2009 at 7:56 PM, Hector Guilarte hector...@gmail.comwrote:

 Thanks for answering so fast.

 Yes, GCL == Guarded Command Language... It is for an assigment I have in my
 Languages and Machines Course.

 About the nicer/Haskellier solution you proposed: If there is a way of
 printing right in the moment the Interpreter finds the show instruction then
 I don't think the teacher is gonna like this soluttion (I would bet on that)
 so, can you (or somebody) explain a little bit better how would the ugly
 solution be? As I said earlier, I'm no expert in monads, actually the truth
 is that I know almost nothing about monads, so please, explain it to me as
 if you are explaining it to a Monads newbie...


The ugly solution is essentially to write it as an imperative program.  IO
monad is a fancy word for imperative programming.

I'm beginning to think the best way to teach monads is not to (until the
student is essentially begging for them without knowing it), and let them be
grown into as the pattern is seen.  So, let's not use them.

Let's give the language a semantics of the form Tabla - ([String], Tabla).
That means that every expression has the meaning of a function which takes a
symbol table, and outputs a series of lines and a new symbol table.  This
will be the range of your evalInstruccion.

I'll do the ShowY case and a Sequence case for sequencing together
multiple instructions, which is important.  The rest should be
straightforward from there.

evalInstruccion :: Instruccion - Tabla - ([String], Tabla)
evalInstruccion (ShowY showY) tabla = ([evalShow showY tabla], tabla)
evalInstruccion (Sequence instr1 instr2) tabla =
let (out1, tabla')  = evalInstruccion instr1 tabla
(out2, tabla'') = evalInstruccion instr2 tabla'
in (out1 ++ out2, tabla'')
...

evalShow :: ShowY - Tabla - String
evalShow = ...

This pattern can be used for more than lists of strings; it can be used for
any monoid.  If I were to follow the pattern of your code, the monoid
would be IO (), and the operation (instead of (++)) would be ().  But
there would still be no unsafePerformIO, the semantics of the langauge would
be Tabla - (IO (), Tabla), and we would put build one big IO () to return
at the end from the output of the subexpressions.

Does this make sense?

Luke



 Also, can somebody explain me how would it be using the Writer Monad?
 remember is for a Monads newbie...

 Thanks a lot!

 Hector Guilarte


 On Thu, Jun 25, 2009 at 6:04 PM, Jochem Berndsen joc...@functor.nlwrote:

 Hector Guilarte wrote:
  I made a GCL compiler using Alex and Happy and now I'm making the
  interpreter to that program. Here's the deal:
 


  First of all, I'm no expert in the usage of monads. Now:
 
  Whenever a show instruction is found in any GCL program while the
  interpretation is being done it is supposed to print on the stdout the
  string or the aritmetic expresion it was called with, so I guessed I
 need to
  run an IO operation and continue the interpretation of my program. I
 managed
  to do this using unsafePerformIO and `seq` like is shown below. My
 question
  is: Is it safe to use it this way? So far it is working great, but I
 need to
  be sure I'm using it in a safe way. Like I said, I'm no expert in
 monads
  and the System.IO.Unsafe documentation says:
 
  
  *unsafePerformIO* ::
  IO
 http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIO
 a
  - a
  This is the back door into the
  IO
 http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIO
 monad,
  allowing
  IO
 http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIO
 computation
  to be performed at any time. For this to be safe, the
  IO
 http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIO
 computation
  should be free of side effects and independent of its
  environment.
  
 
  I don't know if the IO computation I'm doing is free of side effects and
  independent of its enviroment :s. (is just hPutStr stdout )

 Well, writing to the standard output is certainly a side effect. (This
 does not mean that you cannot use unsafePerformIO. The compiler,
 however, may assume that any value is free from side effects. This means
 that you could get, in theory, less or more output from your program
 than you want. In this sense it is not safe.)

  Also I've read something about my code not being executed for sure or
  something like that. Can somebody check the code and tell me if I'm
 safe
  with it?

 It's safe in the sense that it probably won't blow up your computer.
 It may also work. On the other hand, I would not recommend using
 unsafePerformIO in this way.

 I see two possibilities for resolving this issue:
 * (ugly) run your GCL (Guarded Command Language?) interpreter in the IO
 monad, and using print/putStr/... whenever you encounter a 'show'
 statement in the GCL program.
 * (nicer/Haskellier) adapt your interpreter such that it 

Re: [Haskell-cafe] Using unsafePerformIO safely

2009-06-24 Thread Hector Guilarte
On Thu, Jun 25, 2009 at 11:35 PM, Luke Palmer lrpal...@gmail.com wrote:

 On Wed, Jun 24, 2009 at 7:56 PM, Hector Guilarte hector...@gmail.comwrote:

 Thanks for answering so fast.

 Yes, GCL == Guarded Command Language... It is for an assigment I have in
 my Languages and Machines Course.

 About the nicer/Haskellier solution you proposed: If there is a way of
 printing right in the moment the Interpreter finds the show instruction then
 I don't think the teacher is gonna like this soluttion (I would bet on that)
 so, can you (or somebody) explain a little bit better how would the ugly
 solution be? As I said earlier, I'm no expert in monads, actually the truth
 is that I know almost nothing about monads, so please, explain it to me as
 if you are explaining it to a Monads newbie...


 The ugly solution is essentially to write it as an imperative program.  IO
 monad is a fancy word for imperative programming.

 I'm beginning to think the best way to teach monads is not to (until the
 student is essentially begging for them without knowing it), and let them be
 grown into as the pattern is seen.  So, let's not use them.

 Let's give the language a semantics of the form Tabla - ([String],
 Tabla).  That means that every expression has the meaning of a function
 which takes a symbol table, and outputs a series of lines and a new symbol
 table.  This will be the range of your evalInstruccion.

 I'll do the ShowY case and a Sequence case for sequencing together
 multiple instructions, which is important.  The rest should be
 straightforward from there.

 evalInstruccion :: Instruccion - Tabla - ([String], Tabla)
 evalInstruccion (ShowY showY) tabla = ([evalShow showY tabla], tabla)
 evalInstruccion (Sequence instr1 instr2) tabla =
 let (out1, tabla')  = evalInstruccion instr1 tabla
 (out2, tabla'') = evalInstruccion instr2 tabla'
 in (out1 ++ out2, tabla'')
 ...

 evalShow :: ShowY - Tabla - String
 evalShow = ...

 This pattern can be used for more than lists of strings; it can be used for
 any monoid.  If I were to follow the pattern of your code, the monoid
 would be IO (), and the operation (instead of (++)) would be ().  But
 there would still be no unsafePerformIO, the semantics of the langauge would
 be Tabla - (IO (), Tabla), and we would put build one big IO () to return
 at the end from the output of the subexpressions.

 Does this make sense?

 Luke


Hi Luke,

Thanks! Actually,  if I understood well what you proposed, that's how I
first tought of doing it, but with a [Maybe String] and only append whenever
I actually had a (Just string), but as I said before, I don't think my
teacher is gonna like that solution since it is not going to print when the
interpreter finds the show instruction in the GCL code, it is gonna wait
until it finishes to interpret the whole code and then print everything.
That's would be ok with me, but actually in a language point of view that
wouldn't be to usefull, since trying to debug a program printing flags
couldn't be done (and I'm not doing a debbuger for it). I know my language
is not gonna be used for real, but I'm sure that would be my teacher's
argument to tell me I can't do it that way. Still, I sent him an e-mail
asking if it can be done like that just in case.

If I didn't understand what you said, can you explain it again please?

If I did then, does anybody knows how to print on the screen in the moment
the show instruction is interpreted that guarantees that my code is gonna be
safe

Also, nobody has told me why I shouldn't just use my original solution using
unsafePerformIO, is it really bad? is it dangerous? why is it unsafe?


once again

thanks a lot in advance,


Hector Guilarte







 Also, can somebody explain me how would it be using the Writer Monad?
 remember is for a Monads newbie...

 Thanks a lot!

 Hector Guilarte


 On Thu, Jun 25, 2009 at 6:04 PM, Jochem Berndsen joc...@functor.nlwrote:

 Hector Guilarte wrote:
  I made a GCL compiler using Alex and Happy and now I'm making the
  interpreter to that program. Here's the deal:
 


  First of all, I'm no expert in the usage of monads. Now:
 
  Whenever a show instruction is found in any GCL program while the
  interpretation is being done it is supposed to print on the stdout the
  string or the aritmetic expresion it was called with, so I guessed I
 need to
  run an IO operation and continue the interpretation of my program. I
 managed
  to do this using unsafePerformIO and `seq` like is shown below. My
 question
  is: Is it safe to use it this way? So far it is working great, but I
 need to
  be sure I'm using it in a safe way. Like I said, I'm no expert in
 monads
  and the System.IO.Unsafe documentation says:
 
  
  *unsafePerformIO* ::
  IO
 http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIO
 a
  - a
  This is the back door into the
  IO
 http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AIO
 monad,
  allowing
  IO
 

Re: [Haskell-cafe] Using unsafePerformIO safely

2009-06-24 Thread Brandon S. Allbery KF8NH

On Jun 26, 2009, at 00:43 , Hector Guilarte wrote:
Thanks! Actually,  if I understood well what you proposed, that's  
how I first tought of doing it, but with a [Maybe String] and only  
append whenever I actually had a (Just string), but as I said  
before, I don't think my teacher is gonna like that solution since  
it is not going to print when the interpreter finds the show  
instruction in the GCL code, it is gonna wait until it finishes


I think maybe you don't quite have a grasp of lazy evaluation yet.   
Try it.


Also, nobody has told me why I shouldn't just use my original  
solution using unsafePerformIO, is it really bad? is it dangerous?  
why is it unsafe?


You were told earlier:


Well, writing to the standard output is certainly a side effect. (This
does not mean that you cannot use unsafePerformIO. The compiler,
however, may assume that any value is free from side effects. This  
means

that you could get, in theory, less or more output from your program
than you want. In this sense it is not safe.)


Because pure (i.e. non-IO) values by definition never change, the  
compiler is free to assume that it can do them exactly once and  
remember the result.  This means that it is possible for the compiler  
to evaluate your unsafePerformIO once and never again... or, more  
likely, to notice that the pure result is always () (because  
unsafePerformIO hides the IO from the compiler) and optimize it away  
completely (the do it exactly once being at compile time instead of  
run time).


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon universityKF8NH




PGP.sig
Description: This is a digitally signed message part
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Using unsafePerformIO safely

2009-06-24 Thread Hector Guilarte
On Fri, Jun 26, 2009 at 12:58 AM, Brandon S. Allbery KF8NH 
allb...@ece.cmu.edu wrote:

 On Jun 26, 2009, at 00:43 , Hector Guilarte wrote:

 Thanks! Actually,  if I understood well what you proposed, that's how I
 first tought of doing it, but with a [Maybe String] and only append whenever
 I actually had a (Just string), but as I said before, I don't think my
 teacher is gonna like that solution since it is not going to print when the
 interpreter finds the show instruction in the GCL code, it is gonna wait
 until it finishes


 I think maybe you don't quite have a grasp of lazy evaluation yet.  Try it.

 Also, nobody has told me why I shouldn't just use my original solution
 using unsafePerformIO, is it really bad? is it dangerous? why is it
 unsafe?


 You were told earlier:

  Well, writing to the standard output is certainly a side effect. (This
 does not mean that you cannot use unsafePerformIO. The compiler,
 however, may assume that any value is free from side effects. This means
 that you could get, in theory, less or more output from your program
 than you want. In this sense it is not safe.)


 Because pure (i.e. non-IO) values by definition never change, the compiler
 is free to assume that it can do them exactly once and remember the result.
  This means that it is possible for the compiler to evaluate your
 unsafePerformIO once and never again... or, more likely, to notice that the
 pure result is always () (because unsafePerformIO hides the IO from the
 compiler) and optimize it away completely (the do it exactly once being at
 compile time instead of run time).


Ok, I got it this time, thanks! I should really talk this with my teacher.
I'll post whatever he tells me... Let's hope he lets me just acumulate all
the strings and print them in the end.

Thanks again!

Hector Guilarte
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe