Emacs Lisp: Standard way to verify tree structures? - data-structures

In emacs lisp, various tree structures are common. custom.el provides through the :type argument to defcustom a standard way to define the expected shape of customization variables. But is there a standard way to verify the structure of some random emacs lisp value?
Lets say, I have a list of the form
LIST = (ENTRY ...)
ENTRY = (NAME . ((1 VAL1) (2 VAL2) ...))
can I somehow define that structure similiar to a customization type and then check against that structure definition?

In file lisp/wid-edit.el there is this function:
(defun widget-type-match (widget value)
"Non-nil if the :type value of WIDGET matches VALUE.
The value of the :type attribute should be an unconverted widget type."
(widget-apply (widget-convert (widget-get widget :type)) :match value))
which you can adapt to your needs:
(defun my-type-match (type value)
(widget-apply (widget-convert type) :match value))
(my-type-match 'string "foo")
==> t
(my-type-match 'string 10)
==> nil
(my-type-match '(choice (const 1) (const 2) (const t)) 10)
==> nil
(my-type-match '(choice (const 1) (const 2) (const t)) 2)
==> t

Related

Understanding parentheticals on let

I'm having a hard time understanding the syntax of let vs some of the other statements. For example, a "normal" statement has one parentheses:
(+ 2 2)
$2 = 4
Yet the let statement has two:
(let ((x 2)) (+ x 2))
$3 = 4
Why is this so? I find it quite confusing to remember how many parentheses to put around various items.
Firstly, note that let syntax contains two parts, both of which can have zero or more elements. It binds zero or more variables, and evaluates zero or more forms.
All such Lisp forms create a problem: if the elements are represented as a flat list, there is an ambiguity: we don't know where one list ends and the other begins!
(let <var0> <var1> ... <form0> <form1> ...)
For instance, suppose we had this:
(let (a 1) (b 2) (print a) (list b))
What is (print a): is that the variable print being bound to a? Or is it form0 to be evaluated?
Therefore, Lisp constructs like this are almost always designed in such a way that one of the two lists is a single object, or possibly both. In other words: one of these possibilities:
(let <var0> <var1> ... (<form0> <form1> ...))
(let (<var0> <var1> ...) (<form0> <form1> ...))
(let (<var0> <var1> ...) <form0> <form1> ...)
Traditional Lisp has followed the third idea above in the design of let. That idea has the benefit that the pieces of the form are easily and efficiently accessed in an interpreter, compiler or any code that processes code. Given an object L representing let syntax, the variables are easily retrieved as (cadr L) and the body forms as (cddr L).
Now, within this design choice, there is still a bit of design freedom. The variables could follow a structure similar to a property list:
(let (a 1 b 2 c 3) ...)
or they could be enclosed:
(let ((a 1) (b 2) (c 3)) ...)
The second form is traditional. In the Arc dialect of Lisp designed Paul Graham, the former syntax appears.
The traditional form has more parentheses. However, it allows the initialization forms to be omitted: So that is to say if the initial value of a variable is desired to be nil, instead of writing (a nil), you can just write a:
;; These two are equivalent:
(let ((a nil) (b nil) (c)) ...)
(let (a b c) ...)
This is a useful shorthand in the context of a traditional Lisp which uses the symbol nil for the Boolean false and for the empty list. We have compactly defined three variables that are either empty lists or false Booleans by default.
Basically, we can regard the traditional let as being primarily designed to bind a simple list of variables as in (let (a b c) ...) which default to nil. Then, this syntax is extended to support initial values, by optionally replacing a variable var with a (var init) pair, where init is an expression evaluated to specify its initial value.
In any case, thanks to macros, you can have any binding syntax you want. In more than one program I have seen a let1 macro which binds just one variable, and has no parentheses. It is used like this:
(let1 x 2 (+ x 2)) -> 4
In Common Lisp, we can define let1 very easily like this:
(defmacro let1 (var init &rest body)
`(let ((,var ,init)) ,#body))
If we restrict let1 to have a one-form body, we can then write the expression with obsessively few parentheses;
(let1 x 2 + x 2) -> 4
That one is:
(defmacro let1 (var init &rest form)
`(let ((,var ,init)) (,#form)))
Remember that let allows you to bind multiple variables. Each variable binding is of the form (variable value), and you collect all the bindings into a list. So the general form looks like
(let ((var1 value1)
(var2 value2)
(var3 value3)
...)
body)
That's why there are two parentheses around x 2 -- the inner parentheses are for that specific binding, the outer parentheses are for the list of all bindings. It's only confusing because you're only binding one variable, it becomes clearer with multiple variables.

Emacs lisp, how to dynamically create quoted expression including special chars like `?1`?

I would like to dynamically create a list of chars to use with read-char-choice. From this answer of similar question, how to construct the list programmatically with unquoted values as choices, ?1 with a function. The function that I ended up is
(defun prompt-list (name-list)
"docstring"
(let ((names name-list)
(name-num 1)
(choice-list (list)))
(dolist (x names)
(add-to-list 'choice-list
`(,name-num ;; in that part how to create the ?1, ?2 but dynamically
,x (lambda () (setq project-headers x))))
(setq name-num (+ 1 name-num)))
choice-list))
when I try to run it it returns error : Format specifier doesn’t match argument type.
In my understanding it need a char type, so my question is how to produce char types programmatically?
?1 is the read syntax for the character '1', which has the integer value 49. You can use the read syntax to initialize your name-num variable, rather than using the integer 1:
(defun prompt-list (name-list)
"docstring"
(let ((names name-list)
(name-num ?1)
(choice-list (list)))
(dolist (x names)
(add-to-list 'choice-list `(,name-num
,x (lambda () (setq project-headers ',x)))
t)
(setq name-num (+ 1 name-num)))
choice-list))
A couple of things to note:
You want the use ,x when setting project-headers, not just x, as the latter won't be valid by the time the lambda is invoked.
You want to append to choice-list as you build it, which is what the final t argument to add-to-list above does, otherwise your read-char-choice prompt will be in reverse order.

how to use structure member types for hashing?

I am porting a hashing code for XDR communication, so It needs to hash the data type to send it. Types should be uint8 sint8, uint16, sint16, ... , sint64
;; lisp types -- byte := bit
(deftype uint8 () '(UNSIGNED-BYTE 8))
(deftype sint8 () '(SIGNED-BYTE 8)) ;
(deftype uint16 () '(UNSIGNED-BYTE 16))
(deftype sint16 () '(SIGNED-BYTE 16))
(deftype uint32 () '(UNSIGNED-BYTE 32))
(deftype sint32 () '(SIGNED-BYTE 32))
(deftype uint64 () '(UNSIGNED-BYTE 64))
(deftype sint64 () '(SIGNED-BYTE 64))
"I am using SBCL"
The data is stored in a structure with types specified
Problems:
When the data is 0 or 1 it gets type bit which fits in all -fixnum, unsigned-byte, signed-byte- types.
Types size inference!! for signed and unsigned
Types use type hierarchy, so I can't have unique types.
I only use types for hashing the structure with (etypecase, subtypep)
I have read Xdr-Binding-to-Lisp, but I don't understand how they used case or typecase to differ between uint8 and sint8. drx on github uses encode_int, encode_array, ...
What I want:
(defstruct example
(x 0 :type lcm:sint32)
(y "blablabla" :type string)
(z 1.8d0 :type double-float))
quickly hash the structure slots information using (etypecase, subtypep).
EDIT:
I want to hash lisp-structure TYPE SLOTS "string sint8 float array" to read the data correctly when received/sent. If I have a struct. st:
(typecase st
(structure-object (recursive do this))
(sint8 (do this))
(string (recursive do this))
(uint8 ( do this))
...
I use typecase to recursively convert type info. ---> integer
The following is the code for structure definition:
(defvar *struct-types* (make-array 0
:adjustable t
:fill-pointer 0))
(defmacro deflcmstruct (name options &rest slots)
"Define a struct"
(let ((slot-types '()))
`(progn
(defstruct (,name (:include lcm-type options))
,#(mapcar (lambda (slot)
(destructuring-bind (slot-name slot-type &rest slot-args)
slot
()
(declare (ignore slot-type))
`(,slot-name ,#slot-args)))
slots))
,(vector-push-extend *struct-types* name)
,(vector-push-extend *struct-types* (make-hash-table))
Questions:
If a lisp structure has a slot with number say: 5 how to make lisp understand 5 type uniquely as sint8/uint8/sin16/uint16, but not fit all these types only one?
How can I hash data types(custom) using lisp?
If I have to store the type def. then What are options to do so?? I am think of building a hash-table using gensym, but this hash-table would be floating around!!
How to make data-type structure isolated?or better a better design?
Examples would be great.
THANKS IN ADVANCE
Here’s an example of how you might do it:
(defgeneric generic-hash (object))
(defmethod generic-hash ((x integer))
(error “GENERIC-HASH does not work on integers as it does not know what size field to put them in.”))
(defun hash-for-type (type)
;; could also be done with a hash table
(case type
(uint8 'hash-uint8)
;; ...
(otherwise 'generic-hash)))
(defun hash-function-for-struct-definition (var name slots)
(flet ((access (sym)
(intern (concatenate 'string (symbol-name name) "-" (symbol-name sym)) (symbol-package sym))))
(let ((hashed-slots
(loop for slot in slots collect
(let ((type (etypecase slot (symbol t) (cons (or (getf :type slot) t))))
(name (if (consp slot) (car slot) slot)))
(list (hash-for-type type) (list (access name var)))))))
(reduce (lambda (a b) (list 'combine-hash a b)) hashed-slots))))
(defmacro my-defstruct (name &rest slots)
(let* ((var (gensym)) (hash (hash-function-for-struct-definition var name slots)))
`(progn
(defstruct ,name ,#slots)
(defmethod generic-hash ((,var ,name))
,hash))))
The trick is that although you can’t tell what type a field is by the value in it, you do get the types at structure definition time and so you can define your own defstruct-like macro which, knowing the types of the fields, can generate suitable methods based on the declared types. A second way to do this would be at runtime by inspecting the class of the object but that would be quite slow in comparison and the compiler probably wouldn’t be able to optimize that at all.

What is the Common Lisp equivalent of the Scheme default-object? [duplicate]

This question already has an answer here:
Distinguish &optional argument with default value from no value
(1 answer)
Closed 6 years ago.
I am converting some Scheme code to Common Lisp. I don't know Scheme. I know a bit of Common Lisp.
Here is the Scheme code:
(define (close-enuf? h1 h2 #!optional tolerance scale)
(if (default-object? tolerance)
...))
I converted that Scheme code to this Common Lisp:
(defun close-enuf? (h1 h2 &optional tolerance scale)
(if (xxx tolerance)
...))
Aside from xxx, does that look right?
Now, with regard to xxx, what is the Common Lisp equivalent for default-object?
I found this definition of default-object?:
The predicate default-object?, which is true only of default objects, can be used to determine which optional parameters were supplied, and which were defaulted.
I'm not sure what that is saying. Is it saying that default-object? returns true if the argument's value is the default value (not a passed-in value)?
This is covered in the Ordinary Lambda Lists section of the specification:
lambda-list::=
(var*
[&optional {var | (var [init-form [supplied-p-parameter]])}*]
[&rest var]
[&key {var | ({var | (keyword-name var)} [init-form [supplied-p-parameter]])}* [&allow-other-keys]]
[&aux {var | (var [init-form])}*])
The &optional arguments can be single symbols or a list with two or three elements.
In that case, the second value is the default value.
The third value names a variable which holds a boolean value: it is true if and only if the value bound to var was supplied by the caller.
Otherwise, a NIL indicates that the value is the default one.
For example:
(defun foo (&optional (x 1 xp))
(list x xp))
With no argument supplied:
(foo)
=> (1 nil)
With an explicit argument:
(foo 2)
=> (2 T)
With an argument that is indistinguishable from the default value:
(foo 1)
=> (1 T)
In your case, that would be:
(defun close-enough-p (h1 h2 &optional (tolerance nil tolerance-p) scale)
(if tolerance-p
<supplied>
<default>))
Note that the same goes for &key arguments.

Differentiating between characters and Integers in Lisp

I have a list in Lisp which I am sorting through, and I want to make an if statement that checks if the current object in the list is a character or an integer.
Is there something like:
(if (EQUAL currentObject char)
...)
Or
(if (EQUAL currentObject integer)
...)
That I can use??
Many thanks.
There are various ways to determine, which kind of object you have at hand.
(typep EXPR 'character) ;; ==> True, if EXPR evaluates to a character
(characterp EXPR) ;; ==> ------------ " -----------------------
(typep EXPR 'integer) ;; ==> True, if EXPR evaluates to an integer
(integerp EXPR) ;; ==> ------------ " -----------------------
Have a look at the definition of typep, typecase, characterp, ...
(loop
for element in list
do (typecase element
(integer #| element is an integer number ... |#)
(character #| element is a character object ... |#)
(t #| element is something not covered above |#)))
For many built-in types, there are predicate functions available, which can be used in to test, whether a particular value is an instance of that type. Often, these predicates are named after their base type's names, with a "p" appended ("stringp", "symbolp", "numberp", "consp", ...)

Resources