Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lambda list in function description #442

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

mmontone
Copy link

@mmontone mmontone commented Aug 28, 2022

Can we have the lambda-list of functions as part of their descriptions.?
It is useful to have them for tools also.

Description of function after this:

JSCL/ILT> (describe #'format)
#<FUNCTION !FORMAT>
Class: #<builtin-in-class FUNCTION>
Name:!FORMAT
Lambda list:(DESTINATION FMT &REST ARGS)

@vlad-km
Copy link
Member

vlad-km commented Sep 1, 2022

Is it possible to add correct handling of anonymous functions?

CL-USER> (setq kik (lambda (x &optional y) nil))
#<FUNCTION>
CL-USER> (describe 'kik)
KIK
Class: #<builtin-in-class SYMBOL>
:INTERNAL in package CL-USER
Print name: "KIK"
KIK names a special variable
Value: #<FUNCTION>
#<FUNCTION>
Class: #<builtin-in-class FUNCTION>
Name:anonimous
Lambda list:NIL
CL-USER> (defun kek (x &optional y) (cons x y))
KEK
CL-USER> (describe 'kek)
KEK
Class: #<builtin-in-class SYMBOL>
:INTERNAL in package CL-USER
Print name: "KEK"
KEK names a function
#<FUNCTION KEK>
Class: #<builtin-in-class FUNCTION>
Name:KEK
Lambda list:(X &OPTIONAL Y)

@davazp
Copy link
Member

davazp commented Sep 1, 2022

Can we expose this under a function-lambda-list function (inside the jscl package)?

I wonder also if it'd be a good idea to make this pluggable somehow. We could define a (defvar *collect-lambda-lists* ...) variable or something.

That way there is no need to pay the price for the extra bundle if desired. That would allow to change it dynamically too.

Thoughts?

@mmontone
Copy link
Author

mmontone commented Sep 1, 2022

Can we expose this under a function-lambda-list function (inside the jscl package)?

I don't understand what you want here ...

I wonder also if it'd be a good idea to make this pluggable somehow. We could define a (defvar *collect-lambda-lists* ...) variable or something.

I've no problem with that. I would set it to true by default. I've no problem with not making it optional either; CL implementations usually come with this, with no optionality.

That way there is no need to pay the price for the extra bundle if desired. That would allow to change it dynamically too.

Thoughts?

@mmontone
Copy link
Author

mmontone commented Sep 1, 2022

Is it possible to add correct handling of anonymous functions?

I don't know yet.. but I can have a look.

@mmontone
Copy link
Author

mmontone commented Sep 1, 2022

Can we expose this under a function-lambda-list function (inside the jscl package)?

I don't understand what you want here ...

Ah. You just want a function that returns the lambda-list. Of course!.

@mmontone
Copy link
Author

mmontone commented Sep 1, 2022

Would also be nice to attach lambdalists to generic functions and methods. Not done atm.

@mmontone
Copy link
Author

mmontone commented Sep 1, 2022

I'm including a custom writer for functions that show lambda-lists.

Looks like this:

CL-USER> #'prin1-to-string
#<FUNCTION PRIN1-TO-STRING (FORM)>
CL-USER> #'prin1-to-string
#<FUNCTION PRIN1-TO-STRING (FORM)>
CL-USER> #'prin1
#<FUNCTION PRIN1 (FORM &OPTIONAL STREAM)>

@mmontone
Copy link
Author

mmontone commented Sep 1, 2022

Would also be nice to attach lambdalists to generic functions and methods. Not done atm.

I was wrong. This is already being done:

(describe (find-generic-function 'print-object))
A CLOS object
             Printed representation: #<standard-generic-function PRINT-OBJECT>
             Class: #<standard-class STANDARD-GENERIC-FUNCTION>
             Structure 
             JSCL::NAME <- [PRINT-OBJECT]
             JSCL::LAMBDA-LIST <- [(JSCL::INSTANCE &OPTIONAL STREAM)]
             JSCL::METHODS <- [(#<standard-method PRINT-OBJECT((CONDITION JSCL::BAD-DSD-SLOT-DESC) &OPTIONAL (STREAM *STANDARD-OUTPUT*))> #<standard-method PRINT-OBJECT((CONDITION TYPE-ERROR) &OPTIONAL (STREAM *STANDARD-OUTPUT*))> #<standard-method PRINT-OBJECT((METHOD STANDARD-METHOD) &OPTIONAL (STREAM *STANDARD-OUTPUT*))> #<standard-method PRINT-OBJECT((JSCL::GF STANDARD-GENERIC-FUNCTION) &OPTIONAL (STREAM *STANDARD-OUTPUT*))> #<standard-method PRINT-OBJECT((CLASS STANDARD-CLASS) &OPTIONAL (STREAM *STANDARD-OUTPUT*))> #<standard-method PRINT-OBJECT((JSCL::INSTANCE STANDARD-OBJECT) &OPTIONAL (STREAM *STANDARD-OUTPUT*))>)]
             JSCL::METHOD-CLASS <- [#<standard-class STANDARD-METHOD>]
             JSCL::DISCRIMINATING-FUNCTION <- [#<FUNCTION  ()>]
             JSCL::CLASSES-TO-EMF-TABLE <- [#<hash-table :test equal :count 0>]

@mmontone
Copy link
Author

mmontone commented Sep 1, 2022

Is it possible to add correct handling of anonymous functions?

I've implemented it:

CL-USER> (lambda (x y) x)
#<FUNCTION  (X Y)>
CL-USER> (lambda (x y) x)
#<FUNCTION  (X Y)>
CL-USER> (lambda (x y &optional z) z) 
#<FUNCTION  (X Y &OPTIONAL Z)>
CL-USER> (describe *)
#<FUNCTION  (X Y &OPTIONAL Z)>
Class: #<builtin-in-class FUNCTION>
Name:anonimous
Lambda list:(X Y &OPTIONAL Z)
CL-USER> (setq kik (lambda (x &optional y) nil))
#<FUNCTION  (X &OPTIONAL Y)>
CL-USER> (describe 'kik)
KIK
Class: #<builtin-in-class SYMBOL>
:INTERNAL in package CL-USER
Print name: "KIK"
KIK names a special variable
Value: #<FUNCTION  (X &OPTIONAL Y)>
#<FUNCTION  (X &OPTIONAL Y)>
Class: #<builtin-in-class FUNCTION>
Name:anonimous
Lambda list:(X &OPTIONAL Y)

Copy link
Member

@vlad-km vlad-km left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be

(defun function-object-printer (form stream)
  (let ((res)
	      (fname (oget form "fname"))
        (ll-form (function-lambda-list form)))
    (setq res (concat (if fname "#<FUNCTION " "#<LAMBDA ")
		                        (if fname 
                                            fname 
                                            "")
		                        (if ll-form
			                    (princ-to-string ll-form)
                                            "()")
		             ">"))
    (simple-format stream res)))

Mmm?

Copy link
Member

@vlad-km vlad-km left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(defun function-lambda-list (function)
  "Return the lambda-list of FUNCTION."
      (read-from-string (oget (fdefinition function) "lambdalist") nil))

Mmm?

"Return the lambda-list of FUNCTION."
(let ((lambda-list (oget (fdefinition function) "lambdalist")))
(when lambda-list
(read-from-string lambda-list))))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned in the comments, this feels a bit weird.
We could just dump the lambda-list with literal from the compiler I guess so there is no need to re-read it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I dumped it as a string. I'm not expert on the compiler internals.

@mmontone
Copy link
Author

mmontone commented Sep 2, 2022

May be

(defun function-object-printer (form stream)
  (let ((res)
	      (fname (oget form "fname"))
        (ll-form (function-lambda-list form)))
    (setq res (concat (if fname "#<FUNCTION " "#<LAMBDA ")
		                        (if fname 
                                            fname 
                                            "")
		                        (if ll-form
			                    (princ-to-string ll-form)
                                            "()")
		             ">"))
    (simple-format stream res)))

Mmm?

I should revert that. I was playing a bit with the printing of lambda expressions. In SBCL for example, the lambda list is printed: #<FUNCTION (LAMBDA (X Y)) {5400B62B}>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants