Page 1 of 1

Is there an equivalent to flet or labels?

Posted: Thu Dec 06, 2012 5:12 pm
by gatesphere
Hi all,

Wondering if there's an equivalent to flet or labels in newLISP. I don't see any in the docs. There might be a way to hack it together with letex and lambda, but I'm not sure.

Any help?

Thanks.

Re: Is there an equivalent to flet or labels?

Posted: Fri Dec 07, 2012 12:28 pm
by johu
For example:

Code: Select all

(context 'MAIN:labels)
(define-macro (labels:labels)
  (letex (_labels (append '(let) 
                           (list (map (fn (x) (list (x 0) (append '(fn) (list (x 1)) (2 x)))) (args 0)))
                           (1 (args))))
     _labels))
(context MAIN)
Then:

Code: Select all

D:\>newlisp -n
newLISP v.10.4.5 on Win32 IPv4/6 libffi, execute 'newlisp -h' for more info.

> labels
nil
> [cmd]
(context 'MAIN:labels)
(define-macro (labels:labels)
  (letex (_labels (append '(let)
                           (list (map (fn (x) (list (x 0) (append '(fn) (list (x
 1)) (2 x)))) (args 0)))
                           (1 (args))))
     _labels))
(context MAIN)
(define (test-a x)
        (labels ((in-test (x y) (println "test-a " x " " y)))
          (in-test x "a")))

(define (test-b x)
        (labels ((in-test (x y) (println "test-b " x " " y)))
          (in-test "b" x)))

(define (in-test x)
        (println "test-out " x))
[/cmd]
labels
(lambda-macro ()
 (letex (_labels (append '(let) (list (map (lambda (x) (list (x 0) (append '(lam
bda )
         (list (x 1))
         (2 x))))
      (args 0)))
    (1 (args)))) _labels))
MAIN
(lambda (x) (labels ((in-test (x y) (println "test-a " x " " y))) (in-test x "a"
)))
(lambda (x) (labels ((in-test (x y) (println "test-b " x " " y))) (in-test "b" x
)))
(lambda (x) (println "test-out " x))
> (in-test "in-test")
test-out in-test
"in-test"
> (test-a "test-a")
test-a test-a a
"a"
> (test-b "test-b")
test-b b test-b
"test-b"
> (in-test "in-test")
test-out in-test
"in-test"
> [cmd]
(define (test-2 x y)
        (labels ((test-x (x) (println "test1 x=" x))
           (test-y (x) (println "test2 y=" x)))
          (test-x x)
          (test-y y)))
[/cmd]
(lambda (x y) (labels ((test-x (x) (println "test1 x=" x)) (test-y (x) (println
"test2 y="
     x)))
  (test-x x)
  (test-y y)))
> (test-2 "a" "b")
test1 x=a
test2 y=b
"b"
>

Re: Is there an equivalent to flet or labels?

Posted: Fri Dec 07, 2012 4:18 pm
by gatesphere
That's some nice code.

However, I'm failing when trying to use it to write another macro based on it:

Code: Select all

(define-macro (alambda)
  (labels ((self (args 0) (1 args)))
    self))

(setf 'a (alambda (n) (if (= n 0) 1 (* n (self (- n 1))))))

(println (a 5))
I'm getting these errors:

Code: Select all

ERR: symbol is protected in function let : self
called from user defined function labels
called from user defined function alambda
I'd like to be able to access "self" from a macro definition, so that I can define an anaphoric lambda macro to provide easy recursion.

:( My search continues.

Re: Is there an equivalent to flet or labels?

Posted: Fri Dec 07, 2012 4:43 pm
by Lutz
newLISP is not Common Lisp or Scheme and any intent to program in it, like you would in Common Lisp or Scheme, will end in frustration ;)

Try to solve your application problems with the functions built in to newLISP first. Not until you know newLISP's API well, write your own helpers to extend the language.

If you want to enjoy newLISP solving real world application problems, you have to program with newLISP on its own terms. A good start is to read the documentation and introductions available online:

The standard online documentation:

http://www.newlisp.org/downloads/newlisp_manual.html

http://www.newlisp.org/downloads/CodePatterns.html

Some explanation about differences between newLISP and other Lisps:

http://www.newlisp.org/index.cgi?page=D ... ther_LISPs

An introduction for beginners:

http://en.wikibooks.org/wiki/Introduction_to_newLISP

All links are from this page:

http://www.newlisp.org/index.cgi?Documentation

... which also has a list of very nice video tutorials. Some of them for advanced topics like FOOP.

Many small applications and snippets:

http://www.newlisp.org/index.cgi?Tips_and_Tricks

In any case welcome to newLISP, I hope you stay with us a bit longer :)

Re: Is there an equivalent to flet or labels?

Posted: Fri Dec 07, 2012 5:13 pm
by gatesphere
Thanks for all of those links, but I've read them already! :)

I'm aware that it's not CLISP or Scheme. That's why I'm attracted to it. I can't stand CLISP's bloat.

I was able to define an anaphoric if like this:

Code: Select all

(define-macro (aif)
  (let ((it (eval (args 0))))
    (if it
      (eval (args 1))
      (eval (args 2)))))
And an example:

Code: Select all

(aif (+ 23 42)
  (println it)
  (println "it's nil, bub."))
So it's a start. I'm just exploring the idea of anaphora, and figured newLISP would be a good language to try it in.

Re: Is there an equivalent to flet or labels?

Posted: Fri Dec 07, 2012 11:07 pm
by johu
self is a primitive function, then the variable name of self can't be used.

And previous labels's example cound not be used with closure.

Code: Select all

(context 'MAIN:labels)
(define-macro (labels:labels)
  (letex (_labels (append '(begin)
                          (map (fn (x)
                                 (list 'setq (x 0) (append '(fn) (list (x 1)) (2 x))))
                            (args 0))
                          (1 (args))))
    _labels))
(context MAIN)
And alambda is

Code: Select all

(define-macro (alambda)
  (letex (_funcbody (append '(_self) (list (args 0)) (1 (args))))
    (labels (_funcbody)
      _self)))
Then,

Code: Select all

D:\>newlisp -n
newLISP v.10.4.5 on Win32 IPv4/6 libffi, execute 'newlisp -h' for more info.

> self
self@40147C
> [cmd]
(context 'MAIN:labels)
(define-macro (labels:labels)
  (letex (_labels (append '(begin)
                          (map (fn (x)
                                 (list 'setq (x 0) (append '(fn) (list (x 1)) (2
 x))))
                            (args 0))
                          (1 (args))))
    _labels))
(context MAIN)
(define-macro (alambda)
  (letex (_funcbody (append '(_self) (list (args 0)) (1 (args))))
    (labels (_funcbody)
      _self)))
[/cmd]
labels
(lambda-macro ()
 (letex (_labels (append '(begin) (map (lambda (x) (list 'setq (x 0) (append '(l
ambda )
        (list (x 1))
        (2 x))))
     (args 0))
    (1 (args)))) _labels))
MAIN
(lambda-macro ()
 (letex (_funcbody (append '(_self) (list (args 0)) (1 (args)))) (labels (_funcb
ody)
   _self)))
> (set 'a (alambda (n) (if (= n 0) 1 (* n (_self (- n 1))))))
(lambda (n)
 (if (= n 0)
  1
  (* n (_self (- n 1)))))
> (a 3)
6
>
By the way
I rewrote codes of 'On Lisp' to newLISP.
If you are interested,
labels
http://johu02.wordpress.com/2010/06/19/
anaphoric macro
http://johu02.wordpress.com/2010/07/29/
But, Japanese, sorry.

Re: Is there an equivalent to flet or labels?

Posted: Fri Dec 21, 2012 3:33 pm
by William James

Code: Select all

> (set 'a (fn (n) (if (zero? n) 1 (* n (a (- n 1))))))
(lambda (n)
 (if (zero? n)
  1
  (* n (a (- n 1)))))
> (a 5)
120

Re: Is there an equivalent to flet or labels?

Posted: Sun Dec 23, 2012 10:03 pm
by rickyboy
What Lutz is telling you and what William James is showing you is that you don't need constructs like flet or labels in newLISP, which only make sense (in fact, are necessary) in languages like Common Lisp where function names and variable names live in different namespaces.

This is not true in so-called Lisp-1 languages like newLISP and Scheme, so flet and labels are completely unnecessary in those languages.

Asking the question "is there something like flet or labels in newLISP?" is like walking around for years with your pockets full of coins so that you could use the public pay phones any time you needed them; and then one day you got a cell phone and asked the question, "Now that I have this cell phone -- an extra thing to put in my pockets - - what is a good way for me to continue to carry these coins?"