|
View:
New views
6 Messages
—
Rating Filter:
Alert me
|
|
|
how to invoke SML/NJ's built-in pretty printer from a program?SML/NJ has a built-in pretty printer for printing values of various
types used by the top-level REPL. How do I invoke it from a program? There is a function PrettyPrint.pp_to_string of type int -> (stream -> 'a -> unit) -> 'a -> string, but to use it I would have to give it a value of type (stream -> 'a -> unit). How do I construct this argument? To make my question concrete, in the following SML program, by what do I replace “magic_pretty_printer” to make the program print “Happy, happy, joy, joy!”? datatype Xyzzy = C of Xyzzy * Xyzzy | D of string val plugh = C (D "hello",D "sailor") val plugh_string = "C (D \"hello\",D \"sailor\")" if ((magic_pretty_printer plugh) = plugh_string) then (print "Happy, happy, joy, joy!\n") else (raise (Fail "magic pretty printer gave wrong result")) I've browsed around the source for a while and failed to find what I need. Any hints would be helpful. I'd rather not use Backend.Interact.evalStream and capture the output somehow, but if that is my only option I would be grateful for an example of how to do it. Thanks for your time in considering this question. -- Joe -- Heriot-Watt University is a Scottish charity registered under charity number SC000278. ------------------------------------------------------------------------------ Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H _______________________________________________ Smlnj-list mailing list Smlnj-list@... https://lists.sourceforge.net/lists/listinfo/smlnj-list |
|
|
Re: how to invoke SML/NJ's built-in pretty printer from a program?I don't think that what you want is possible in SML/NJ, since it
requires runtime type information. In the REPL, we are able to pretty-print results because we know their type, but that is not true in general. Sorry. - John On Feb 26, 2009, at 7:10 AM, Joe Wells wrote: > SML/NJ has a built-in pretty printer for printing values of various > types used by the top-level REPL. > > How do I invoke it from a program? > > There is a function PrettyPrint.pp_to_string of type int -> (stream -> > 'a -> unit) -> 'a -> string, but to use it I would have to give it a > value of type (stream -> 'a -> unit). How do I construct this > argument? > > To make my question concrete, in the following SML program, by what do > I replace “magic_pretty_printer” to make the program print “Happy, > happy, joy, joy!”? > > datatype Xyzzy = C of Xyzzy * Xyzzy | D of string > > val plugh = C (D "hello",D "sailor") > val plugh_string = "C (D \"hello\",D \"sailor\")" > > if ((magic_pretty_printer plugh) = plugh_string) > then (print "Happy, happy, joy, joy!\n") > else (raise (Fail "magic pretty printer gave wrong result")) > > I've browsed around the source for a while and failed to find what I > need. Any hints would be helpful. > > I'd rather not use Backend.Interact.evalStream and capture the output > somehow, but if that is my only option I would be grateful for an > example of how to do it. > > Thanks for your time in considering this question. > > -- > Joe > > > -- > Heriot-Watt University is a Scottish charity > registered under charity number SC000278. > > > ------------------------------------------------------------------------------ > Open Source Business Conference (OSBC), March 24-25, 2009, San > Francisco, CA > -OSBC tackles the biggest issue in open source: Open Sourcing the > Enterprise > -Strategies to boost innovation and cut costs with open source > participation > -Receive a $600 discount off the registration fee with the source > code: SFAD > http://p.sf.net/sfu/XcvMzF8H > _______________________________________________ > Smlnj-list mailing list > Smlnj-list@... > https://lists.sourceforge.net/lists/listinfo/smlnj-list ------------------------------------------------------------------------------ Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H _______________________________________________ Smlnj-list mailing list Smlnj-list@... https://lists.sourceforge.net/lists/listinfo/smlnj-list |
|
|
Re: how to invoke SML/NJ's built-in pretty printer from a program?John Reppy <jhr@...> writes:
> I don't think that what you want is possible in SML/NJ, since it > requires > runtime type information. In the REPL, we are able to pretty-print > results > because we know their type, but that is not true in general. Sorry. Thanks very much for the answer. Let me ask a followup question. Is there a way to add type information to the global environment (what is in EnvRef.state) from a program? Here is a concrete example of what I have in mind: let val x = "world!”; in do_magic (); Backend.Interact.useStream (TextIO.openString "print (\"Hello, \"^x);") end Is there anything I can replace do_magic by in the above example to make it work? -- Thanks, Joe > - John > > On Feb 26, 2009, at 7:10 AM, Joe Wells wrote: > >> SML/NJ has a built-in pretty printer for printing values of various >> types used by the top-level REPL. >> >> How do I invoke it from a program? >> >> There is a function PrettyPrint.pp_to_string of type int -> (stream -> >> 'a -> unit) -> 'a -> string, but to use it I would have to give it a >> value of type (stream -> 'a -> unit). How do I construct this >> argument? >> >> To make my question concrete, in the following SML program, by what do >> I replace “magic_pretty_printer” to make the program print “Happy, >> happy, joy, joy!”? >> >> datatype Xyzzy = C of Xyzzy * Xyzzy | D of string >> >> val plugh = C (D "hello",D "sailor") >> val plugh_string = "C (D \"hello\",D \"sailor\")" >> >> if ((magic_pretty_printer plugh) = plugh_string) >> then (print "Happy, happy, joy, joy!\n") >> else (raise (Fail "magic pretty printer gave wrong result")) >> >> I've browsed around the source for a while and failed to find what I >> need. Any hints would be helpful. >> >> I'd rather not use Backend.Interact.evalStream and capture the output >> somehow, but if that is my only option I would be grateful for an >> example of how to do it. >> >> Thanks for your time in considering this question. >> >> -- >> Joe -- Heriot-Watt University is a Scottish charity registered under charity number SC000278. ------------------------------------------------------------------------------ Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H _______________________________________________ Smlnj-list mailing list Smlnj-list@... https://lists.sourceforge.net/lists/listinfo/smlnj-list |
|
|
Re: how to invoke SML/NJ's built-in pretty printer from a program?Joe Wells <jbw@...> writes:
> John Reppy <jhr@...> writes: > >> I don't think that what you want is possible in SML/NJ, since it >> requires runtime type information. In the REPL, we are able to >> pretty-print results because we know their type, but that is not >> true in general. Sorry. > > Thanks very much for the answer. > > Let me ask a followup question. Is there a way to add type > information to the global environment (what is in EnvRef.state) from > a program? Here is a concrete example of what I have in mind: > > let > val x = "world!”; > in > do_magic (); > Backend.Interact.useStream (TextIO.openString "print (\"Hello, \"^x);") > end Here is maybe a better version of what I have in mind: let val x = "world!”; in put_binding_of_type_string_for_identifier_y_in_global_environment x; Backend.Interact.useStream (TextIO.openString "print (\"Hello, \"^y);") end That's less confusing than what I wrote in the previous message. Is there any way to implement put_binding_of_type_string_for_identifier_y_in_global_environment so that it will work when called from inside a program like this? -- Joe > Is there anything I can replace do_magic by in the above example to > make it work? > > -- > Thanks, > > Joe > >> - John >> >> On Feb 26, 2009, at 7:10 AM, Joe Wells wrote: >> >>> SML/NJ has a built-in pretty printer for printing values of various >>> types used by the top-level REPL. >>> >>> How do I invoke it from a program? >>> >>> There is a function PrettyPrint.pp_to_string of type int -> (stream -> >>> 'a -> unit) -> 'a -> string, but to use it I would have to give it a >>> value of type (stream -> 'a -> unit). How do I construct this >>> argument? >>> >>> To make my question concrete, in the following SML program, by what do >>> I replace “magic_pretty_printer” to make the program print “Happy, >>> happy, joy, joy!”? >>> >>> datatype Xyzzy = C of Xyzzy * Xyzzy | D of string >>> >>> val plugh = C (D "hello",D "sailor") >>> val plugh_string = "C (D \"hello\",D \"sailor\")" >>> >>> if ((magic_pretty_printer plugh) = plugh_string) >>> then (print "Happy, happy, joy, joy!\n") >>> else (raise (Fail "magic pretty printer gave wrong result")) >>> >>> I've browsed around the source for a while and failed to find what I >>> need. Any hints would be helpful. >>> >>> I'd rather not use Backend.Interact.evalStream and capture the output >>> somehow, but if that is my only option I would be grateful for an >>> example of how to do it. >>> >>> Thanks for your time in considering this question. >>> >>> -- >>> Joe -- Heriot-Watt University is a Scottish charity registered under charity number SC000278. ------------------------------------------------------------------------------ Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H _______________________________________________ Smlnj-list mailing list Smlnj-list@... https://lists.sourceforge.net/lists/listinfo/smlnj-list |
|
|
Re: how to invoke SML/NJ's built-in pretty printer from a program?John Reppy <jhr@...> writes:
> I don't think that what you want is possible in SML/NJ, since it > requires runtime type information. In the REPL, we are able to > pretty-print results because we know their type, but that is not > true in general. Sorry. Hi, John, Appended below is one way to do it. Sadly, it's not elegant. Here are some thoughts that occur to me based on what I needed to do. 1. It would be helpful if there was some easy way to force the declarations already processed in a file to be contributed to the global environment so that “use” can use them. Right now I have to split my SML into two files both processed with useFile (by the command-line processing). Not only is this awkward, but it interferes with modularity because any portion of a large program that wants to use pretty printing will have to contribute something to the first file that gets loaded. 2. It is awkward to have to depend on the side effect of declarations being printed by useFile. Among other problems with this, I have to strip off the “val x =” prefix and the type suffix to get the desired pretty-printed result. It would be really nice if the pretty printer were exported. At the very least, it seems like it should not be to hard to allow directly requesting the pretty printing of the value bound to an identifier in the global environment (whose type will therefore already be known). 3. It would be nice if there was some way to tell the pretty printer to place no limits on nesting. Right now, one must specify large positive limits and hope they are big enough. (I suppose one could avoid using a bad result by testing to see if the pretty printed result gets parsed as the same value, but one should not need to do that.) I hope this message is somehow interesting and useful. -- Joe > - John > > On Feb 26, 2009, at 7:10 AM, Joe Wells wrote: > >> SML/NJ has a built-in pretty printer for printing values of various >> types used by the top-level REPL. >> >> How do I invoke it from a program? >> >> There is a function PrettyPrint.pp_to_string of type int -> (stream -> >> 'a -> unit) -> 'a -> string, but to use it I would have to give it a >> value of type (stream -> 'a -> unit). How do I construct this >> argument? >> >> To make my question concrete, in the following SML program, by what do >> I replace “magic_pretty_printer” to make the program print “Happy, >> happy, joy, joy!”? >> >> datatype Xyzzy = C of Xyzzy * Xyzzy | D of string >> >> val plugh = C (D "hello",D "sailor") >> val plugh_string = "C (D \"hello\",D \"sailor\")" >> >> if ((magic_pretty_printer plugh) = plugh_string) >> then (print "Happy, happy, joy, joy!\n") >> else (raise (Fail "magic pretty printer gave wrong result")) >> >> I've browsed around the source for a while and failed to find what I >> need. Any hints would be helpful. >> >> I'd rather not use Backend.Interact.evalStream and capture the output >> somehow, but if that is my only option I would be grateful for an >> example of how to do it. ====================================================================== #!/bin/bash # -*-SML-*- #(* TmpDir="`mktemp -d -t smlnj-script.XXXXXX`" CleanUp () { rm -r "$TmpDir"; } trap 'CleanUp; exit 1' INT TERM HUP trap CleanUp EXIT ln -s /dev/fd/4 "$TmpDir/a.sml" ln -s /dev/fd/5 "$TmpDir/b.sml" #*) sml -Ccm.verbose=false "$TmpDir/a.sml" "$TmpDir/b.sml" XyzzyPlugh "$0" "$@" 3<&0 <<'AAAA' 4<&0- <<'BBBB' 5<&0- 0<&3- (* Control.Print.out := { flush = fn () => (), say = fn _ => () }; *) datatype Xyzzy = C of Xyzzy * Xyzzy | D of string val xyzzy_tmp : Xyzzy option ref = ref NONE; AAAA fun evalString s = Backend.Interact.evalStream (TextIO.openString s, EnvRef.combined ()); fun unwind_protect body unwind_fn = ( (body ()) before (* EEEK! If this use of unwind_fn raises an exception, then unwind_fn will be run again from the exception handler. *) (unwind_fn ())) handle e => (unwind_fn (); raise e); fun capturePrinting f = let val old_out = ! Control.Print.out val data = ref "" in Control.Print.out := { flush = (fn () => ()), say = (fn s => data := !data ^ s) }; unwind_protect (fn () => (f (); !data)) (fn () => (Control.Print.out := old_out)) end; fun format_xyzzy xyz = (xyzzy_tmp := SOME xyz; (* *** TODO: must ensure printing is not truncated due to depth/length/etc. limits *) let val e = "val x = valOf (! xyzzy_tmp);" (* val _ = print (e^"\n") *) val s = capturePrinting (fn () => evalString e) in (* the length of "val x = " is 8, the length of " : Xyzzy\n" is 9 *) String.substring (s, 8, (String.size s) - 9 - 8) end) val plugh = C (D "hello",D "sailor") val plugh_string = "C (D \"hello\",D \"sailor\")" val z = format_xyzzy plugh; if (z = plugh_string) then (print "Happy, happy, joy, joy!\n") else (raise (Fail "magic pretty printer gave wrong result")); ignore (OS.Process.exit OS.Process.success); BBBB -- Heriot-Watt University is a Scottish charity registered under charity number SC000278. ------------------------------------------------------------------------------ Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are powering Web 2.0 with engaging, cross-platform capabilities. Quickly and easily build your RIAs with Flex Builder, the Eclipse(TM)based development software that enables intelligent coding and step-through debugging. Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com _______________________________________________ Smlnj-list mailing list Smlnj-list@... https://lists.sourceforge.net/lists/listinfo/smlnj-list |
|
|
Re: how to invoke SML/NJ's built-in pretty printer from a program?Joe Wells <jbw@...> writes:
> Here are some thoughts that occur to me based on what I needed to > do. > > 1. It would be helpful if there was some easy way to force the > declarations already processed in a file to be contributed to the > global environment so that “use” can use them. Right now I have > to split my SML into two files both processed with useFile (by > the command-line processing). Not only is this awkward, but it > interferes with modularity because any portion of a large program > that wants to use pretty printing will have to contribute > something to the first file that gets loaded. Okay, I now have a better understanding of this issue. What I was doing in my previous message involved this arrangement of nested function calls: procCmdLine (CM's function to handle command-line arguments) | +-useFile | +-useFile | +-evalStream (the one from Interact, not the one from EvalLoop) Because of some failures I encountered, I had gained the wrong understanding that declarations processed by an invocation of useFile would not be available to a nested useFile. That is, given a stack of function calls like useFile "a.sml" | +-useFile "b.sml" I had reached the wrong understanding that the declarations in b.sml would not be able to use datatypes or value identifiers declared in a.sml prior to the invocation of useFile. I know that this problem really does happen when the (useFile "b.sml") invocation is inside the same top-level form as the declarations that b.sml wants to use, but I'm pretty sure I was not doing this, so I am confused as to how I got confused. So anyway I now understand that this works fine. The other issues I raised are still a concern. Is there anything that can be done about them? > 2. It is awkward to have to depend on the side effect of > declarations being printed by useFile. Among other problems with > this, I have to strip off the “val x =” prefix and the type > suffix to get the desired pretty-printed result. It would be > really nice if the pretty printer were exported. At the very > least, it seems like it should not be to hard to allow directly > requesting the pretty printing of the value bound to an > identifier in the global environment (whose type will therefore > already be known). > > 3. It would be nice if there was some way to tell the pretty printer > to place no limits on nesting. Right now, one must specify large > positive limits and hope they are big enough. (I suppose one > could avoid using a bad result by testing to see if the pretty > printed result gets parsed as the same value, but one should not > need to do that.) Thanks for your time in any responses you make to my message. -- Joe >> On Feb 26, 2009, at 7:10 AM, Joe Wells wrote: >> >>> SML/NJ has a built-in pretty printer for printing values of various >>> types used by the top-level REPL. >>> >>> How do I invoke it from a program? >>> >>> There is a function PrettyPrint.pp_to_string of type int -> (stream -> >>> 'a -> unit) -> 'a -> string, but to use it I would have to give it a >>> value of type (stream -> 'a -> unit). How do I construct this >>> argument? >>> >>> To make my question concrete, in the following SML program, by what do >>> I replace “magic_pretty_printer” to make the program print “Happy, >>> happy, joy, joy!”? >>> >>> datatype Xyzzy = C of Xyzzy * Xyzzy | D of string >>> >>> val plugh = C (D "hello",D "sailor") >>> val plugh_string = "C (D \"hello\",D \"sailor\")" >>> >>> if ((magic_pretty_printer plugh) = plugh_string) >>> then (print "Happy, happy, joy, joy!\n") >>> else (raise (Fail "magic pretty printer gave wrong result")) >>> >>> I've browsed around the source for a while and failed to find what I >>> need. Any hints would be helpful. >>> >>> I'd rather not use Backend.Interact.evalStream and capture the output >>> somehow, but if that is my only option I would be grateful for an >>> example of how to do it. > > ====================================================================== > #!/bin/bash > # -*-SML-*- > #(* > TmpDir="`mktemp -d -t smlnj-script.XXXXXX`" > CleanUp () { rm -r "$TmpDir"; } > trap 'CleanUp; exit 1' INT TERM HUP > trap CleanUp EXIT > ln -s /dev/fd/4 "$TmpDir/a.sml" > ln -s /dev/fd/5 "$TmpDir/b.sml" > #*) > sml -Ccm.verbose=false "$TmpDir/a.sml" "$TmpDir/b.sml" XyzzyPlugh "$0" "$@" 3<&0 <<'AAAA' 4<&0- <<'BBBB' 5<&0- 0<&3- > > (* Control.Print.out := { flush = fn () => (), say = fn _ => () }; *) > > datatype Xyzzy = C of Xyzzy * Xyzzy | D of string > val xyzzy_tmp : Xyzzy option ref = ref NONE; > > AAAA > > fun evalString s = > Backend.Interact.evalStream (TextIO.openString s, EnvRef.combined ()); > > fun unwind_protect body unwind_fn = > ( (body ()) > before > (* EEEK! If this use of unwind_fn raises an exception, then unwind_fn will be run again from the exception handler. *) > (unwind_fn ())) > handle > e => (unwind_fn (); raise e); > > fun capturePrinting f = > let > val old_out = ! Control.Print.out > val data = ref "" > in > Control.Print.out := > { flush = (fn () => ()), > say = (fn s => data := !data ^ s) }; > unwind_protect > (fn () => (f (); !data)) > (fn () => (Control.Print.out := old_out)) > end; > > fun format_xyzzy xyz = > (xyzzy_tmp := SOME xyz; > (* *** TODO: must ensure printing is not truncated due to depth/length/etc. limits *) > let val e = "val x = valOf (! xyzzy_tmp);" > (* val _ = print (e^"\n") *) > val s = capturePrinting (fn () => evalString e) > in (* the length of "val x = " is 8, the length of " : Xyzzy\n" is 9 *) > String.substring (s, 8, (String.size s) - 9 - 8) > end) > > val plugh = C (D "hello",D "sailor") > val plugh_string = "C (D \"hello\",D \"sailor\")" > val z = format_xyzzy plugh; > if (z = plugh_string) > then (print "Happy, happy, joy, joy!\n") > else (raise (Fail "magic pretty printer gave wrong result")); > > ignore (OS.Process.exit OS.Process.success); > > BBBB > > > -- > Heriot-Watt University is a Scottish charity > registered under charity number SC000278. > > > ------------------------------------------------------------------------------ > Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are > powering Web 2.0 with engaging, cross-platform capabilities. Quickly and > easily build your RIAs with Flex Builder, the Eclipse(TM)based development > software that enables intelligent coding and step-through debugging. > Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com > _______________________________________________ > Smlnj-list mailing list > Smlnj-list@... > https://lists.sourceforge.net/lists/listinfo/smlnj-list -- Heriot-Watt University is a Scottish charity registered under charity number SC000278. ------------------------------------------------------------------------------ Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are powering Web 2.0 with engaging, cross-platform capabilities. Quickly and easily build your RIAs with Flex Builder, the Eclipse(TM)based development software that enables intelligent coding and step-through debugging. Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com _______________________________________________ Smlnj-list mailing list Smlnj-list@... https://lists.sourceforge.net/lists/listinfo/smlnj-list |
| Free embeddable forum powered by Nabble | Forum Help |