Suppose I have this struct:
(struct pos (x y))
I can create instances of this struct using:
(pos 1 2)
Suppose I want to use keyword arguments instead. For example:
(pos #:x 1 #:y 2)
This results in an error:
> (pos #:x 1 #:y 2)
; application: procedure does not accept keyword arguments
; procedure: pos
; [,bt for context]
How can I use keyword arguments when creating instances of structs?
You can't do that with native struct, so you either have to roll your own constructor as #tfb suggests, or use third-party libraries that provide this feature.
https://docs.racket-lang.org/struct-plus-plus/
https://docs.racket-lang.org/rebellion/Record_Types.html
Related
In regular Racket, ((curry * 2) 3) works as expected, with 6 as a result.
However, in Typed Racket:
> ((curry * 2) 3)
; readline-input:3:0: Type Checker: could not apply function;
; wrong number of arguments provided
; expected: 0
; given: 1
; in: ((curry * 2) 3)
; [,bt for context]
Why?
I believe it has something to do with the fact that * can take only one argument, so when you curry it with a parameter, it is returning a procedure that takes no additional arguments. Type (curry * 2) at the command line in typed/racket and observe the result: (-> Number).
Note that there is only a return type and no parameter. I don't see a way around this in typed racket, but I hope that at least explains why it is happening. You should be safe to use currying with more complex procedures as long as they do not have an option to take only one parameter.
I have the following structures:
(defstruct track
size
env
startpos
endpositions)
(defstruct state
pos
vel
action
cost
track
other)
I have a state and Im trying to access endpositions(list of lists)
(setq coluna_final (nth 1 (nth 0 (state-track-endpositions st))))
but I get the error: EVAL: undefined function STATE-TRACK-ENDPOSITIONS
What am I doing wrong?
The first defstruct defines (inter alia) function track-endpositions, and the second defines state-track. Lisp has no way to know that the latter returns a track (even if you declare the slot type, it will not define the function you want).
You can do it yourself:
(defun state-track-endpositions (st)
(track-endpositions (state-track st)))
I want to create a lisp function which corresponds to a macro in C.
e.g., there is one HIWORD in win32 API, which is defined as a macro in the header file.
I tried to define it as below but was told that HIWORD is unresolved.
CL-USER 4 > (hiword #xFFFFFFFF)
Error: Foreign function HIWORD trying to call to unresolved external function "HIWORDW".
I just want to know how to create a wrapper for C macros like for C functions.
(fli:define-c-typedef DWORD (:unsigned :long))
(fli:define-c-typedef WORD (:unsigned :short))
(fli:define-foreign-function
(HIWORD "HIWORD" :dbcs)
((dwVal dword))
:result-type word :calling-convention :stdcall)
You cannot do this directly. C preprocessor macros are not preserved in the compilation process, i.e., there is simply no artifact in the generated object files, which would correspond to the C macro itself (though its expansion may be part of the object file multiple times). And since there is no artifact, there is nothing to bind to with FFI.
You can, however, provide a wrapper function
#define HIGHWORD(x) /* whatever */
int
highword_wrapper(int x)
{
return HIGHWORD(x);
}
and this one can be used with FFI.
No need to jump into another language. Shifting and masking in Lisp:
(defun hiword (val)
(logand (ash val -16) #xFFFF)
(defun loword (val) ;; ditto
(logand val #xFFFF))
Another way: using the ldb accessor with ranges expressed using byte syntax:
(defun hiword (val)
(ldb (byte 16 16) val) ;; get 16-bit-wide "byte" starting at bit 16.
(defun loword (val)
(ldb (byte 16 0) val) ;; get 16-bit-wide "byte" at position 0.
I read sbcl manual,and have a problem at the 8.5 Foreign Data Structure Examples chapter.
I use following examples to verify whether it can run correct.
_______________________________________________________________
Or consider this example of an external C variable and some accesses:
struct c_struct {
short x, y;
char a, b;
int z;
c_struct *n;
};
extern struct c_struct *my_struct;
my_struct->x++;
my_struct->a = 5;
my_struct = my_struct->n;
which can be manipulated in Lisp like this:
(define-alien-type nil
(struct c-struct
(x short)
(y short)
(a char)
(b char)
(z int)
(n (* c-struct))))
(define-alien-variable "my_struct" (* c-struct))
(incf (slot my-struct 'x))
(setf (slot my-struct 'a) 5)
(setq my-struct (slot my-struct 'n))
________________________________________________________________
Now I run above example code on slime,and it signaled a error.
unknown alien type: C-STRUCT
[Condition of type SIMPLE-ERROR]
Restarts:
0: [RETRY] Retry SLIME REPL evaluation request.
1: [ABORT] Return to sldb level 7.
2: [RETRY] Retry SLIME REPL evaluation request.
3: [ABORT] Return to sldb level 6.
4: [RETRY] Retry SLIME REPL evaluation request.
5: [ABORT] Return to sldb level 5.***
What should I do to define such a struct that can contain it's self point.
Note that the manual also says:
Types may be either named or anonymous. With structure and union types, the name is part of the type specifier, allowing recursively defined types such as:
(struct foo (a (* (struct foo))))
I haven't used SBCL's FFI, but I'd guess that means that you should use:
(define-alien-variable "my_struct" (* (struct c-struct)))
I'm trying to make racket bindings for libgphoto2. Its API uses CameraText struct for outputting strings, which just wraps char array.
My first attempt was:
(define _Camera-ptr (_cpointer 'Camera))
(define _CameraText-ptr (_cpointer 'CameraText))
(define-gphoto gp_camera_get_about
(_fun _Camera-ptr (v : _CameraText-ptr) _GPContext-ptr
-> _int))
But this was giving me segfaults (not to mention the pointer here is opaque and there are no getter functions in API).
Later on I've stumbled across https://github.com/dyoo/ffi-tutorial/blob/master/ffi/tutorial/examples/struct-with-array/struct-with-array.rkt so I've tried this:
(define _Camera-ptr (_cpointer 'Camera))
(define camera-text-size (* 32 1024))
(define-cstruct _CameraText ([text (_bytes/len camera-text-size)]))
(define-gphoto gp_camera_get_about
(_fun _Camera-ptr (v : _CameraText-pointer) _GPContext-ptr
-> _int))
(Where bytes/len is helper taken from that example)
How can I initialize this struct to mimic C CameraText txt;? Is there some better way to handle char arrays (and converting them to strings) than _byte array? Or should I go with something like:
(define-cstruct _CameraText ([text _string]))