From jan@swi.psy.uva.nl  Tue May 16 12:39:14 2000
Received: from gollem.swi.psy.uva.nl (root@gollem [145.18.152.30])
	by swi.psy.uva.nl (8.9.3/8.9.3) with ESMTP id MAA02612
	for <prolog@swi.psy.uva.nl>; Tue, 16 May 2000 12:39:14 +0200 (MET DST)
Received: from localhost (localhost [[UNIX: localhost]])
	by gollem.swi.psy.uva.nl (8.9.3/8.9.3/SuSE Linux 8.9.3-0.1) id MAA01018
	for prolog; Tue, 16 May 2000 12:39:33 +0200
From: Jan Wielemaker <jan@swi.psy.uva.nl>
Organization: SWI, University of Amsterdam
To: prolog@gollem.swi.psy.uva.nl
Subject: Idea: [] != '[]'?
Date: Tue, 16 May 2000 12:07:14 +0200
X-Mailer: KMail [version 1.0.28]
Content-Type: text/plain
MIME-Version: 1.0
Message-Id: <00051612393305.00382@gollem>
Content-Transfer-Encoding: 8bit

Hi,

Sometime ago Paul Singleton talked about using nested lists for various
purposes.  He pointed at the ambiguity that [] is both an atom and the
empty list.  I've come across this various times, as I also sometimes
come acress foo == foo().  I.e. with a representation where I have
atoms (for example representing text) and actions represented as
structures and I want:

	doit(Text) :-
		atom(Text), !,
		...
	doit(foo()) :-
		...

But as foo() is illegal syntax, this doesn't work.

* [] != '[]
===========

Both can be cured, extending SWI-Prolog.  First let us consider the
empty list.  This is an odd atom (and it is odd that the empty list,
which is a list after all is also an atom).  All these thing yield
exactly the same thing: an atom with the two characters [ and ].

	[], [ ], [/*hello*], '[]'

An alternative would be to turn [] into an atom that has some odd
properties:

	* It is returned by reading [], [ ], [/*hello*/]
	* It is written as [] (note that without precautions in
	  write/1 it is written as '[]').
	* It does *not* unify with '[]'

We can even go further:

	* atom/1 fails on it.  Just is_list/1 succeeds.
	* atom_chars/codes, etc. raise an exception on it:
	  it has no character representation.

Of course, '[]' behaves as an atom holding these two characters
and printed as '[]'.

Compatibility issues:

	* Code explicitly using '[]' as an empty-list will fail.
	  Does such code exist?

	* Foreign code doing PL_new_atom("[]") to get access to
	  the empty list will fail.  The interface already defines
	  PL_put_nil(), PL_unify_nil(), etc.  This appears
	  acceptable.

Implementation:

	* Most likely simple.  We just create the atom [] using
	  special code such that no such atom can be created from
	  a string.  Read and write already have special code.

Votes?

* Introducing foo()

I.e. compounds without arguments.  Basically this just means making
read/1 not check for it: internally these things already exist.  More
difficult is the integration with atoms.  What about the following:

	* X =.. [foo] ---> X = foo()
	
	* Does calling foo() fire the clause foo :- bar?  Or just
	  foo() :- bar?  In the first case writing foo :- bar is
	  no more then a shorthand for writing foo() :- bar, which
	  is actually the case if you look at the current compiler.

	  Same holds for calling an atom.

	* It is easy to add a compatibility flag (which is not the
	  case for the []/'[]' thing).

Votes?

	Regards --- Jan


