Scaling the outer walls: Oz/Mozart, osc and ozengine

Positive: There is an Oz tutorial started at eclectic

Warning: since Unicode there is no longer a single quote and a dbl-quote character: just as the left-Alt key was never the same scan code as the right-Alt key. In all that follows, copy the code into a reliable ANSI code editor and flip all ’single’ quotes to an ANSI apostrophe as on an American ASCII QWERTY keyboard and all dbl quotes to a SHIFT-apostrophe. Otherwise you are left with left single quotes, right-single quotes, left-dbl-quotes and right-dbl-quotes which will cause errors in Mozart. Do not use ‘back-tick’ (unshifted-~) as your apostrophe character.

You should not have to be a Prolog programmer to learn Oz, but short of being one already, what sense could you make of the errors you will encounter trying to follow the introduction to compiling an Oz application? The ‘Aufhebung’ issue again. Or you must almost know it just to learn it.

Here goes.

In Rebol you would just script it so:

write %dump.txt read http://localhost:8080/perl/get_env.prl

But in Oz you will need to compile to a functor, so let’s get started on the tutorial’s Webget.oz

You will need to wrap the file as a functor, so we start with

functor

end

We will open STDIN and STDOUT so we need Open and this will be an Application so we will import both:

functor
import
   Application
   Open
end

What follows is the code from the tutorial which will not compile (not in OPI, not on a cmd line):


functor
import
  Application
  Open
define
   Args = {Application.getArgs record('in'(single type:string)
                                  'out'(single type:string))}
   Status = try
	I={New Open.file init(url:  Args.'in')}
	O={New Open.file init(name: Args.'out'
        flags:[write create truncate])}
	in
	  local
	      proc { Copy}
	          S={I read(list:$)}
	       in
	          if S=="" then
	             {O write(vs:S)} { Copy}
	          end
	       end
	    in
	{ Copy}
    end
	catch _ then 1
	end
{Application.exit Status}
end

The warning we will receive will be an arity mismatch for Copy.
I experimented with {CopyWWW _} and with {CopyWWW X} in place of {Copy}
Running ozc -c in TextPad compiles succesfully by using {Copy _} in the first 2 occurences of {Copy}. Ditto for selecting ‘Compile File’ on the emacs oz menu.
Now on to compiling that oza file.
To get the oza file I had to use a cmd session:

ozc -c Webget.oz -o Webget.oza

Otherwise compiling (in TextPad or emacs) gave me just Webget.ozf
Now I could run the ozengine against a web page:

ozengine Webget.oza --in http://localhost:8080/perl/get_env.prl --out dump.txt

The program will only exit with CTRL-C CTRL-C and leaves file handles open but if you are content to run it just once

type dump.txt

Oops… no file?

We back track by revisiting the code.


functor
import
  Application
  Open
  Show           ; we will try to Show Status
define
   Args = {Application.getArgs record(
                'in'(single type:string)
                'out'(single type:string))}  ;; variable names are words
   Status = try
	In={New Open.file init(url:  Args.'in')}
	Out={New Open.file init(name: Args.'out'
        flags:[write create truncate])}
	in
	  local
	      proc { Copy}
	          Str={In read(list:$)}   ;; lhs var name is now a word
	       in
	          if Str=="" then
	             {Out write(vs:Str)} { Copy}
	          end
                     {In close}
                     {Out close}
	       end
	    in
	{ Copy}
    end
               0   ;; this was a missing ZERO as in 'success' ?
                    ;; (given that a ONE follows next on error)
	catch _ then
                    {Show Status}
                    1   ;; any exception is failure -
                        ;; was the file readonly?
	end
{Application.exit Status}     ;; Status remains unknown
end

Now we compile without ARITY issues … but still fail to write a file …

So now to look at file IO.

Hmm. The file io.oz offered for our edification has no error handling.

We try Webget2.oz for local disk files as follows:


functor import Application Open define Args = {Application.getArgs record('in' (single type:string) 'out' (single type:string))} Status = try In={New Open.file init(name: Args.'in')} Out={New Open.file init(name: Args.'out' flags:[write create truncate])} in local proc { Copy } Str={In read(list:$)} in if Str=="" then {Out write(vs:Str)} { Copy } end {In close} {Out close} end in { Copy } end 0 catch _ then 1 end {Application.exit Status} end

Which works great so the issue is reading the URL … It comes up in the browser and Rebol reads it fine as follows:

write %dump.txt “” ; we nix that file
write %dump.txt read http://localhost:8080/perl/get_env.prl

in a Rebol shell. So

if Str\=”" then

must be non-terminating for some URL’s on Win32. So we will read the whole URL first.
Now, how to iterate over a list … and then we start back at Lists and progress to the list module

Leave a Reply

You must be logged in to post a comment.