From: Jon Harrop
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <4305ff27$0$17470$ed2e19e4@ptn-nntp-reader04.plus.net>
Marco Antoniotti wrote:
> But the following looks very much like Common Lisp
> 
> (use-package "UNIFY")
> 
> (defun map2 (fun list-1 list-2)
>     (match-case (list list-1 list-2)
>        ((() ()) ())
>        (((?h1 . ?t1) (?h2 . ?t2))
>         (cons (funcall fun h1 h2) (map2 fun t1 t2)))
>        ((_ _) (error "Invalid list arguments to map2: ~S ~S." list-1
> list-2)))
> 
> Not only it looks like Common Lisp.  It is written in Common Lisp and it
> runs on every decent Common Lisp system.
> 
> http://common-lisp.net/project/cl-unification

Can I just check: that function is:

let rec map2 f l1 l2 = match l1, l2 with
  | [], [] -> []
  | h1 :: t1, h2 :: t2 -> f h1 h2 :: map2 f t1 t2
  | _ -> invalid_arg "list arguments to map2"

So "?" gives a variable in a pattern, "." is cons in a pattern. What does
"funcall" do?

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com

From: M Jared Finder
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <MMSdnf7v-dajnpveRVn-og@speakeasy.net>
Jon Harrop wrote:
> Marco Antoniotti wrote:
> 
>>But the following looks very much like Common Lisp
>>
>>(use-package "UNIFY")
>>
>>(defun map2 (fun list-1 list-2)
>>    (match-case (list list-1 list-2)
>>       ((() ()) ())
>>       (((?h1 . ?t1) (?h2 . ?t2))
>>        (cons (funcall fun h1 h2) (map2 fun t1 t2)))
>>       ((_ _) (error "Invalid list arguments to map2: ~S ~S." list-1
>>list-2)))
>>
>>Not only it looks like Common Lisp.  It is written in Common Lisp and it
>>runs on every decent Common Lisp system.
>>
>>http://common-lisp.net/project/cl-unification
> 
> 
> Can I just check: that function is:
> 
> let rec map2 f l1 l2 = match l1, l2 with
>   | [], [] -> []
>   | h1 :: t1, h2 :: t2 -> f h1 h2 :: map2 f t1 t2
>   | _ -> invalid_arg "list arguments to map2"
> 
> So "?" gives a variable in a pattern, "." is cons in a pattern. What does
> "funcall" do?

Funcall calls a function that is stored in a variable.  This is needed 
because Common Lisp is a "Lisp-2" that separates the value namespace 
from the function namespace  (Unlike Scheme, which is a Lisp-1).

See <http://www.nhplace.com/kent/Papers/Technical-Issues.html> for a 
discussion of this very topic.

   -- MJF
From: Marco Antoniotti
Subject: "Pattern arguments" in Common Lisp (Re: Ray tracer in Stalin)
Date: 
Message-ID: <dgoNe.48$DJ5.69105@typhoon.nyu.edu>
Jon Harrop wrote:
> Marco Antoniotti wrote:
> 
>>But the following looks very much like Common Lisp
>>
>>(use-package "UNIFY")
>>
>>(defun map2 (fun list-1 list-2)
>>    (match-case (list list-1 list-2)
>>       ((() ()) ())
>>       (((?h1 . ?t1) (?h2 . ?t2))
>>        (cons (funcall fun h1 h2) (map2 fun t1 t2)))
>>       ((_ _) (error "Invalid list arguments to map2: ~S ~S." list-1
>>list-2)))
>>
>>Not only it looks like Common Lisp.  It is written in Common Lisp and it
>>runs on every decent Common Lisp system.
>>
>>http://common-lisp.net/project/cl-unification
> 
> 
> Can I just check: that function is:
> 
> let rec map2 f l1 l2 = match l1, l2 with
>   | [], [] -> []
>   | h1 :: t1, h2 :: t2 -> f h1 h2 :: map2 f t1 t2
>   | _ -> invalid_arg "list arguments to map2"
> 
> So "?" gives a variable in a pattern, "." is cons in a pattern. What does
> "funcall" do?

FUNCALL calls a function stored in a variable because CL is a Lisp-2 
(unlike Scheme, Dylan, ML, and OCaml, which are essentially all Lisp-1).

Apart from that, the system I built (which is built in Common Lisp and 
it runs under any self-respecting CL implementation - here you should 
get the hint why Lispers stick to Lisp) is even more "expressive" than 
the OCaml system; I refrain from using the word "powerful" because it 
the compiler does not do anything particular with it.

Yet it is more expressive, because the system does full unification and 
not only pattern matching.  In particular, you have access to the UNIFY 
function and can set up your own modified macro that did the folllowing 
(actually this is a good idea and I will just go ahead and add it to the 
library)

	(unifying ()
	   ((foo ?x) (?y bar) (list x y))
	   (otherwise 42)))


Cheers
--
marco
From: Jon Harrop
Subject: Re: "Pattern arguments" in Common Lisp (Re: Ray tracer in Stalin)
Date: 
Message-ID: <430624c6$0$1300$ed2619ec@ptn-nntp-reader02.plus.net>
Marco Antoniotti wrote:
> FUNCALL calls a function stored in a variable because CL is a Lisp-2
> (unlike Scheme, Dylan, ML, and OCaml, which are essentially all Lisp-1).

Ok. But what else could the compiler do? That looks like an unambiguous
function application to me.

> Apart from that, the system I built (which is built in Common Lisp and
> it runs under any self-respecting CL implementation - here you should
> get the hint why Lispers stick to Lisp)

Extensibility? So Lisp should be good for compiler and interpreter writing?

> is even more "expressive" than the OCaml system;

Ok.

> I refrain from using the word "powerful" because it the compiler does not
> do anything particular with it. 

You're beginning to lose me here. What do you mean "it doesn't do anything
particular with it"?

> Yet it is more expressive, because the system does full unification and
> not only pattern matching.  In particular, you have access to the UNIFY
> function and can set up your own modified macro that did the folllowing
> (actually this is a good idea and I will just go ahead and add it to the
> library)
> 
> (unifying ()
> ((foo ?x) (?y bar) (list x y))
> (otherwise 42)))

Now I'm completely lost. What does that do?

To me, "unify" is from a type inference algorithm. I assume this is
something completely different.

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
From: Paul Dietz
Subject: Re: "Pattern arguments" in Common Lisp (Re: Ray tracer in Stalin)
Date: 
Message-ID: <de5j07$m7d$1@avnika.corp.mot.com>
Jon Harrop wrote:

> Extensibility? So Lisp should be good for compiler and interpreter writing?

Yes.  Most lisp compilers are written in lisp.

(Yum.  Dogfood.)

	Paul
From: David Golden
Subject: Re: "Pattern arguments" in Common Lisp (Re: Ray tracer in Stalin)
Date: 
Message-ID: <yqqNe.4141$R5.623@news.indigo.ie>
Jon Harrop wrote:
 
> Ok. But what else could the compiler do? That looks like an
> unambiguous function application to me.
> 
Not okay, because you apparently haven't got  what Lisp-1 vs. Lisp-2
means?

"(fun x y)" calls the function that is in the "function-value" of the
symbol fun with x and y.
"(funcall fun x y)" calls the function that is in the "variable-value"
of the symbol fun with x and y.

Any clearer?

Compare english:
"shovel dirt with shovel"
(shovel dirt shovel)
- one shovel is used as a verb, the other a noun, one names the action
of shovelling, one an implement for shovelling.

(though I believe many lispers might write 
"(shovel-with shovel dirt)")

Here, english is being a bit Lisp-2-ish.
From: Matthias Buelow
Subject: Re: "Pattern arguments" in Common Lisp (Re: Ray tracer in Stalin)
Date: 
Message-ID: <3mn6laF15ej7vU1@news.dfncis.de>
David Golden <············@oceanfree.net> wrote:

>Compare english:
>"shovel dirt with shovel"
>(shovel dirt shovel)
>- one shovel is used as a verb, the other a noun, one names the action
>of shovelling, one an implement for shovelling.
>(though I believe many lispers might write 
>"(shovel-with shovel dirt)")
>Here, english is being a bit Lisp-2-ish.

I don't think comparing natural languages with programming languages
will work for an argument; you'll probably always lose such an
argument.  If you compare Lisp with English, the following examples
should be equivalent and evaluated the same by Lisp:

(shovel dirt with shovel)
(shovel shovel dirt)
(shovel dirt)
(shovle drit showvl)
(scoop filth with the friggin blade)

mkb.
From: David Golden
Subject: Re: "Pattern arguments" in Common Lisp (Re: Ray tracer in Stalin)
Date: 
Message-ID: <BYtNe.4155$R5.879@news.indigo.ie>
Matthias Buelow wrote:


>>Here, english is being a bit Lisp-2-ish.
> 
> I don't think comparing natural languages with programming languages
> will work for an argument; you'll probably always lose such an
> argument. 

I wouldn't expect to win many arguments solely on a loose analogy to
natural language. On the other hand, I wasn't trying to win any
argument there in the first place?! I was just trying to demonstrate
that in English as in Lisp, the same symbol can stand for different
things in different contexts, because the OP seemed to be stuck on it.

After all,  I did say "a bit" - I meant in a vague sense of the same
symbol standing for more than one thing, not anything beyond that.

Anyway, in lisp, to know confidently what "(shovel dirt shovel)" meant,
you'd need to know about a  
"(defun shovel (stuff-to-be-shovelled implement-to-shovel-with) ...)"
because ordinary arguments (arguments in the sense I don't _think_ you
meant ?!) are positional - one could imagine another programmer
reversing the argument order in his defun, and thus (other:shovel
shovel dirt) would be what you wanted if using their #'other:shovel, or
you could write a glue macro to juggle the arguments around if you
really couldn't stand the argument order the other programmer picked.
From: Ulrich Hobelmann
Subject: Re: "Pattern arguments" in Common Lisp (Re: Ray tracer in Stalin)
Date: 
Message-ID: <3mmoatF171pl9U1@individual.net>
Jon Harrop wrote:
> Marco Antoniotti wrote:
>> FUNCALL calls a function stored in a variable because CL is a Lisp-2
>> (unlike Scheme, Dylan, ML, and OCaml, which are essentially all Lisp-1).
> 
> Ok. But what else could the compiler do? That looks like an unambiguous
> function application to me.

At first I hated Lisp-2 too, but after a while it seems to be natural ;)

(list foo bar) creates a list containing foo and bar.

(+ (first list) 4) adds 4 to the first element of "list."

So basically you can use the same name for variables and functions.  You 
could call a pair "cons" etc.

While this might seem unnecessary, in Common Lisp most things have their 
own namespaces (classes; types I think; probably other things too).

>> Apart from that, the system I built (which is built in Common Lisp and
>> it runs under any self-respecting CL implementation - here you should
>> get the hint why Lispers stick to Lisp)
> 
> Extensibility? So Lisp should be good for compiler and interpreter writing?

Well, ML is good for compiler writing too, IMHO.  Lisp makes it easy to 
represent arbitrary structured data as sexps (kindof like XML), so you 
don't have to decide on the whole AST type from the beginning.

So compilation, but also symbolic processing in general works nicely.

-- 
I believe in Karma.  That means I can do bad things to people
all day long and I assume they deserve it.
	Dogbert
From: Jon Harrop
Subject: Re: "Pattern arguments" in Common Lisp (Re: Ray tracer in Stalin)
Date: 
Message-ID: <430631c6$0$22943$ed2619ec@ptn-nntp-reader01.plus.net>
Ulrich Hobelmann wrote:
> Jon Harrop wrote:
>> Marco Antoniotti wrote:
>>> FUNCALL calls a function stored in a variable because CL is a Lisp-2
>>> (unlike Scheme, Dylan, ML, and OCaml, which are essentially all Lisp-1).
>> 
>> Ok. But what else could the compiler do? That looks like an unambiguous
>> function application to me.
> 
> At first I hated Lisp-2 too, but after a while it seems to be natural ;)
> 
> (list foo bar) creates a list containing foo and bar.
> 
> (+ (first list) 4) adds 4 to the first element of "list."
> 
> So basically you can use the same name for variables and functions.  You
> could call a pair "cons" etc.

This is interesting. But I don't understand how Lisp-2 improves over Lisp-1.
In ML you have:

  [foo; bar]
  List.hd list + 4

Hang on, you mean the first use of "list" is different from the second
because the first is a type constructor and the second is a variable? So
the OCaml equivalent is probably:

  List (foo, bar)
  List.hd list + 4

and the difference is implied by capitalisation.

> While this might seem unnecessary, in Common Lisp most things have their
> own namespaces (classes; types I think; probably other things too).
> 
>> Extensibility? So Lisp should be good for compiler and interpreter
>> writing?
> 
> Well, ML is good for compiler writing too, IMHO.  Lisp makes it easy to
> represent arbitrary structured data as sexps (kindof like XML), so you
> don't have to decide on the whole AST type from the beginning.

There is probably a much bigger activation barrier for interpreter and
compiler writing in ML than in Lisp. In ML, you have to reimplement
everything yourself. Also, there aren't many decent examples out there. In
Lisp, you can knock up little ideas as you think them up. That would be
really useful.

> So compilation, but also symbolic processing in general works nicely.

Ok.

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
From: Ulrich Hobelmann
Subject: Re: "Pattern arguments" in Common Lisp (Re: Ray tracer in Stalin)
Date: 
Message-ID: <3mmtj9F17lk1pU1@individual.net>
Jon Harrop wrote:
> This is interesting. But I don't understand how Lisp-2 improves over Lisp-1.
> In ML you have:
> 
>   [foo; bar]
>   List.hd list + 4
> 
> Hang on, you mean the first use of "list" is different from the second
> because the first is a type constructor and the second is a variable? So
> the OCaml equivalent is probably:
> 
>   List (foo, bar)
>   List.hd list + 4
> 
> and the difference is implied by capitalisation.

Well, actually the List module is like a Lisp package, so you could 
write list:hd in Lisp.  I think package names also have their own namespace.

Lisp-2 IMHO isn't a big improvement, but it's ok that functions have 
their own namespace, because almost everything else does too.

> There is probably a much bigger activation barrier for interpreter and
> compiler writing in ML than in Lisp. In ML, you have to reimplement
> everything yourself. Also, there aren't many decent examples out there. In
> Lisp, you can knock up little ideas as you think them up. That would be
> really useful.

Well, in ML you write the parser, and the AST as a datatype definition. 
  The rest is pattern-matching, so Lisp doesn't buy you too much there. 
  Of course, Lisp's other advantages (macros, OO) could help you.

[One of the better compiler books out there IMHO is "Modern compiler 
implementation in ML" by Andrew Appel (one of the people behind SML/NJ). 
  It's instructive to compare that book to the Java version.  Talk about 
workarounds. :D
]

-- 
I believe in Karma.  That means I can do bad things to people
all day long and I assume they deserve it.
	Dogbert
From: Pascal Costanza
Subject: Re: "Pattern arguments" in Common Lisp (Re: Ray tracer in Stalin)
Date: 
Message-ID: <3mpd2nF17rsp3U1@individual.net>
Jon Harrop wrote:

> This is interesting. But I don't understand how Lisp-2 improves over Lisp-1.

I think Lisp-2 is better than Lisp-1, but I don't think it's important 
enough for someone new to Lisp. It will become clear while working with 
Lisp as soon as the difference becomes really important. There are other 
issues that are more important in the beginning.


Pascal

-- 
OOPSLA'05 tutorial on generic functions & the CLOS Metaobject Protocol
++++ see http://p-cos.net/oopsla05-tutorial.html for more details ++++
From: Joe Marshall
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <wtmhak99.fsf@ccs.neu.edu>
Jon Harrop <······@jdh30.plus.com> writes:

> What does "funcall" do?

It is a namespace escape.  Unlike Scheme, Common Lisp has separate
function and variable namespaces.  The first element of a form is
resolved in the function namespace (there's an unimportant exception),
other identifiers are resolved in the variable namespace.

If you find that you want to use the non-default namespace you
need an escape mechanism.  The FUNCTION keyword resolves identifiers
in the function namespace.  FUNCALL is a bit of a hack:  it invokes
its first argument on all the rest of the arguments.  Since all
arguments are resolved in the variable namespace, this has the effect
of a namespace operator.
From: GP lisper
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <1124654412.6851e6843606a9cf251f1a8af1e3b4b9@teranews>
On Fri, 19 Aug 2005 13:50:42 -0400, <···@ccs.neu.edu> wrote:
>
> Jon Harrop <······@jdh30.plus.com> writes:
>
>> What does "funcall" do?
>
> It is a namespace escape....
>
> If you find that you want to use the non-default namespace you
> need an escape mechanism....

Thank you.  Between your explanation and the last Hyperspec example, I
see how neat FUNCALL is.  Being able to have your cake and eat it too
is tough to beat.  The other references I consulted had FUNCALL
explanations similar to Grahams ACL, which is not as good as yours.


-- 
Program A uses CLOS, Program B is implemented with structs, leading
to a fourfold increase in execution speed.  --J. B. Heimatseiten
From: Rob Thorpe
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <1124703770.270763.25810@o13g2000cwo.googlegroups.com>
GP lisper wrote:
> On Fri, 19 Aug 2005 13:50:42 -0400, <···@ccs.neu.edu> wrote:
> >
> > Jon Harrop <······@jdh30.plus.com> writes:
> >
> >> What does "funcall" do?
> >
> > It is a namespace escape....
> >
> > If you find that you want to use the non-default namespace you
> > need an escape mechanism....
>
> Thank you.  Between your explanation and the last Hyperspec example, I
> see how neat FUNCALL is.  Being able to have your cake and eat it too
> is tough to beat.  The other references I consulted had FUNCALL
> explanations similar to Grahams ACL, which is not as good as yours.

It's also worth mentioning that the prescence of function/funcall means
that you can use variable names that have the same names as functions.
In scheme for example you can't call a list "list" because it's the
name of a function.

It does mean a functions aren't really first class, but I don't think
that matters much.
From: ·········@gmail.com
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <1124713031.958624.89280@g44g2000cwa.googlegroups.com>
Rob Thorpe wrote:

> In scheme for example you can't call a list "list" because it's the
> name of a function.

Incorrect
From: Rob Thorpe
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <1124714770.703088.144620@f14g2000cwb.googlegroups.com>
·········@gmail.com wrote:
> Rob Thorpe wrote:
>
> > In scheme for example you can't call a list "list" because it's the
> > name of a function.
>
> Incorrect

I thought if you gave a variable the name "list" then the identifier is
rebound, so it's no longer bound to the function called list (Hence
"Germanic" naming).  Is this not the case in Scheme?
From: Pascal Bourguignon
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <87hddh7vmn.fsf@thalassa.informatimago.com>
"Rob Thorpe" <·············@antenova.com> writes:

> ·········@gmail.com wrote:
>> Rob Thorpe wrote:
>>
>> > In scheme for example you can't call a list "list" because it's the
>> > name of a function.
>>
>> Incorrect
>
> I thought if you gave a variable the name "list" then the identifier is
> rebound, so it's no longer bound to the function called list (Hence
> "Germanic" naming).  Is this not the case in Scheme?

It is the case in Scheme, but this doesn't prevent you to name a
variable "list":

[1]> (load"loaders:pseudo")
[2]> (scheme)
This is Pseudoscheme 2.12.

scheme[3]>  (let ((scheme-list list)
                  (list (list 1 2 3))) ; note the lexical scopes!
              (scheme-list list list))
((1 2 3) (1 2 3))

And since scheme doesn't treat : specially:

scheme[4]> (symbol->string 'scheme:list)
"SCHEME:LIST"
scheme[5]> (let ((scheme:list list) (list (list 1 2))) (scheme:list list list))
((1 2) (1 2))

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Grace personified,
I leap into the window.
I meant to do that.
From: Jon Harrop
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <4309a4a2$0$17485$ed2e19e4@ptn-nntp-reader04.plus.net>
Rob Thorpe wrote:
> It does mean a functions aren't really first class, but I don't think
> that matters much.

Really? It gives me the eebes. :-)

I especially don't understand why it wouldn't search the function stack for
a variable that is being applied - it must be a function?!

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
From: Rob Thorpe
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <1124717890.659698.294530@g14g2000cwa.googlegroups.com>
Jon Harrop wrote:
> Rob Thorpe wrote:
> > It does mean a functions aren't really first class, but I don't think
> > that matters much.
>
> Really? It gives me the eebes. :-)

It's not that nasty, they about 1.5th class.  It only really affects
the way a function is accessed slightly, you have to do #'something or
(function something) to refer to the function namespace.

It makes sense in a language with latent/dynamic types, very little
syntax and a huge number of functions.  Imagine, you're writing a
program, you want to do something and you look up the function to do
it, and find it's called, say "string=".  You then go "oh %$£#", I've
used that name as a variable in 15 different places in the code.  That
means wherever you've used it you've unbound the meaning of string= as
a function.

Huge amounts of discussion have gone into this issue, see:
http://www.nhplace.com/kent/Papers/Technical-Issues.html
for example.

If I were writing a new form of lisp I'd probably try to find a better
solution, but having too namespaces isn't really a problem.

> I especially don't understand why it wouldn't search the function stack for
> a variable that is being applied - it must be a function?!

That would be fine for the interpreter - I don't know about the
compiler though.  Lisp implementations have to think of ways to do
variable and function accesses that the compiler and the interpreter
can deal with efficiently.  And, both have to be able to deal with it
in the same running lisp.
From: Joe Marshall
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <64ty3pbd.fsf@ccs.neu.edu>
Jon Harrop <······@jdh30.plus.com> writes:

> Rob Thorpe wrote:
>> It does mean a functions aren't really first class, but I don't think
>> that matters much.
>
> Really? It gives me the eebes. :-)

They are first-class, you just have to use a namespace qualifier when
you want to use the function name to refer to them.

> I especially don't understand why it wouldn't search the function stack for
> a variable that is being applied - it must be a function?!

It would lead to bizarre behavior.  Suppose I defined foo like this:

(defun foo (bar)
  (bar 22))

This won't work correctly because BAR is bound in the variable
namespace, but the form (BAR 22) looks in the function namespace.

But suppose we modified lisp so that it figures `Hey, BAR isn't bound
in the function namespace, but there is this variable binding here
that names a function, he must've meant that.'  Now

(foo (lambda (x) (+ x 3)))
 => 25

Great!

But.....

We load a file and suddenly:

(foo (lambda (x) (+ x 3)))
 => #p"/home/~jrm/"

WTF?  The file we loaded defined BAR as

(defun bar (x)
  (declare (ignore x))
  (user-homedir-pathname))

In Common Lisp (without our bizarre extension), you can tell that
identifier BAR names the variable in this expression:

(defun foo (bar)
  (funcall bar 22))

and names a global function (if it is defined) in this one:

(defun foo (bar)
  (bar 22))

but in the bizarre one, where BAR's binding is resolved to can't be
determined by inspection.
From: Peter Seibel
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <m2zmr9ubq4.fsf@gigamonkeys.com>
"Rob Thorpe" <·············@antenova.com> writes:

> GP lisper wrote:
>> On Fri, 19 Aug 2005 13:50:42 -0400, <···@ccs.neu.edu> wrote:
>> >
>> > Jon Harrop <······@jdh30.plus.com> writes:
>> >
>> >> What does "funcall" do?
>> >
>> > It is a namespace escape....
>> >
>> > If you find that you want to use the non-default namespace you
>> > need an escape mechanism....
>>
>> Thank you.  Between your explanation and the last Hyperspec
>> example, I see how neat FUNCALL is.  Being able to have your cake
>> and eat it too is tough to beat.  The other references I consulted
>> had FUNCALL explanations similar to Grahams ACL, which is not as
>> good as yours.
>
> It's also worth mentioning that the prescence of function/funcall
> means that you can use variable names that have the same names as
> functions.  In scheme for example you can't call a list "list"
> because it's the name of a function.
>
> It does mean a functions aren't really first class, but I don't
> think that matters much.

Uh, you are using some personal definition of "first class" here,
right?

-Peter

-- 
Peter Seibel           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/
From: Rob Thorpe
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <1124793458.844452.322540@z14g2000cwz.googlegroups.com>
Peter Seibel wrote:
> "Rob Thorpe" <·············@antenova.com> writes:
>
> > GP lisper wrote:
> >> On Fri, 19 Aug 2005 13:50:42 -0400, <···@ccs.neu.edu> wrote:
> >> >
> >> > Jon Harrop <······@jdh30.plus.com> writes:
> >> >
> >> >> What does "funcall" do?
> >> >
> >> > It is a namespace escape....
> >> >
> >> > If you find that you want to use the non-default namespace you
> >> > need an escape mechanism....
> >>
> >> Thank you.  Between your explanation and the last Hyperspec
> >> example, I see how neat FUNCALL is.  Being able to have your cake
> >> and eat it too is tough to beat.  The other references I consulted
> >> had FUNCALL explanations similar to Grahams ACL, which is not as
> >> good as yours.
> >
> > It's also worth mentioning that the prescence of function/funcall
> > means that you can use variable names that have the same names as
> > functions.  In scheme for example you can't call a list "list"
> > because it's the name of a function.
> >
> > It does mean a functions aren't really first class, but I don't
> > think that matters much.
>
> Uh, you are using some personal definition of "first class" here,
> right?

Unfortunately, a lot of people consider something to be a first class
object only if it behaves in every way like the other first class
objects.  This is not the case in CL where they live in the same name
space and must be accessed by "function".

I don't think it's really useful to make the distinction this way
though.
From: Pascal Costanza
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <3n0dqiF18ddsaU1@individual.net>
Rob Thorpe wrote:

> Peter Seibel wrote:
> 
>>"Rob Thorpe" <·············@antenova.com> writes:
>>
>>>It does mean a functions aren't really first class, but I don't
>>>think that matters much.
>>
>>Uh, you are using some personal definition of "first class" here,
>>right?
> 
> Unfortunately, a lot of people consider something to be a first class
> object only if it behaves in every way like the other first class
> objects.  This is not the case in CL where they live in the same name
> space and must be accessed by "function".
> 
> I don't think it's really useful to make the distinction this way
> though.

It's just wrong. See http://en.wikipedia.org/wiki/First-class_object

Functions in Common Lisp fulfil _all_ of the possible meanings listed at 
that page.


Pascal

-- 
OOPSLA'05 tutorial on generic functions & the CLOS Metaobject Protocol
++++ see http://p-cos.net/oopsla05-tutorial.html for more details ++++
From: Rob Thorpe
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <1124799219.225426.175490@z14g2000cwz.googlegroups.com>
Pascal Costanza wrote:
> Rob Thorpe wrote:
>
> > Peter Seibel wrote:
> >
> >>"Rob Thorpe" <·············@antenova.com> writes:
> >>
> >>>It does mean a functions aren't really first class, but I don't
> >>>think that matters much.
> >>
> >>Uh, you are using some personal definition of "first class" here,
> >>right?
> >
> > Unfortunately, a lot of people consider something to be a first class
> > object only if it behaves in every way like the other first class
> > objects.  This is not the case in CL where they live in the same name
> > space and must be accessed by "function".
> >
> > I don't think it's really useful to make the distinction this way
> > though.
>
> It's just wrong. See http://en.wikipedia.org/wiki/First-class_object
>
> Functions in Common Lisp fulfil _all_ of the possible meanings listed at
> that page.

The problem is this one:
"being passable as a parameter to a procedure/function"

If functions are defined the normal way they cannot be directly passed,
though they can be passed through "(function fun)".  Of-course if one
puts a function in the variable namespace then they can be passed the
normal way - but I don't think that really counts.

This is why some people would say that functions are not first class in
CL.  I don't think that this is a particularly helpful definition, I
was using it only because it's how I've seen other people refer to what
a first-order function is.

None of this is really very important to programming it though.
From: Edi Weitz
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <u64tw6dj6.fsf@agharta.de>
On 23 Aug 2005 05:13:39 -0700, "Rob Thorpe" <·············@antenova.com> wrote:

> The problem is this one:
> "being passable as a parameter to a procedure/function"
>
> If functions are defined the normal way they cannot be directly
> passed, though they can be passed through "(function fun)".
> Of-course if one puts a function in the variable namespace then they
> can be passed the normal way - but I don't think that really counts.
>
> This is why some people would say that functions are not first class
> in CL.  I don't think that this is a particularly helpful
> definition, I was using it only because it's how I've seen other
> people refer to what a first-order function is.

Functions can of course be passed as parameters to other functions
like any other Lisp object.  You are confusing functional objects and
their names.

Cheers,
Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Rob Thorpe
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <1124817270.834588.169260@z14g2000cwz.googlegroups.com>
Edi Weitz wrote:
> On 23 Aug 2005 05:13:39 -0700, "Rob Thorpe" <·············@antenova.com> wrote:
>
> > The problem is this one:
> > "being passable as a parameter to a procedure/function"
> >
> > If functions are defined the normal way they cannot be directly
> > passed, though they can be passed through "(function fun)".
> > Of-course if one puts a function in the variable namespace then they
> > can be passed the normal way - but I don't think that really counts.
> >
> > This is why some people would say that functions are not first class
> > in CL.  I don't think that this is a particularly helpful
> > definition, I was using it only because it's how I've seen other
> > people refer to what a first-order function is.
>
> Functions can of course be passed as parameters to other functions
> like any other Lisp object.  You are confusing functional objects and
> their names.

I understand the difference (and how it's generally implemented, and
why).  A function can of course be passed as a parameter to a lisp
function, but that isn't really the point.  Normally, a function is
defined with defun and therefore placed in the function namespace,
where it needs escaping with special forms to access the object.

Anyway, this is nitpicking, so I'm going to shut-up.
From: Pascal Costanza
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <3n0qtsF1915qmU1@individual.net>
Rob Thorpe wrote:
> Pascal Costanza wrote:
> 
>>>>"Rob Thorpe" <·············@antenova.com> writes:
>>>>
>>>>
>>>>>It does mean a functions aren't really first class, but I don't
>>>>>think that matters much.
[...]

>>It's just wrong. See http://en.wikipedia.org/wiki/First-class_object
>>
>>Functions in Common Lisp fulfil _all_ of the possible meanings listed at
>>that page.
> 
> The problem is this one:
> "being passable as a parameter to a procedure/function"
> 
> If functions are defined the normal way they cannot be directly passed,
> though they can be passed through "(function fun)".  Of-course if one
> puts a function in the variable namespace then they can be passed the
> normal way - but I don't think that really counts.

Functions in Common Lisp can be passed to, and returned from, other 
functions. Full stop. It doesn't matter how inconvenient this is, and 
the inconvenience is even very low. What matters is that this sets a 
language apart from other languages in which you cannot pass functions 
to, and return from, other functions at all.


Pascal

-- 
OOPSLA'05 tutorial on generic functions & the CLOS Metaobject Protocol
++++ see http://p-cos.net/oopsla05-tutorial.html for more details ++++
From: Tobias C. Rittweiler
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <87slx0wpfs.fsf@GNUlot.localnet>
Pascal Costanza <··@p-cos.net> wrote:

> Functions in Common Lisp can be passed to, and returned from, other
> functions. Full stop. It doesn't matter how inconvenient this is, and
> the inconvenience is even very low.

Given that it's in fact so elegant! Isn't it a bit wondrous that it's
Scheme that's a Lisp-1? I mean, I'd expect a ``mysophobian'' to
appreciate not having everything in one big sack but having things
ordered in several distinct baskets instead: it's so more hygienic!

-tcr
From: Jon Harrop
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <430b0511$0$97109$ed2619ec@ptn-nntp-reader03.plus.net>
Pascal Costanza wrote:
> Rob Thorpe wrote:
>> Unfortunately, a lot of people consider something to be a first class
>> object only if it behaves in every way like the other first class
>> objects.  This is not the case in CL where they live in the same name
>> space and must be accessed by "function".
>> 
>> I don't think it's really useful to make the distinction this way
>> though.
> 
> It's just wrong. See http://en.wikipedia.org/wiki/First-class_object
> 
> Functions in Common Lisp fulfil _all_ of the possible meanings listed at
> that page.

Equality?

There is certainly some kind of an artificial distinction for function names
in Lisp that doesn't appear in other FPLs. It sounds as though this is due
to some of Lisp's dynamic features but I still haven't fully understood
why/how.

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
From: Edi Weitz
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <u1x4k6d7m.fsf@agharta.de>
On Tue, 23 Aug 2005 12:11:48 +0100, Jon Harrop <······@jdh30.plus.com> wrote:

> Pascal Costanza wrote:
>
>> It's just wrong. See http://en.wikipedia.org/wiki/First-class_object
>> 
>> Functions in Common Lisp fulfil _all_ of the possible meanings
>> listed at that page.
>
> Equality?

What do you mean?  Functions in Common Lisp are of course "comparable
for equality with other entities."

  * (let* ((foo (lambda (x) x))
           (bar foo) 
           (baz 42))
      (values (eql foo bar)
              (eql foo baz)))
  T
  NIL
  * (eql (lambda (x) x)
         (lambda (x) x))
  NIL

You might expect the second expression to return T but that's not
required by the definition in question.

Cheers,
Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Jon Harrop
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <430b59d2$0$1286$ed2619ec@ptn-nntp-reader02.plus.net>
Edi Weitz wrote:
> What do you mean?

I wasn't sure if functions were comparable in CL.

> Functions in Common Lisp are of course "comparable 
> for equality with other entities."
> 
>   * (let* ((foo (lambda (x) x))
>            (bar foo)
>            (baz 42))
>       (values (eql foo bar)
>               (eql foo baz)))
>   T
>   NIL
>   * (eql (lambda (x) x)
>          (lambda (x) x))
>   NIL
> 
> You might expect the second expression to return T but that's not
> required by the definition in question.

Ok. The situation is similar in OCaml, with physical and structural
equality. In Mathematica, there is only structural equality between ASTs.

So closures are first class objects in CL, as you would expect. The
confusion is that there are separate namespaces. Do variables with closure
values appear in the non-function namespace but their exact equivalents as
functions appear in the function namespace? So how you get a closure value
from a function/variable name in CL depends upon how that closure was
defined?

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
From: Pascal Costanza
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <3n1f19F194louU1@individual.net>
Jon Harrop wrote:

> So closures are first class objects in CL, as you would expect. The
> confusion is that there are separate namespaces. Do variables with closure
> values appear in the non-function namespace but their exact equivalents as
> functions appear in the function namespace? So how you get a closure value
> from a function/variable name in CL depends upon how that closure was
> defined?

(declaim (notinline foo))

(defun foo (x) (+ x x))

(let ((bar (lambda (x) (* x x))))
   (print (foo 5))
   (print (funcall bar 6))
   (let ((temp (function foo)))
     (setf (symbol-function 'foo) bar)
     (setf bar temp))
   (print (foo 5))
   (print (funcall bar 6)))

10
36
25
12

FUNCALL takes a first-class function object and calls it. FUNCTION takes 
a name and returns the function associated with it from the function 
name space as a first-class function object. SYMBOL-FUNCTION takes a 
symbol and returns the function associated with it from the function 
name space as a first-class function object. The difference between 
FUNCTION and SYMBOL-FUNCTION is that SYMBOL-FUNCTION only works on 
global functions whereas FUNCTION also works on local functions. On the 
other hand, the symbol passed to SYMBOL-FUNCTION can be a computed value 
whereas the name of the function returned by FUNCTION must be statically 
known.

In other words:

(foo ...) <=> (funcall (function foo) ...) for local and global foo 
functions.
(foo ...) <=> (funcall (symbol-function 'foo) ...) for global foo functions.

As Joe already said, FUNCTION and FUNCALL are operators that shift 
values between the function and the value name spaces. Whenever you 
divide things up into different name spaces, you need such shifting 
operators. That shouldn't be surprising.


Pascal

-- 
OOPSLA'05 tutorial on generic functions & the CLOS Metaobject Protocol
++++ see http://p-cos.net/oopsla05-tutorial.html for more details ++++
From: Pascal Costanza
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <3n0q9cF199a6pU1@individual.net>
Edi Weitz wrote:
> On Tue, 23 Aug 2005 12:11:48 +0100, Jon Harrop <······@jdh30.plus.com> wrote:
> 
> 
>>Pascal Costanza wrote:
>>
>>
>>>It's just wrong. See http://en.wikipedia.org/wiki/First-class_object
>>>
>>>Functions in Common Lisp fulfil _all_ of the possible meanings
>>>listed at that page.
>>
>>Equality?
> 
> What do you mean?  Functions in Common Lisp are of course "comparable
> for equality with other entities."

There are also discussions in papers by Henry Baker, and Sussman and 
Steele, how that could be useful. I don't recall the exact papers 
though. (Probably "Equal rights for functional objects" and one or more 
of the lambda papers.)


Pascal

-- 
OOPSLA'05 tutorial on generic functions & the CLOS Metaobject Protocol
++++ see http://p-cos.net/oopsla05-tutorial.html for more details ++++
From: Nathan Baum
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <defulk$hoo$1@news7.svr.pol.co.uk>
Jon Harrop wrote:
> Pascal Costanza wrote:
> 
>>Rob Thorpe wrote:
>>
>>>Unfortunately, a lot of people consider something to be a first class
>>>object only if it behaves in every way like the other first class
>>>objects.  This is not the case in CL where they live in the same name
>>>space and must be accessed by "function".
>>>
>>>I don't think it's really useful to make the distinction this way
>>>though.
>>
>>It's just wrong. See http://en.wikipedia.org/wiki/First-class_object
>>
>>Functions in Common Lisp fulfil _all_ of the possible meanings listed at
>>that page.
> 
> 
> Equality?

Certainly. Whilst you can't compare two _mathematical_ functions for 
equality, a Lisp function isn't quite a mathematical function: it's a 
particular implementation of an algorithm for applying a mathematical 
function.

   (equal #'car #'car)    -->  T
   (equal #'car #'cdr)    -->  NIL

However,

   (equal #'car #'first)  --> NIL

but that's okay because although CAR and FIRST are the same function in 
a mathematical sense, they aren't the same function in a Lisp sense.
From: Matthias Buelow
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <3mmi94F179t5uU1@news.dfncis.de>
Jon Harrop <······@jdh30.plus.com> wrote:
>Marco Antoniotti wrote:
>> But the following looks very much like Common Lisp
>> 
>> (use-package "UNIFY")
>> 
>> (defun map2 (fun list-1 list-2)
>>     (match-case (list list-1 list-2)
>>        ((() ()) ())
>>        (((?h1 . ?t1) (?h2 . ?t2))
>>         (cons (funcall fun h1 h2) (map2 fun t1 t2)))
>>        ((_ _) (error "Invalid list arguments to map2: ~S ~S." list-1
>> list-2)))
>> 
>> Not only it looks like Common Lisp.  It is written in Common Lisp and it
>> runs on every decent Common Lisp system.
>> 
>> http://common-lisp.net/project/cl-unification
>
>Can I just check: that function is:
>
>let rec map2 f l1 l2 = match l1, l2 with
>  | [], [] -> []
>  | h1 :: t1, h2 :: t2 -> f h1 h2 :: map2 f t1 t2
>  | _ -> invalid_arg "list arguments to map2"


In SML its:

fun map2 f [] [] = []
  | map2 h1::t1, h2::t2 = f h1 h2 :: map2 f t1 t2


The "invalid arguments" case is caught by the compiler at compile
time, and the result is guaranteed to unify.

Looks clea[rn]est to me of the above, imho.

mkb.
From: Marco Antoniotti
Subject: CL and ML patterns (Re: Ray tracer in Stalin)
Date: 
Message-ID: <n3qNe.51$DJ5.69230@typhoon.nyu.edu>
Matthias Buelow wrote:
> Jon Harrop <······@jdh30.plus.com> wrote:
> 
>>Marco Antoniotti wrote:
>>
>>>But the following looks very much like Common Lisp
>>>
>>>(use-package "UNIFY")
>>>
>>>(defun map2 (fun list-1 list-2)
>>>    (match-case (list list-1 list-2)
>>>       ((() ()) ())
>>>       (((?h1 . ?t1) (?h2 . ?t2))
>>>        (cons (funcall fun h1 h2) (map2 fun t1 t2)))
>>>       ((_ _) (error "Invalid list arguments to map2: ~S ~S." list-1
>>>list-2)))
>>>
>>>Not only it looks like Common Lisp.  It is written in Common Lisp and it
>>>runs on every decent Common Lisp system.
>>>
>>>http://common-lisp.net/project/cl-unification
>>
>>Can I just check: that function is:
>>
>>let rec map2 f l1 l2 = match l1, l2 with
>> | [], [] -> []
>> | h1 :: t1, h2 :: t2 -> f h1 h2 :: map2 f t1 t2
>> | _ -> invalid_arg "list arguments to map2"
> 
> 
> 
> In SML its:
> 
> fun map2 f [] [] = []
>   | map2 h1::t1, h2::t2 = f h1 h2 :: map2 f t1 t2
> 
> 
> The "invalid arguments" case is caught by the compiler at compile
> time, and the result is guaranteed to unify.

Well, that is the point of static type checking, isn't it?  I didnt' 
claim CL (or the UNIFY package) has static type checking (although with 
proper declarations some compilers will "flag" the violation at compile 
time).

> Looks clea[rn]est to me of the above, imho.

I will definitively grant you that.  However, given the UNIFY package 
the following

(def fun map2 f () () = ()
      or  map2 f (?h1 . ?t1) (?h2 . ?t2)
                = (cons (funcall f h1 h2) (map2 f t1 t2)))

is only one (DEFINER) macro away :)

Cheers
--
Marco



> 
> mkb.
From: Matthias Buelow
Subject: Re: CL and ML patterns (Re: Ray tracer in Stalin)
Date: 
Message-ID: <3mmp7pF17g6miU1@news.dfncis.de>
Marco Antoniotti <·······@cs.nyu.edu> wrote:

>(def fun map2 f () () = ()
>      or  map2 f (?h1 . ?t1) (?h2 . ?t2)
>                = (cons (funcall f h1 h2) (map2 f t1 t2)))
>
>is only one (DEFINER) macro away :)

It's surely possible; from what I know, the first ML was implemented
on top of Lisp, although I don't know how much it looked like today's
dialects and I don't know how much that Lisp was like Common Lisp.

mkb.
From: Matthias Buelow
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <3mmiilF179t5uU2@news.dfncis.de>
I wrote:

>fun map2 f [] [] = []
>  | map2 h1::t1, h2::t2 = f h1 h2 :: map2 f t1 t2
                ^
small typo, without the comma, of course.

mkb.
From: Jon Harrop
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <4306149a$0$1300$ed2619ec@ptn-nntp-reader02.plus.net>
Matthias Buelow wrote:
> In SML its:
> 
> fun map2 f [] [] = []
>   | map2 h1::t1, h2::t2 = f h1 h2 :: map2 f t1 t2
> 
> The "invalid arguments" case is caught by the compiler at compile
> time, and the result is guaranteed to unify.

I don't understand. The invalid arguments case cannot be caught by the
compiler at compile time because it is necessarily a run-time error. The
compiler should spot that your pattern is incomplete.

If by "unify" you mean it will type check then yes, of course. You wouldn't
get far if it didn't. ;-)

> Looks clea[rn]est to me of the above, imho.

The SML is certainly the shortest. I'm guessing, but a little syntactic
sugar could probably make the Lisp a lot shorter.

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
From: Matthias Buelow
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <3mmj6lF179t5uU3@news.dfncis.de>
Jon Harrop <······@jdh30.plus.com> wrote:

>I don't understand. The invalid arguments case cannot be caught by the
>compiler at compile time because it is necessarily a run-time error. The
>compiler should spot that your pattern is incomplete.

Hmm, well ok. Using case would make it look very much like the OCaml
version and one can use wildcards in the same way.

mkb
From: Förster vom Silberwald
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <1124700432.276948.85240@g43g2000cwa.googlegroups.com>
Matthias Buelow wrote:

> In SML its:
>
> fun map2 f [] [] = []
>   | map2 h1::t1, h2::t2 = f h1 h2 :: map2 f t1 t2
>
>
> The "invalid arguments" case is caught by the compiler at compile
> time, and the result is guaranteed to unify.

One additional side note: I once happend to read that Bigloo its
pattern-matching facility is more general than  OCaml its one.
Although, I am not sure what that means in reality.

That said, one shouldn't forget that neither OCaml (I think) nor Bigloo
features "list comprehension" (e.g. Clean does).

Schneewittchen
PS: OCaml and Bigloo had some common releations in the past, e.g:
http://groups.google.com/group/comp.lang.scheme/browse_frm/thread/23dad0e8a32a20c1/c10d3fd6751b1096?q=Bigloo+pattern+matching&rnum=14#c10d3fd6751b1096
From: Jon Harrop
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <430997a6$0$17485$ed2e19e4@ptn-nntp-reader04.plus.net>
F�rster vom Silberwald wrote:
> One additional side note: I once happend to read that Bigloo its
> pattern-matching facility is more general than  OCaml its one.
> Although, I am not sure what that means in reality.

MLs limit themselves to patterns that can be matching in linear time. I'd be
surprised if Bigloo didn't do this too. Mathematica doesn't, which lets you
write complicated algorithms as a simple pattern match but then you've no
idea how long it'll take to run.

OCaml also omits some linear patterns (for no good reason, AFAICT) such as
[|a; b; ..; c|] to match "a" and "b" at the start of a >=3-element array
and "c" at the end.

> That said, one shouldn't forget that neither OCaml (I think) nor Bigloo
> features "list comprehension" (e.g. Clean does).

Yes. I think Haskell has them. I've never used a language with list
comprehensions but I can see why they'd be useful.

> Schneewittchen
> PS: OCaml and Bigloo had some common releations in the past, e.g:
>
http://groups.google.com/group/comp.lang.scheme/browse_frm/thread/23dad0e8a32a20c1/c10d3fd6751b1096?q=Bigloo+pattern+matching&rnum=14#c10d3fd6751b1096

The site linked to no longer exists but it would be an interesting project,
to learn Lisp/Scheme.

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
From: Förster vom Silberwald
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <1124787246.253422.74400@g44g2000cwa.googlegroups.com>
Jon Harrop wrote:
http://groups.google.com/group/comp.lang.scheme/browse_frm/thread/23dad0e8a32a20c1/c10d3fd6751b1096?q=Bigloo+pattern+matching&rnum=14#c10d3fd6751b1096
>
> The site linked to no longer exists but it would be an interesting project,
> to learn Lisp/Scheme.

I am not sure whether I understand you right. However, it seems google
cut the tail. If you read the thread (in comp.lang.lisp) of your ray
tracer  in www.deja.com you will be able to follow the link.

The link is an old post of the developers of Bigloo where they
demonstrate how to call and intermix Bigloo modules with OCaml modules.
However, nowadays nobody calls OCaml from Bigloo anymore - I guess.

Schneewittchen
From: Marco Antoniotti
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <bbqOe.57$DJ5.70033@typhoon.nyu.edu>
F�rster vom Silberwald wrote:
> Matthias Buelow wrote:
> 
> 
>>In SML its:
>>
>>fun map2 f [] [] = []
>>  | map2 h1::t1, h2::t2 = f h1 h2 :: map2 f t1 t2
>>
>>
>>The "invalid arguments" case is caught by the compiler at compile
>>time, and the result is guaranteed to unify.
> 
> 
> One additional side note: I once happend to read that Bigloo its
> pattern-matching facility is more general than  OCaml its one.
> Although, I am not sure what that means in reality.
> 
> That said, one shouldn't forget that neither OCaml (I think) nor Bigloo
> features "list comprehension" (e.g. Clean does).
> 

But "list comprehension" is trivial in Common Lisp. :)  It can be built 
by itself or on top of (shameless plug 
http://common-lisp.net/project/cl-enumeration)


Cheers
--
Marco
From: David Golden
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <u3oNe.4128$R5.804@news.indigo.ie>
Jon Harrop wrote:

> So "?" gives a variable in a pattern, "." is cons in a pattern. What
> does "funcall" do?
> 

Just in case, as that "in a pattern" might indicate misunderstanding:

"(x . y)" is a cons ... period (groan). i.e. "(x . y)" is how a literal
cons is denoted in lisp  - "cons" names a function that returns a fresh
cons of its arguments.
From: Ulrich Hobelmann
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <3mmdr3F176cosU2@individual.net>
Jon Harrop wrote:
> Marco Antoniotti wrote:
>> But the following looks very much like Common Lisp
>>
>> (use-package "UNIFY")
>>
>> (defun map2 (fun list-1 list-2)
>>     (match-case (list list-1 list-2)
>>        ((() ()) ())
>>        (((?h1 . ?t1) (?h2 . ?t2))
>>         (cons (funcall fun h1 h2) (map2 fun t1 t2)))
>>        ((_ _) (error "Invalid list arguments to map2: ~S ~S." list-1
>> list-2)))
>>
>> Not only it looks like Common Lisp.  It is written in Common Lisp and it
>> runs on every decent Common Lisp system.
>>
>> http://common-lisp.net/project/cl-unification
> 
> Can I just check: that function is:
> 
> let rec map2 f l1 l2 = match l1, l2 with
>   | [], [] -> []
>   | h1 :: t1, h2 :: t2 -> f h1 h2 :: map2 f t1 t2
>   | _ -> invalid_arg "list arguments to map2"
> 
> So "?" gives a variable in a pattern, "." is cons in a pattern. What does
> "funcall" do?

Serious?  It calls a function... ;)

I think your Caml does the right thing there.

-- 
I believe in Karma.  That means I can do bad things to people
all day long and I assume they deserve it.
	Dogbert
From: Jon Harrop
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <430609c8$0$1300$ed2619ec@ptn-nntp-reader02.plus.net>
Ulrich Hobelmann wrote:
> Jon Harrop wrote:
>> Marco Antoniotti wrote:
>>> (use-package "UNIFY")
>>>
>>> (defun map2 (fun list-1 list-2)
>>>     (match-case (list list-1 list-2)
>>>        ((() ()) ())
>>>        (((?h1 . ?t1) (?h2 . ?t2))
>>>         (cons (funcall fun h1 h2) (map2 fun t1 t2)))
>>>        ((_ _) (error "Invalid list arguments to map2: ~S ~S." list-1
>>> list-2)))
>>>
>>> Not only it looks like Common Lisp.  It is written in Common Lisp and it
>>> runs on every decent Common Lisp system.
>>>
>>> http://common-lisp.net/project/cl-unification
>> 
>> Can I just check: that function is:
>> 
>> let rec map2 f l1 l2 = match l1, l2 with
>>   | [], [] -> []
>>   | h1 :: t1, h2 :: t2 -> f h1 h2 :: map2 f t1 t2
>>   | _ -> invalid_arg "list arguments to map2"
>> 
>> So "?" gives a variable in a pattern, "." is cons in a pattern. What does
>> "funcall" do?
> 
> Serious?  It calls a function... ;)

But so is "map2" and that doesn't require "funcall". What happens if you
miss out the "funcall"?

> I think your Caml does the right thing there.

Note that the OCaml can't print the lists easily in the case of an error.
The nearest you'll get is something like:

let string_of_list string_of l =
  "["^String.concat "; " (List.map string_of l)^"]"

let rec map2 string_of f l1 l2 = match l1, l2 with
 | [], [] -> []
 | h1 :: t1, h2 :: t2 -> f h1 h2 :: map2 f t1 t2
 | _ -> invalid_arg ("list arguments to map2 "^
      string_of_list string_of l1^" "^
      string_of_list string_of l2)

But that is the price you pay for optimising away run-time types and keeping
separate compilation.

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
From: Marco Antoniotti
Subject: Re: Ray tracer in Stalin
Date: 
Message-ID: <dDoNe.50$DJ5.69105@typhoon.nyu.edu>
Jon Harrop wrote:
> Ulrich Hobelmann wrote:
> 
>>>So "?" gives a variable in a pattern, "." is cons in a pattern. What does
>>>"funcall" do?
>>
>>Serious?  It calls a function... ;)
> 
> 
> But so is "map2" and that doesn't require "funcall". What happens if you
> miss out the "funcall"?

Most likely you will get an UNDEFINED-FUNCTION error.

> 
>>I think your Caml does the right thing there.
> 
> 
> Note that the OCaml can't print the lists easily in the case of an error.

Another reason to stick with Common Lisp :)

Cheers
--
Marco