4 ms·
I could write a function that automatically defines functions of the form you want, but it would have to define them one at a time. The problem is that it could
by smanek 17y ago
I could write a function that automatically defines functions of the form you want, but it would have to define them one at a time. The problem is that it could only define a finite number of functions.
It's pretty straightforward to do what you want by writing a reader macro, but then you have to prefix your sexp with some special macro character.
If the prefix is a deal breaker there may be some deep read-macro voodoo that could do what you want but, but before doing research, I have to ask the obvious question: "Why?".
Incidentally, pg's On Lisp has a decent intro to reader macros (http://www.bookshelf.jp/texi/onlisp/onlisp_18.html http://www.bookshelf.jp/texi/onlisp/onlisp_18.html)
- mahmud 17y agoCode or it didn't happen ;-) Come'on, it's a nice trivia question. Let's light this joint up with parentheses folks! Schemers, Clojeristas ..
- DaveKruglinsky 17y agoWhy? Paul Graham says that "Programming languages teach us not to want what they cannot provide". I'm just curious if this is the case with lisp and c[a|d]+r
- mahmud 17y agoNo it's not. If there is anything Lisp provides out of the box, it's support for non-builtin language features. A friken paradox, enjoy it! :-)
- philh 17y agoSo far there's only one solution: "this can be done (for common lisp) by handling undefined-function condition and invoking appropriate restart (which is unfortunately implementation-specific)." Which makes it sound like there is in fact no way to do this in standard CL, to say nothing of other lisps. Untested perl code to do this (taking a cons to be a [car, cdr] array reference): AUTOLOAD { unless ($AUTOLOAD =~ m/::c([ad]{1,})r$/) { die "Attempted to call undefined function $AUTOLOAD"; } my $ads = $1; my $cons = shift; while (my $c = chop $ads) { $cons = $cons->[$c eq 'a' ? 0 : 1]; } return $cons; } Example of a situation this feature might be useful: "I have this object with lots of properties which I don't necessarily know what they are. How do I define getter/setter methods on them?"
- bvttf 17y agoMore appropriately, there's no standard way to do this with CL. One might ask the same about threads. What are threads? We just don't know.
- mahmud 17y agoWhat do you mean there is no standard way to do this? There is a MetaObject Protocol which is supported by most platforms, and for those that don't have it, there is the widely portable CloserMOP. Threads are not "standard" but the last thread-less Common Lisp just got them this month. Every maintained Common Lisp implementation today has Threads; and all support Bordeaux-Threads. Show me a single mainstream language where threads are "standardized" other than Java?
- bvttf 17y agoYou're over-thinking this. My comment was a response to the idea that every lisp can that but there's no single standard. My awkward phrasing was a reference to about 1:53 in this: http://www.youtube.com/watch?v=bCWA7uevo_Q http://www.youtube.com/watch?v=bCWA7uevo_Q
- mahmud 17y agoSo far there's only one solution: "this can be done (for common lisp) by handling undefined-function condition and invoking appropriate restart (which is unfortunately implementation-specific)." Before you go far and wide on speculation alone, you might stop and reread what has been posted so far, again. Both me and lnostdal submitted working CL solutions. Example of a situation this feature might be useful: "I have this object with lots of properties which I don't necessarily know what they are. How do I define getter/setter methods on them?" ;; if you know the slot names (slot-value object 'slot-name) ==> value (setf (slot-value object 'slot-name) new-value) ;; if you don't. ;; let's define a class hierarchy first CL-USER> (defclass foo () ((a) (b))) #<STANDARD-CLASS FOO> CL-USER> (defclass bar (foo) ((c) (d))) #<STANDARD-CLASS BAR> CL-USER> (defclass baz (bar) ((e) (f))) #<STANDARD-CLASS BAZ> ;; use COMPUTE-SLOTS to get the class's slots CL-USER> (closer-mop:compute-slots (find-class 'baz)) (#<STANDARD-EFFECTIVE-SLOT-DEFINITION A #x1A0F62C5> #<STANDARD-EFFECTIVE-SLOT-DEFINITION B #x1A0F6305> #<STANDARD-EFFECTIVE-SLOT-DEFINITION C #x1A0F6345> #<STANDARD-EFFECTIVE-SLOT-DEFINITION D #x1A0F6385> #<STANDARD-EFFECTIVE-SLOT-DEFINITION E #x1A0F63C5> #<STANDARD-EFFECTIVE-SLOT-DEFINITION F #x1A0F6405>) ;; if you have an object and not a class, do the same CL-USER> (closer-mop:compute-slots (class-of (make-instance 'baz))) (#<STANDARD-EFFECTIVE-SLOT-DEFINITION A #x1A1202A1> #<STANDARD-EFFECTIVE-SLOT-DEFINITION B #x1A1202E1> #<STANDARD-EFFECTIVE-SLOT-DEFINITION C #x1A120321> #<STANDARD-EFFECTIVE-SLOT-DEFINITION D #x1A120361> #<STANDARD-EFFECTIVE-SLOT-DEFINITION E #x1A1203A1> #<STANDARD-EFFECTIVE-SLOT-DEFINITION F #x1A1203E1>)
- rsheridan6 17y agoI don't think so. c[a|d]+r is already too confusing with the builtin functions when there are more than a few [a|d]'s. There are better ways to get at items in a list.