How to call a method object with standard functions - methods

How does one call a method object as a function?
Closer-mop and clos packages both provide method-function for turning a method object into a function. However, is there a way to do it without including another package? And if not, which package? (Using SBCL), but if a package is needed then how does the discrimination function do it?
Here is an example of using find-method to get a method object. The question is then how to call method-to-be-called.
(defclass a () ((x :accessor x :initform 0)))
(defgeneric inc (i))
(defmethod inc ((i a)) (incf (x i)))
(defvar r (make-instance 'a))
;; ... in a land far far away:
(defvar method-to-be-called (find-method #'inc '() '(a)))
(funcall method-to-be-called r);; crashes and burns
As a secondary question, the docs say that the discrimination function first tries to compute-applicable-methods-by-class to find a method object, and if that fails, it uses compute-applicable-methods. Why do this two layer approach? Is it correct to assume the find-method is doing this two layer approach, so it is better to use find-method ?
-- Appendix --
In the comments below Rainer Joswig pointed out that this find-method form is implementation dependent:
(find-method #'inc '() '(a))) ; works on sbcl 1.3.1
He says the specifier list should be classes and suggests instead:
(find-method #'inc '() (list (find-class 'a))))
So I thought to just put my class in there:
(find-method #'inc '() (list a)) ; crashes and burns
Apparently (defclass a ... ) does not set a to a class. In fact it doesn't set it to anything!
* (defclass a () ((x :accessor x :initform 0)))
#<STANDARD-CLASS COMMON-LISP-USER::A>
* a
...
The variable A is unbound.
However, this works:
* (defvar ca (defclass a () ((x :accessor x :initform 0))))
CA
* (defmethod inc ((i a)) (incf (x i)))
WARNING: Implicitly creating new generic function COMMON-LISP-USER::INC.
#<STANDARD-METHOD COMMON-LISP-USER::INC (A) {1005EE8263}>
enter code here
* (find-method #'inc '() (list ca))
#<STANDARD-METHOD COMMON-LISP-USER::INC (A) {1005EE8263}>
*
So a class is the return value from the defclass, not the value of the symbol that is provided to defclass.

(find-method #'inc '() '(a))
Above does not work. We need a list of classes, not a list of symbols.
(funcall (method-function (find-method #'inc
'()
(list (find-class 'a))))
r)
Since the function method-function belongs to the MOP, many implementations provide it and it is in some implementation specific package. CLOSER-MOP makes it available, too.
But usually, if you are already trying extracting method functions, then you are probably using CLOS the wrong way or you are really knowing what you are doing...

How does one call a method object as a function?
Honest question: why do you want to do that? Did you specify how the method's function is built in the first place, or not?
Even with closer-mop, I believe that the function returned by closer-mop:method-function is, at most, consistent with closer-mop:make-method-lambda in terms of its lambda-list, so perhaps you can use a package to know what you can count on portably.
A method's function does not have to be a function with the same lambda-list as the generic function, and usually it isn't due to next-method-p and call-next-method. Some implementations might use dynamic bindings for the next method list, so these might have a method lambda-list congruent with the generic function. Just don't count on it, generically.
I believe SBCL is not one of these implementations, the next method list is passed to the method's function to support next-method-p and call-next-method.
Why do this two layer approach?
Because it allows memoizing (or caching) based on the list of classes, when possible. If the generic function is called again with arguments of the same classes, and the generic function has not been updated (see "Dependent Maintenance Protocol" in the MOP), it can reuse the last result without further processing, for instance, by keeping the results in a hash table which keys are lists of classes.
However, if compute-applicable-methods-using-classes returns a false second value, then compute-applicable-methods is used. The reason is that no method could be found using classes alone, and this means some method has a non-class specializer.
This is different than saying there are no applicable methods, for instance, if all methods are specialized on classes and there are no applicable methods, compute-applicable-methods-using-classes should return an empty list and a true second value. There's no point in calling compute-applicable-methods, it won't (or rather, it shouldn't, if well implemented) find anything further.
It's still possible to perform memoization when compute-applicable-methods is used, but the memoization is no longer as trivial as, for instance, using a list of classes as a key in a hash table. Perhaps you could use a tree structure where you'd try to look up a method for each specializer (instance, then class) sequentially for each argument, until a tree node matched the whole specializable parameter list.
With non-standard specializers, you'd have to change the search order for each node. Unless such specializer's priority is not strictly before, between or after eql and a class, then you're in uncharted areas.
Actually, you'll have to change compute-applicable-methods-using-classes to recognize the non-standard specializers and return false early, and you'll have to change compute-applicable-methods to process these specializers, anyway, so perhaps you'll have a good knowledge on, if possible, how to memoize with the results of compute-applicable-methods anyway.
Is it correct to assume the find-method is doing this two layer approach, so it is better to use find-method ?
No, the purpose of find-method is to find a specific method, not an applicable method. It does not use compute-applicable-methods-using-classes or compute-applicable-methods at all. In fact, it couldn't use the latter ever, as it takes actual arguments instead of specializers.

For the particular case of method-function, closer-mop for SBCL simply reexport the existing symbol from sb-pcl, as seen in closer-mop-packages.lisp. The whole file make use of read-time conditionals (see 1.5.2.1 Use of Implementation-Defined Language Features).
That means that if you are working with SBCL, you might call sb-pcl:method-function (PCL means Portable Common Loops).
The generic function compute-applicable-methods-by-class allows you to know which methods are applicable given classes. This is useful if you don't have actual instances on which you can operate.
It seems also that compute-applicable-methods-using-classes allows the implementation to memoize the applicable methods when the second return value is true. This generic method does not allow you to find applicable methods specialized with eql specializers.
I am speculating here, but it makes sense to fall back on compute-applicable-methods to allow for example eql-specializers or because it is slightly easier to define a method for compute-applicable-methods.
Note the paragraph about consistency:
The following consistency relationship between compute-applicable-methods-using-classes and compute-applicable-methods must be maintained: for any given generic function and set of arguments, if compute-applicable-methods-using-classes returns a second value of true, the first value must be equal to the value that would be returned by a corresponding call to compute-applicable-methods. The results are undefined if a portable method on either of these generic functions causes this consistency to be violated.
I don't think there is a find-method-using-classes generic function specified anywhere.

Related

Of what use is identity function in Racket?

What is the use of identity function? It simply returns the same value. Hence, instead of putting (identity x), why not simply put x? Could someone give some examples of using identity function in Racket/Scheme? There are no examples on these documentation page: https://docs.racket-lang.org/htdp-langs/beginner.html#%28def.htdp-beginner.%28%28lib._lang%2Fhtdp-beginner..rkt%29.identity%29%29 and https://docs.racket-lang.org/reference/procedures.html?q=identity#%28def.%28%28lib._racket%2Ffunction..rkt%29._identity%29%29
The identity function is mostly useful as an argument to certain higher-order functions (functions which take functions as arguments) when a function performs a certain sort of mapping customized by its argument, and you wish to pass the value through unchanged.†
One extremely common idiom in Scheme/Racket is using (filter identity ...) to remove all #f values from a list:
> (filter identity '(1 2 #f 4))
'(1 2 4)
This works because filter applies the provided function to each of the elements of a list, then discards values that result in #f. By using identity, the values themselves are checked. In this sense, identity is the functional “no-op”.
You may sometimes see this idiom spelled (filter values ...) instead of (filter identity ...) because values happens to be the identity function when provided with one argument, and it comes from racket/base instead of racket/function. I prefer the version that uses identity explicitly, though, because I think it is a little bit clearer what’s going on.
† This description of the identity function comes from this nice answer for the Haskell equivalent question.

How to determine if a variable exists in Chicken Scheme?

Is there a way in Chicken Scheme to determine at run-time if a variable is currently defined?
(let ((var 1))
(print (is-defined? var)) ; #t
(print (is-defined? var)) ; #f
EDIT: XY problem.
I'm writing a macro that generates code. This generated code must call the macro in mutual recursion - having the macro simply call itself won't work. When the macro is recursively called, I need it to behave differently than when it is called initially. I would use a nested function, but uh....it's a macro.
Rough example:
(defmacro m (nested)
(if nested
BACKQUOTE(print "is nested")
BACKQUOTE(m #t)
(yes, I know scheme doesn't use defmacro, but I'm coming from Common Lisp. Also I can't seem to put backquotes in here without it all going to hell.)
I don't want the INITIAL call of the macro to take an extra argument that only has meaning when called recursively. I want it to know by some other means.
Can I get the generated code to call a macro that is nested within the first macro and doesn't exist at the call site, maybe? For example, generating code that calls (,other-macro) instead of (macro)?
But that shouldn't work, because a macro isn't a first-class object like a function is...
When you write recursive macros I get the impression that you have an macro expansion (m a b ...) that turns into a (m-helper a (b ...)) that might turn into (let (a ...) (m b ...)). That is not directly recursive since you are turning code into code that just happens to contain a macro.
With destructuring-bind you really only need to keep track of two variables. One for car and one for cdr and with an implicit renaming macro the stuff not coming from the form is renamed and thus hygenic:
(define-syntax destructuring-bind
(ir-macro-transformer
(lambda (form inject compare?)
(define (parse-structure structure expression optional? body)
;;actual magic happens here. Returns list structure with a mix of parts from structure as well as introduced variables and globals
)
(match form
[(structure expression) . body ]
`(let ((tmp ,expression))
,(parse-structure structure 'tmp #f body))))))
To check if something from input is the same symbol you use the supplied compare? procedure. eg. (compare? expression '&optional).
There's no way to do that in general, because Scheme is lexically scoped. It doesn't make much sense to ask if a variable is defined if an referencing an undefined variable is an error.
For toplevel/global variables, you can use the symbol-utils egg but it is probably not going to work as you expect, considering that global variables inside modules are also rewritten to be something else.
Perhaps if you can say what you're really trying to do, I can help you with an alternate solution.

Difference between multiple values and plain tuples in Racket?

What is the difference between values and list or cons in Racket or Scheme? When is it better to use one over the other? For example, what would be the disadvantage if quotient/remainder returns (cons _ _) rather than (values _ _)?
Back in 2002 George Caswell asked that question in comp.lang.scheme.
The ensuing thread is long, but has many insights. The discussion
reveals that opinions are divided.
https://groups.google.com/d/msg/comp.lang.scheme/ruhDvI9utVc/786ztruIUNYJ
My answer back then:
> What are the motivations behind Scheme's multiple return values feature?
> Is it meant to reflect the difference in intent, or is there a
> runtime-practical reason?
I imagine the reason being this.
Let's say that need f is called by g. g needs several values from f.
Without multiple value return, f packs the values in a list (or vector),
which is passed to g. g then immediately unpacks the list.
With multple values, the values are just pushed on the stack. Thus no
packing and unpacking is done.
Whether this should be called an optimization hack or not, is up to you.
--
Jens Axel Søgaard
We don't need no side-effecting We don't need no allocation
We don't need no flow control We don't need no special-nodes
No global variables for execution No dark bit-flipping for debugging
Hey! did you leave the args alone? Hey! did you leave those bits alone?
(Chorus) -- "Another Glitch in the Call", a la Pink Floyd
They are semantically the same in Scheme and Racket. In both you need to know how the return looks like to use it.
values is connected to call-with-values and special forms like let-values are just syntax sugar with this procedure call. The user needs to know the form of the result to use call-with-values to make use of the result. A return is often done on a stack and a call is also on a stack. The only reason to favor values in Scheme would be that there are no overhead between the producer return and the consumer call.
With cons (or list) the user needs to know how the data structure of the return looks like. As with values you can use apply instead of call-with-values to do the same thing. As a replacement for let-values (and more) it's easy to make a destructuring-bind macro.
In Common Lisp it's quite different. You can use values always if you have more information to give and the user can still use it as a normal procedure if she only wants to use the first value. Thus for CL you wouldn't need to supply quotient as a variant since quotient/remainder would work just as well. Only when you use special forms or procedures that take multiple values will the fact that the procedure does return more values work the same way as with Scheme. This makes values a better choice in CL than Scheme since you get away with writing one instead of more procedures.
In CL you can access a hash like this:
(gethash 'key *hash* 't)
; ==> T; NIL
If you don't use the second value returned you don't know if T was the default value or the actual value found. Here you see the second value indicating the key was not found in the hash. Often you don't use that value if you know there are only numbers the default value would already be an indication that the key was not found. In Racket:
(hash-ref hash 'key #t)
; ==> #t
In racket failure-result can be a thunk so you get by, but I bet it would return multiple values instead if values did work like in CL. I assume there is more housekeeping with the CL version and Scheme, being a minimalistic language, perhaps didn't want to give the implementors the extra work.
Edit: Missed Alexis' comment on the same topic before posting this
One oft-overlooked practical advantage of using multiple return values over lists is that Racket's compose "just works" with functions that return multiple values:
(define (hello-goodbye name)
(values (format "Hello ~a! " name)
(format "Goodbye ~a." name)))
(define short-conversation (compose string-append hello-goodbye))
> (short-conversation "John")
"Hello John! Goodbye John."
The function produced by compose will pass the two values returned by hello-goodbye as two arguments to string-append. If you're writing code in a functional style with lots of compositions, this is very handy, and it's much more natural than explicitly passing values around yourself with call-with-values and the like.
It's also related to your programming style. If you use values, then it usually means you want to explicitly return n values. Using cons, list or vector usually means you want to return one value which contains something.
There are always pros/cons. For values: It may use less memory on some implemenentations. The caller need to use let-values or other multiple values specific syntax. (I wish I could use just let like CL.)
For cons or other types: You can use let or lambda to receive the returning value. You need to explicitly deconstruct it to get the value you want using car or other procedures.
Which to use and when? Again depending on your programming style and case by case but if the returning value can't be represented in one object (e.g. quotient and remainder), then it might be better to use values to make the procedure's meaning clearer. If the returning value is one object (e.g. name and age for a person), then it might be better to use cons or other constructor (e.g. record).

How to capture the return value of `string-search-forward` in Scheme?

I want to write a procedure (function) that checks if a string contains another string. I read the documentation of string library from http://sicp.ai.mit.edu/Fall-2004/manuals/scheme-7.5.5/doc/scheme_7.html
According from to them,
Pattern must be a string. Searches
string for the rightmost occurrence of
the substring pattern. If successful,
the index to the right of the last
character of the matched substring is
returned; otherwise, #f is returned.
This seemed odd to me, cause the return value is either integer or boolean, so what should I compare my return value with?
I tried
(define (case-one str)
(if (= #f (string-search-forward "me" str))
#t
#f))
DrScheme don't like it,
expand: unbound identifier in module in: string-search-forward
Thanks,
string-search-forward is not a standardized Scheme procedure; it is an extension peculiar to the MIT-Scheme implementation (that's why your link goes to the "MIT Scheme Reference Manual.") To see only those procedures that are guaranteed, look at the R5RS document.
In Scheme, #f is the only value that means "false," anything else when used in a conditional expression will mean "true." There is therefore no point in "comparing" it to anything. In cases like string-search-forward that returns mixed types, you usually capture the return value in a variable to test it, then use it if it's non-false:
(let ((result (string-search-forward "me" str)))
(if result
(munge result) ; Execute when S-S-F is successful (result is the index.)
(error "hurf") ; Execute when S-S-F fails (result has the value #f.)
))
A more advanced tactic is to use cond with a => clause which is in a sense a shorthand for the above:
(cond ((string-search-forward "me" str) => munge)
(else (error "hurf")))
Such a form (<test> => <expression>) means that if <test> is a true value, then <expression> is evaluated, which has to be a one-argument procedure; this procedure is called with the value of <test> as an argument.
Scheme has a very small standard library, which is both a blessing (you can make small scheme implementations to embed in an application or device, you can learn the language quickly) and a curse (it's missing a lot of useful functions). string-search-forward is a non-standard function of MIT Scheme, it's not present in DrScheme.
Many library additions are available in the form of SRFIs. An SRFI is a community-adopted extension to the base language — think of it as an optional part of a Scheme implementation. DrScheme (or at least its successor Racket) implements many SRFIs.
DrScheme has a number of string functions as part of SRFI 13. Amongst the string searching functions, there is string-contains, which is similar except that it takes its arguments in the opposite order.
(require srfi/13)
(define (case-one str)
(integer? (string-contains str "me")))
You'll notice that the two implementations used a different argument order (indicating that they were developed independently), yet use the same return value. This illustrates that it's quite natural in Scheme to have a function return different types depending on what it's conveying. In particular, it's fairly common to have a function return a useful piece of information if it can do its job, or #f if it can't do its job. That way, the function naturally combines doing its job (here, returning the index of the substring) with checking whether the job is doable (here, testing whether the substring occurs).
Error message seems a little odd (I don't have drscheme installed unfortunately so can't investigate too much).
Are you sure str is a string?
Additionally = is for integer comparisons only, you can use false? instead.
As for the return value of string-search-forward having mixed types, scheme has the mindset that if any useful value can be returned it should be returned, so this means different return types are common for functions.
Try using srfi-13's string-index: http://docs.racket-lang.org/srfi-std/srfi-13.html#Searching The documentation you are looking at isn't specifically for PLT. and probably corresponds to some other version of Scheme.

How do I return a copy of an object?

I need to implement a function of one argument -- obj -- that returns a Scheme expression that, when evaluated, will return a copy of obj.
Any ideas on how to proceed with the problem?
I'm guessing that you meant to write "a function expr-returning [that accepts an] obj [and] returns a Scheme expression that, when evaluated, ..."
Assuming this is the case: what you really need here is the design recipe. To begin with: write down examples of what your function accepts, and what it returns. This will clarify what you're trying to do, both to others and (probably more importantly) to yourself.
Hope this is helpful; sorry to be so opaque...
If you want your procedure to be able to duplicate any object, then the object could be any one of Scheme's basic types. By virtue of being different types, they have differing "natures," or structure, or what have you, and so making a copy of an object of one type is necessarily going to involve different strategies from making a copy of another object of a different type.
So how you approach this is to examine each of Scheme's types (or rather, the subset of Scheme's types you care about handling) and puzzle out what it means to duplicate an object of that type. If you do this in the obvious way, you should end up with a set of specialized procedures like COPY-NUMBER, COPY-SYMBOL, etc. (spoiler: a lot of these procedures aren't going to be very interesting.)
To unite these specialized procedures into a single one that can duplicate any object you give it reduces down to determining the object's real type and calling out to the COPY-FOO procedure to do the work (you could as well expand the procedure inline). You can organize this really easily with a COND and the type-determining predicates:
(define (copy-object obj)
(cond ((number? obj) (copy-number obj))
((boolean? obj) (copy-boolean obj))
...
))
This is a general design pattern for performing an operation on a datum regardless of its type called "dispatch on type." It's actually a pretty piss-poor way to do generic programming, not that that matters too much in this situation.
The last thing is the added wrinkle of returning a thing you can evaluate to get the copies. Might as well tell you what that is straight up: encapsulate a call to COPY-OBJECT inside a lambda-expression of no arguments:
(define (expr-returning obj)
(lambda () (copy-object obj)))
Then you can do stuff like
guile> (define x (list 1 2 3 4))
guile> (define y (expr-returning x))
guile> (define cx (y))
guile> x
(1 2 3 4)
guile> cx
(1 2 3 4)
guile> (set-cdr! x 'foo)
guile> x
(1 . foo)
guile> z
(1 2 3 4)
etc.

Resources