Archive for the ‘programming tip’ Category

Really cool Curl

Thursday, September 13th, 2007

I was pointing out JSForth to a developer on-line (Forth interpreter in JavaScript) which I thought was cool but then I see this in Curl: a folding coding window in a web page.

Here is the Curl 5.0 code for the applet:


{curl 5.0 applet}
{curl-file-attributes character-encoding = "windows-latin-1"}
{applet manifest = "manifest.mcurl"}

{include "./utils/guide-header.scurl"}
{include "./utils/support.scurl"}

   {x-example-ref
        title = "Folding Tree example",
        {url "./examples/RIA_with_Curl.curl"}
    }

What this does is create a labeled hotspot on my page: with one click an entire Curl client-side scripting environment opens. The running example is there; the code that is running is there; buttons to execute, save applet; revert changes; close popup – and the panel allows editing the script.

Clicking on ‘Execute’ causes a popup version of the script to run with your changes.

I had seen this cool way of working with code as part of the example macro

{example

}

What was new was the ‘expandable’ and ‘collapsible’.

I cannot imagine this being more concise in JavaFX or in Groovy. Here is the Curl procedure from the include file:


|| Copyright (C) 1998-2006, Sumisho Computer Systems Corp.
|| All Rights Reserved.
{define-proc {x-example-ref
                 title:String = {message Example},
                 href:Url, ...}:Visual
    let display:Graphic = {example-ref title = title, href, ...}
    {for-each-graphic
        {proc {g:Graphic}:void
            {type-switch g
             case g:TextEditPanel do
                || consume right click, so TreeControl ignores it
                {g.add-event-handler
                    {on e:PointerPress do
                        {if e.button == right-button then
                            {e.consume}}}}}},
        display}
    {return
        {text-width-display
            {expandable
                border-width = 2px,
                {bold {value title}},
                display}}}
}
|| *** calls the following ***
{define-proc public {example-ref
                        loc:Url,
                        title:#String = null,
                        base-url:Url = {get-base-url},
                        manifest:ComponentManifest =
                           {get-default-manifest},
                        package:OpenPackage =
                            {OpenPackage
                                CURL.IMPLICIT.APPLET,
                                CURL.IDE.DOCUMENTATION,
                                manifest = manifest},
                        ...
                    }:Graphic
    let result:any =
        {try
            {evaluate
                base-url = loc,
                package = package,
                {format "\{example title = %w,\n %s\}",
                    title,
                    {read-from loc}}}
         catch e:Exception do
            {paragraph
                Error in {bold {value loc}}:{br}
                {text color = "red", {value e}}}}
    {return {Frame result, ...}}
}

It is perfectly readable. When you see ‘…’ inside { } what you are seeing are rest arguments, or unnamed arguments for variable parameter procedure calls. And then again in the

{ return {Frame result, …} }

– these are not code elisions! The critical {example } macro is in the evaluate block. Dynamic language fans will note that the result is their preferred type: any.

And to learn to use this expand/collapse ‘live’ code environment/widget all I had to do was right-click on a folding code-editor page in the Curl Documentation Viewer which is itself Curl. I copied in the files to include for my applet and set a few imports in my ‘manifest.mcurl’ file. No CLASSPATH to look at, no question of which JARs are where. No JavaScript library required. As cool as Smalltalk, Strongtalk or the XOTcl IDE.

To see one in action, you will need the XML Document Model for Curl 5.0 from curl.com
Just install the RTE, then the IDE and then the XDM. Open your Documentation Viewer and search for ‘WSDK XML Document Model’ or just ‘build-xml

The proc identifies an anonymous procedure and we pass in what Groovy calls a ‘closure’ at on e:PointerPress do or what would likely be an inner class Listener in Java.

If you know something as cool using FLASH with ActionScript, post a snippet or a link to same.
Of course you could do this using AJAX with Prototype and Scriptaculous. But I got this page out in a matter of minutes. Oh yes, Sun says JavaFX is not about ‘throwing up pages’ …

Imagine that you are working on a problematic page. You drop in a gem like this and now you are displaying and experimenting with your code. Only Seaside for Smalltalk can rival this as far as I am aware but that requires some understanding of Smalltalk. I love Seaside, but I know of nothing that can beat this. Of course Rebol 3.0 is on the way …

As for snide remarks from Sun in their JavaFX promo, there are quick ways to throw up a web page… I like blocknote and there is the Meta/HyperCard Revolution product or even MS Word or FrontPage in a pinch…

LRcurl Curlr, LcurlR and (CURL) parentheses

Sunday, June 17th, 2007

LRcurl would be the application of a Right and then a Left curly brace to a CURL expression.

Curl is proud to be LISP-like without the parentheses.

But it is sometimes less than clear how parentheses are to be interpreted in CURL.

It is clear enough how parentheses affect the application of mathematical operators.

But consider this: {let t1:int, t2:int = 42}

You may be aware that this leaves the value of t1 as zero.

So consider this: {set (t1, t2) = (1, 2)}

How are we to understand this as a CURL assignment statement?

The index to the on-line CURL documentation is resoundingly silent on the rationale for this syntax.

Set with parentheses is a fact. Is it because () is an operator?

But why should it not be the case that after {set (t1, t2) = 42} both t1 and t2 are 42 instead of this being a syntax error?

In the case of {set (t1, t2) = {my_func}} we know that the number of values returned by my_func must be two values.

You may want to guess at these values: {let t3:int, t4:int = (3,4)}

If you guessed 0 and 3, can you also tell me why this was not also a syntax error? It is enough to make my curly hair, well, curl left then right.
LcurlR

Joys of JavaScript

Thursday, June 14th, 2007

There is a web interpreter for JavaScript at www.squarefree.com which is just terrific. The up-arrow cmd history requires a backspace to edit ( at least in Opera ) but it is otherwise great.

It is the next best thing to running JavaScript persisted in a Smalltalk image.

But if you like a cool REPL for JS and are running even VisualStudio 2003 on .NET then you must compile the JScript ijs shell from the ListeningToReason blog.

Test either shell with

typeof Object(42)

and

Object(42).toString().length

or anything which you suspect might choke a toy Read-Eval-Print-Loop for JS.

Afterall, maybe you will find your inner Self in a LiveScript

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

Wednesday, June 13th, 2007

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

Scripting with Tcl on MS Windows

Wednesday, June 13th, 2007

If you use a Tcl shell such as tclsh84.exe for any scripting, you will want rlwrap.

What you get is not just prior commands a keystroke away with the up-arrow key, you also get the command history from previous sessions which you have aleady closed.

rlwrap is a ‘readline’ wrapper for most any console application ( I used to use it for io, the language, before I built my own shell.)

My tclsh.bat is as follows:

@echo off
i:
cd \scripts\tcl
i:\usr\bin\rlwrap tclsh84.exe

One little note: the first edition of Brent Welch’s ‘Practical Programming in Tcl and Tk’ was about 400+ pages. I picked up a new 3rd edition on abebooks.com for pennies – but it rang in at about 800 pages. Almost perlish by page count, but you are getting so much more ;-)

One nice thing: while the book has not blank pages at the back for my automatic pencil, it does have some 20 blank pages scattered through the book. Don’t tell Rich Tennant. Of course a guy with some toxic rubber cement could always paste in a few choice 5th Wave ‘toons.

Rebol CGI gremlin under Apache2

Monday, June 11th, 2007

Very little is required to run Rebol CGI scripts under Apache’s HTTP server if you are already running Perl or PHP scripts.

What spooked me was a peculiar echo in my HTML page of

Content-Type: html/text

which I could not shake.

There was an explanation. On my first test I used the singularly unimaginative file name of rebol.r just to be sure that I did not need to use a CGI file extension, e.g., rebol.cgi

Because my initial rebol.r worked fine, I went on to try test_002.r and my problems began …

It turns out that even in a /cgi-bin directory, if Rebol finds a file called Rebol.r then that file is executed before your own file.

Now this could be useful as a default header for all rebol CGI scripts in that directory. But if a script contains its own

prin “Content-Type: text/html”

the ghost will have been inserted into the machine.

Once I had renamed rebol.r to rebol_0001.r all was well. The following test script works fine:

#!I:/rebol/core/rebol.exe -cswq
Rebol [
Title: "CGI test 004"
]
prin "content-type: text/html^/^/"

comment {filename is rebol_004.r
test URl is http://localhost:8080/cgi-bin/Rebol_004.r
}

html32: make string! 2048

emitr: func [dat] [repend html32 dat]

emitr [{ html header goes here} ]

emitr [{ some dynamic html goes here
}]

emitr: [{closing html tags go here}]

prin html32

On with Rebolting Web Pages!

The Obol (Sufrin/Oxford) interpreter

Thursday, June 7th, 2007

Bernard Sufrin of Oxford has an interpreted language available for the JVM. His Obol language can be used in conjunction with Java rather as one uses Jython scripts.
About the only information available is a PDF. My interest was in the Obol shell. I have added a disambiguation page to Wikipedia to differentiate Sufrin’s Obol from the other two: the Tromso Obol and the Berkeley Obol. These days ‘Rio’ is about as overloaded a project name as ‘Obol’.

Passing Obol any arg other than -w would seem to result in a console-only interpreter, e.g.,

I:\Obol>java -cp . -jar Obol.jar -h

If you load a GUI script, e.g.,

I:\Obol>java -cp . -jar Obol.jar .\Examples\swing.ob

you may see warnings. In this respect Obol scripting is rather like Perl

if () {
…} else

where else follows on the same line as the closing brace.

In the case of Obol, this means that

let jb=JButton(“Test Button”) in
{ jb.addActionListener
(java.awt.event.ActionListener.new
{| actionPerformed event =

must be re-written as

let jb=JButton(“Test Button”) in
{ jb.addActionListener
(java.awt.event.ActionListener.new {|
actionPerformed event = { …

and the warnings disappear.

For more of Sufrin’s work and ideas see his projects page on Scala and such.

And if the obol is under your tongue …

Perl amok

Sunday, May 20th, 2007

The ‘camel’ book has become a little too thick, given what I just saw on my console.

I:\Tags_Project>perl tags_test002.prl
Creating pipe “PipeInTags”.
Can’t locate auto/Win32/Pipe/connect.al in @INC (@INC contains: [...]

What this means of course is that I have a typo.
I have typed

$PipeInTags->console()

where I should have typed

$PipeInTags->Console()

Perl cannot report that a string of text has a possible match in a PM in the same string with a leading Cap. Perl.

Perhaps a unix utility run amok. If Ruby is Smalltalk-as-perl where Objective-C is Smalltalk-as-Next-C then perhaps Ruby is the answer. But not for this task. Because Tclx remains buggy, I am left with Perl.

Many implementations of Smalltalk do not do much better with typos, which doubtless is why Unit testing started as SUnit (Dolphin 6 does quite well.)

MTF.

More to follow on Perl and the IDE.

Ruby and Gnome2 aka gtk2 and the iconv.dll

Wednesday, May 9th, 2007

My heart went out to the author of a mail list request for suggestions:

“I encountered the current problem I’m having about a year ago and thought I had figured what was wrong but can’t seem to remember how to fix it.”

Naturally after installing Gnome2, the simple ruby

require ‘gtk2′

failed.

I began slowly, conservatively, moving gtk2 site-ruby into my dev ruby tree.

I finally got to the iconv.dll missing entry-point error.

Here is my tip if you find that your ruby/bin already has an iconv.dll

In ruby/bin create a safety dir and move your current iconv.exe and iconv.dll into that backup area.

Now copy from the the gnome2/bin into ruby/bin

You should now get a reassuring true when you require ‘gtk2′

There are good tips on rubyscript2exe elsewhere on the web.

When the Io frontend won’t come back … an Io language tip

Monday, May 7th, 2007

If you are in the default frontend to Io, the language, and happen to revert to Smalltalk for a moment as in

CleverObj := KludgedObj clone.

and then find that you cannot recover without the offending ‘period’ with

CleverObj := KludgedObj clone

because now there is another error one line below the first …

Don’t panic!

Just enter

diddly

or

nil

or

whaddevvvah

and watch that error trump the previous exception.

Now you can happily clone again.

This seems to depend on the Win32 shell that I am running Io in, so you may never see this glitch …