From: Zaka on 22 Sep 2009 20:31 Hello!! Thanks to all (specifically to Pascal Bourguignon) for the answers. That helps me a lot. I'm trying to subdivide a string in an arbitrary length (provided as arguments) substrings. It would look like this. (various-parts-st "0123456789" 1 3 3 3) => ("1" "123" "456" "789") But I only could got this: (various-parts-st "0123456789" '(1 3 3 3)) => ("1" "123" "456" "789") The thing is that I have an &optional argument around, and it must be the last argument, so if I don't want to use it, it just has his default value. But, being not possible to have a &rest argument before an &optional one (that's what I understood, maybe I'm mistaken) I couldn't realize how to solve it the way I want. I hope you understand my ugly English, if not I could try to explain it other way. Here I let my code: (defun various-parts-st (string parts &optional (string-length (length string))) (cond ((null parts (list string)) ((<= string-length (car parts (list string)) (t (cons (subseq string 0 (car parts)) (various-parts-st (subseq string (car parts string-length) (cdr parts (- string-length (car parts))))))) Thanks for your help. Zaka.
From: D Herring on 22 Sep 2009 21:17 Zaka wrote: > I'm trying to subdivide a string in an arbitrary length (provided as > arguments) > substrings. > > It would look like this. > > (various-parts-st "0123456789" 1 3 3 3) > => ("1" "123" "456" "789") > > But I only could got this: > > (various-parts-st "0123456789" '(1 3 3 3)) > => ("1" "123" "456" "789") > > The thing is that I have an &optional argument around, and it must be > the last argument, > so if I don't want to use it, it just has his default value. But, > being not possible to have > a &rest argument before an &optional one (that's what I understood, > maybe I'm mistaken) > I couldn't realize how to solve it the way I want. With &rest, you can do arbitrary parsing or defaults... Try something like (defun various-parts-st (string &rest parts) (unless parts (setf parts (list (length string)))) ...) - Daniel
From: Barry Margolin on 22 Sep 2009 23:50 In article <9412a711-150a-4150-b4c5-89a4efc355c2(a)z34g2000vbl.googlegroups.com>, Zaka <shanatorio(a)gmail.com> wrote: > Hello!! > > Thanks to all (specifically to Pascal Bourguignon) for the answers. > That helps me a lot. > > I'm trying to subdivide a string in an arbitrary length (provided as > arguments) > substrings. > > It would look like this. > > (various-parts-st "0123456789" 1 3 3 3) > => ("1" "123" "456" "789") > > But I only could got this: > > (various-parts-st "0123456789" '(1 3 3 3)) > => ("1" "123" "456" "789") > > The thing is that I have an &optional argument around, and it must be > the last argument, > so if I don't want to use it, it just has his default value. But, > being not possible to have > a &rest argument before an &optional one (that's what I understood, > maybe I'm mistaken) Your understanding is correct. How is it supposed to tell whether the last argument is the last element of the &rest list or the argument that goes with &optional? E.g. in (various-parts-st "0123456789" 1 2 3 4) should it be PARTS = (1 2 3) STRING-LENGTH = 4 or PARTS = (1 2 3 4) STRING-LENGTH = default You may have a preference, but how is CL supposed to figure it out? You need to come up with an unambiguous way to call your function. What's so bad about using a list instead of &rest? > I couldn't realize how to solve it the way I want. > > I hope you understand my ugly English, if not I could try to explain > it other way. > > Here I let my code: > > (defun various-parts-st (string parts &optional (string-length (length > string))) > (cond > ((null parts (list string)) > ((<= string-length (car parts (list string)) > (t > (cons (subseq string 0 (car parts)) > (various-parts-st (subseq string (car parts string-length) (cdr > parts (- string-length (car parts))))))) > > Thanks for your help. > > Zaka. -- Barry Margolin, barmar(a)alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** *** PLEASE don't copy me on replies, I'll read them in the group ***
From: Kaz Kylheku on 23 Sep 2009 00:50 On 2009-09-23, Zaka <shanatorio(a)gmail.com> wrote: > the last argument, so if I don't want to use it, it just has his default > value. But, being not possible to have a &rest argument before an &optional > one (that's what I understood, maybe I'm mistaken) I couldn't realize how to > solve it the way I want. You can can begin the rest list after the last required argument, and process it with another lambda list inside your function, using destructuring-bind: (defun fun (required &rest rest) (destructuring-bind (&optional (optional 'default-val) &rest ignored) rest (declare (ignore ignored)) ...)) So now you have access to all arguments after REQUIRED in the rest variable, and also you have the OPTIONAL variable parsed out, which gets the first element of REST, or else the default value if REST is empty. Also, look into keywords. The built-in Lisp feature which gives you a rest list in parallel with a structured parse of some of its elements is the keyword feature, in particular when used with &allow-other-keys. (defun fun (required &rest rest &key a (b 42) c &allow-other-keys) ...) You get all the rest arguments in REST, and those of them which match the keys are also parsed out into their respective keyword arguments. Keys are effectively optional arguments in the sense that a keyword argument is never mandatory, and defaulting of values is supported. Only, the syntax is different.
From: Zaka on 24 Sep 2009 15:24 Thanks all for your answers! Finally I put off the optional argument without which is easy to solve the problem the manner I wanted. Daniel Herring: Your solution can't be applied cause I wanted to use the optional argument and the list at the same time. Barry Margolin: Thanks for your explanation. Is nothing bad about the usage of lists as arguments (I'm using Lisp), but, firstly, is kind of a challenge while I'm learning the ins and outs of the language, and, secondly and more important, is that the problem is proposed that way so the solution must be that way. Kaz Kylheku: I've learned a lot reading about the subjects you recommended me, but I hadn't be able to realize a way to solve my problem with those tools. Here a let the code, which is less efficient because it has to compute the length of the string every execution of the function. (defun various-parts-st (string &rest parts) (let ((string-length (length string))) (cond ((null (car parts)) (list string)) ((<= string-length (car parts)) (list string)) (t (cons (subseq string 0 (car parts)) (apply 'various-parts-st (cons (subseq string (car parts) string-length) (cdr parts)))))))) Zaka.
|
Next
|
Last
Pages: 1 2 Prev: 2 Articles on Continuations Next: Avoiding LispWorks Personal annoyances |