[mercury-users] Lisp-like syntax for Mercury (Mercury & macros)

Milan Zamazal pdm at zamazal.org
Thu Jun 6 19:25:59 AEST 2002

This message is primarily targeted to Lisp lovers, so don't hit my head
if you don't like the idea :-).  I tried to rewrite the source `sort.m'
from Mercury examples to a Lisp-like syntax, see below.  The idea is to
use an improved syntax for Mercury sources, more readable and
extensible.  Although the example below might not look much more
readable than the original Mercury source at the first glance, the
syntax has at least the following significant properties:

- No longer need to use crazy Perl-like operators (e.g. >, ->, -->,
  --->, maybe ----> in future?).

- More comfortable identifier syntax.

- You can use the full power of Lisp transformations, including macros.

- Good editor support (as a former participant of an attempt to create a
  modern Prolog mode for Emacs, I know how painful Prolog's syntax is
  from the point of view of editor support).

The idea is to write a simple Lisp translator to the native Mercury
syntax (with significant help of macros, of course).  The next step
might be to interface Mercury to Lisp systems, it might not be too
difficult to call Mercury from CMUCL or SBCL.

Is there anyone here considering this a good idea?  (It's useless to say
you don't like the idea at all -- satisfied Mercury users can just
ignore it, and if nobody expresses an interest I won't waste my limited
resources to go further with the idea.)

Milan Zamazal

(use-package :mercury)

(defmodule sort
  (:export main))

(import-module io string char require std-util)

(define main (* *)
  (:types (io:state io:state)
   :modes ((di uo :det)))
  "Some documentation."
  [io:command-line-arguments Args]
  (or [= Args '()]
      [handle-args [no] [no] * *]
      [sort * *]
      [= Args '(Input)]
      [handle-args [yes Input] [no] * *]
      [sort * *]
      [= Args '(Input Output)]
      [handle-args [yes Input] [yes Output] * *]
      [sort * *]
      [= Args '(_ _ _ . _)]
      [io:write-string "Usage: sort [Input [Output]]~%" * *]))

(define handle-args (In-arg Out-arg * *)
  (:types ((maybe string) (maybe string) io:state io:state)
   :modes ((in in di uo :det)))
  "Some documentation."
  (or [= In-arg [yes In-filename]]
      [io:see In-filename In-result * *]
      (or [= In-result [ok]]
	  [= In-result [error In-error]]
	  [io:error-message In-error In-msg]
	  [error In-msg])
      [= In-arg [no]])
  (or [= Out-arg [yes Out-filename]]
      [io:tell Out-filename Out-result * *]
      (or [= Out-result [ok]]
	  [= Out-result [error Out-error]]
	  [io:error-message Out-error Out-msg]
	  [error Out-msg])
      [= Out-arg no]))

(define sort (* *)
  (:types (io:state io:state)
   :modes ((di uo :det)))
  "Some documentation."
  [sort-2 '() * *])

(define sort-2 (Lines0)
  (:types ((list string) io:state io:state)
   :modes ((in di uo :det)))
  "Some documentation."
  [io:read-line-as-string Result]
  (or [= Result [error Error]]
      [io:error-message Error Msg]
      [error Msg]
      [= Result [eof]]
      [sort-output Lines0 * *]
      [= Result [ok Line]]
      [insert Lines0 Line Lines1]
      [sort-2 Lines1 * *]))

(define insert (List I L)
  (:types ((list T) T (list T))
   :modes ((in in out :det)))
  "Some documentation."
  (or [= List '()]
      [= L '(I)]
      [= List '(H . T)]
      [compare R I H]
      (if [= R [<]]
	  [= L '(I H . T)]
	  [insert T I NT]
	  [= L '(H . NT)])))

(define sort-output (Line-list * *)
  (:types ((list string) io:state io:state)
   :modes ((in di uo :det)))
  "Some documentation."
  (or [= Line-list '()]
      [= Line-list '(Line . Lines)]
      [io:write-string Line * *]
      [sort-output Lines * *]))
mercury-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe

More information about the users mailing list