Listcomprehension-macro? Macros with args inside macro-name?

This is a discussion on Listcomprehension-macro? Macros with args inside macro-name? within the lisp forums in Programming Languages category; I am trying to learn lisp macros and I generally find listcomprehensions to be elegant and they dont exist in lisp. This has to be a macro right? Cant be a function? But how would I get started when it needs the arguments inside its name? In Python: >>> [x**2 for x in [12,31,2,33] if x > 20] [961, 1089] >>> [expr loop &optional cond] Could I perhaps make a macro [ that triggers another macro? (defmacro [ () ((let listcomp (read until next ]) (filter (cond) (mapcar expr loop)))...

Go Back   Application Development Forum > Programming Languages > lisp

Object Mix

Register FAQ Calendar Search Today's Posts Mark Forums Read
  #1  
Old 08-22-2008, 06:16 PM
defn noob
Guest
 
Default Listcomprehension-macro? Macros with args inside macro-name?

I am trying to learn lisp macros and I generally find
listcomprehensions to be elegant and they dont exist in lisp.
This has to be a macro right? Cant be a function?

But how would I get started when it needs the arguments inside its
name?

In Python:
>>> [x**2 for x in [12,31,2,33] if x > 20]

[961, 1089]
>>>



[expr loop &optional cond]

Could I perhaps make a macro [ that triggers another macro?

(defmacro [ ()
((let listcomp (read until next ])
(filter (cond) (mapcar expr loop)))
Reply With Quote
  #2  
Old 08-22-2008, 06:47 PM
David Golden
Guest
 
Default Re: Listcomprehension-macro? Macros with args inside macro-name?

defn noob wrote:

> I am trying to learn lisp macros and I generally find
> listcomprehensions to be elegant and they dont exist in lisp.
> This has to be a macro right? Cant be a function?
>


You might want to look at the COLLECT macro
http://user.it.uu.se/~svenolof/Collect/

> [x**2 for x in [12,31,2,33] if x > 20]
> [961, 1089]



(collect list ((expt x 2)) (in x '(12 31 2 33)) (when (> x 20)))
=> (961 1089)

vectors work too...

(collect vector ((expt x 2)) (in x #(12 31 2 33)) (when (> x 20)))
=> #(961 1089)



Reply With Quote
  #3  
Old 08-22-2008, 06:52 PM
Thomas A. Russ
Guest
 
Default Re: Listcomprehension-macro? Macros with args inside macro-name?

defn noob <circularfunc@yahoo.se> writes:

> I am trying to learn lisp macros and I generally find
> listcomprehensions to be elegant and they dont exist in lisp.
> This has to be a macro right? Cant be a function?


Not sure exactly what a listcomphrehension is.

But looking below, you need to be able to separate the syntactic
concerns from the actual function or semantics of what you want to do.

For new control structure, you generally want or need to use macros in
lisp. Once you have the construct that you want, using standard lisp
syntax, then you can worry about how to change the surface syntax. That
will generally involve modifying the readtable and using reader macros.

> But how would I get started when it needs the arguments inside its
> name?
>
> In Python:
> >>> [x**2 for x in [12,31,2,33] if x > 20]

> [961, 1089]
> >>>


The standar way to do this in lisp would involve using one of the
built-in macros, namely the loop or dolist construct:

(loop for x in '(12 31 2 33)
when (> x 20) collect (expt x 2))

(let ((result nil))
(dolist (x '(12 31 2 33) (nreverse result))
(when (> x 20) (push (expt x 2) result))))

Or alternatively, you could use one of the mapping constructs, but that
is a bit trickier to manage the splicing since you don't necessarily
want all values.

(mapcan #'(lambda (x) (when (> x 20) (list (expt x 2))))
'(12 31 2 33))


So, it doesn't seem like you really need to add much of anything to the
language.

> [expr loop &optional cond]


So, you could perhaps write a macro that takes the arguments that you
specify. It might be more convenient to re-arrange the order perhaps,
to take better advantage of the lambda list argument types.

Remember not to get too hung up on the syntax of the language. You want
to have an equivalent construct, even if it doesn't look the same.
Otherwise why bother changing languages?

> Could I perhaps make a macro [ that triggers another macro?
>
> (defmacro [ ()
> ((let listcomp (read until next ])
> (filter (cond) (mapcar expr loop)))




--
Thomas A. Russ, USC/Information Sciences Institute
Reply With Quote
  #4  
Old 08-22-2008, 07:37 PM
Tobias C. Rittweiler
Guest
 
Default Re: Listcomprehension-macro? Macros with args inside macro-name?

defn noob <circularfunc@yahoo.se> writes:

> I am trying to learn lisp macros and I generally find
> listcomprehensions to be elegant and they dont exist in lisp.
> This has to be a macro right? Cant be a function?


I'd recommend to abstain from trying to judge what's missing and what
should be fixed on the language until you passed "noob" status.

> In Python:
> [x**2 for x in [12,31,2,33] if x > 20]


Take a look at LOOP.


> Could I perhaps make a macro [ that triggers another macro?
>
> (defmacro [ ()
> ((let listcomp (read until next ])
> (filter (cond) (mapcar expr loop)))


This is syntactically so wrong that I suggest to spend some time
actually learning the language before trying to extend it in non-trivial
ways. I can recommend the book Practical Common Lisp which is even
available online for free.

-T.
Reply With Quote
  #5  
Old 08-22-2008, 07:52 PM
Benjamin Teuber
Guest
 
Default Re: Listcomprehension-macro? Macros with args inside macro-name?

> (defmacro [ ()
> * * ((let listcomp (read until next ])
> * * * (filter (cond) (mapcar expr loop)))


To do something like this, the thing you're looking for are reader
macros. But beware, they are already quite advanced and far from
normal macros...
So maybe you should simplify your task for now and use a lispy syntax
for your comprehensions instead of python syntax:

(comprehend-or-whatever-name-you-choose (* x x)
(for x '(12 31 2 33))
(if (> x 20)))

But even this is quite difficult as there are a lot of cases to catch
(with/without if/unless etc.), so you might as well find different
quests for now =)

I strongly recommend Graham's "On Lisp" (free download available on
his website) for learning macros.

Cheers,
Benjamin
Reply With Quote
  #6  
Old 08-22-2008, 08:22 PM
Frank Buss
Guest
 
Default Re: Listcomprehension-macro? Macros with args inside macro-name?

defn noob wrote:

> I am trying to learn lisp macros and I generally find
> listcomprehensions to be elegant and they dont exist in lisp.
> This has to be a macro right? Cant be a function?


Yes, it has to be a macro, if you need it fast and if you want your own
syntax, like used for list comprehensions in other languages like Haskell.
A nice example is this one, which was presented at ILC2007:

http://www.iro.umontreal.ca/~latendr...tCompFinal.pdf

Maybe you should take a look at Liskell, too. Liskell is a new Lisp syntax
frontend for Haskell, so I assume it implements list comprehensions and it
might help to find a good Lisp-like syntax.

--
Frank Buss, fb@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
Reply With Quote
  #7  
Old 08-23-2008, 03:51 AM
Rainer Joswig
Guest
 
Default Re: Listcomprehension-macro? Macros with args inside macro-name?

In article
<7fa79503-6d89-4dc0-bcac-12e327de7b66@m44g2000hsc.googlegroups.com>,
Benjamin Teuber <beteub@web.de> wrote:

> > (defmacro [ ()
> > * * ((let listcomp (read until next ])
> > * * * (filter (cond) (mapcar expr loop)))

>
> To do something like this, the thing you're looking for are reader
> macros. But beware, they are already quite advanced and far from
> normal macros...
> So maybe you should simplify your task for now and use a lispy syntax
> for your comprehensions instead of python syntax:
>
> (comprehend-or-whatever-name-you-choose (* x x)
> (for x '(12 31 2 33))
> (if (> x 20)))
>
> But even this is quite difficult as there are a lot of cases to catch
> (with/without if/unless etc.), so you might as well find different
> quests for now =)
>
> I strongly recommend Graham's "On Lisp" (free download available on
> his website) for learning macros.
>
> Cheers,
> Benjamin


Here is a very simple implementation (that I didn't write):

(defmacro comp ((e &rest qs) l2)
(if (null qs)
`(cons ,e ,l2)
(let ((q1 (car qs))
(q (cdr qs)))
(if (not (eq (cadr q1) '<-))
`(if ,q1
(comp (,e . ,q) ,l2) ,l2)
(let ((v (car q1))
(l1 (third q1))
(h (gensym "H-"))
(us (gensym "US-"))
(us1 (gensym "US1-")))
`(labels ((,h (,us)
(if (null ,us)
,l2
(let ((,v (car ,us))
(,us1 (cdr ,us)))
(comp (,e . ,q) (,h ,us1))))))
(,h ,l1)))))))

(defun open-bracket (stream ch)
(do ((l nil)
(c (read stream t nil t) (read stream t nil t)))
((eq c '|]|)
`(comp ,(reverse l) ()))
(push c l)))

(defun closing-bracket (stream ch)
'|]|)

(set-macro-character #\[ #'open-bracket)
(set-macro-character #\] #'closing-bracket)



Then you can write code like this:

(let ((xs '(1 2 3 4 5 6 7 8)))
[x (x <- xs) (oddp x)])

or this (with an ugly append, I know):

(defun qsort (ax)
(and ax
(let ((a (car ax))
(x (cdr ax)))
(append (qsort [y (y <- x) (< y a)])
(list a)
(qsort [y (y <- x) (>= y a)])))))



Now, homework: how does the above macro work?

--
http://lispm.dyndns.org/
Reply With Quote
  #8  
Old 08-23-2008, 04:08 AM
verec
Guest
 
Default Re: Listcomprehension-macro? Macros with args inside macro-name?

On 2008-08-22 23:16:27 +0100, defn noob <circularfunc@yahoo.se> said:

> I am trying to learn lisp macros and I generally find
> listcomprehensions to be elegant and they dont exist in lisp.
> This has to be a macro right? Cant be a function?
>
> But how would I get started when it needs the arguments inside its
> name?
>
> In Python:
>>>> [x**2 for x in [12,31,2,33] if x > 20]

> [961, 1089]
>>>>

>
>
> [expr loop &optional cond]
>
> Could I perhaps make a macro [ that triggers another macro?
>
> (defmacro [ ()
> ((let listcomp (read until next ])
> (filter (cond) (mapcar expr loop)))


Before reaching for lisp macro guru status, maybe you
might want to consider a plain old function?

(defun retain (pred transform list)
(mapcan
#'(lambda(x)
(when (funcall pred x)
(list (funcall transform x))))
list))

CL-USER 57 > (retain #'(lambda(x) (> x 20)) #'(lambda(x) (* x x)) '(12
31 2 33))
(961 1089)

Macro-ising and getting rid of the five letter repeated noise left as
an exrecise :-)
--
JFB

Reply With Quote
  #9  
Old 08-23-2008, 09:50 AM
Grant Rettke
Guest
 
Default Re: Listcomprehension-macro? Macros with args inside macro-name?

On Aug 22, 5:16*pm, defn noob <circularf...@yahoo.se> wrote:
> I am trying to learn lisp macros and I generally find
> listcomprehensions to be elegant and they dont exist in lisp.
> This has to be a macro right? Cant be a function?


For inspiration here is one option for list comprehensions in Scheme:
http://srfi.schemers.org/srfi-42/srfi-42.html

Or PLT Scheme in particular: http://docs.plt-scheme.org/reference/for.html
Reply With Quote
  #10  
Old 08-23-2008, 10:20 AM
Marco Antoniotti
Guest
 
Default Re: Listcomprehension-macro? Macros with args inside macro-name?

On Aug 23, 9:50*am, Grant Rettke <gret...@gmail.com> wrote:
> On Aug 22, 5:16*pm, defn noob <circularf...@yahoo.se> wrote:
>
> > I am trying to learn lisp macros and I generally find
> > listcomprehensions to be elegant and they dont exist in lisp.
> > This has to be a macro right? Cant be a function?

>
> For inspiration here is one option for list comprehensions in Scheme:http://srfi.schemers.org/srfi-42/srfi-42.html
>
> Or PLT Scheme in particular:http://docs.plt-scheme.org/reference/for.html


Vintage 2001. Inspiration: SETL

http://groups.google.com/group/comp....461d383f8f7e32

ping me for the code.

Cheers
--
Marco

Reply With Quote
Reply


Thread Tools
Display Modes


All times are GMT -5. The time now is 02:14 AM.


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
vB Ad Management by =RedTyger=

In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.